Python: A2UI (Agent-to-UI) support for the AG-UI adapter - #7423
Open
ranst91 wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds Python-side A2UI (agent-to-UI) support to the AG-UI adapter for parity with the existing .NET implementation, enabling rich surface generation with progressive streaming and recovery semantics via the shared ag-ui-a2ui-toolkit.
Changes:
- Introduces a new
agent_framework_ag_ui._a2uimodule (state plumbing, context replay wrapper, A2UI generation wrapper, and auto-injection factory) with lazy imports so the base package remains usable without the optional toolkit. - Updates the AG-UI hosting path to (a) stamp forwarded A2UI context into run options, (b) auto-inject the
generate_a2uitool when requested by the runtime, and (c) suppress the terminal snapshot for A2UI runs to preserve streamed ordering. - Adds an A2UI-focused test suite and expands the examples server with A2UI demo endpoints.
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| python/uv.lock | Adds ag-ui-a2ui-toolkit and registers the new a2ui extra for agent-framework-ag-ui. |
| python/packages/ag-ui/tests/ag_ui/test_a2ui.py | New unit suite covering A2UI context plumbing, wrapper agents, streaming/non-streaming generation, and key regressions. |
| python/packages/ag-ui/pyproject.toml | Defines the a2ui optional dependency and configures mypy overrides for the toolkit. |
| python/packages/ag-ui/agent_framework_ag_ui/_endpoint.py | Adds a2ui_config parameter to the FastAPI endpoint helper and forwards it into config. |
| python/packages/ag-ui/agent_framework_ag_ui/_agent.py | Extends agent configuration to carry a2ui_config for runtime auto-injection. |
| python/packages/ag-ui/agent_framework_ag_ui/_agent_run.py | Implements A2UI auto-injection, AG-UI context stamping, and suppresses terminal snapshot for A2UI runs. |
| python/packages/ag-ui/agent_framework_ag_ui/_a2ui/_state.py | New toolkit-free state/context utilities (slice building, stamping, stripping, history mapping). |
| python/packages/ag-ui/agent_framework_ag_ui/_a2ui/_factory.py | New enable_a2ui helper and plan_a2ui_injection decision logic (Strands-parity rules). |
| python/packages/ag-ui/agent_framework_ag_ui/_a2ui/_context_agent.py | New wrapper to replay forwarded A2UI catalog/guidelines into the prompt via a system message. |
| python/packages/ag-ui/agent_framework_ag_ui/_a2ui/_agent.py | New A2UIAgent implementing streaming progressive paint + validate/retry and non-streaming tool execution. |
| python/packages/ag-ui/agent_framework_ag_ui/_a2ui/init.py | New lazy-export package initializer for A2UI-related symbols. |
| python/packages/ag-ui/agent_framework_ag_ui/init.py | Adds lazy exports for A2UI symbols at the package root. |
| python/packages/ag-ui/agent_framework_ag_ui_examples/server/main.py | Updates examples server to support OpenAI Chat Completions and adds A2UI demo endpoints. |
| python/packages/ag-ui/agent_framework_ag_ui_examples/agents/a2ui_agents.py | Adds A2UI demo agents (dynamic schema, advanced zero-config, recovery, fixed schema). |
| python/packages/ag-ui/agent_framework_ag_ui_examples/agents/init.py | Exposes new A2UI demo agents/config via the examples agents package. |
Comments suppressed due to low confidence (1)
python/packages/ag-ui/agent_framework_ag_ui_examples/server/main.py:88
- After making python-dotenv optional, the .env load call also needs a guard; otherwise load_dotenv may be None and this will raise at runtime.
# Load the examples .env (OPENAI_API_KEY etc.) before constructing any chat client.
# override=True so a stale/empty exported OPENAI_API_KEY doesn't shadow the .env value.
load_dotenv(Path(__file__).resolve().parent.parent / ".env", override=True)
Comment on lines
+16
to
+18
| from agent_framework.azure import AzureOpenAIChatClient | ||
| from agent_framework.openai import OpenAIChatCompletionClient | ||
| from dotenv import load_dotenv |
Comment on lines
+38
to
+40
| # NOTE: requires the toolkit release that includes singular-`child` validation + | ||
| # `child_cycle` detection (ag-ui-protocol/ag-ui#1944); bump the floor to that | ||
| # published version once it ships (currently unreleased; 0.0.3 lacks it). |
Comment on lines
+49
to
+53
| # The recovery-exhausted envelope builder is not part of the toolkit's public | ||
| # surface yet; import the shared implementation so the streaming twin and the | ||
| # synchronous loop cannot drift on the exhaustion envelope shape. | ||
| from ag_ui_a2ui_toolkit.recovery import _wrap_recovery_exhausted_envelope | ||
| from agent_framework import Content, FunctionTool, Message |
Comment on lines
+787
to
+788
| _forwarded = input_data.get("forwarded_props") or input_data.get("forwardedProps") | ||
| if read_inject_a2ui_flag(_forwarded): |
Member
|
@ranst91 please use the defined PR template, and there are a number of merge conflicts |
Adds an in-package _a2ui module to agent-framework-ag-ui delivering progressive-streaming, error-recovery, and sub-agent-based A2UI surface generation, reusing the shared ag-ui-a2ui-toolkit. Includes example agents, a unit suite, and two bridge fixes (strip unanswered tool calls from replayed history; suppress the terminal MESSAGES_SNAPSHOT for A2UI runs to keep streamed order stable). Signed-off-by: ran <ran@copilotkit.ai>
ranst91
force-pushed
the
feat/a2ui-python-finish
branch
from
July 30, 2026 13:07
2d849e8 to
61ef22a
Compare
Author
|
@eavanvalkenburg All comments (including about the PR body) seems to be addressed now. Lmk if there's anything else |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation & Context
A2UI lets an agent generate rich, interactive UI (cards, forms, dashboards) that renders live in the client instead of plain text. It already shipped for .NET (#6494); this brings the same capability to the Python AG-UI adapter for parity. It reuses the shared, framework-agnostic
ag-ui-a2ui-toolkit.Description & Review Guide
What are the major changes? Adds an in-package
_a2uimodule toagent-framework-ag-ui, delivering:render_a2uisub-agent's argument deltas reach the wire as the surface builds, so the client paints it incrementally.generate_a2uidelegates UI design to a forcedrender_a2uistructured-output sub-agent, run through the toolkit's recovery loop.Plus two small bridge fixes needed for A2UI to behave in a real client: strip unanswered tool calls from replayed history before the planner call (A2UI surfaces persist as activities, so a surface action like a card button would otherwise fail the next turn), and skip the terminal
MESSAGES_SNAPSHOTfor A2UI runs so the streamed transcript order stays stable (mirrors the existing predictive-tool snapshot suppression). Also adds example agents and a unit suite.What is the impact of these changes? Purely additive. The toolkit is imported lazily behind an optional
a2uiextra, so the base package is unchanged for anyone not using A2UI; the newa2ui_configparameters are optional with existing defaults. Verified end to end against a real model, not only fixtures.What do you want reviewers to focus on? The auto-injection gate in
_agent_run.py(nullish precedence between the runtimeinjectA2UIToolflag and a backendinject_a2ui_toolopt-in) and the streaming coalescing in_a2ui/_agent.py.Related Issue
No dedicated Python issue; this is the Python counterpart of the .NET A2UI work in #6494.
Contribution Checklist