Overview
Render rich, declarative UI surfaces from your Microsoft Agent Framework agent using the A2UI protocol.
A2UI (Agent-to-UI) is a Declarative Generative UI specification led by Google, with CopilotKit as a launch and design partner. It lets your agent render structured UI components using a JSON-based schema. Instead of sending plain text, the agent produces surfaces — cards, lists, buttons, images — that render natively in the chat.
You can design and preview A2UI schemas visually using the A2UI Composer.
Setup#
Enable A2UI in your CopilotRuntime by adding a2ui: true, or pass an object to customise:
import { CopilotRuntime } from "@copilotkit/runtime";
// Simple — enable with defaults
const runtime = new CopilotRuntime({
agents: { default: myAgent },
a2ui: true,
});
// Or customise — e.g. inject a render tool into the agent
const runtime = new CopilotRuntime({
agents: { default: myAgent },
a2ui: {
injectA2UITool: true,
},
});This tells the runtime to apply the A2UI middleware to your agents. The middleware intercepts tool results containing A2UI operations and renders them as rich UI surfaces in the chat.
Without a2ui configured in your CopilotRuntime, A2UI surfaces will not render — tool results will appear as plain text.
Approaches#
CopilotKit supports two approaches to A2UI, each with different tradeoffs:
- Fixed Schema — Pre-defined schema loaded from JSON. Agent provides data only. Fastest — no LLM schema generation.
- Dynamic Schema — A secondary LLM generates both the schema and data. Fully flexible — any UI from any prompt.
When to use which?#
| Approach | Schema source | Rendering | Best for |
|---|---|---|---|
| Fixed Schema | JSON file | Instant (all at once) | Known UI patterns (flight cards, product lists) |
| Dynamic Schema | LLM-generated | Progressive (card by card) | Unknown/varied UI — the agent decides what to show |
Both approaches use the same A2UI protocol and renderer. The difference is where the schema comes from and how data reaches the client.
How it works#
Every A2UI v0.9 surface is built from three operations:
createSurface— initializes the surface with its catalog (must come first)updateComponents— defines the component tree (the schema)updateDataModel— provides the data that populates the components
Wrapped in an a2ui_operations container, the operations look like this:
{
"a2ui_operations": [
{"version": "v0.9", "createSurface": {"surfaceId": ..., "catalogId": ...}},
{"version": "v0.9", "updateComponents": {"surfaceId": ..., "components": [...]}},
{"version": "v0.9", "updateDataModel": {"surfaceId": ..., "path": "/", "value": {...}}},
]
}For fixed schema, your tool returns this container directly; for dynamic schema, the agent-framework-ag-ui adapter builds it for you.
Continue to one of the approach guides above to see the full implementation.