Skip to content

Python: A2UI (Agent-to-UI) support for the AG-UI adapter - #7423

Open
ranst91 wants to merge 1 commit into
microsoft:mainfrom
ranst91:feat/a2ui-python-finish
Open

Python: A2UI (Agent-to-UI) support for the AG-UI adapter#7423
ranst91 wants to merge 1 commit into
microsoft:mainfrom
ranst91:feat/a2ui-python-finish

Conversation

@ranst91

@ranst91 ranst91 commented Jul 30, 2026

Copy link
Copy Markdown

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 _a2ui module to agent-framework-ag-ui, delivering:

    • Progressive streaming — the render_a2ui sub-agent's argument deltas reach the wire as the surface builds, so the client paints it incrementally.
    • Error recovery — a validate-and-retry loop. An invalid surface never paints, and exhaustion produces a failure envelope instead of throwing.
    • Sub-agent basedgenerate_a2ui delegates UI design to a forced render_a2ui structured-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_SNAPSHOT for 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 a2ui extra, so the base package is unchanged for anyone not using A2UI; the new a2ui_config parameters 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 runtime injectA2UITool flag and a backend inject_a2ui_tool opt-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

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change.

Copilot AI review requested due to automatic review settings July 30, 2026 07:08
@ranst91
ranst91 temporarily deployed to github-app-auth July 30, 2026 07:08 — with GitHub Actions Inactive
@ranst91
ranst91 temporarily deployed to github-app-auth July 30, 2026 07:08 — with GitHub Actions Inactive
@ranst91
ranst91 temporarily deployed to github-app-auth July 30, 2026 07:08 — with GitHub Actions Inactive
@ranst91
ranst91 temporarily deployed to github-app-auth July 30, 2026 07:08 — with GitHub Actions Inactive
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Jul 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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._a2ui module (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_a2ui tool 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 thread python/packages/ag-ui/pyproject.toml Outdated
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):
@moonbox3 moonbox3 self-assigned this Jul 30, 2026
@eavanvalkenburg

Copy link
Copy Markdown
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
ranst91 force-pushed the feat/a2ui-python-finish branch from 2d849e8 to 61ef22a Compare July 30, 2026 13:07
@ranst91
ranst91 temporarily deployed to github-app-auth July 30, 2026 13:07 — with GitHub Actions Inactive
@ranst91
ranst91 temporarily deployed to github-app-auth July 30, 2026 13:10 — with GitHub Actions Inactive
@ranst91

ranst91 commented Jul 30, 2026

Copy link
Copy Markdown
Author

@eavanvalkenburg All comments (including about the PR body) seems to be addressed now. Lmk if there's anything else

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants