Commit 52144dc
authored
feat: add AG-UI (AGUI) as fourth first-class protocol mode (#858)
* feat: add AG-UI (AGUI) as fourth first-class protocol mode
Add AGUI protocol support across the full CLI stack:
- Schema: Add 'AGUI' to ProtocolModeSchema, PROTOCOL_FRAMEWORK_MATRIX
(Strands, LangChain_LangGraph, GoogleADK), and RESERVED_PROJECT_NAMES
- Types: New agui-types.ts with 27 event type enum, typed interfaces,
parseAguiEvent parser, and buildAguiRunInput helper
- Templates: Python AGUI agent templates for Strands (ag-ui-strands),
LangGraph (ag-ui-langgraph), and GoogleADK (ag-ui-adk) frameworks
- Invoke: invokeAguiRuntime with dual-stream architecture (typed events
for TUI, text-only for CLI), local dev invokeAguiStreaming with
RunAgentInput body, protocol dispatch in invokeForProtocol
- TUI: Rich AGUI event rendering with MessagePart type (text, tool_call,
reasoning, error) in InvokeScreen, AGUI placeholder text in DevScreen
- Validation: Updated error messages and help text to include AGUI
- Tests: 24 unit tests for parseAguiEvent/buildAguiRunInput, snapshot
updates for new template files
* fix: address review findings for AGUI protocol implementation
HIGH fixes:
- Add sessionId to AguiInvokeOptions, pass as runtimeSessionId (H-1)
- Throw early for bearerToken on AGUI (not yet supported) (H-2)
- Add bedrock-agentcore dep to all 3 template pyproject.toml files (H-4/5/6)
- Fix LangGraph /ping to return "healthy" not "ok" (H-7)
- Match TOOL_CALL_RESULT to tool_call parts by toolCallId, not position (H-12)
- Add complete enum coverage to agui-types test (H-15)
MEDIUM fixes:
- Fix langchain version pin from 1.2.0 (nonexistent) to 0.3.0 (M-11)
- Remove invalid allow_credentials=True with wildcard CORS (M-12)
- Replace in-place parts mutation with immutable updates for React safety (M-5)
- Surface readLoop errors in consumer generators instead of swallowing (M-1)
- Disable retry once streaming starts to prevent duplicate output (M-3)
- Handle TEXT_MESSAGE_CHUNK events alongside TEXT_MESSAGE_CONTENT (M-2)
- Update gemini model from 2.0-flash to 2.5-flash in GoogleADK (M-8)
- Add missing event type exports to barrel index.ts (M-18)
LOW fixes:
- Move AGUI imports to top-level in action.ts (L-1)
- Gate OTEL_SDK_DISABLED on LOCAL_DEV env var in Strands template (L-9)
- Add explanatory comment for LANGGRAPH_FAST_API env var (L-10)
* fix: add AGUI to TUI protocol picker and dev mode dispatch
- Add AGUI option to PROTOCOL_OPTIONS in generate/types.ts so users
can select AGUI from the interactive create/add wizards
- Add AGUI case to useDevServer.ts sendMessage dispatch so local dev
TUI sends correct RunAgentInput body via invokeAguiStreaming
- Add AGUI case to dev/command.tsx non-interactive dispatch so
agentcore dev "prompt" uses invokeForProtocol('AGUI')
* fix: A2A GoogleADK template passes model=None to Agent constructor
load_model() returns None (it only sets GOOGLE_API_KEY env var as a
side effect). Passing model=load_model() to Agent() results in
model=None, causing the agent to either crash or use a default model.
Fix: call load_model() standalone for the side effect, then pass the
model ID string directly to Agent().
* chore: update protocol references to include AGUI across CLI
- AddScreen description: 'HTTP, MCP, A2A' → includes AGUI
- create --protocol help text: includes AGUI
- JSDoc comments in agent/types.ts, templates/types.ts, agent-env.ts
- codezip-dev-server comment: 'MCP/A2A' → 'MCP/A2A/AGUI'
- agent-env.test.ts: add AGUI to protocol acceptance test
* fix: add InvokeLogger to AGUI CLI path and improve UX polish
- Add InvokeLogger to AGUI CLI invoke block (action.ts) for prompt/response
logging and log file creation — parity with HTTP invoke path
- Track RUN_ERROR events in textStream and return success: false when
agent errors are detected
- Pass sessionId and logger to invokeAguiRuntime options
- Improve AGUI protocol picker description from circular 'AG-UI
agent-to-user interaction protocol' to actionable 'Stream rich agent
events to frontends (AG-UI)'
* fix: template bugs found during deployment testing
Bugs found by deploying all 3 AGUI frameworks to AWS and invoking:
- Bump ag-ui-strands to >= 0.1.4 (0.1.3 crashes on strands >= 1.19.0
due to accessing removed private attr agent.state._state)
- Remove parallel_tool_calls=False from LangGraph template (Bedrock
rejects this OpenAI-specific parameter with ValidationException)
- Remove aws-opentelemetry-distro from GoogleADK template (conflicts
with google-adk >= 1.16.0 OpenTelemetry dependencies — agents using
this template should set instrumentation.enableOtel: false)
* fix: add ToolNode + ReAct loop to AGUI LangGraph template
The AGUI LangGraph template had a single-node graph (chat → END) with
no tool execution loop. When the model called add_numbers, the graph
exited without executing the tool or generating a text response,
producing "(no content in AGUI response)" in agentcore dev.
Template fix:
- Add ToolNode(tools=backend_tools) as a "tools" node
- Replace set_finish_point("chat") with tools_condition conditional edge
- Add edge from "tools" back to "chat" for the ReAct loop
- Separate backend_tools list from frontend tools (state["tools"])
This matches the standard LangGraph ReAct pattern (agent → tools →
agent → ... → END) and how the HTTP/A2A templates use create_react_agent.
Dev invoke fix:
- invoke-agui.ts now tracks TOOL_CALL_START/ARGS/END/RESULT events
- When no text is produced but tool calls were seen, surfaces them
as [Tool: name(args)] instead of generic "(no content)" message
* fix: address all review findings from AG-UI protocol code review
16 issues from 4-lane parallel code review, all addressed:
Critical fixes:
- Strands template: use session_manager_provider from ag-ui-strands 0.1.7
instead of hardcoded "default-session"/"default-user"
- Dev client: persist threadId per session for multi-turn conversations
- CRLF handling: use /\r?\n/ in SSE parsers (invoke-agui + invoke.ts)
- Malformed JSON no longer yielded as content (shared parser skips)
- Unbounded aguiEvents array replaced with bounded cursor-based pruning
Structural improvements:
- Unified SSE parser (agui-parser.ts) replaces two divergent parsers
in invoke-agui.ts (dev) and agentcore.ts (deployed). Net -39 LOC.
- Dual-consumer support with singleConsumer mode for dev path
- AguiEvent type union completed (4 missing members added)
- Dynamic imports converted to static where non-intentional (AGENTS.md)
Python template fixes:
- LangGraph: add LangchainInstrumentor + dep, remove unused END import,
MemorySaver already removed in prior commit
- GoogleADK: remove dead load_model() + bedrock-agentcore dep, remove
hardcoded user_id (ADK defaults to per-thread identity)
- Strands: bump ag-ui-strands pin to >= 0.1.7
enableOtel plumbing:
- Dockerfile CMD conditional on enableOtel (Handlebars)
- enableOtel threaded through AgentRenderConfig + BaseRenderer
- Import path: ProtocolModeSchema.safeParse replaces unsafe as-cast
- Import path: MCP enableOtel clamped regardless of YAML value
- GoogleADK uses plain opentelemetry-distro (aws-distro conflicts)
DX + testing:
- formatZodIssue falls back to issue.code instead of literal "undefined"
- New dockerfile-render.test.ts covers both enableOtel branches
- All snapshots updated
* fix: add AGUI to JSON schema protocol enum
The static JSON schema file used for CDK validation was not updated
when AGUI was added to the Zod schema. This caused CDK synth to
reject protocol: "AGUI" with a misleading validation error.
* fix: restore MemorySaver in AGUI LangGraph template
ag_ui_langgraph calls aget_state(config) with thread_id which requires
a checkpointer. Without it, every invocation throws ValueError: No
checkpointer set. The original msgpack crash only triggers with numbers
exceeding 2^63 (ormsgpack limitation), not with normal large numbers.
Bug bash confirmed: 325435 + 435634563456456 works correctly with
MemorySaver present.
* fix: address final review findings in AGUI parser
- Wrap reader.releaseLock() in try/catch to prevent error masking
if lock is already released (HIGH from code review)
- Replace textStream! non-null assertion with runtime guard
(MEDIUM from code review)
* fix: use toolCallId for TOOL_CALL_RESULT matching in dev client
Previously matched by activeToolName which was already reset to '' by
TOOL_CALL_END. The find() never matched, falling through to the last
tool call — wrong for parallel tool calls. Now matches by toolCallId
which is the unique identifier AG-UI provides per tool invocation.
* revert: remove manual JSON schema edit (auto-generated during release)
The schemas/ directory is auto-regenerated from Zod schemas during the
release workflow. AGUI is already in ProtocolModeSchema (constants.ts)
and will appear in the JSON schema on next release.
* fix: add configurable PORT env var to AGUI templates + update snapshots
All 3 AGUI templates now read PORT from env with default 8080:
uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", "8080")))
Addresses PR review comment requesting configurable port for local testing.
* fix: use AG-UI in user-facing strings instead of AGUI
Schema enum stays 'AGUI' (internal), but TUI display text uses
'AG-UI' which is the protocol's official name.
* fix: restore credential wiring in AGUI GoogleADK template
The template was missing load_model() call and bedrock-agentcore dep,
so GOOGLE_API_KEY was never set from the AgentCore credential. Both
dev mode and deployed agents failed with "No API key provided."
* fix: convert AGUI dynamic import to static in invokeForProtocol
AGENTS.md requires all imports at top of file. The dynamic import had
no meaningful performance benefit — AGUI parser is ~4KB in a 2.1MB CLI.1 parent 13f16d3 commit 52144dc
61 files changed
Lines changed: 3068 additions & 33 deletions
File tree
- src
- assets
- __tests__
- __snapshots__
- container/python
- python
- a2a/googleadk/base
- agui
- googleadk/base
- model
- langchain_langgraph/base
- model
- strands
- base
- model
- capabilities/memory
- cli
- aws
- __tests__
- commands
- add
- create
- dev
- import
- invoke
- operations
- agent/generate
- dev
- primitives
- templates
- tui
- hooks
- screens
- add
- agent
- dev
- generate
- invoke
- lib/errors
- schema
- __tests__
- llm-compacted
- schemas
- __tests__
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 858 additions & 1 deletion
Large diffs are not rendered by default.
Lines changed: 77 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
34 | 35 | | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
10 | 12 | | |
11 | 13 | | |
12 | 14 | | |
| |||
73 | 75 | | |
74 | 76 | | |
75 | 77 | | |
76 | | - | |
| 78 | + | |
77 | 79 | | |
78 | 80 | | |
79 | 81 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
0 commit comments