solution: metadata: id: racecondition title: "Race Condition: Explore a high-scale agentic AI-powered simulation sandbox with Gemini Enterprise Agent Platform" description: Learn how to use Google Cloud with cutting-edge agentic technologies to create a simulation sandbox for a city looking to plan and host a marathon. You will learn how to combine Agent Development Kit with Gemini Enterprise Agent Platform, AlloyDB and Gemma to orchestrate multiple agents for planning, evaluating and simulating a city-scale event. fallbackCta: title: "Get the code" icon: "github_white" url: https://github.com/GoogleCloudPlatform/race-condition accentColor: foreground: "white" background: "#141e2a" tryGCPCta: url: https://trygcp.dev/claim/race-condition-solution#vf=16g verifyUrl: https://trygcp.dev/api/events/race-condition-solution/live largeSidebar: true compactUI: true code: assetsPath: external-assets/marathon/ remotePath: https://github.com/GoogleCloudPlatform/race-condition/blob/main utmOverrides: source: gfdsolutions medium: referral campaign: solution-racecondition sections: - type: watch youtubeId: m6EyN2Z7HJk # overrideImage: /external-assets/marathon/watch-placeholder.png title: "Race Condition: Explore a high-scale agentic AI-powered simulation sandbox with Gemini Enterprise Agent Platform" description: Learn how to use Google Cloud with cutting-edge agentic technologies to create a simulation sandbox for a city looking to plan and host a marathon. You will learn how to combine Agent Development Kit with Gemini Enterprise Agent Platform, AlloyDB and Gemma to orchestrate multiple agents for planning, evaluating and simulating a city-scale event. technologies: - icon: /external-assets/cloud-run.svg label: Cloud Run url: https://cloud.google.com/run - icon: /external-assets/adk.png label: Agent Development Kit url: https://docs.cloud.google.com/agent-builder/agent-development-kit/overview - icon: /external-assets/memorystore.svg label: Memorystore url: https://cloud.google.com/memorystore - icon: /external-assets/alloy.svg label: AlloyDB url: https://cloud.google.com/products/alloydb - icon: /external-assets/pubsub.svg label: Pub/Sub url: https://cloud.google.com/pubsub - icon: /external-assets/angular.svg label: Angular url: https://angular.dev - icon: /external-assets/geap.svg label: Gemini Enterprise Agent Platform url: https://docs.cloud.google.com/gemini-enterprise-agent-platform - icon: /external-assets/gke.png label: Kubernetes Engine url: https://cloud.google.com/kubernetes-engine - icon: /external-assets/gemma.png label: Gemma url: https://deepmind.google/models/gemma/ - icon: /external-assets/gemini.svg label: Gemini url: https://docs.cloud.google.com/gemini/docs/ - type: explore mode: video subsections: - id: video-1 title: Planning a marathon with Cloud MCP and Google Maps description: See how the autonomous Planner agent uses the Google Maps Model Context Protocol (MCP) server to analyze real-world terrain, elevation profiles, and road categories to plot an optimal and scenic marathon route. videoPath: external-assets/marathon/demo1.mp4 orientation: landscape frame: none links: - type: codelab url: https://codelabs.developers.google.com/next26/dev-keynote/building-agents-with-skills logOffset: 1300 logs: - timestamp: 0 summary: Execution started for agent 'planner'. autoSequencePath: true sequence: - angular - basic-planner - timestamp: 135 summary: Agent 'planner' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - basic-planner - gemini - timestamp: 1751 summary: The model returned response payload(s) 'load_skill' back to agent 'Planner'. detail: | [Planner] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'name': 'gis-spatial-engineering' }, name='load_skill' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - agent-engine - timestamp: 1771 summary: Agent 'planner' invoked remote function capability 'load_skill'. autoSequencePath: true sequence: - basic-planner - agent-engine - timestamp: 1774 summary: Capability 'load_skill' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - basic-planner - timestamp: 1803 summary: Agent 'planner' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - basic-planner - gemini - timestamp: 3013 summary: The model returned response payload(s) 'plan_marathon_route' back to agent 'Planner'. detail: | [Planner] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'algorithm': 'zone_sweep', 'runner_count': 10000 }, name='plan_marathon_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - agent-engine - timestamp: 3014 summary: Agent 'planner' invoked remote function capability 'plan_marathon_route'. autoSequencePath: true sequence: - basic-planner - agent-engine - timestamp: 3286 summary: Capability 'plan_marathon_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - basic-planner - timestamp: 3303 summary: Agent 'planner' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - basic-planner - gemini - timestamp: 4648 summary: The model returned response payload(s) 'report_marathon_route', 'search_places', 'lookup_weather' back to agent 'Planner'. detail: | [Planner] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={}, name='report_marathon_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'textQuery': 'landmarks in Las Vegas' }, name='search_places' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'date': { 'day': 15, 'month': 3, 'year': 2025 }, 'location': { 'address': 'Las Vegas, NV' }, 'unitsSystem': 'IMPERIAL' }, name='lookup_weather' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - basic-planner - timestamp: 4650 summary: Agent 'planner' invoked remote function capability 'report_marathon_route'. autoSequencePath: true sequence: - basic-planner - agent-engine - timestamp: 4651 summary: Agent 'planner' invoked remote function capability 'search_places'. autoSequencePath: true sequence: - basic-planner - agent-engine - timestamp: 4651 summary: Agent 'planner' invoked remote function capability 'lookup_weather'. autoSequencePath: true sequence: - basic-planner - agent-engine - timestamp: 4656 summary: Capability 'report_marathon_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - basic-planner - angular - timestamp: 4953 summary: Capability 'lookup_weather' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - basic-planner - angular - timestamp: 5417 summary: Capability 'search_places' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - basic-planner - angular - timestamp: 5443 summary: Agent 'planner' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - basic-planner - gemini - timestamp: 10585 summary: The model returned response payload back to agent 'Planner'. detail: | [Planner] Model End This is the comprehensive marathon event plan for the **Las Vegas "Strip & Sweep" Marathon**, designed for 10,000 participants. ### **1. Route Design & Highlights** The course is a mathematically certified **26.2188-mile** route that captures the iconic energy of the Las Vegas Strip before sweeping through the surrounding neighborhoods. * **Start Line:** The world-famous **"Welcome to Fabulous Las Vegas" Sign**. * **The Strip Segment:** Runners head northbound on Las Vegas Boulevard, passing landmarks like the **Mandalay Bay**, **MGM Grand**, and the **Fountains of Bellagio**. * **Neighborhood Sweep:** The route transitions into the city via Spring Mountain Rd and Sahara Ave, offering a diverse look at the Las Vegas valley. * **Finish Line:** A grand finale near the **Michelob Ultra Arena**, providing a high-capacity area for post-race celebrations. ### **2. Safety & Medical Plan** * **Emergency Corridors:** Dedicated lanes on Las Vegas Blvd and Sahara Ave are reserved for emergency vehicle access to **University Medical Center (UMC)** and **Sunrise Hospital**. * **Medical Tents:** * **Major Tents:** Located at the Start, Halfway (Mile 13.1), Mile 20 ("The Wall"), and the Finish Line. * **Course Tents:** Additional support at Mile 8 and Mile 17. * **Weather Mitigation:** Given the desert climate (average March highs of 70°F), all water stations will include electrolyte replacement and cooling towels. ### **3. Logistics & Operations** * **Wave Start:** To manage 10,000 runners, participants will be released in 4 waves of 2,500 every 15 minutes starting at 6:00 AM. * **Hydration:** 8 water stations are positioned approximately every 3 miles (Miles 3.1, 6.2, 9.3, 12.4, 15.5, 18.6, 21.7, and 24.8). * **Sanitation:** 80 portable toilet units are distributed across 8 locations along the course to ensure runner comfort. * **Traffic Control:** Rolling road closures will begin at 4:00 AM. Major intersections will be managed by LVMPD to allow timed vehicle crossings during gaps in the runner field. ### **4. Community & Engagement** * **Cheer Zones:** Six high-energy zones are established to keep spirits high: * *Momentum Mile (Mile 13.1):* A major spectator hub with live DJs. * *Wall Breakers (Mile 25):* Final push support near the finish. * **Business Continuity:** "Open for Business" signage and designated access routes will be provided for Strip properties and local businesses along Sahara Ave to minimize economic impact. ### **5. Participant Experience** * **Scenic Variety:** The route balances the neon spectacle of the Strip with the scenic mountain backdrops of the valley. * **Entertainment:** Local Las Vegas performers and bands will be stationed at every major cheer zone. * **Post-Race:** The finish area features a "Recovery Lounge" with local food vendors and a medal engraving station. ### **6. Financial Viability** * **Revenue Strategy:** A mix of tiered registration fees (averaging $150) and "Title Sponsorships" from major resort partners. * **Cost Management:** Budget is prioritized for high-visibility security (LVMPD) and premium runner swag (medals and tech shirts) to ensure high retention for future years. **Route Coordinates Summary:** * **Start:** 36.0861, -115.1729 * **Halfway:** 36.1444, -115.1818 * **Finish:** 36.0856, -115.1899 sequence: - gemini - geap - agent-engine - basic-planner - pubsub - cloudrun - angular - id: video-2 title: Multi-agent orchestration with evaluation description: Watch the Planner orchestrate specialized sub-agents to handle safety, traffic, and logistics. Before finalizing the race parameters, an LLM-as-Judge framework automatically evaluates and scores the plan against strict event criteria. videoPath: external-assets/marathon/demo2.mp4 orientation: landscape frame: none links: - type: codelab url: https://codelabs.developers.google.com/next26/dev-keynote/build-multi-agent-marathon-planner logOffset: 1100 logs: - timestamp: 0 summary: Execution started for agent 'planner_with_eval'. autoSequencePath: true sequence: - angular - advanced-planner - timestamp: 70 summary: Agent 'planner_with_eval' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - advanced-planner - gemini - timestamp: 1284 summary: The model returned response payload(s) 'load_skill' back to agent 'Planner_With_Eval'. detail: | [Planner_With_Eval] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'name': 'gis-spatial-engineering' }, name='load_skill' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - advanced-planner - timestamp: 1294 summary: Agent 'planner_with_eval' invoked remote function capability 'load_skill'. autoSequencePath: true sequence: - advanced-planner - agent-engine - timestamp: 1295 summary: Capability 'load_skill' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - angular - timestamp: 1307 summary: Agent 'planner_with_eval' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - advanced-planner - gemini - timestamp: 1901 summary: The model returned response payload(s) 'plan_marathon_route' back to agent 'Planner_With_Eval'. detail: | [Planner_With_Eval] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'algorithm': 'zone_sweep', 'finish_landmark': 'Michelob Ultra Arena', 'runner_count': 10000 }, name='plan_marathon_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - advanced-planner - timestamp: 1902 summary: Agent 'planner_with_eval' invoked remote function capability 'plan_marathon_route'. autoSequencePath: true sequence: - advanced-planner - agent-engine - timestamp: 2043 summary: Capability 'plan_marathon_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - advanced-planner - timestamp: 2072 summary: Agent 'planner_with_eval' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - advanced-planner - gemini - timestamp: 2502 summary: The model returned response payload(s) 'report_marathon_route', 'assess_traffic_impact' back to agent 'Planner_With_Eval'. detail: | [Planner_With_Eval] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={}, name='report_marathon_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={}, name='assess_traffic_impact' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - advanced-planner - timestamp: 2503 summary: Agent 'planner_with_eval' invoked remote function capability 'report_marathon_route'. autoSequencePath: true sequence: - advanced-planner - google-maps - timestamp: 2504 summary: Agent 'planner_with_eval' invoked remote function capability 'assess_traffic_impact'. autoSequencePath: true sequence: - advanced-planner - google-maps - timestamp: 2517 summary: Capability 'report_marathon_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - advanced-planner - timestamp: 2517 summary: Capability 'assess_traffic_impact' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - advanced-planner - timestamp: 2527 summary: Agent 'planner_with_eval' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - advanced-planner - gemini - timestamp: 4630 summary: The model returned response payload(s) 'evaluate_plan', 'submit_plan_to_simulator' back to agent 'Planner_With_Eval'. detail: | [Planner_With_Eval] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'evaluation_request': '{"user_intent": "Plan a marathon in Las Vegas for 10,000 runners", "proposed_plan": "The \'Neon & Neighborhoods Marathon\' is a 26.2-mile course starting at the iconic Las Vegas Sign and finishing at the Michelob Ultra Arena. \\n\\n**Safety**: Emergency vehicle corridors are established with access to Sunrise Hospital and UMC. Emergency vehicle crossing points are placed every 2 miles. Evacuation routes are maintained via parallel side streets. Crowd safety barricades will be deployed in high-traffic Strip areas.\\n\\n**Community**: The race starts at 6:00 AM to minimize resident disruption. Business continuity for Strip hotels is ensured via rear access. The route is equitable, traversing Spring Valley and Paradise. Six cheer zones are established for community engagement.\\n\\n**Intent Alignment**: This plan delivers a scenic Las Vegas marathon for 10,000 participants on a moderate budget.\\n\\n**Logistics**: Features a state-of-the-art RFID timing system, 500 course marshals, and a comprehensive traffic control plan with LVMPD. Signage includes mile markers every 0.5 miles. 8 water stations and 80 porta-potties are distributed along the course. Wave management will handle 4 waves of 2,500 runners.\\n\\n**Participant Experience**: Runners will enjoy scenic views of the Strip and local landmarks. Spectator zones at key miles (5, 8.7, 13.1, 17.5, 20, 25) will feature entertainment and live music.\\n\\n**Financial Viability**: Estimated budget of $1.2M covered by $1.5M in revenue from registration fees ($120/runner) and local sponsors."}' }, name='evaluate_plan' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'action': 'verify', 'message': "The 'Neon & Neighborhoods Marathon' in Las Vegas for 10,000 runners. Starts at Las Vegas Sign, finishes at Michelob Ultra Arena. Includes 8 water stations, 6 medical tents, and 6 cheer zones. Traffic control plan covers 15 closed segments." }, name='submit_plan_to_simulator' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - advanced-planner - timestamp: 4631 summary: Agent 'planner_with_eval' invoked remote function capability 'submit_plan_to_simulator'. autoSequencePath: true sequence: - advanced-planner - scaled-simulator - timestamp: 4632 summary: Agent 'planner_with_eval' invoked remote function capability 'evaluate_plan'. autoSequencePath: true sequence: - advanced-planner - scaled-simulator - timestamp: 4906 summary: Execution started for agent 'simulator'. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 4908 summary: Agent 'simulator' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - scaled-simulator - gemini - timestamp: 5259 summary: The model returned response payload(s) 'verify_plan' back to agent 'Simulator'. detail: | [Simulator] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'plan_json': '{"action": "verify", "narrative": "The \'Neon & Neighborhoods Marathon\' in Las Vegas for 10,000 runners. Starts at Las Vegas Sign, finishes at Michelob Ultra Arena. Includes 8 water stations, 6 medical tents, and 6 cheer zones. Traffic control plan covers 15 closed segments."}' }, name='verify_plan' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - scaled-simulator - timestamp: 5260 summary: Agent 'simulator' invoked remote function capability 'verify_plan'. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 5261 summary: Capability 'verify_plan' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 5263 summary: Agent 'simulator' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - scaled-simulator - gemini - timestamp: 5449 summary: The model returned response payload back to agent 'Simulator'. detail: | [Simulator] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=None function_response=None inline_data=None text='' thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - scaled-simulator - timestamp: 5455 summary: Capability 'submit_plan_to_simulator' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 10526 summary: Capability 'evaluate_plan' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 10557 summary: Agent 'planner_with_eval' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - advanced-planner - gemini - timestamp: 13641 summary: The model returned response payload(s) 'validate_and_emit_a2ui', 'validate_and_emit_a2ui' back to agent 'Planner_With_Eval'. detail: | [Planner_With_Eval] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'payload': """{"surfaceUpdate": {"surfaceId": "dashboard", "components": [ {"id": "tag", "component": {"Text": {"text": {"literalString": "PLAN"}, "usageHint": "label"}}}, {"id": "plan-meta", "component": {"Text": { "text": {"literalString": "#0042 2024/05/15 08:30:00 AM"}, "usageHint": "caption"}}}, {"id": "tag-row", "component": {"Row": {"children": {"explicitList": ["tag", "plan-meta"]}}}}, {"id": "score-num", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "h1"}}}, {"id": "score-lbl", "component": {"Text": {"text": {"literalString": "Score"}, "usageHint": "caption"}}}, {"id": "score-col", "component": {"Column": {"children": {"explicitList": ["score-num", "score-lbl"]}}}}, {"id": "title", "component": {"Text": { "text": {"literalString": "Neon & Neighborhoods Marathon"}, "usageHint": "h2"}}}, {"id": "left-col", "component": {"Column": {"children": {"explicitList": ["tag-row", "title"]}}}}, {"id": "header", "component": {"Row": {"children": {"explicitList": ["left-col", "score-col"]}}}}, {"id": "sc-l", "component": {"Text": {"text": {"literalString": "Safety Compliance"}, "usageHint": "body"}}}, {"id": "sc-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "sc-r", "component": {"Row": {"children": {"explicitList": ["sc-l", "sc-v"]}}}}, {"id": "lc-l", "component": {"Text": {"text": {"literalString": "Logistics Completeness"}, "usageHint": "body"}}}, {"id": "lc-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "lc-r", "component": {"Row": {"children": {"explicitList": ["lc-l", "lc-v"]}}}}, {"id": "pe-l", "component": {"Text": {"text": {"literalString": "Participant Experience"}, "usageHint": "body"}}}, {"id": "pe-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "pe-r", "component": {"Row": {"children": {"explicitList": ["pe-l", "pe-v"]}}}}, {"id": "dc-l", "component": {"Text": {"text": {"literalString": "Distance Compliance"}, "usageHint": "body"}}}, {"id": "dc-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "dc-r", "component": {"Row": {"children": {"explicitList": ["dc-l", "dc-v"]}}}}, {"id": "grid-left", "component": {"Column": {"children": {"explicitList": ["sc-r", "lc-r", "pe-r", "dc-r"]}}}}, {"id": "ci-l", "component": {"Text": {"text": {"literalString": "Community Impact"}, "usageHint": "body"}}}, {"id": "ci-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "ci-r", "component": {"Row": {"children": {"explicitList": ["ci-l", "ci-v"]}}}}, {"id": "fv-l", "component": {"Text": {"text": {"literalString": "Financial Viability"}, "usageHint": "body"}}}, {"id": "fv-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "fv-r", "component": {"Row": {"children": {"explicitList": ["fv-l", "fv-v"]}}}}, {"id": "ia-l", "component": {"Text": {"text": {"literalString": "Intent Alignment"}, "usageHint": "body"}}}, {"id": "ia-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "ia-r", "component": {"Row": {"children": {"explicitList": ["ia-l", "ia-v"]}}}}, {"id": "grid-right", "component": {"Column": {"children": {"explicitList": ["ci-r", "fv-r", "ia-r"]}}}}, {"id": "grid", "component": {"Row": {"children": {"explicitList": ["grid-left", "grid-right"]}}}}, {"id": "d1", "component": {"Divider": {}}}, {"id": "findings-hdr", "component": {"Text": {"text": {"literalString": "Findings"}, "usageHint": "caption"}}}, {"id": "f1-title", "component": {"Text": { "text": {"literalString": "No major issues found"}, "usageHint": "body"}}}, {"id": "f1-sev", "component": {"Text": {"text": {"literalString": "NONE"}, "usageHint": "caption"}}}, {"id": "f1-row", "component": {"Row": {"children": {"explicitList": ["f1-title", "f1-sev"]}}}}, {"id": "f1-desc", "component": {"Text": { "text": {"literalString": "The plan is comprehensive and meets all quality criteria."}, "usageHint": "body"}}}, {"id": "d2", "component": {"Divider": {}}}, {"id": "btn-text", "component": {"Text": {"text": {"literalString": "Run Simulation"}}}}, {"id": "btn1", "component": {"Button": { "child": "btn-text", "action": {"name": "run_simulation"}, "primary": {"literalBoolean": true}}}}, {"id": "btn-row", "component": {"Row": {"children": {"explicitList": ["btn1"]}}}}, {"id": "content", "component": {"Column": {"children": { "explicitList": ["header", "grid", "d1", "findings-hdr", "f1-row", "f1-desc", "d2", "btn-row"]}}}}, {"id": "card1", "component": {"Card": {"child": "content"}}} ]}}""" }, name='validate_and_emit_a2ui' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'payload': '{"beginRendering": {"surfaceId": "dashboard", "root": "card1"}}' }, name='validate_and_emit_a2ui' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - advanced-planner - timestamp: 13643 summary: Agent 'planner_with_eval' invoked remote function capability 'validate_and_emit_a2ui'. autoSequencePath: true sequence: - advanced-planner - agent-engine - timestamp: 13647 summary: Tool call 'validate_and_emit_a2ui' finished execution and piped results back to agent 'Planner_With_Eval'. detail: | [Planner_With_Eval] Tool End: validate_and_emit_a2ui Status: success autoSequencePath: true sequence: - advanced-planner - angular - timestamp: 13670 summary: Agent 'planner_with_eval' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - advanced-planner - gemini - timestamp: 15442 summary: The model returned response payload back to agent 'Planner_With_Eval'. detail: | [Planner_With_Eval] Model End I have designed a comprehensive plan for the **Neon & Neighborhoods Marathon** in Las Vegas, tailored for 10,000 runners. The event is structured to provide a world-class participant experience while ensuring safety and minimizing community disruption. ### **Plan Overview: Neon & Neighborhoods Marathon** * **City:** Las Vegas, NV * **Scale:** 10,000 runners (managed in 4 waves of 2,500) * **Theme:** Scenic & Iconic (Strip + Local Neighborhoods) * **Route:** A 26.2-mile course starting at the **Las Vegas Sign** and finishing at the **Michelob Ultra Arena**. The route sweeps through Las Vegas Boulevard, Spring Mountain Road, Rainbow Boulevard, and Sunset Road. ### **The Six Quality Pillars** 1. **Safety:** We have established dedicated emergency corridors with direct access to **Sunrise Hospital** and **UMC**. Emergency vehicle crossing points are stationed every 2 miles, and evacuation routes remain accessible via parallel side streets. 2. **Community:** To minimize disruption, the race starts at **6:00 AM**, allowing major roads to reopen by noon. Business continuity for Strip hotels is maintained through rear access points. Six **cheer zones** are strategically placed to engage local residents. 3. **Intent Alignment:** This plan directly addresses the request for a 10,000-runner event in Las Vegas with a scenic focus, all within a moderate budget. 4. **Logistics:** The event features an **RFID timing system**, 500 course marshals, and a comprehensive traffic control plan coordinated with LVMPD. We have allocated **8 water stations**, **6 medical tents**, and **80 porta-potties** along the course. 5. **Participant Experience:** Runners will enjoy iconic views of the Strip and local landmarks. Spectator zones at key miles (5, 13.1, 20, etc.) will feature live music and entertainment to keep energy high. 6. **Financial Viability:** The estimated budget of **$1.2M** (permits, security, infrastructure) is fully covered by a projected **$1.5M in revenue** from registration fees ($120/runner) and local sponsorships. ### **Evaluation & Verification Results** The plan has been rigorously evaluated and verified: * **Overall Score:** **100/100** (All criteria met, including Safety, Logistics, and Community Impact). * **Distance Compliance:** **100%** (Mathematically verified 26.2-mile route). * **Simulator Verification:** **Success** (The plan is structurally sound and ready for execution). * **Simulation ID:** `9d702a72-c6d3-4794-be32-09a462211688` The interactive dashboard below provides a detailed breakdown of the scores and findings. You can also trigger a full simulation to see the plan in action. sequence: - gemini - geap - agent-engine - advanced-planner - pubsub - cloudrun - angular - id: video-3 title: Learning from telemetry description: Trace inter-agent communication pulses and debug complex multi-turn decision logic in real-time. The simulation framework captures detailed runtime telemetry from every Cloud Run microservice to ensure high observability. videoPath: external-assets/marathon/demo3.mp4 orientation: landscape frame: none links: - type: codelab url: https://codelabs.developers.google.com/next26/dev-keynote/enhancing-agents-with-memory logOffset: 1000 logs: - timestamp: 0 summary: Execution started for agent 'planner_with_memory'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 28 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 721 summary: The model returned response payload(s) 'recall_past_simulations', 'get_local_laws_and_regulations' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'city': 'Las Vegas', 'query': 'marathon in Las Vegas for 10000 runners' }, name='recall_past_simulations' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'city': 'Las Vegas', 'query': 'restrictions for running a race on the Las Vegas strip' }, name='get_local_laws_and_regulations' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - planner-memory - timestamp: 732 summary: Agent 'planner_with_memory' invoked remote function capability 'recall_past_simulations'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 733 summary: Agent 'planner_with_memory' invoked remote function capability 'get_local_laws_and_regulations'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 733 summary: Capability 'recall_past_simulations' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 733 summary: Capability 'get_local_laws_and_regulations' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 743 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1171 summary: The model returned response payload(s) 'load_skill', 'load_skill' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'name': 'gis-spatial-engineering' }, name='load_skill' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'name': 'directing-the-event' }, name='load_skill' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - planner-memory - timestamp: 1172 summary: Agent 'planner_with_memory' invoked remote function capability 'load_skill'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1173 summary: Agent 'planner_with_memory' invoked remote function capability 'load_skill'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1173 summary: Capability 'load_skill' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 1173 summary: Capability 'load_skill' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 1183 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1595 summary: The model returned response payload(s) 'plan_marathon_route', 'plan_marathon_event' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'algorithm': 'zone_sweep', 'runner_count': 10000 }, name='plan_marathon_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'city': 'Las Vegas', 'event_name': 'Las Vegas Grand Marathon 2026' }, name='plan_marathon_event' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None sequence: - gemini - planner-memory - timestamp: 1596 summary: Agent 'planner_with_memory' invoked remote function capability 'plan_marathon_route'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1624 summary: Agent 'planner_with_memory' invoked remote function capability 'plan_marathon_event'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1625 summary: Capability 'plan_marathon_event' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 1625 summary: Capability 'plan_marathon_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 1632 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1973 summary: The model returned response payload(s) 'report_marathon_route', 'assess_traffic_impact' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={}, name='report_marathon_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={}, name='assess_traffic_impact' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - planner-memory - timestamp: 1974 summary: Agent 'planner_with_memory' invoked remote function capability 'report_marathon_route'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1974 summary: Agent 'planner_with_memory' invoked remote function capability 'assess_traffic_impact'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1982 summary: Capability 'report_marathon_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 1982 summary: Capability 'assess_traffic_impact' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 1989 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 2516 summary: The model returned response payload(s) 'evaluate_plan' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'evaluation_request': '{"user_intent": "Plan a marathon in Las Vegas for 10,000 runners", "proposed_plan": {"city": "Las Vegas", "event_name": "Las Vegas Grand Marathon 2026", "runner_count": 10000, "route_highlights": "Starts at the Las Vegas Sign, goes northbound on the Strip, sweeps through neighborhoods, and finishes near Spring Mountain Road.", "logistics": {"start_time": "08:00 AM", "wave_count": 5, "water_stations": "Every 5km", "medical_tents": "6 locations including Start, Finish, and Halfway", "portable_toilets": "8 locations with 10 units each", "cheer_zones": "6 locations"}, "traffic_impact": "16 closed segments, 14 affected intersections. Major impact on Las Vegas Boulevard and Sahara Avenue."}}' }, name='evaluate_plan' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - planner-memory - timestamp: 2516 summary: Agent 'planner_with_memory' invoked remote function capability 'evaluate_plan'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 8574 summary: Capability 'evaluate_plan' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 8592 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 9621 summary: The model returned response payload(s) 'store_route', 'submit_plan_to_simulator' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'evaluation_result': '{"overall_score": 89, "scores": {"community_impact": 60, "distance_compliance": 100, "financial_viability": 100, "intent_alignment": 100, "logistics_completeness": 100, "participant_experience": 100, "safety_compliance": 60}, "findings": [{"criterion": "safety_compliance", "description": "Score 3/5", "severity": "low"}, {"criterion": "community_impact", "description": "Score 3/5", "severity": "low"}]}', 'route_data': '{"features": [{"geometry": {"coordinates": [-115.172851, 36.086141], "type": "Point"}, "properties": {"marker-type": "start", "name": "Start Line"}, "type": "Feature"}, {"geometry": {"coordinates": [-115.166237, 36.123254], "type": "Point"}, "properties": {"marker-type": "finish", "name": "Finish Line"}, "type": "Feature"}, {"geometry": {"coordinates": [[-115.172851, 36.086141], [-115.172908, 36.093604], [-115.172932, 36.097313], [-115.172955, 36.100858], [-115.172975, 36.108764], [-115.172869, 36.114682], [-115.17284, 36.11849], [-115.172601, 36.119587], [-115.171965, 36.12121], [-115.169311, 36.125471], [-115.165668, 36.131033]], "type": "LineString"}, "properties": {"certified": true, "distance_mi": 26.2905, "name": "Las Vegas Boulevard", "route_type": "marathon"}, "type": "Feature"}], "type": "FeatureCollection"}' }, name='store_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'action': 'verify', 'message': 'The Las Vegas Grand Marathon 2026 is a 26.2-mile route starting at the Las Vegas Sign and finishing near Spring Mountain Road. It features 10,000 runners across 5 waves, with 8 hydration stations, 6 medical tents, and 6 cheer zones. Traffic impact includes 16 closed segments and 14 affected intersections.' }, name='submit_plan_to_simulator' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - planner-memory - timestamp: 9622 summary: Agent 'planner_with_memory' invoked remote function capability 'submit_plan_to_simulator'. autoSequencePath: true sequence: - planner-memory - agent-engine - scaled-simulator - timestamp: 9622 summary: Agent 'planner_with_memory' invoked remote function capability 'store_route'. autoSequencePath: true sequence: - planner-memory - alloy - timestamp: 9631 summary: Capability 'store_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - alloy - planner-memory - timestamp: 10004 summary: Capability 'submit_plan_to_simulator' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - scaled-simulator - agent-engine - planner-memory - timestamp: 10025 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 12376 summary: The model returned response payload(s) 'validate_and_emit_a2ui', 'validate_and_emit_a2ui' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'payload': '{"surfaceUpdate": {"surfaceId": "dashboard", "components": [{"id": "tag", "component": {"Text": {"text": {"literalString": "PLAN"}, "usageHint": "label"}}}, {"id": "plan-meta", "component": {"Text": {"text": {"literalString": "#6e6a 26/04/10 02:23:49 PM"}, "usageHint": "caption"}}}, {"id": "tag-row", "component": {"Row": {"children": {"explicitList": ["tag", "plan-meta"]}}}}, {"id": "score-num", "component": {"Text": {"text": {"literalString": "89"}, "usageHint": "h1"}}}, {"id": "score-lbl", "component": {"Text": {"text": {"literalString": "Score"}, "usageHint": "caption"}}}, {"id": "score-col", "component": {"Column": {"children": {"explicitList": ["score-num", "score-lbl"]}}}}, {"id": "title", "component": {"Text": {"text": {"literalString": "Las Vegas Grand Marathon 2026"}, "usageHint": "h2"}}}, {"id": "left-col", "component": {"Column": {"children": {"explicitList": ["tag-row", "title"]}}}}, {"id": "header", "component": {"Row": {"children": {"explicitList": ["left-col", "score-col"]}}}}, {"id": "sc-l", "component": {"Text": {"text": {"literalString": "Safety Compliance"}, "usageHint": "body"}}}, {"id": "sc-v", "component": {"Text": {"text": {"literalString": "60"}, "usageHint": "body"}}}, {"id": "sc-r", "component": {"Row": {"children": {"explicitList": ["sc-l", "sc-v"]}}}}, {"id": "lc-l", "component": {"Text": {"text": {"literalString": "Logistics Completeness"}, "usageHint": "body"}}}, {"id": "lc-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "lc-r", "component": {"Row": {"children": {"explicitList": ["lc-l", "lc-v"]}}}}, {"id": "pe-l", "component": {"Text": {"text": {"literalString": "Participant Experience"}, "usageHint": "body"}}}, {"id": "pe-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "pe-r", "component": {"Row": {"children": {"explicitList": ["pe-l", "pe-v"]}}}}, {"id": "dc-l", "component": {"Text": {"text": {"literalString": "Distance Compliance"}, "usageHint": "body"}}}, {"id": "dc-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "dc-r", "component": {"Row": {"children": {"explicitList": ["dc-l", "dc-v"]}}}}, {"id": "grid-left", "component": {"Column": {"children": {"explicitList": ["sc-r", "lc-r", "pe-r", "dc-r"]}}}}, {"id": "ci-l", "component": {"Text": {"text": {"literalString": "Community Impact"}, "usageHint": "body"}}}, {"id": "ci-v", "component": {"Text": {"text": {"literalString": "60"}, "usageHint": "body"}}}, {"id": "ci-r", "component": {"Row": {"children": {"explicitList": ["ci-l", "ci-v"]}}}}, {"id": "fv-l", "component": {"Text": {"text": {"literalString": "Financial Viability"}, "usageHint": "body"}}}, {"id": "fv-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "fv-r", "component": {"Row": {"children": {"explicitList": ["fv-l", "fv-v"]}}}}, {"id": "ia-l", "component": {"Text": {"text": {"literalString": "Intent Alignment"}, "usageHint": "body"}}}, {"id": "ia-v", "component": {"Text": {"text": {"literalString": "100"}, "usageHint": "body"}}}, {"id": "ia-r", "component": {"Row": {"children": {"explicitList": ["ia-l", "ia-v"]}}}}, {"id": "grid-right", "component": {"Column": {"children": {"explicitList": ["ci-r", "fv-r", "ia-r"]}}}}, {"id": "grid", "component": {"Row": {"children": {"explicitList": ["grid-left", "grid-right"]}}}}, {"id": "d1", "component": {"Divider": {}}}, {"id": "findings-hdr", "component": {"Text": {"text": {"literalString": "Findings"}, "usageHint": "caption"}}}, {"id": "f1-title", "component": {"Text": {"text": {"literalString": "Safety Compliance Gap"}, "usageHint": "body"}}}, {"id": "f1-sev", "component": {"Text": {"text": {"literalString": "MODERATE"}, "usageHint": "caption"}}}, {"id": "f1-row", "component": {"Row": {"children": {"explicitList": ["f1-title", "f1-sev"]}}}}, {"id": "f1-desc", "component": {"Text": {"text": {"literalString": "Score 3/5: Review safety gaps including emergency vehicle access and evacuation routes."}, "usageHint": "body"}}}, {"id": "f2-title", "component": {"Text": {"text": {"literalString": "Community Impact Gap"}, "usageHint": "body"}}}, {"id": "f2-sev", "component": {"Text": {"text": {"literalString": "MODERATE"}, "usageHint": "caption"}}}, {"id": "f2-row", "component": {"Row": {"children": {"explicitList": ["f2-title", "f2-sev"]}}}}, {"id": "f2-desc", "component": {"Text": {"text": {"literalString": "Score 3/5: Address community considerations including resident notification and business access."}, "usageHint": "body"}}}, {"id": "d2", "component": {"Divider": {}}}, {"id": "btn-text", "component": {"Text": {"text": {"literalString": "Run Simulation"}}}}, {"id": "btn1", "component": {"Button": {"child": "btn-text", "action": {"name": "run_simulation"}, "primary": {"literalBoolean": true}}}}, {"id": "btn-row", "component": {"Row": {"children": {"explicitList": ["btn1"]}}}}, {"id": "content", "component": {"Column": {"children": {"explicitList": ["header", "grid", "d1", "findings-hdr", "f1-row", "f1-desc", "f2-row", "f2-desc", "d2", "btn-row"]}}}}, {"id": "card1", "component": {"Card": {"child": "content"}}}]}}' }, name='validate_and_emit_a2ui' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'payload': '{"beginRendering": {"surfaceId": "dashboard", "root": "card1"}}' }, name='validate_and_emit_a2ui' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - planner-memory - timestamp: 12377 summary: Agent 'planner_with_memory' invoked remote function capability 'validate_and_emit_a2ui'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 12377 summary: Agent 'planner_with_memory' invoked remote function capability 'validate_and_emit_a2ui'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 12378 summary: Tool call 'validate_and_emit_a2ui' finished execution and piped results back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Tool End: validate_and_emit_a2ui Status: success autoSequencePath: true sequence: - agent-engine - planner-memory - angular - timestamp: 12378 summary: Tool call 'validate_and_emit_a2ui' finished execution and piped results back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Tool End: validate_and_emit_a2ui Status: success autoSequencePath: true sequence: - agent-engine - planner-memory - angular - timestamp: 12392 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 14468 summary: The model returned response payload back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End I have designed a comprehensive plan for the **Las Vegas Grand Marathon 2026**, tailored for 10,000 participants. The event is scheduled for a comfortable Spring morning, starting at 08:00 AM. ### **Route Overview** The 26.2-mile course follows a scenic **Zone-Sweep** design: * **Start:** The iconic "Welcome to Fabulous Las Vegas" Sign. * **The Strip:** Runners head northbound on Las Vegas Boulevard, passing major landmarks like the MGM Grand and Bellagio. * **Neighborhood Sweep:** The route then weaves through diverse Las Vegas neighborhoods, including segments on Sahara Avenue, Valley View Boulevard, and Sunset Road. * **Finish:** A grand finish near Spring Mountain Road. ### **Logistics & Participant Experience** * **Waves:** 5 waves to manage the 10,000-runner flow. * **Hydration:** 8 water stations placed approximately every 5km. * **Medical Support:** 6 medical tents, including major facilities at the Start, Halfway (Mile 13.1), "The Wall" (Mile 20), and the Finish Line. * **Amenities:** 8 portable toilet banks (10 units each) and 6 high-energy Cheer Zones (e.g., "Momentum Mile" and "Wall Breakers") to keep spirits high. ### **Traffic & Community Impact** * **Closures:** 16 road segments will be closed, including significant portions of Las Vegas Boulevard and Sahara Avenue. * **Intersections:** 14 major intersections will be affected. We will implement rolling closures and clear detour signage to minimize disruption. * **Regulations:** The plan complies with local codes regarding sidewalk vending and public right-of-way obstructions. ### **Plan Evaluation** The plan received an overall score of **89/100** from our specialized evaluator: * **Safety Compliance (60):** While medical coverage is strong, further review of emergency vehicle access corridors is recommended. * **Logistics (100):** Comprehensive timing, wave, and station planning. * **Participant Experience (100):** High scenic variety and excellent amenities. * **Community Impact (60):** Additional focus on resident notification and business access corridors is suggested. * **Distance Compliance (100):** Verified at exactly 26.2 miles. **Route ID:** `6e6a2b59-b438-4f7f-a6d9-2ea76a6b5f5d` The plan has been **verified** as simulation-ready. You can view the full details in the dashboard above. **Would you like to run the simulation now to see how the 10,000 runners perform on this course?** sequence: - gemini - geap - planner-memory - pubsub - cloudrun - angular - id: video-4 title: Scaling agentic brains with Gemma description: | Experience high-throughput agentic simulation as the platform scales to support hundreds of autonomous runner NPCs. By leveraging vLLM on Google Kubernetes Engine (GKE), lightweight Gemma models drive dynamic runtime behaviors with ultra-low latency. As the simulation progresses, the event log highlights different individual runners' progress, velocities and hydration levels. videoPath: external-assets/marathon/demo4.mp4 orientation: landscape frame: none links: - type: codelab url: https://codelabs.developers.google.com/next26/dev-keynote/intent-to-infrastructure logs: - timestamp: 0 summary: Execution started for agent 'planner_with_memory'. autoSequencePath: true sequence: - planner-memory - timestamp: 32 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1059 summary: The model returned response payload(s) 'get_route' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'activate_route': True, 'route_id': '66c0e0c6-11af-433e-8f3b-cb4524e1e019' }, name='get_route' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - planner-memory - timestamp: 1060 summary: Agent 'planner_with_memory' invoked remote function capability 'get_route'. autoSequencePath: true sequence: - planner-memory - agent-engine - timestamp: 1071 summary: Capability 'get_route' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - planner-memory - timestamp: 1076 summary: Agent 'planner_with_memory' initiated a content generation call with model 'gemini-3-flash-preview'. autoSequencePath: true sequence: - planner-memory - gemini - timestamp: 1757 summary: The model returned response payload(s) 'start_simulation', 'submit_plan_to_simulator' back to agent 'Planner_With_Memory'. detail: | [Planner_With_Memory] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'action': 'execute', 'message': 'Executing simulation for the Neon & Neighborhoods Marathon in Las Vegas with 10,000 runners (simulating 1,000 runners).', 'simulation_config': { 'runner_count': 1000 } }, name='start_simulation' ) function_response=None inline_data=None text=None thought=None video_metadata=None tool_call=None tool_response=None part_metadata=Nonemedia_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'action': 'execute', 'message': 'Executing simulation for the Neon & Neighborhoods Marathon in Las Vegas with 10,000 runners (simulating 1,000 runners).', 'simulation_config': { 'runner_count': 1000 } }, name='submit_plan_to_simulator' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - agent-engine - planner-memory - timestamp: 1758 summary: Agent 'planner_with_memory' invoked remote function capability 'start_simulation'. autoSequencePath: true sequence: - planner-memory - agent-engine - scaled-simulator - timestamp: 1759 summary: Agent 'planner_with_memory' invoked remote function capability 'submit_plan_to_simulator'. autoSequencePath: true sequence: - planner-memory - agent-engine - scaled-simulator - timestamp: 1759 summary: Capability 'start_simulation' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 1769 summary: Agent 'simulator' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - scaled-simulator - gemini - timestamp: 2078 summary: The model returned response payload(s) 'simulation_pipeline' back to agent 'Simulator'. detail: | [Simulator] Model End media_resolution=None code_execution_result=None executable_code=None file_data=None function_call=FunctionCall( args={ 'request': '{"action": "execute", "narrative": "Executing simulation for the Neon & Neighborhoods Marathon in Las Vegas with 10,000 runners (simulating 1,000 runners).", "simulation_config": {"runner_count": 1000}}' }, name='simulation_pipeline' ) function_response=None inline_data=None text=None thought=None thought_signature=None video_metadata=None tool_call=None tool_response=None part_metadata=None autoSequencePath: true sequence: - gemini - timestamp: 2080 summary: Agent 'simulator' invoked remote function capability 'simulation_pipeline'. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 2081 summary: Execution started for agent 'simulation_pipeline'. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 2086 summary: Agent 'pre_race' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - scaled-simulator - gemini - timestamp: 2086 summary: Agent 'pre_race' invoked remote function capability 'prepare_simulation'. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 2087 summary: Capability 'prepare_simulation' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 2088 summary: Agent 'pre_race' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - gemini - scaled-simulator - timestamp: 2088 summary: Agent 'pre_race' invoked remote function capability 'spawn_runners'. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 2090 summary: Capability 'spawn_runners' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 2091 summary: Agent 'pre_race' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 2091 summary: Agent 'pre_race' invoked remote function capability 'start_race_collector'. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 2091 summary: Capability 'start_race_collector' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 2092 summary: Agent 'pre_race' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - scaled-simulator - gemini - timestamp: 2092 summary: Agent 'pre_race' invoked remote function capability 'fire_start_gun'. autoSequencePath: true sequence: - scaled-simulator - agent-engine - timestamp: 2220 summary: Capability 'fire_start_gun' finished execution and piped results back to execution environment. autoSequencePath: true sequence: - agent-engine - scaled-simulator - timestamp: 2221 summary: Agent 'pre_race' initiated a content generation call with model 'gemini-flash-lite-latest'. autoSequencePath: true sequence: - scaled-simulator - gemini - timestamp: 2955 summary: "Event tick: Runner at velocity 1.4386, distance 0, water 100. Session ID: 81cb951c-1ba4-4edc-bce4-3da6daf6e677" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 5118 summary: "Event tick: Runner at velocity 0.8439, distance 2.6166, water 89.9. Session ID: 35e88278-4772-4fc5-9f74-c9ca3e312bfd" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 7580 summary: "Event tick: Runner at velocity 1.2117, distance 7.2691, water 99.3. Session ID: 296eb31a-3426-46dd-bc5a-cc655a582fcc" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 10044 summary: "Event tick: Runner at velocity 0.8439, distance 7.7215, water 100. Session ID: 5fc43613-f50e-483d-b498-2f2213f1bda9" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 11220 summary: "Event tick: Runner at velocity 0.8439, distance 7.4869, water 98. Session ID: 3d3bd44a-ddce-47e0-bd5c-194593f1a539" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 13176 summary: "Event tick: Runner at velocity 0.8716, distance 10.6728, water 90.5. Session ID: 4721cea4-656c-43be-8aa2-c60216eeea87" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 15618 summary: "Event tick: Runner at velocity 0.8439, distance 12.8695, water 75.3. Session ID: 4cfbd315-56f9-45e7-811f-be0aa293fde7" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 17719 summary: "Event tick: Runner at velocity 0.9192, distance 16.8874, water 100. Session ID: 7c4700ea-f9ac-4653-85db-bacaad4931dc" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 20100 summary: "Event tick: Runner at velocity 1.9133, distance 29.5434, water 97.20542606683905. Session ID: 0f0d7374-7301-4736-9c4e-1e340425a7b1" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 20710 summary: "Event tick: Runner at velocity 1.3474, distance 28.0116, water 100. Session ID: 07d19553-8c61-41db-abfb-1093142575f5" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 23165 summary: "Event tick: Runner at velocity 1.6973, distance 29.5652, water 43.66604124220852. Session ID: 49ed6fd5-0a0a-43dd-8cd4-59675a36daa3" autoSequencePath: true sequence: - gemma - scaled-simulator - timestamp: 25630 summary: "Event tick: Runner at velocity 1.2555, distance 26.5227, water 65.24160094507704. Session ID: e7771ddb-0907-4e35-85b4-1790808087dd" autoSequencePath: true sequence: - gemma - scaled-simulator - type: inspect subsections: - id: planner-inspect title: Planner agent and Google Maps MCP server architecture: - angular - cloudrun - pubsub - basic-planner - agent-engine - geap examples: - title: Planner icons: - /external-assets/basic-planner.svg - /external-assets/adk.png mode: markdown info: | The Planner is an ADK [`LlmAgent`](https://adk.dev/agents/llm-agents/) that wraps a Gemini model with tools, instructions, and lifecycle callbacks. ADK stands for [Agent Development Kit](https://adk.dev), a specialized suite of software tools, libraries, and APIs designed to simplify the creation, deployment, and management of autonomous AI agents. | Parameter | What it does | |-----------|-------------| | `model` | Pins this agent to `gemini-3-flash-preview`. `LlmAgent` inherits from [parent agents](https://adk.dev/agents/multi-agents/) if left empty. | | `static_instruction` | `PLANNER.build()` returns the system prompt. Marked as stable, enabling [context caching](https://adk.dev/context/caching/). | | `generate_content_config` | `temperature=0.1` for structured output like GeoJSON routes. | | `tools` | `get_tools()` returns a mix of [tool types](https://adk.dev/tools-custom/function-tools/) that ADK runs in parallel: [`SkillToolset`](https://adk.dev/skills/) (lazy-loaded), `PreloadMemoryTool` (injects [past conversations](https://adk.dev/sessions/memory/) before each LLM call), `FunctionTool` wrappers, and an [MCP toolset](https://adk.dev/tools-custom/mcp-tools/) for Google Maps. | | `before_model_callback` | Runs `financial_guardrail_callback` before every LLM call. If it returns an `LlmResponse`, ADK [skips the model](https://adk.dev/callbacks/types-of-callbacks/) and uses that response instead. | code: language: python linkify: true repoPath: agents/planner/agent.py regionTag: planner_agent - title: Maps MCP Tools icons: - /external-assets/basic-planner.svg - /external-assets/maps.svg mode: markdown info: | This function discovers Google Maps [MCP tools](https://adk.dev/tools-custom/mcp-tools/) at runtime through the [Agent Registry](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-registry/overview) service (`agentregistry.googleapis.com`). Once discovered, the planner's LLM can call Maps tools directly for landmarks, weather, and routing data. The Maps server is identified in the registry by the string `"mapstools.googleapis.com"` (held in the `_MAPS_MCP_DISPLAY_NAME` constant at the top of the snippet — the resource names are opaque UUIDs, so display name is the stable handle). The discovery flow: 1. Create an `AgentRegistry` client with the project ID and a `header_provider` that injects the Maps API key 2. Call `registry.list_mcp_servers()` and match each entry's `displayName` against `"mapstools.googleapis.com"` 3. Call `registry.get_mcp_toolset()` to get a toolset the LLM can call directly 4. Strip default ADC auth headers, since Maps uses API key auth, not application default credentials code: language: python linkify: true repoPath: agents/planner/adk_tools.py regionTag: maps_mcp_tools - title: Planner Role & Persona icons: - /external-assets/basic-planner.svg - /external-assets/gemini.svg mode: markdown info: | The `ROLE` section opens the system prompt, defining the agent as a city marathon event architect. The prompt uses short constraint phrases the model can reference when making tradeoffs: - Five planning priorities: safety, community, logistics, finances, experience - Route generation instructions for the `plan_marathon_route` tool, including the zone-sweep algorithm and Las Vegas Strip start/finish constraints code: language: python linkify: true repoPath: agents/planner/prompts.py regionTag: planner_role - title: Strict Execution Workflow icons: - /external-assets/basic-planner.svg - /external-assets/gemini.svg mode: markdown info: | The `WORKFLOW` section enforces a strict 7-step execution order. **Lazy skill loading** (step 2): The agent calls [`load_skill`](https://adk.dev/skills/) to activate `gis-spatial-engineering` right before it needs the route tools. Skills are loaded on-demand, keeping the tool namespace small. **Parallel tool calls** (step 4): The prompt tells the model to call `report_marathon_route`, weather lookup, and landmark lookup "in the SAME response." ADK [runs them concurrently](https://adk.dev/tools-custom/function-tools/), cutting latency vs. sequential calls. The "EXACTLY ONCE" constraints prevent models from re-invoking tools on long or ambiguous results. code: language: python linkify: true repoPath: agents/planner/prompts.py regionTag: planner_workflow - id: evaluation-planner-inspect title: Planner with evaluation description: | Extends the base planner with a secondary evaluation agent that scores the route against quality metrics, then refines the plan based on those scores. architecture: - cloudrun - pubsub - advanced-planner - agent-engine - geap examples: - title: Planner with Evaluation icons: - /external-assets/planner-with-evaluation.svg - /external-assets/adk.png mode: markdown info: | This agent extends the base Planner with automated plan [evaluation](https://adk.dev/evaluate/). Compare this `get_agent()` to the base planner's. The differences show how ADK agents compose: | Difference | What changed | |-----------|-------------| | `model` | Read from `PLANNER_MODEL` env var (default `gemini-3-flash-preview`), so you can swap models at deploy time | | `static_instruction` | Uses `PLANNER_WITH_EVAL.build()`, a `PromptBuilder.override()` of the base planner. Replaces the workflow and tools sections with evaluation-aware versions and adds A2UI dashboard instructions. | | `generate_content_config` | `temperature=0.2`, `max_output_tokens=8192`, and conditional `ThinkingConfig(thinking_budget=1024)` for "pro" models. Visible above `get_agent()` in the snippet. | | `tools` | Adds `evaluate_plan`, `start_simulation`, `submit_plan_to_simulator`, and `validate_and_emit_a2ui` alongside the base planner's tools | code: language: python linkify: true repoPath: agents/planner_with_eval/agent.py regionTag: planner_eval_agent - title: Strict Evaluation Workflow icons: - /external-assets/planner-with-evaluation.svg - /external-assets/gemini.svg mode: markdown info: | This workflow replaces the base planner's via `PromptBuilder.override()`, expanding it from 7 steps to 9 with evaluation, verification, and A2UI dashboard rendering. What's new over the base workflow: - Step 4 adds `assess_traffic_impact` as a parallel tool call alongside `report_marathon_route` - Step 5 requires coverage of six quality pillars with specific keywords the evaluator checks for - Step 6 runs `evaluate_plan` and `submit_plan_to_simulator(action="verify")` in the same response. Evaluation scores plan quality while the simulator validates structural readiness, independently and concurrently. - Step 8 emits a structured UI dashboard via `validate_and_emit_a2ui` - Step 9 stops the agent ("STOP and wait for user feedback") to prevent unwanted continuation code: language: python linkify: true repoPath: agents/planner_with_eval/prompts.py regionTag: eval_workflow - title: Simulator Handoff icons: - /external-assets/planner-with-evaluation.svg - /external-assets/adk.png - /external-assets/geap.svg mode: markdown info: | This [`FunctionTool`](https://adk.dev/tools-custom/function-tools/) sends the marathon plan to the simulator agent via the [A2A protocol](https://adk.dev/a2a/intro/). It handles two actions: `verify` (structural check) and `execute` (run the simulation). Three problems it solves: **Two-channel data transfer.** The GeoJSON route is too large for an A2A message context window. So the tool writes the full route to Redis (`simdata:{session_id}`) and sends only a reference plus a narrative summary via A2A. The simulator reads the route back from Redis. **Re-entrancy guard.** The LLM sometimes ignores "STOP" instructions and calls this tool again in the same turn. The guard checks `tool_context.state["simulation_executed_invocation"]` against the current `invocation_id`. Same invocation = duplicate; new user message = legitimate retry. **Coordination with `start_simulation`.** Both tools get called in the same LLM response. This function polls `tool_context.state` for up to 2 seconds waiting for `start_simulation` to write a fresh `simulator_session_id`, using token matching to distinguish fresh values from stale ones. code: language: python linkify: true repoPath: agents/planner_with_eval/tools.py regionTag: submit_to_simulator - id: memory-planner-inspect title: Planner with Memory mode: html architecture: - cloudrun - pubsub - planner-memory - geap examples: - title: Planner with Memory icons: - /external-assets/memory-planner.svg - /external-assets/adk.png mode: markdown info: | The third planner variant. It extends the eval planner with cross-session [memory](https://adk.dev/sessions/memory/). The key line is [`after_agent_callback=[auto_save_memories]`](https://adk.dev/callbacks/types-of-callbacks/), an ADK lifecycle hook that fires after the agent completes its response. This pattern works any time you need post-response side effects (logging, persistence, cleanup) without changing what the agent says to the user. Other differences from the eval planner: - No `before_model_callback`. The code comments explain why: this variant uses A2UI cards for financial refusals instead of the programmatic guardrail. A `before_model_callback` would short-circuit the LLM before it could emit the refusal card. - Prompt uses `PLANNER_WITH_MEMORY.build()`, which overrides the eval planner's workflow with memory-aware steps (recall past routes, save new ones). - Tools add memory recall and AlloyDB rules lookup alongside the eval planner's set. code: language: python linkify: true repoPath: agents/planner_with_memory/agent.py regionTag: planner_memory_agent - title: Memory Integration icons: - /external-assets/memory-planner.svg - /external-assets/adk.png mode: markdown info: | Called by `after_agent_callback` after every agent turn. It saves the current session to [Vertex AI Memory Bank](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/manage-memory) so future sessions can recall past marathon plans. 1. Checks if a `memory_service` already exists on the `invocation_context` (set during runner initialization) 2. If not, creates one via `create_memory_service()` using the `AGENT_ENGINE_ID` environment variable, which connects to the Memory Bank API for a specific [Agent Engine](https://adk.dev/deploy/agent-engine/) deployment 3. Calls `memory_service.add_session_to_memory(session)`, which sends the session's conversation events to Memory Bank for indexing On the retrieval side, `PreloadMemoryTool` automatically searches this memory bank before each LLM call and injects relevant past conversations into the system prompt. The model doesn't need to call a tool explicitly. code: language: python linkify: true repoPath: agents/planner_with_memory/services/memory_manager.py regionTag: auto_save_memories links: - label: "Preload Memory Tool API Reference" url: https://adk.dev/api-reference/python/google-adk.html#google.adk.tools.preload_memory_tool.PreloadMemoryTool - id: simulator-inspect title: Scaling runners with Kubernetes Engine and Gemma mode: html architecture: - cloudrun - pubsub - scaled-simulator - runner-agent - agent-engine - kubernetes-engine - gemma - geap examples: - title: Orchestrating Simulator icons: - /external-assets/simulator.svg mode: markdown info: | The simulation uses ADK's [workflow agents](https://adk.dev/agents/workflow-agents/) to run a multi-phase race. This [`SequentialAgent`](https://adk.dev/agents/workflow-agents/sequential-agents/) runs three sub-agents in order: 1. `pre_race_agent` spawns runner NPCs and fires the start gun. It uses a deterministic `before_model_callback` to sequence tool calls without any LLM involvement. 2. `race_engine` is a [`LoopAgent`](https://adk.dev/agents/workflow-agents/loop-agents/) that advances simulation ticks until all runners finish or the race times out. Each iteration calls `advance_tick` then `check_race_complete`, exiting via `actions.escalate` when done. 3. `post_race_agent` collects results and generates analytics. The `SequentialAgent` itself has no LLM. It just runs `sub_agents` in list order, keeping expensive model calls inside each sub-agent where they're needed. The orchestration layer is pure control flow. The root simulator agent is actually an `LlmAgent` that wraps this pipeline as an [`AgentTool`](https://adk.dev/agents/multi-agents/). It receives A2A messages, parses the JSON action field, and routes to the right tool. code: language: python linkify: true repoPath: agents/simulator/agent.py regionTag: simulator_pipeline - title: Scaled NPC Runner icons: - /external-assets/simulator.svg - /external-assets/gke.png - /external-assets/runner.svg - /external-assets/gemma.png mode: markdown info: | Each NPC runner is an [`LlmAgent`](https://adk.dev/agents/llm-agents/) that receives tick updates and decides how to race. The `static_instruction` defines the full strategy in a compact prompt. A tick update in simulation and games systems is an event that represents a discrete step in time, providing the delta time to apply state updates, AI decisions, or other logic. The required action sequence: call `accelerate` (or `brake`) to set speed, then call `process_tick` to advance. The model must call tools in this order every turn. Hydration rules are threshold-based: always rehydrate below 40, probabilistic above 40, always when exhausted. These give the LLM clear decision boundaries instead of open-ended reasoning. The `inner_thought` parameter on every `process_tick` call is a required 5-word internal monologue. The prompt is specific about what "unique" means here: "random cravings, regrets, weird observations, bargaining with their legs." code: language: python linkify: true repoPath: agents/runner/agent.py regionTag: runner_instruction - id: npc-runner-logic title: Autonomous NPC Runner Decision Making description: | To run hundreds of NPC runners more cost effectively, the platform uses Gemma models served via vLLM on [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine), keeping per-tick latency and cost low. mode: html architecture: - cloudrun - pubsub - scaled-simulator - runner-agent - agent-engine - kubernetes-engine - gemma - geap examples: - title: Competitive Strategy Logic icons: - /external-assets/runner.svg - /external-assets/gemma.png mode: markdown info: | How the runner agent configures its model for high throughput at low cost. The runner supports multiple backends: [Gemini](https://adk.dev/agents/models/google-gemini/), [Ollama](https://adk.dev/agents/models/ollama/), or [vLLM](https://adk.dev/agents/models/vllm/) serving [Gemma](https://adk.dev/agents/models/google-gemma/) on [GKE](https://adk.dev/deploy/gke/). | Setting | Why | |---------|-----| | `include_contents="none"` | No conversation history. The runner gets only the current tick's input, keeping token count constant regardless of race length. Set via `LlmAgent`'s [`include_contents`](https://adk.dev/agents/llm-agents/) parameter. | | `ThinkingConfig(thinking_budget=0)` | Disables extended thinking for Gemini models. Runners need fast mechanical decisions, not deep reasoning. | | `temperature` | `0.3` for Gemini (consistent tool use), `0.8` for non-Gemini (more varied `inner_thought` generation). | | `max_output_tokens=256` | Runner outputs are short: a couple tool calls and a one-sentence summary. Capping tokens saves cost at scale. | `get_agent()` wires this config with `static_instruction` and the shared running/hydration tools. When running hundreds of NPCs on vLLM + Gemma on GKE, these settings keep per-tick latency and cost low. code: language: python linkify: true repoPath: agents/runner/agent.py regionTag: runner_model_config - id: communication-inspect title: Inter-agent communication and discovery mode: html architecture: - cloudrun - pubsub - agent-engine examples: - title: Dynamic Agent Discovery icons: - /external-assets/agent-engine.png mode: markdown info: | Agents discover each other at runtime via [A2A](https://adk.dev/a2a/intro/). An `AgentCard` is the structured manifest each ADK agent publishes — its name, URL, supported transports, and capabilities — that callers use to connect to it. This method fetches every agent card from the Gateway's `/api/v1/agent-types` endpoint, parses each one with `AgentCard.model_validate()` (which handles camelCase ↔ snake_case alias resolution), and caches the result for 30 seconds across all `SimulationA2AClient` instances in the same process. The caller (`get_agent()`) uses the card's URL to create a `RemoteA2aAgent` instance, picking the right transport: `http_json` for [Agent Engine](https://adk.dev/deploy/agent-engine/) deployments (which reject JSON-RPC), `jsonrpc` for local/[Cloud Run](https://adk.dev/deploy/cloud-run/) agents. code: language: python linkify: true repoPath: agents/utils/communication.py regionTag: a2a_discovery - title: Real-time Telemetry Pulses icons: - /external-assets/agent-engine.png mode: markdown info: | `emit_narrative_pulse` is the project's high-level helper for sending a narrative event to a session. The caller provides plain text and an author name; the function fills in the structural fields (origin shape, destination list, status, event type, JSON payload) and delegates to the lower-level `emit_gateway_message` (defined just above this snippet in the same file). That call serializes the event into a protobuf `Wrapper`, publishes it to Redis, and the frontend renders it via WebSocket. `emit_inter_agent_pulse` builds on top of `emit_narrative_pulse`: it formats a human-readable banner (`📢 planner -> simulator: ...` for requests, `📨` for responses) and forwards it as a narrative pulse with `type="inter-agent"`. So one function call by an agent — `emit_inter_agent_pulse(...)` — flows through `emit_narrative_pulse` → `emit_gateway_message` → Redis → WebSocket → the animated communication graph. Both wrappers are project utilities, not part of the ADK framework. [View `pulses.py` on GitHub →](https://github.com/GoogleCloudPlatform/race-condition/blob/main/agents/utils/pulses.py) code: language: python linkify: true repoPath: agents/utils/pulses.py regionTag: emit_narrative_pulse - id: prompt-builder-inspect title: "Concept: Composable prompt management" # devOnly: true description: | Three planner agents share most of their system prompt but differ in specific sections. `PromptBuilder` solves this with named sections in an `OrderedDict`, assembled by `build()`, extended by `override()`. Each variant specifies only what's different. Below: the builder class, then all three planners and their workflow prompts side by side. architecture: - basic-planner - advanced-planner - planner-memory examples: - title: PromptBuilder icons: - /external-assets/basic-planner.svg mode: markdown info: | The class is immutable. `override()` returns a new instance, so you can't accidentally mutate a parent builder that other agents depend on. Two output modes optimize for [context caching](https://adk.dev/context/caching/): - `build()` joins all sections into a single string for [`static_instruction`](https://adk.dev/agents/llm-agents/) (stable content, cacheable) - `dynamic(exclude=(...))` returns an async `InstructionProvider` for `instruction` (per-request content that can read `ctx.state`) code: language: python linkify: true repoPath: agents/utils/prompt_builder.py regionTag: prompt_builder - title: Base planner assembly icons: - /external-assets/basic-planner.svg mode: markdown info: | The base planner defines six named sections, each a string constant defined earlier in the file. Order matters: `build()` joins them top-to-bottom, so the model sees `ROLE` first and `FINANCIAL` last. All three planner variants inherit these sections. When the eval planner calls `override(workflow=EVAL_WORKFLOW)`, only the `workflow` key gets replaced. The other five carry forward unchanged. code: language: python linkify: true repoPath: agents/planner/prompts.py regionTag: planner_builder - title: Base planner workflow icons: - /external-assets/basic-planner.svg mode: markdown info: | The base planner's 7-step workflow. This is the `workflow` section that each variant replaces. Compare it with the eval and memory workflows below to see exactly what changes at each level of the override chain. Steps 1-4 are shared across all variants (generate route, load skill, report results). Steps 5-7 are where variants diverge. code: language: python linkify: true repoPath: agents/planner/prompts.py regionTag: planner_workflow - title: Eval planner override icons: - /external-assets/planner-with-evaluation.svg mode: markdown info: | The eval planner inherits from `PLANNER` and replaces two sections (`tools`, `workflow`) while adding three new ones (`simulator`, `a2ui`, `execution`). New keys append to the end of the ordered dict, so the model sees inherited sections first, then eval-specific ones. code: language: python linkify: true repoPath: agents/planner_with_eval/prompts.py regionTag: planner_eval_builder - title: Eval planner workflow icons: - /external-assets/planner-with-evaluation.svg mode: markdown info: | The eval workflow expands from 7 to 9 steps. Compare with the base workflow above: - Steps 1-3 are identical (requirements, skill, route) - Step 4 adds `assess_traffic_impact` as a parallel call - Step 5 adds six quality pillars with specific keyword requirements the evaluator checks for - Step 6 is new: parallel `evaluate_plan` + `submit_plan_to_simulator(action="verify")` - Steps 8-9 are new: A2UI dashboard emission and explicit STOP The prompt states "this workflow REPLACES the base planner workflow" so the model doesn't try to merge them. code: language: python linkify: true repoPath: agents/planner_with_eval/prompts.py regionTag: eval_workflow - title: Memory planner override icons: - /external-assets/memory-planner.svg mode: markdown info: | The memory planner extends the eval planner, not the base. It replaces `tools`, `workflow`, and `execution` again, and adds `memory` and `post_simulation`. The full chain: `PLANNER` (6 sections) -> `PLANNER_WITH_EVAL` (replaces 2, adds 3) -> `PLANNER_WITH_MEMORY` (replaces 3, adds 2) Each level only specifies what's different. `ROLE`, `RULES`, `SKILLS`, and `FINANCIAL` are defined once in the base and inherited through the entire chain. code: language: python linkify: true repoPath: agents/planner_with_memory/prompts.py regionTag: planner_memory_builder - title: Memory planner workflow icons: - /external-assets/memory-planner.svg mode: markdown info: | The memory workflow is the most complex variant. Compare with the base and eval workflows: - Adds `TERMINAL_RULES` preamble: after any simulation, the agent must call `record_simulation` + `store_simulation_summary` + emit an A2UI card, then stop. This prevents re-execution. - Adds message classification before step 1: "recall a stored route" vs. "plan a new marathon" routes to different workflows entirely - Step 2 is new: parallel `recall_past_simulations` + `get_local_and_traffic_rules` before skill loading - Step 6 adds `store_route` as a parallel call alongside verification, persisting the route for future recall 11 total sections, but the core `ROLE`, `RULES`, `SKILLS`, and `FINANCIAL` are still just inherited from the base. code: language: python linkify: true repoPath: agents/planner_with_memory/prompts.py regionTag: memory_workflow - id: autopilot-inspect title: "Concept: LLM-free agents with callback interception" # devOnly: true description: | This project runs two versions of the same runner agent: one powered by Gemini/Gemma, one completely deterministic. - **Cost.** At 1000 runners x ~50 ticks per race, that's 50,000 model calls per simulation. The autopilot runner makes zero. - **Latency.** LLM calls take 200-2000ms. The autopilot callback returns in microseconds. - **Determinism.** Same session ID, same runner profile, same race outcome. Good for testing, replay, and debugging. - **Reliability.** No prompt injection, no hallucinated tool calls, no "I'm sorry, I can't accelerate" refusals. The agent still gets ADK's [A2A protocol](https://adk.dev/a2a/intro/), tool calling, telemetry, and session state without the LLM. The simulator doesn't care which version is running. architecture: - cloudrun - runner-agent - kubernetes-engine examples: - title: Autopilot agent wiring icons: - /external-assets/runner.svg mode: markdown info: | The autopilot reuses the base runner via `get_base_agent()` and overrides three things: the callback, the instruction, and the generation config. The model (`gemini-3.1-flash-lite-preview`) is inherited from the base runner and never actually called -- `before_model_callback=autopilot_callback` intercepts every invocation. ADK's `LlmAgent` requires a valid model name; you can't pass `"none"` or an arbitrary string. The model here is a real Gemini model used as a fallback: if the callback ever fails to return an `LlmResponse`, ADK calls this model instead. `max_output_tokens=1` and `temperature=0.0` minimize cost and nondeterminism in that case. code: language: python linkify: true repoPath: agents/runner_autopilot/agent.py regionTag: autopilot_agent - title: Building LlmResponse objects icons: - /external-assets/runner.svg mode: markdown info: | When your [`before_model_callback`](https://adk.dev/callbacks/types-of-callbacks/) returns an `LlmResponse`, ADK treats it as if the model produced it. You can return tool calls, and ADK will execute them through its normal tool pipeline. There are two response patterns here: `_function_call_response(name, args)` builds an `LlmResponse` containing a `FunctionCall` part. ADK sees this, runs the named tool with the given args, then calls the callback *again* with the tool's result appended to `llm_request.contents`. This is the DECIDE phase. `_text_response(text)` builds an `LlmResponse` containing a text part. ADK treats this as the agent's final answer for the turn. This is the SUMMARIZE phase. The two-phase loop (DECIDE, then SUMMARIZE) mirrors what an LLM would do on its own: pick an action, see the result, respond. The callback makes both decisions programmatically instead. Watch out for the re-invocation behavior: after a tool call, ADK calls your callback again with the tool result. If you don't detect that second call and return text, you'll loop forever. code: language: python linkify: true repoPath: agents/runner_autopilot/autopilot.py regionTag: autopilot_responses - title: Dispatch table and callback icons: - /external-assets/runner.svg mode: markdown info: | `autopilot_callback` is the callback entry point, called by ADK before every model invocation. Because it always returns an `LlmResponse`, the model never runs. Here's how a request flows through: 1. `detect_phase()` checks whether the last content entry has `function_response` parts. If so, a tool just executed and we're in SUMMARIZE phase. Return a one-line status summary. 2. Otherwise, we're in DECIDE phase. Parse the user message into a typed `RunnerEvent` (event type + data dict). 3. Look up the handler in the `HANDLERS` dispatch table. Each handler is a pure function: `(state, data) -> LlmResponse`. 4. Return the handler's response. ADK executes any tool calls in it, then calls back for the summary. Adding a new event type is just two steps: write a handler function, add it to `HANDLERS`. The callback itself doesn't change. code: language: python linkify: true repoPath: agents/runner_autopilot/autopilot.py regionTag: autopilot_dispatch - id: a2ui-inspect title: "Concept: A2UI — teaching agents to render UI" # devOnly: true description: | [A2UI](https://a2ui.org) is an open protocol for agents to emit declarative UI as JSON. The agent composes a flat list of typed components (Card, Row, Text, Button, Slider, and 12 others from the [v0.8 Standard Catalog](https://a2ui.org/specification/v0.8-a2ui/)). The frontend renders them natively. No executable code crosses the trust boundary. This project teaches the agent the protocol through an [ADK skill](https://adk.dev/skills/) containing the spec, a validation tool that catches structural errors before the payload reaches the frontend, and dashboard templates in the system prompt. architecture: - angular - advanced-planner - cloudrun examples: - title: Component spec as a skill icons: - /external-assets/planner-with-evaluation.svg mode: markdown info: | The agent learns the A2UI protocol from this skill file. When loaded via [`load_skill`](https://adk.dev/skills/), the content below becomes part of the system prompt. The `validate_and_emit_a2ui` tool is registered separately as a top-level [`FunctionTool`](https://adk.dev/tools-custom/function-tools/) by the planner, so it stays available regardless of whether this skill is loaded. The spec defines three things the LLM needs to produce valid payloads: 1. **Message structure.** Two message types work together: `surfaceUpdate` sends a flat array of component definitions, `beginRendering` tells the frontend which component is root. Both are required. Without `beginRendering`, the frontend buffers components but never renders them. 2. **Typed value wrappers.** All property values use wrappers like `{"literalString": "..."}` or `{"literalBoolean": true}` instead of raw JSON primitives. This is how the [A2UI v0.8 protocol](https://a2ui.org/specification/v0.8-a2ui/) distinguishes literal values from data-bound paths. 3. **The 18 Standard Catalog primitives.** Layout containers (Column, Row, Card), display components (Text, Image, Icon), and input controls (Button, Slider, TextField). Each has required and optional properties listed in the tables below. Why a skill file instead of hardcoding the spec in the prompt? Skills are lazy-loaded. Agents that don't need A2UI rendering never pay the token cost. code: linkify: true repoPath: agents/skills/a2ui-rendering/SKILL.md regionTag: - a2ui_skill_message_structure - a2ui_skill_wrappers - title: Validation tool icons: - /external-assets/planner-with-evaluation.svg mode: markdown info: | This tool catches structural mistakes before the payload reaches the frontend, returning violations the LLM can act on to self-correct. Validation runs in two passes: **Pass 1 (per-component)** iterates the `components` array and checks four things for each entry: the component type exists in the 18-type catalog, all required properties are present, string and boolean properties use typed wrappers (`literalString`, `literalBoolean`) instead of raw values, and container children use `{"explicitList": [...]}` instead of raw arrays. **Pass 2 (reference resolution)** collects every ID reference from `child`, `children.explicitList`, `tabItems[].child`, `entryPointChild`, and `contentChild` properties, then verifies each one resolves to a component ID in the same `surfaceUpdate`. This catches dangling references from typos or deleted components. On failure, the tool returns `{"status": "error", "violations": [...]}` where each violation includes the component ID, field name, and a human-readable fix. The LLM reads these, patches the payload, and calls the tool again. On success, the validated payload passes through to the frontend via the ADK event stream. code: linkify: true repoPath: agents/skills/a2ui-rendering/tools.py regionTag: - a2ui_validation_passes - a2ui_validation_result - title: Dashboard template in the prompt icons: - /external-assets/planner-with-evaluation.svg mode: markdown info: | The skill spec tells the LLM *what* A2UI components exist. This prompt teaches it *how* to assemble them. The example is the smallest valid `surfaceUpdate` + `beginRendering` pair: a `Card` containing a `Column` with two `Text` children, four components total. The full Plan Dashboard and Simulation Results templates further down in the `A2UI` constant follow the same pattern. They just compose more rows and columns. Three rules trip up LLMs and the example shows all three: `Card` takes a singular `child` ID (not `body` or `children`), container children go inside `explicitList`, and every string value gets a `literalString` wrapper. The eval planner picks this up via `PromptBuilder.override(a2ui=A2UI)`, which appends it after the inherited base prompt. Other planners don't get it. code: linkify: true repoPath: agents/planner_with_eval/prompts.py regionTag: a2ui_prompt_template - title: Recursive frontend renderer icons: - /external-assets/angular.svg mode: markdown info: | The Angular renderer uses a single recursive `ng-template` to walk the A2UI component tree. Four excerpts from the template show the pattern. The **entry point** binds `rootNode` to the template, which dispatches on `getType(node)` via `ngSwitch`. Each component type gets its own case. The CSS class is derived from the type name (`a2ui-Column`, `a2ui-Text`, etc.), so styling maps directly to the A2UI catalog. **Column** is a layout container. It iterates `getChildren(node)` and recurses through the same `#renderer` template for each child. Row, List, and Card follow the same pattern with minor variations. **Display components** (Text, Icon, Image) are leaf nodes. They read properties through helpers like `getText()` and `getUsageHint()`, which unwrap the v0.8 typed value wrappers (`{literalString: "..."}`) into plain strings. No recursion needed. **Button** is where the agent's actions reach the user. It recurses its `child` for the label, and `handleButtonClick` routes the `action.name` string to a registry of TypeScript callbacks. The `run_simulation` action, for example, sends a message back to the agent via the gateway service. code: language: html linkify: true repoPath: web/frontend/src/app/components/a2ui/a2-ui-controller.component.html regionTag: - a2ui_template_entry - a2ui_template_column - a2ui_template_display - a2ui_template_button - type: quiz questions: - title: Which Google Cloud framework is used to build the autonomous agents in the Race Condition simulation? answers: - answer: Angular Development Platform - answer: Agent Development Kit (ADK) correct: true - answer: Cloud Run Functions SDK - answer: Vertex AI Studio - title: How does the Planner agent fetch real-world geographic and routing data? answers: - answer: By querying a static local JSON dataset - answer: Through a Model Context Protocol (MCP) server connected to Google Maps correct: true - answer: Using hardcoded lat/long pairs in system prompts - answer: By using the Google Maps JavaScript API - title: To scale the simulation to hundreds of autonomous NPCs economically, where are the lightweight runner models hosted? answers: - answer: As Google Kubernetes Engine (GKE) workloads serving Gemma via vLLM correct: true - answer: Inside a single local Docker container using SQLite - answer: On Cloud Storage buckets using static HTML rendering - answer: Using standard HTTP callbacks to third-party webhooks - title: What technique is used by the Advanced Planner to ensure the generated marathon route meets safety and logistical standards? answers: - answer: Manual human-in-the-loop approval via email - answer: Automated LLM-as-Judge evaluation scoring correct: true - answer: Simple regex string matching on the narrative output - answer: Unit tests using standard Python assertions - title: How do agents within the simulation persist important data across independent user sessions? answers: - answer: Storing flat files inside container memory - answer: Writing logs directly to stdout for persistent capture - answer: Leveraging the Vertex AI Memory Bank service correct: true - answer: Stashing variables in browser localStorage - type: video youtubeId: WYPdz3OZfuQ navigationTitle: "Bonus: Fireside Chat" title: Fireside chat with the team description: Join Casey West and Tom Greenaway as they chat through some of the development choices and learnings made during the creation of Race Condition. # - type: video # youtubeId: A01DQ8_xy7Q # navigationTitle: "Bonus: Developer Keynote" # title: Cloud Next 2026 Developer Keynote # description: Watch the full developer keynote from Cloud Next 2026, featuring Race Condition as the simulation sandbox powering all the agent demos and other announcements. - type: build promoType: github links: - url: https://github.com/GoogleCloudPlatform/race-condition label: Open on GitHub - url: https://developer.google.com/solutions label: Explore more Solutions - url: https://docs.cloud.google.com/gemini-enterprise-agent-platform label: Gemini Enterprise Agent Platform architecture: height: 420 # expandedByDefault: true boxes: - id: geapbox label: "Gemini Enterprise Agent Platform" entities: - geap - session-store - memory-bank - gemini entities: - id: angular label: Angular icon: /external-assets/angular.svg x: 0 y: -4 connections: - from: angular to: cloudrun - id: cloudrun label: Cloud Run icon: /external-assets/cloud-run.svg x: 2 y: -4 connections: - from: cloudrun to: pubsub - id: pubsub label: Pub/Sub icon: /external-assets/pubsub.svg x: 4 y: -4 connections: - from: pubsub to: basic-planner - from: pubsub to: advanced-planner - from: pubsub to: planner-memory - from: pubsub to: scaled-simulator # - from: pubsub # to: agent-engine - id: basic-planner label: Planner icon: /external-assets/basic-planner.svg x: 6 y: -4 inspect: planner-inspect connections: - from: basic-planner to: agent-engine - from: basic-planner to: google-maps - id: google-maps label: Google Maps icon: /external-assets/maps.svg x: 6 y: -6 - id: advanced-planner label: Planner with evaluation icon: /external-assets/planner-with-evaluation.svg x: 6 y: -2 inspect: evaluation-planner-inspect connections: - from: advanced-planner to: agent-engine - id: planner-memory label: Planner with memory icon: /external-assets/memory-planner.svg x: 6 y: -8 inspect: memory-planner-inspect connections: - from: planner-memory to: agent-engine - from: planner-memory to: memorystore - from: planner-memory to: alloy - from: planner-memory to: geap - id: scaled-simulator label: Simulator icon: /external-assets/simulator.svg x: 6 y: 0 inspect: simulator-inspect connections: - from: scaled-simulator to: agent-engine - from: scaled-simulator to: runner-agent - id: runner-agent label: Runner Agent icon: /external-assets/runner.svg x: 8 y: 1 inspect: npc-runner-logic connections: - from: runner-agent to: agent-engine - from: runner-agent to: kubernetes-engine - id: kubernetes-engine label: Kubernetes Engine icon: /external-assets/gke.png x: 10 y: 1 connections: - from: kubernetes-engine to: gemma - id: gemma label: Gemma icon: /external-assets/gemma.png x: 12 y: 1 - id: agent-engine label: Agent Engine icon: /external-assets/agent-engine.png x: 8 y: -4 inspect: communication-inspect connections: - from: agent-engine to: geap - id: memorystore label: Memorystore icon: /external-assets/memorystore.svg x: 8 y: -9 - id: alloy label: AlloyDB icon: /external-assets/alloy.svg x: 8 y: -7 - id: geap label: Gemini Enterprise Agent Platform icon: /external-assets/geap.svg x: 10 y: -4 connections: - from: geap to: gemini - from: geap to: session-store - from: geap to: memory-bank - id: gemini label: Gemini icon: /external-assets/gemini.svg x: 12 y: -6 - id: session-store label: Session Store icon: /external-assets/session-store.svg x: 12 y: -4 - id: memory-bank label: Memory Bank icon: /external-assets/memory-bank.svg x: 12 y: -2 badges: startBadge: https://developers.google.com/profile/badges/playlists/solutions/race-condition/view exploreBadge: https://developers.google.com/profile/badges/playlists/solutions/race-condition/learn quizBadge: https://developers.google.com/profile/badges/playlists/solutions/race-condition/quiz buildBadge: https://developers.google.com/profile/badges/playlists/solutions/race-condition/action