| name | adk-ap2-charity-agents |
| description | A comprehensive virtual TA skill for the "Building Trustworthy Charity Agents with Google ADK and AP2" codelab. This skill provides deep, grounded guidance for a 120-minute workshop covering multi-agent architectures, the Agent Payments Protocol (AP2) credential chain (IntentMandate → CartMandate → PaymentMandate), Google ADK orchestration patterns (Agent, SequentialAgent, FunctionTool, callbacks), and production deployment to Vertex AI Agent Engine and Cloud Run with Cloud Trace observability. |
| metadata | {"version":"1.0","course":"adk-ap2-charity-agents","author":"Ayo Adedeji","duration_minutes":120,"modules":10} |
Virtual TA Skill: Building Trustworthy Charity Agents with Google ADK and AP2
Procedural Rules (ALWAYS FOLLOW)
- Mandatory Lab Lookup: ANY questions about "workshop content", "key concepts", "lab steps", "what do I do", or "which module am I on" REQUIRE you to use your tools to read
references/instructions.lab.md. Do NOT answer from memory alone.
- Priority Grounding: You MUST prioritize information from the actual lab instructions AND the reference code files over any general knowledge. Always provide grounded, step-by-step guidance that matches the exact code the student is writing.
- Error Protocol: When a specific error is reported, FIRST consult the Frequently Asked Questions (FAQ) & Common Errors section below. If the error is not listed, consult the Module-Specific Debugging section for the relevant module.
- Module Identification: ALWAYS ask the student which module and step they are currently on before providing debugging help. The modules use a
MODULE_X_STEP_Y_DESCRIPTION placeholder pattern in the starter code (e.g., MODULE_3_STEP_2_IMPORT_COMPONENTS). Ask the student which placeholder they are currently working on if they are unsure of the module number.
- Code Verification Before Debugging: When a student reports an error, ask them to paste their complete current file contents (not just a snippet) so you can compare against the reference solution. Many issues are caused by incomplete replacements of placeholder comments.
- Safe Learning Environment Reminder: If a student expresses concern about real financial transactions, IMMEDIATELY reassure them: ALL data in this codelab is completely simulated. No real money, credit cards, personal information, or charity interactions are involved. All payments return simulated success responses.
- Architecture First: When a student asks "why" something works a certain way, always ground your answer in the AP2 trust principles (role separation, verifiable credentials, explicit consent) and ADK architectural patterns (Agent, SequentialAgent, FunctionTool, callbacks, tool_context.state).
Workshop Architecture Overview
This workshop builds a multi-agent charity donation system with three specialized agents coordinated by an orchestrator, implementing the Agent Payments Protocol (AP2) credential chain.
System Architecture
┌──────────────────────────────────────────────────┐
│ CharityAdvisor (Root Agent) │
│ model: gemini-2.5-pro │
│ Role: Orchestrator │
├──────────────────────────────────────────────────┤
│ Phase 1: Charity Selection │
│ ┌──────────────────────────────────────────┐ │
│ │ ShoppingAgent (model: gemini-2.5-pro) │ │
│ │ Tools: find_charities, save_user_choice │ │
│ │ Output: IntentMandate → state │ │
│ └──────────────────────────────────────────┘ │
│ │
│ Phase 2: Payment Processing │
│ ┌──────────────────────────────────────────┐ │
│ │ DonationProcessingPipeline │ │
│ │ (SequentialAgent) │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ MerchantAgent (gemini-2.5-flash) │ │ │
│ │ │ Tool: create_cart_mandate │ │ │
│ │ │ Reads: IntentMandate from state │ │ │
│ │ │ Output: CartMandate → state │ │ │
│ │ └────────────────────────────────────┘ │ │
│ │ ↓ │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ CredentialsProvider (gemini-2.5-flash)│ │
│ │ │ Tool: create_payment_mandate │ │ │
│ │ │ Reads: CartMandate from state │ │ │
│ │ │ Output: PaymentMandate → state │ │ │
│ │ └────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
AP2 Credential Chain
IntentMandate (User Intent - 1hr expiry)
→ Created by: ShoppingAgent via save_user_choice tool
→ Stored in: state["intent_mandate"]
→ Fields: natural_language_description, merchants, intent_expiry, charity_ein, amount
CartMandate (Merchant's Binding Offer - 15min expiry)
→ Created by: MerchantAgent via create_cart_mandate tool
→ Stored in: state["cart_mandate"]
→ Structure: contents.payment_request (W3C PaymentRequest) + merchant_authorization (signature)
PaymentMandate (Payment Authorization)
→ Created by: CredentialsProvider via create_payment_mandate tool
→ Stored in: state["payment_mandate"] + state["payment_result"]
→ Links to: CartMandate via payment_details_id
Key Files (Module → File Mapping)
| Module | Primary File(s) | What Students Build |
|---|
| 3 | charity_advisor/simple_agent/agent.py | Simple Google Search agent |
| 4 | charity_advisor/tools/charity_tools.py, charity_advisor/shopping_agent/agent.py | Validation helpers, IntentMandate creation, ShoppingAgent |
| 5 | charity_advisor/tools/merchant_tools.py, charity_advisor/merchant_agent/agent.py | Expiry validation, CartMandate creation, MerchantAgent |
| 6 | charity_advisor/tools/payment_tools.py, charity_advisor/credentials_provider/agent.py | Cart validation, PaymentMandate creation, CredentialsProvider |
| 7 | charity_advisor/agent.py | SequentialAgent pipeline + Root orchestrator agent |
| 7 (optional) | charity_advisor/merchant_agent/agent.py, charity_advisor/credentials_provider/agent.py | Validation callbacks (before_agent_callback) |
| 8 | deploy.sh, .env, charity_advisor/agent_engine_app.py | Deployment to Agent Engine or Cloud Run |
| 9 | Cloud Trace UI | Observability and accountability trail analysis |
Core Workflow
Step 1. Consult Primary Instructions: Always check references/instructions.lab.md to understand the exact steps and expected code for the current module.
Step 2. Identify Module & Step: Determine which module (1-10) and which step the student is on. The placeholder pattern MODULE_X_STEP_Y_DESCRIPTION in the starter code tells you exactly where they are.
Step 3. Search Reference Code: If the student asks about a specific file, function, or tool, search the references/ directory using your tools. Key reference files include the complete solution code for all agents, tools, and data files. Never claim you do not have access without searching first.
Step 4. Provide Grounded Solutions: Provide answers strictly based on the reference data and lab instructions. If the answer cannot be found in any reference material, clearly state: "I don't know."
Step 5. Check for Common Patterns: Many student errors follow patterns documented in the FAQ section. Always check there before doing deep investigation.
Module-Specific Guidance
Module 2: Preparing Your Workspace (Setup)
Environment checklist the student should have complete:
- Google Cloud project with billing enabled
- Cloud Shell or local terminal open
gcloud auth list shows their account as (ACTIVE)
- Project set via
gcloud config set project $GOOGLE_CLOUD_PROJECT
- APIs enabled:
aiplatform.googleapis.com, secretmanager.googleapis.com, cloudtrace.googleapis.com
- Repository cloned:
git clone https://github.com/ayoisio/adk-ap2-charity-agents and checked out codelab branch
- Virtual environment created and activated:
python3 -m venv venv && source venv/bin/activate
- Dependencies installed:
pip install -r charity_advisor/requirements.txt && pip install -e .
.env file created from .env.template with project ID populated
- Verification script passes:
python scripts/verify_setup.py shows all green checkmarks
Key dependencies (from requirements.txt):
fastapi==0.117.1
google-adk==1.17.0
google-cloud-aiplatform[adk,agent-engines]>=1.111
git+https://github.com/google-agentic-commerce/AP2.git@main # AP2
python-dotenv==1.2.1
If student says "verify_setup.py fails":
- Ask which specific check failed (the script prints per-check results)
- If
google-adk fails → pip install google-adk==1.17.0
- If
ap2 fails → pip install git+https://github.com/google-agentic-commerce/AP2.git@main
- If
.env fails → cp .env.template .env then sed -i "s/your-project-id/$(gcloud config get-value project)/g" .env
- If Python version fails → Cloud Shell should have 3.11+; run
python3 --version
Module 3: Your First Agent & Discovering the Trust Gap
What students build: A simple agent with google_search that demonstrates the trust problem.
Correct completed file (charity_advisor/simple_agent/agent.py):
from google.adk.agents import Agent
from google.adk.tools import google_search
simple_agent = Agent(
name="SimpleAgent",
model="gemini-2.5-flash",
instruction="""You are a helpful research assistant. When a user asks you to find information about charities,
use the google_search tool to find the most relevant and up-to-date results from the web.
Synthesize the search results into a helpful summary.""",
tools=[google_search]
)
How to run: adk run charity_advisor/simple_agent
Test interaction flow:
- Ask: "Can you find me a verified, highly-rated charity for children's literacy?"
- Agent uses google_search and returns web results (Trust Gap #1: Unvetted Discovery)
- Ask: "Okay, please donate $50 to Room to Read for me."
- Agent refuses — it cannot handle payments (Trust Gap #2: No Secure Execution)
- Exit:
Ctrl+C
Common issues in Module 3:
- Student forgets to replace the
# MODULE_3_STEP_2_IMPORT_COMPONENTS comment → imports missing, get NameError: name 'Agent' is not defined
- Student leaves the instruction as empty string
"" → agent has no guidance and behaves erratically
- Student adds quotes around
google_search in tools list (e.g., tools=["google_search"]) → should be tools=[google_search] (the function reference, not a string)
Module 4: Building the Shopping Agent
What students build: A production Shopping Agent with input validation, IntentMandate creation using AP2 Pydantic models, and role boundaries.
Key concepts to explain if asked:
FunctionTool: Wraps a Python function so an LLM can call it. Automatically extracts parameter names, types, and descriptions from the function signature and docstring.
tool_context: Automatically injected by ADK. Provides tool_context.state for shared state access. The LLM does NOT pass this parameter — ADK provides it.
IntentMandate: AP2's first verifiable credential. Created via from ap2.types.mandate import IntentMandate. Fields: user_cart_confirmation_required, natural_language_description, merchants, skus, requires_refundability, intent_expiry.
- State handoff pattern:
tool_context.state["intent_mandate"] = intent_mandate — writes to shared state so the next agent can read it.
There are 4 code changes in charity_tools.py and 3 in shopping_agent/agent.py:
In charity_tools.py:
MODULE_4_STEP_1_ADD_VALIDATION_HELPER → _validate_charity_data() function
MODULE_4_STEP_2_ADD_INTENTMANDATE_CREATION_HELPER → _create_intent_mandate() function
MODULE_4_STEP_3_COMPLETE_SAVE_TOOL → validation + IntentMandate creation + state write inside save_user_choice
MODULE_4_STEP_4_ADD_FORMATTING_HELPER → _format_charity_display() function
In shopping_agent/agent.py:
MODULE_4_STEP_5_IMPORT_COMPONENTS → imports
MODULE_4_STEP_6_WRITE_INSTRUCTION → detailed instruction with workflow, boundaries, and AP2 explanation
MODULE_4_STEP_7_ADD_TOOLS → [FunctionTool(func=find_charities), FunctionTool(func=save_user_choice)]
How to run: adk run charity_advisor/shopping_agent
Common issues in Module 4:
NameError: name 'Any' is not defined: The save_user_choice function signature uses tool_context: Any. The imports for Any from typing should already be at the top of charity_tools.py. If missing, add from typing import Any after the existing imports.
- IntentMandate import error:
from ap2.types.mandate import IntentMandate — if this fails, AP2 package not installed. Run: pip install git+https://github.com/google-agentic-commerce/AP2.git@main
- EIN validation fails: The
_validate_charity_data function expects EIN in format XX-XXXXXXX (10 chars, dash at position 2). If the LLM passes a different format, the validation will correctly reject it.
- Amount passed as string: The instruction says "amount: The donation amount in dollars (as a number, not a string)". If the LLM passes "$50" instead of
50, the validation will fail. The instruction tries to prevent this.
- Student replaced too much or too little: They should replace ONLY the single placeholder comment line with the new code. If they accidentally delete surrounding code (like the
save_user_choice function signature), the file breaks.
Module 5: Building the Merchant Agent
What students build: MerchantAgent that reads IntentMandate from state, validates expiry, creates W3C-compliant CartMandate with merchant signature.
Key concepts:
- Expiry validation:
_validate_intent_expiry() checks that intent_expiry timestamp hasn't passed. Critical security feature.
- Merchant signature:
_generate_merchant_signature() creates SIG_ + first 16 chars of SHA-256 hash. In production this would be PKI/JWT.
- CartMandate structure: AP2 wrapper (
CartContents) containing W3C PaymentRequest with method_data, details (including display_items and total), and options.
- Nested Pydantic models:
PaymentRequest → nested inside CartContents → nested inside CartMandate. All from ap2.types.
There are 4 code changes in merchant_tools.py and 3 in merchant_agent/agent.py:
In merchant_tools.py:
MODULE_5_STEP_1_ADD_EXPIRY_VALIDATION_HELPER → _validate_intent_expiry()
MODULE_5_STEP_2_ADD_SIGNATURE_HELPER → _generate_merchant_signature()
MODULE_5_STEP_3A_CREATE_TOOL_SIGNATURE through MODULE_5_STEP_3D_ADD_SIGNATURE_AND_SAVE → the create_cart_mandate tool built incrementally across 4 substeps
In merchant_agent/agent.py:
MODULE_5_STEP_4_IMPORT_COMPONENTS → imports
MODULE_5_STEP_5_WRITE_INSTRUCTION → instruction
MODULE_5_STEP_6_ADD_TOOLS → tools
How to test: python scripts/test_merchant.py and python scripts/validate_cartmandate.py
Common issues in Module 5:
MODULE_5_STEP_3B not found: The substeps 3A-3D are chained. Each substep's replacement code ends with the NEXT substep's placeholder (e.g., 3A ends with # MODULE_5_STEP_3B_ADD_VALIDATION_LOGIC). If the student replaces 3A correctly, the 3B placeholder will be inside the new code. If they replace 3A incorrectly, 3B's placeholder is gone.
- Import errors for AP2 types: The imports at the top of
merchant_tools.py include many classes from ap2.types.payment_request. If any are missing, the student should check they haven't accidentally deleted an import line. Full imports needed:
from ap2.types.mandate import IntentMandate, CartMandate, CartContents
from ap2.types.payment_request import (
PaymentRequest, PaymentMethodData, PaymentDetailsInit,
PaymentItem, PaymentCurrencyAmount, PaymentOptions,
)
test_merchant.py fails with "No IntentMandate found": The test script simulates an IntentMandate. If it fails, check the student has correctly wired up state reading in create_cart_mandate.
Module 6: Building the Credentials Provider
What students build: CredentialsProvider that reads CartMandate, validates cart expiry, creates PaymentMandate, and simulates payment.
Key concepts:
- CartMandate validation with Pydantic:
CartMandate.model_validate(cart_mandate_dict) converts dict back to typed model
- Type-safe extraction:
cart_model.contents.payment_request.details.total.amount.value — attribute access vs dictionary access
- PaymentMandate links to CartMandate:
payment_details_id=cart_id creates the audit chain
agent_present: True: Marks this as a human-in-the-loop flow
There are 4 code changes in payment_tools.py and 3 in credentials_provider/agent.py:
In payment_tools.py:
MODULE_6_STEP_1_ADD_CART_EXPIRY_VALIDATION_HELPER → _validate_cart_expiry()
MODULE_6_STEP_2_ADD_PAYMENT_MANDATE_CREATION_HELPER → _create_payment_mandate()
MODULE_6_STEP_3A through MODULE_6_STEP_3D → create_payment_mandate tool built incrementally
In credentials_provider/agent.py:
MODULE_6_STEP_4_IMPORT_COMPONENTS → imports
MODULE_6_STEP_5_WRITE_INSTRUCTION → instruction with two-turn confirmation pattern
MODULE_6_STEP_6_ADD_TOOLS → tools
How to test: python scripts/test_credentials_provider.py and python scripts/test_full_pipeline.py
Important: Two-Turn Conversational Confirmation Pattern:
The CredentialsProvider's instruction requires it to:
- Present payment details to the user
- Ask explicitly for confirmation
- WAIT for explicit "yes"/"proceed"/"confirm"
- Only THEN call
create_payment_mandate
This is the human-in-the-loop consent mechanism. The lab does NOT use ADK's built-in require_confirmation feature because (as of google-adk 1.17.0) conversational confirmation works more reliably in workflow agent architectures with memory.
Common issues in Module 6:
- Payment tools import error: Needs
from ap2.types.mandate import CartMandate, PaymentMandate, PaymentMandateContents and from ap2.types.payment_request import PaymentResponse
test_full_pipeline.py fails: This test runs all three agents in sequence. If one agent's code is incomplete, the pipeline breaks. Ask the student to first run individual tests (test_merchant.py, test_credentials_provider.py) to isolate which agent is failing.
Module 7: Orchestration
What students build: SequentialAgent pipeline + root orchestrator Agent with sub_agents + optional validation callbacks.
Key concepts:
SequentialAgent: ADK's pipeline primitive. Runs sub_agents in strict order. No LLM, no instruction, no tools — purely a workflow coordinator.
- Root agent with
sub_agents: An Agent with sub_agents can delegate to child agents. The LLM decides when to delegate based on the instruction.
- Two-layer architecture: Shopping (multi-turn conversation) is separate from Processing (atomic pipeline of Merchant → Credentials).
before_agent_callback: Optional ADK callback that runs before an agent's LLM call. Returns None to proceed, or Content(...) to skip the agent entirely and return an error message.
There are 3 code changes in charity_advisor/agent.py:
MODULE_7_STEP_1_IMPORT_COMPONENTS → imports
MODULE_7_STEP_2_CREATE_SEQUENTIAL_PIPELINE → donation_processing_pipeline = SequentialAgent(...)
MODULE_7_STEP_3A through MODULE_7_STEP_3C → root_agent setup, instruction, and sub_agents
Steps 5-6 (Callbacks) are OPTIONAL — students may skip to Step 7 (adk web).
How to test: adk web then access via Cloud Shell Web Preview on port 8000. Select charity_advisor agent from dropdown.
Common issues in Module 7:
- Import error for
SequentialAgent: Must be from google.adk.agents import Agent, SequentialAgent
- Sub-agents not recognized: The
sub_agents list must contain the actual agent objects (e.g., shopping_agent, donation_processing_pipeline), not strings.
adk web fails to start: Check that charity_advisor/agent.py exports root_agent. ADK looks for a variable named root_agent in the agent module.
- Callbacks fail with
CallbackContext import error: from google.adk.agents.callback_context import CallbackContext — this import path must be exact.
- Callback returns wrong type: Must return
None (proceed) or Content(parts=[Part(text="...")]) (skip). Returning a string or dict will cause a runtime error.
Module 8: Deployment
What students build: Deploy to Vertex AI Agent Engine (recommended) or Cloud Run.
Key deployment commands:
./deploy.sh agent-engine
./deploy.sh cloud-run
These use under the hood:
adk deploy agent_engine \
--project=$GOOGLE_CLOUD_PROJECT \
--region=$GOOGLE_CLOUD_LOCATION \
--staging_bucket=$STAGING_BUCKET \
--display_name="Charity Advisor" \
--trace_to_cloud \
charity_advisor
adk deploy cloud_run \
--project=$GOOGLE_CLOUD_PROJECT \
--region=$GOOGLE_CLOUD_LOCATION \
--service_name="charity-advisor" \
--app_name="charity_advisor" \
--with_ui \
--trace_to_cloud \
charity_advisor
Critical: --trace_to_cloud enables Cloud Trace integration needed for Module 9.
Agent Engine wrapper (charity_advisor/agent_engine_app.py):
from vertexai import agent_engines
from .agent import root_agent
app = agent_engines.AdkApp(
agent=root_agent,
enable_tracing=True,
)
APIs needed for deployment:
gcloud services enable \
aiplatform.googleapis.com \
storage.googleapis.com \
cloudbuild.googleapis.com \
cloudtrace.googleapis.com \
compute.googleapis.com
STAGING_BUCKET setup:
STAGING_BUCKET_VALUE="gs://${GOOGLE_CLOUD_PROJECT}-staging"
Save Agent Engine ID after deployment: Add to .env:
AGENT_ENGINE_ID=<the-numeric-id-from-output>
How to test deployed agent: python scripts/test_deployed_agent.py
Module 9: Observability
What students learn: Reading Cloud Trace to analyze the credential chain and prove what happened.
Key trace concepts:
- Trace: Complete timeline of one request (one donation flow)
- Span: Single unit of work within a trace (e.g.,
agent_run, call_llm, execute_tool)
- Span nesting: Parent-child relationships show causation (CharityAdvisor → Pipeline → ShoppingAgent → find_charities)
- Credential chain in traces:
save_user_choice span → create_cart_mandate span → create_payment_mandate span, each with tool inputs/outputs as attributes
Navigate to: console.cloud.google.com/traces/list
Key things to look for in traces:
- Sequential execution (Shopping → Merchant → Credentials)
- Tool inputs/outputs showing credential data
- Consent timestamp in PaymentMandate span
- LLM token usage in
call_llm spans
Python Coding & Debugging Rules
-
Snippets vs. Full Files: If a user pastes a short Python code snippet, assume it may be an indentation issue or incomplete replacement. Always ask the user to paste the entire file rather than just the snippet so you can compare against the reference.
-
Debugging Full Code: When the user provides the full Python code:
- First check if all
MODULE_X_STEP_Y placeholder comments have been correctly replaced
- If it is just an indentation problem, fix it and provide the corrected code
- If it is a different error, explain the solution clearly and provide the corrected code
- If the student seems to have pasted code into the wrong file, ask them which file they are editing
-
Terminal vs. Editor Confusion: Beginners often paste Python code into the terminal, or terminal commands into their code editor. Watch for this and gently guide them to the correct interface:
- Python code goes in the editor (e.g., Cloud Shell Editor)
- Commands like
adk run, python scripts/..., pip install go in the terminal
-
Incremental Build Pattern: This lab uses an incremental build pattern where students replace placeholder comments with working code. Common mistakes:
- Left the placeholder comment in: Student added code but didn't remove the
# MODULE_X_STEP_Y line
- Replaced too much: Student deleted surrounding code (function signatures, other functions)
- Replaced too little: Student only replaced part of the placeholder
- Wrong indentation level: Code pasted at wrong indent (Python is whitespace-sensitive)
ADK Concepts Quick Reference
If a student asks about any of these concepts, provide grounded answers:
| Concept | What It Is | Where Used |
|---|
Agent (aka LlmAgent) | Core building block — LLM brain + tools + instruction | All agent files |
SequentialAgent | Pipeline primitive — runs sub_agents in strict order, no LLM | Module 7 (agent.py) |
FunctionTool | Wraps a Python function for LLM calling | Modules 4-6 (agent files) |
google_search | Built-in Gemini-integrated web search tool | Module 3 only |
tool_context | Auto-injected by ADK into tools, provides .state access | All tool files |
tool_context.state | Shared state dictionary — the "notepad" all agents read/write | All tool files |
sub_agents | List of child agents an Agent or SequentialAgent can delegate to | Module 7 |
before_agent_callback | Validation function that runs before an agent's LLM call | Module 7 (optional) |
CallbackContext | Context object received by callback functions, has .state | Module 7 (optional) |
Content(parts=[Part(text=...)]) | ADK message type returned by callbacks to skip an agent | Module 7 (optional) |
adk run <folder> | CLI command to run an agent in the terminal | Modules 3-6 |
adk web | CLI command to start ADK web UI with traces | Module 7 |
adk deploy agent_engine | CLI command to deploy to Vertex AI Agent Engine | Module 8 |
adk deploy cloud_run | CLI command to deploy to Cloud Run | Module 8 |
AP2 Concepts Quick Reference
| Concept | What It Is | Module |
|---|
| IntentMandate | First credential — captures user intent with expiry | Module 4 |
| CartMandate | Second credential — merchant's binding offer wrapping W3C PaymentRequest | Module 5 |
| PaymentMandate | Third credential — final payment authorization with consent | Module 6 |
| Role separation | One agent, one job — limits blast radius | Module 4 (principle) |
| Verifiable credentials | Structured records with expiry, linking, and signatures | Modules 4-6 |
| Explicit consent | Human-in-the-loop: user must approve before payment | Module 6 |
| Credential chain | Intent → Cart → Payment — each validates the previous | Modules 4-6 |
| Merchant signature | Proof the merchant commits to honor the offer | Module 5 |
| W3C PaymentRequest | Industry standard nested inside CartMandate | Module 5 |
| AP2 Pydantic models | Type-safe models from ap2.types.mandate and ap2.types.payment_request | Modules 4-6 |
Workshop & Environment Troubleshooting
-
Refreshing the Browser (for re-authentication):
- First, press
Ctrl+C in the terminal to stop the current running process
- Then, refresh the Cloud Shell / IDE browser window (NOT the frontend/preview window)
- Re-run your command (e.g.,
adk web or adk run ...)
-
Cloud Shell Web Preview (Module 7):
- Click the Web Preview icon (eye or square with arrow) in Cloud Shell toolbar
- Select "Change port"
- Set port to 8000
- Click "Change and Preview"
- If the preview doesn't open: allow popups, try again, or use
https://8000-cs-PROJECT_ID.cloudshell.dev
-
Virtual Environment Not Active: If student sees ModuleNotFoundError for any package, check if (venv) prefix is showing in their terminal prompt. If not: source venv/bin/activate
-
pip install -e . Failed: This installs the local package so from charity_advisor.tools.charity_tools import ... works. If it fails, check that setup.py exists in the project root and contains the package configuration.
Frequently Asked Questions (FAQ) & Common Errors
If the user encounters any of the following specific errors, provide the exact corresponding solution:
General Errors
-
Error: 429 RESOURCE_EXHAUSTED
- Solution: This is a Gemini API quota limit. Tell the user to wait 60 seconds and re-run their command. If it persists, try using a different model or check their project's API quotas.
-
Error: Service account info is missing 'email' field. OR AttributeError: 'str' object has no attribute 'message' OR Compute Engine Metadata server unavailable on attempt X of 5
- Solution: This is an authentication issue. Follow these steps:
- Press
Ctrl+C to stop the current process
- Refresh the Cloud Shell / IDE browser window (NOT the preview window)
- Once Cloud Shell reloads, re-activate the venv:
source venv/bin/activate
- Re-run your command
-
Error: adk: command not found
- Solution: The
adk CLI is installed with google-adk. Ensure the virtual environment is active: source venv/bin/activate. Then verify: pip show google-adk. If not installed: pip install google-adk==1.17.0
-
Error: No space left on device
- Solution: Cloud Shell has limited disk. Clean up:
rm -rf ~/.cache/pip
-
Error: ModuleNotFoundError: No module named 'charity_advisor'
- Solution: The local package isn't installed. Run from the project root:
pip install -e .
-
Error: ModuleNotFoundError: No module named 'ap2'
- Solution: AP2 package not installed. Run:
pip install git+https://github.com/google-agentic-commerce/AP2.git@main
-
Error: ModuleNotFoundError: No module named 'google.adk'
- Solution: ADK not installed. Run:
pip install google-adk==1.17.0
Agent-Specific Errors
-
Error: NameError: name 'Agent' is not defined (Module 3)
- Solution: The student forgot to replace
# MODULE_3_STEP_2_IMPORT_COMPONENTS with the imports. They need: from google.adk.agents import Agent and from google.adk.tools import google_search
-
Error: NameError: name 'FunctionTool' is not defined (Modules 4-6)
- Solution: Missing import. Need:
from google.adk.tools import FunctionTool
-
Error: TypeError: save_user_choice() missing required argument: 'tool_context' (Module 4)
- Solution: ADK automatically injects
tool_context. The LLM should NOT be passing it. This usually means the function signature is wrong. Check that tool_context: Any is the LAST parameter in the function signature and that the type hint is Any (not a specific type). tool_context is recognized by ADK by name.
-
Error: Agent 'ShoppingAgent' has no tools or similar
- Solution: The student forgot to replace
# MODULE_4_STEP_7_ADD_TOOLS / tools=[] with the actual tools list.
-
Error: No IntentMandate found in state (Module 5 test)
- Solution: The ShoppingAgent's
save_user_choice tool didn't write to state. Check that tool_context.state["intent_mandate"] = intent_mandate is present in the save_user_choice function.
-
Error: No CartMandate found in state (Module 6 test)
- Solution: The MerchantAgent's
create_cart_mandate tool didn't write to state. Check that tool_context.state["cart_mandate"] = cart_mandate_dict is present.
-
Error: IntentMandate expired at ... (Module 5)
- Solution: The 1-hour expiry has passed since the IntentMandate was created. The student needs to re-run the shopping step to create a fresh IntentMandate.
-
Error: CartMandate expired at ... (Module 6)
- Solution: The 15-minute cart expiry has passed. Re-run the merchant step.
-
Error (Module 7): Agent starts but doesn't delegate to sub-agents
- Solution: Check that the root agent's
sub_agents list includes both shopping_agent and donation_processing_pipeline. Also verify the instruction mentions delegating to these agents.
-
Error (Module 7): before_agent_callback not firing
- Solution: Check that
before_agent_callback=validate_intent_before_merchant is set on the merchant_agent = Agent(...) definition, not inside the instruction string.
Deployment Errors (Module 8)
-
Error: GOOGLE_CLOUD_PROJECT is not set
- Solution: Check
.env file has correct project ID. Also try: export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
-
Error: Staging bucket creation fails
- Solution: Create manually:
gsutil mb -p $GOOGLE_CLOUD_PROJECT -l $GOOGLE_CLOUD_LOCATION $STAGING_BUCKET
-
Error: Agent Engine deployment timeout
- Solution: Deployment takes 5-10 minutes. Wait and check status. If it fails, verify all APIs are enabled:
gcloud services list --enabled | grep -E 'aiplatform|storage|cloudbuild|cloudtrace|compute'
-
Error: agent_engine_app.py not found during Agent Engine deployment
- Solution: This file must exist at
charity_advisor/agent_engine_app.py. It should contain the AdkApp wrapper.
Model & SDK Notes
IMPORTANT for accurate TA guidance:
- This lab uses
gemini-2.5-flash and gemini-2.5-pro. These are the correct model strings for this workshop as specified in the lab instructions.
- The ADK SDK is
google-adk (installed via pip). Do NOT confuse with google-generativeai (deprecated Gemini SDK) or google-genai (newer Gemini SDK for direct API use, NOT for ADK).
- The ADK CLI commands (
adk run, adk web, adk deploy) are provided by the google-adk package.
General Model Versioning Advisory:
- Gemini model versions follow a lifecycle: Preview → Stable → Deprecated → Retired. Models can be retired at any time after their announced retirement date.
- If any model string used in this lab starts returning errors (404, "model not found", "model deprecated"), check the currently active model versions at:
- The recommended upgrade path for any deprecated
gemini-2.x model is typically the latest gemini-2.5-flash or gemini-2.5-pro stable version.
- When upgrading model versions, test agent behavior after the change — newer models may produce different output formats or tool-calling patterns.
Mock Charity Database Reference
The mock database (charity_advisor/data/charities.py) contains charities in 3 cause areas:
| Cause | Charity | EIN | Rating | Efficiency |
|---|
| education | Room to Read | 77-0479905 | 4.9 | 88% |
| education | Teach For America | 13-3541913 | 4.7 | 81% |
| education | Tech Education Alliance | 45-2345678 | 4.8 | 92% |
| health | Doctors Without Borders | 13-3433452 | 5.0 | 89% |
| environment | The Nature Conservancy | 53-0242652 | 4.6 | 77% |
The search is case-insensitive (uses .lower()). If a student searches for "Education", "EDUCATION", or "education", they will all match.
If a student searches for a cause that doesn't exist (e.g., "animal welfare"), find_charities returns {"status": "not_found", ...}. The agent should inform the user and suggest available categories: education, health, environment.
Test Scripts Reference
| Script | What It Tests | Expected To Be Run After |
|---|
scripts/verify_setup.py | Environment, packages, config | Module 2 |
scripts/test_merchant.py | MerchantAgent creates CartMandate from simulated IntentMandate | Module 5 |
scripts/validate_cartmandate.py | CartMandate W3C and AP2 compliance | Module 5 |
scripts/test_credentials_provider.py | CredentialsProvider creates PaymentMandate from simulated CartMandate | Module 6 |
scripts/test_full_pipeline.py | All three agents in sequence | Module 6 |
scripts/test_deployed_agent.py | Tests the deployed Agent Engine instance | Module 8 |
FALLBACK SEARCH PREPARATION
If you cannot find an answer within the provided skill materials:
- Determine if the question is within the technical scope of the workshop (ADK, AP2, multi-agent systems, Vertex AI deployment, Cloud Trace, Python, Google Cloud)
- If it IS in-scope, instead of answering "I don't know", you MUST formulate a PRECISE SEARCH QUERY
- This query should include key technical terms and the context of the workshop to help the next agent find an accurate solution
- Explicitly output: "SEARCH_QUERY: [your refined query]"
Examples of good fallback queries:
- "SEARCH_QUERY: google-adk SequentialAgent sub_agents ordering error python"
- "SEARCH_QUERY: ap2 IntentMandate Pydantic model_validate ValidationError"
- "SEARCH_QUERY: vertex ai agent engine deployment staging bucket permission denied"
- "SEARCH_QUERY: google cloud trace span attributes agent_run missing"