Apply the same fixes to both the strands (Python) and strands-typescript
integrations for 1:1 parity:
- Lift RunAgentInput.context into the prompt (buildStatePrompt /
build_state_prompt) so useAgentContext values (readonly-state-agent-context)
and the openGenerativeUI design-skill / sandbox-function context actually
reach the model. The adapter does not surface context on its own; this
mirrors langgraph's lift-context-into-prompt pattern.
- open-gen-ui: prepend an imperative to the visualization design skill (and add
a design skill to the advanced cell) so the model calls generateSandboxedUi
instead of answering in plain text, and clarify that sandbox functions are
iframe->host bridges, not LLM tools.
- hitl-in-chat: sharpen the book_call description so it wins scheduling intents
over the shared backend schedule_meeting tool (which renders no picker).
- Add a roll_dice tool (shared python tools + TS tools) so the tool-rendering
catch-all 'Roll a d20' and 'Chain tools' pills work.
Brings the Google ADK showcase back to parity with the langgraph-python
north-star across the 14 issues catalogued in PR #4792's TL;DR. Four
independent classes of bug fixed; all 36 demos now route, terminate, and
render correctly against real Gemini.
1. Universal Gemini infinite tool loop
ADK's LlmAgent does not naturally terminate after a tool result with
Gemini 2.5-flash — every backend or frontend tool fired forever. Lifted
the (orphaned) `simple_after_model_modifier` from agents/main.py into
shared_chat.stop_on_terminal_text without the SalesPipelineAgent
name-gate; wired it as `after_model_callback=` into every registered
LlmAgent (22 dedicated agents plus the build_simple_chat_agent /
build_thinking_chat_agent factories). simple_after_model_modifier is
kept as a thin alias so the existing test file keeps resolving.
2. Stale @ag-ui/client trapped on deprecated event names
ag_ui_adk v0.6.1 emits the canonical REASONING_* events but the
integration's package.json pinned `@ag-ui/client: ^0.0.43` which under
npm's pre-1.0 caret rule resolves to strictly 0.0.43 — a version that
only knows the deprecated THINKING_* names. Every Gemini response
tripped the runtime's Zod discriminator. Bumped to ^0.0.53 and
regenerated the lockfile.
3. Frontend agent IDs out of sync with backend mounts
page.tsx for hitl-in-chat / frontend-tools-async / prebuilt-popup
declared underscored agent IDs that didn't appear in the runtime's
agent map, so useAgent threw "Agent not found after runtime sync"
and the React tree crashed. Renamed to the dashed form that matches
the registry. MCP Apps had the same class of bug at the route level —
copilotkit-mcp-apps/route.ts pointed HttpAgent at /mcp_apps but the
FastAPI mount is /mcp-apps; fixed to dash.
4. A2UI ops in deprecated v0.8 flat shape
tools/generate_a2ui.py:build_a2ui_operations_from_tool_call,
tools/search_flights.py, and agents/a2ui_fixed_agent.py emitted
`{type: "create_surface", surfaceId, ...}` (flat). The
@ag-ui/a2ui-middleware matcher only walks the v0.9 nested keys
(`{createSurface: {surfaceId, ...}}`), so every op was grouped under
the fallback "default" surface and the renderer threw
`Catalog not found: default` or
`Component 'undefined' is missing an 'id'`. Rewrote to v0.9 nested
shape with `version: "v0.9"` and `updateDataModel` using `path` +
`value` (matching copilotkit.a2ui Python helper).
Three follow-on fixes in agents/main.py and beautiful_chat_agent.py
that surfaced once the structural fix landed:
- _AGENT_NAME_TO_CATALOG_ID table + _resolve_pinned_catalog_id helper:
Gemini hallucinated catalog IDs because the schema for catalogId
was unconstrained; the north-star hardcodes CUSTOM_CATALOG_ID per
agent file, mirrored here with a name to id table so one shared
generate_a2ui dispatches per demo.
- Tightened parametersJsonSchema for components.items to require
id + component AND explicitly declare the optional text / label /
value / children / child / data props. Gemini's structured-output
path drops fields not in the schema even with default
additionalProperties: true, which produced [{}, {}, {}].
- Hard-requirements prompt prefix with a concrete PieChart example
ported from langgraph-python's _GENERATE_A2UI_PROMPT_HEADER, plus
_sanitize_a2ui_components / _has_root_component validators and
_unstringify_json_fields to round-trip Gemini's quirk of emitting
"data": "[{...}]" as a JSON string instead of an actual array.
Windows note: the integration's tools/ symlink does not materialize on
Windows worktrees (git stores it as mode 100644). The local copies under
showcase/integrations/google-adk/tools/ are kept byte-identical to the
canonical sources under showcase/shared/python/tools/. On Linux/macOS
where the symlink works, only the shared/ copy is authoritative.
Two follow-up fixes layered on the previous internal-tool rename:
(1) `a2ui_fixed.py` — fixed-schema demo infinite loop on deploy. The
`display_flight` tool returns the raw `a2ui.render(...)` JSON descriptor
as its tool result. gpt-4o-mini reads that opaque blob, can't tell the
flight was rendered, and re-calls `display_flight` indefinitely (visible
on the deployed showcase as 6+ duplicate flight cards stacked under
repeated assistant text). Local was just lucky.
Hardened the docstring + system prompt to spell out: the JSON return
value is the surface descriptor, the card is already rendered, do NOT
call again, reply with one short confirmation and stop.
(2) Rename `render_a2ui` → `_design_a2ui_surface` in shared and
langgraph-python parity copies of `tools/generate_a2ui.py` (+
`tools/__init__.py` re-export `RENDER_A2UI_TOOL_SCHEMA` →
`DESIGN_A2UI_SURFACE_TOOL_SCHEMA`), and in `showcase/shared/typescript/
tools/generate-a2ui.ts`. These shared helpers were the source-of-truth
for the secondary-LLM tool name across integrations; renaming here keeps
parity with the langgraph-python agents already renamed in
`beautiful_chat.py` / `a2ui_dynamic.py`. Other framework integrations
keep their own `render_a2ui` for now (separate parity sweep).
(3) `showcase/aimock/feature-parity.json` — added a sibling fixture
matching `toolName: "_design_a2ui_surface"` for the beautiful-chat Sales
Dashboard pill so the langgraph-python e2e suite still hits a
deterministic mock on Railway. The original `render_a2ui` fixture is
kept above it so other integrations whose secondary LLM still requests
`render_a2ui` continue to match.
(4) Comment update in `beautiful-chat.spec.ts` to name the new internal
tool.
1. EACCES on /home/app: Dockerfile templates now create home dir for
non-root user before USER app (langgraph-ts, claude-sdk-ts, mastra)
2. IndexError Path.parents[4]: search_flights.py schema fallback now
guards against shallow Docker paths (agno, claude-sdk-py, ms-agent-py)
3. Wrong import path: rewritePythonImports() now converts
from agents.X to relative imports in starter agent dirs (langroid, crewai)