Skip to content

Overview

The autogen.beta.a2ui module lets an AG2 Agent produce rich, interactive user interfaces — cards, forms, lists, buttons — instead of plain text, using the A2UI protocol. The LLM emits conversational prose plus a validated A2UI message block; AG2 surfaces each message as a typed event and serializes it to A2UI's transport-agnostic wire format, so any A2UI-capable client can render it.

A2UI is a transport over a plain Agent (mirroring A2A and AG-UI): you build a normal autogen.beta.Agent and wrap it in an A2UI transport — A2UIServer (REST/SSE) or A2UIAgentExecutor (A2A) — configured with flat A2UI kwargs. There is no special agent subclass.

When To Use A2UI#

Reach for A2UI when a text answer isn't enough and the user needs to see and act on something:

  • A booking or settings form the user fills in and submits.
  • A list of results with per-item actions (approve, schedule, open).
  • A card summarising data with clickable buttons that drive the next turn.

If you only need a conversational reply, serve a plain autogen.beta.Agent directly. A2UI is additive: an A2UI-wrapped agent still answers in prose when a UI wouldn't help.

Mental Model#

   ┌────────────────────────────┐                       ┌─────────────────────────┐
   │ Agent + A2UI transport     │   server→client        │ A2UI client             │
   │  prose + <a2ui-json> block │   createSurface /       │  renders surfaces       │
   │  ── validate vs catalog ── │   updateComponents …    │  & components           │
   │  emits A2UIMessageEvent     │ ────────────────────▶  │                         │
   │                            │                         │  user clicks a button   │
   │  action → handler / prompt │   client→server         │                         │
   │  ◀──────────────────────── │   action / functionResp │ ◀──────────────────────│
   └────────────────────────────┘   (the next request)    └─────────────────────────┘

The transport applies A2UI behaviour to the plain agent per turn (prompt + validation middleware) and validates every A2UI message against the chosen catalog schema (with retry-on-error), so malformed UI never reaches the client — on repeated failure it gracefully degrades to prose. A button click travels back as a client→server action (or v1.0 functionResponse) envelope, which the transport rewrites into the next turn.

Core Concepts#

Concept Lives in Purpose
Agent autogen.beta A plain agent — wrap it in an A2UI transport to emit validated A2UI output
a2ui_action autogen.beta.a2ui Decorator turning a function into a clickable button (server event action). A click runs the handler on the server — the agent is not invoked. Declared on the transport via actions=[...]
A2UIMessageEvent autogen.beta.a2ui One validated A2UI server→client message on the stream — the event seam every transport consumes
A2UIClientEvent autogen.beta.a2ui One client→server interaction received from the renderer (click / functionResponse / error) — the inbound observability seam
A2UIValidationFailedEvent autogen.beta.a2ui Observability signal that validation exhausted its retries and the turn degraded to prose
A2UIClientCapabilities autogen.beta.a2ui Catalog negotiation — tells the agent which catalogs/components the client can render
A2UIServer autogen.beta.a2ui Wraps a plain Agent into an ASGI app and serves it over HTTP, using a transport= for the wire encoding (REST/SSE or AG-UI)
A2UIAgentExecutor autogen.beta.a2ui.a2a Wraps a plain Agent for the A2A transport, carrying A2UI as DataParts

Protocol Versions#

The A2UI transports accept three protocol versions via protocol_version=:

  • "v0.9" (default) and "v0.9.1" — server→client surfaces and components, plus server event actions.
  • "v1.0" — adds the callFunction / functionResponse / actionResponse round-trip for richer client→server interaction.

Note

A2UI's wire is transport-agnostic. The same validated messages serialize identically whether served over the built-in REST/SSE adapter, embedded in an A2A DataPart, or carried by AG-UI events.

Public API#

The broadly-reusable surface is re-exported from autogen.beta.a2ui:

1
2
3
4
5
6
7
from autogen.beta.a2ui import (
    a2ui_action,
    A2UIClientCapabilities,
    A2UIMessageEvent,
    A2UIClientEvent,
    A2UIValidationFailedEvent,
)

The agent itself is a plain autogen.beta.Agent. The HTTP server picks its wire encoding from a transport=, and the A2A executor lives in its own submodule (kept out of the core import so the package never pulls in the a2a-sdk):

1
2
3
from autogen.beta.a2ui import A2UIServer                       # HTTP server (ASGI app)
from autogen.beta.a2ui.transports import RestTransport, AgUiTransport
from autogen.beta.a2ui.a2a import A2UIAgentExecutor            # A2A

Quickstart#

Build a plain Agent, then wrap it in an A2UIServer — the server is the ASGI app, the wire encoding comes from transport=, and clickable buttons are declared via actions= (the agent stays plain):

import uvicorn

from autogen.beta import Agent
from autogen.beta.a2ui import A2UIServer, a2ui_action
from autogen.beta.a2ui.transports import RestTransport
from autogen.beta.config import AnthropicConfig

@a2ui_action(description="Book the selected dinner reservation")
def book_table(time: str, party_size: int) -> str:
    return f"booked a table for {party_size} at {time}"

agent = Agent(name="ui_agent", config=AnthropicConfig(model="claude-sonnet-4-6"))

app = A2UIServer(
    agent,
    transport=RestTransport(encoding="jsonl"),  # POST /a2ui  →  A2UI NDJSON
    actions=[book_table],
    protocol_version="v0.9",
)

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8000)

See Server for the request/response contract and a client that drives this app.

Reading Order#

  1. Server — wrap an Agent in A2UIServer and drive it over HTTP (SSE / NDJSON).
  2. A2A Transport — serve the same agent over A2A, carrying A2UI messages as canonical DataParts.
  3. Actions — clickable buttons backed by server-side @a2ui_action handlers, the click round-trip, and the inbound A2UIClientEvent.
  4. Catalogs & Capabilities — the component schema the agent validates against, custom catalogs, and client capability negotiation.