Skip to main content

AG-UI and A2UI Protocol Architecture

Why this chapter matters

AG-UI and A2UI sound similar, but they are not interchangeable. Confusing them leads to architectures where the frontend does not know whether it is implementing a transport protocol, an event stream, a component schema, or an agent runtime.

Use this distinction:

  • AG-UI: agent-to-user interaction protocol. It describes how agent backends and user-facing apps exchange events, state, tool progress, UI intents, and user interactions.
  • A2UI: generative UI specification. It describes how an agent can express UI in a declarative format that a trusted client can render.

They can work together. AG-UI can carry events and lifecycle. A2UI-style payloads can describe generated surfaces or component trees.

CopilotKit's developer-facing taxonomy is a useful practical lens:

GenUI styleMeaningProtocol implication
Static GenUIThe agent selects from predefined UI components or tool-result renderersAG-UI-style events can identify tool outputs and component intents
Declarative GenUIThe agent emits a constrained UI description that a client rendersA2UI-style schemas and component catalogs become central
Open-ended GenUIThe system can expose richer application-like surfaces through app/plugin boundariesRequires much stronger sandboxing, permissions, performance controls, and review

For most product teams, static and declarative GenUI are the safer path. Open-ended UI generation should be treated like running a third-party app surface, not like rendering a normal message.

Core mental model

AG-UI is the conversation channel. A2UI is the generated interface language.

ConcernAG-UI-style responsibilityA2UI-style responsibility
Transport lifecycleStart, stream, cancel, resume, completeUsually outside scope
Agent stateShared state, diffs, tool events, progressComponent data bindings may reference state
Generated UIUI intent events and rendering handoffsDeclarative component structures
User actionsSend user interaction events to agentComponent events reference allowed actions
DebuggingEvent traces and protocol messagesSchema validation and render decisions
SafetyEvent allowlists and state boundariesComponent allowlists and prop validation

AG-UI event architecture

Agentic experiences do not fit a single request-response shape. A frontend may need to render:

  • token streaming
  • tool call progress
  • retrieved source summaries
  • generated components
  • state diffs
  • approval requests
  • cancellation results
  • nested sub-agent activity
  • final artifacts

An event protocol gives the frontend a stable vocabulary. Instead of parsing arbitrary text like "I am searching now," the app receives a typed event such as tool.started or retrieval.completed.

{
"id": "evt_018",
"workflowId": "wf_491",
"type": "component.proposed",
"timestamp": "2026-05-24T10:00:00Z",
"actor": "renewal-agent",
"payload": {
"surface": "customer-review",
"component": {
"id": "next-best-action",
"type": "approval_action",
"version": "2",
"props": {
"label": "Draft renewal offer",
"requiresConfirmation": true
}
}
}
}

This event is still untrusted. The frontend validates the component before rendering it.

A2UI rendering architecture

A2UI-style systems use declarative UI structures that can be rendered across clients. The important architectural advantage is that the agent does not need to know the internal React, Angular, Flutter, or native implementation. It speaks in abstract components and data.

Renderer responsibilities

ResponsibilityRequired behavior
ParseAccept only valid JSON/schema input
ValidateReject unknown components, invalid props, invalid bindings, unsafe URLs
AuthorizeCheck user permission before binding sensitive data or actions
RenderMap abstract components to local design-system primitives
InstrumentEmit analytics for generated surface impressions and actions
RecoverShow fallback UI when part of the generated tree is invalid

Integration patterns

Pattern 1: Chat plus generated cards

Use AG-UI-style events for the chat/task lifecycle. Use generated component payloads for specific cards such as summaries, tables, recommendations, or approval panels.

This is the best starting point for many products because it preserves a familiar conversation while adding richer interaction where needed.

Pattern 2: Agentic workspace

Use the AI interaction as the main work surface. The agent streams a dynamic workspace: filters, comparisons, generated drafts, data tables, timelines, and approval steps.

This works when the task has many possible shapes, but it requires stronger validation, persistence, and replay.

Pattern 3: Deterministic app with agent sidecar

The main app remains deterministic. The agent observes context and proposes actions through a side panel. Generated UI is limited to suggestions, explanations, and safe previews.

This is useful for regulated, high-risk, or legacy systems.

Protocol boundary decisions

QuestionDecision guidance
Should the frontend talk directly to the model?Usually no. Put model access behind an application backend for auth, cost, prompts, tools, and audit.
Should the frontend render arbitrary model content?No. Render typed content through approved components.
Should generated UI be persisted?Persist enough to replay, debug, resume, and audit.
Should every event be user-visible?No. Show progress that improves trust; hide noisy internal mechanics.
Should AG-UI replace REST/GraphQL?No. It complements normal APIs for agentic interaction flows.
Should A2UI replace the design system?No. It should target the design system through a constrained registry.
Should open-ended GenUI be allowed?Only inside sandboxed, permissioned, observable boundaries with explicit product justification.

Observability requirements

For every AI interaction, collect:

  • workflow id
  • user/session id
  • agent runtime and version
  • model/provider/version
  • prompt/template version
  • retrieval query and source ids
  • event stream timing
  • generated component ids and validation results
  • user approvals, edits, rejects, and cancellations
  • final outcome and cost

Frontend telemetry should connect generated UI behavior to backend traces. Otherwise, a failed AI interaction becomes impossible to debug across protocol, model, retrieval, and rendering boundaries.

End-to-end protocol lifecycle

Think of AG-UI-style interaction as a lifecycle, not a stream of random messages.

PhaseTypical eventsFrontend responsibility
Initializeworkflow.started, state.snapshotCreate task shell, attach trace id, show cancel affordance
Understandintent.parsed, clarification.requestedShow interpreted goal or ask for missing input
Retrieveretrieval.started, retrieval.completedShow context gathering and source quality
Executetool.started, tool.progress, tool.completedShow named progress and partial results
Generate UIcomponent.proposed, component.updatedValidate, render, patch, or reject generated components
Human gateapproval.requested, approval.resolvedCapture approve/edit/reject with audit metadata
Commitmutation.started, mutation.completedShow durable side-effect status
Terminalworkflow.completed, workflow.failed, workflow.cancelledPreserve outcome, recovery, replay, and next actions

This lifecycle gives designers and engineers a shared language. It also prevents the common anti-pattern where every stage is represented by the same spinner.

Event taxonomy

Define event classes before defining individual event names.

ClassExamplesUser-visible?
Lifecyclestarted, paused, resumed, completed, failed, cancelledUsually yes
Statesnapshot, diff, conflict, restoreSometimes
Retrievalquery, source candidate, source accepted, insufficient contextOften yes
Toolstarted, progress, output, failed, retriedOften yes, summarized
UIcomponent proposed, patched, rejected, removedYes when it changes the surface
Approvalrequested, edited, approved, rejected, expiredYes
Auditpolicy decision, capability denied, budget exceededUsually trace-only, sometimes visible
Debugraw model/provider metadataTrace-only

The frontend should not expose all protocol events literally. It should translate events into useful user states while preserving trace fidelity for debugging.

A2UI payload validation pipeline

A2UI-style payloads should move through a deterministic pipeline:

raw payload
-> JSON parse
-> envelope validation
-> component allowlist check
-> version normalization
-> prop schema validation
-> permission/data-binding validation
-> design-system/a11y constraints
-> render or fallback
-> telemetry event

Each stage should return a reason code on failure. "Failed to render generated UI" is not enough. Useful reason codes include unknown_component, unsupported_version, invalid_props, unauthorized_binding, unsafe_url, missing_citation, payload_too_large, and client_unsupported.

Compatibility across clients

Generated UI becomes harder when web, mobile, desktop, and embedded clients have different capabilities.

Use a capability handshake:

{
"client": {
"platform": "web",
"appVersion": "2026.05.24",
"supportedComponents": {
"summary_panel": ["1", "2"],
"source_list": ["1"],
"approval_action": ["2"],
"comparison_table": ["1"]
},
"constraints": {
"maxPayloadBytes": 120000,
"supportsStreamingPatches": true,
"supportsFilePreview": false
}
}
}

The agent should receive or be mediated by these capabilities before proposing UI. The renderer still validates, because prompts are advisory and client capability can change.

Protocol security considerations

Protocol events are input. Treat them as hostile until validated.

Controls:

  • authenticate the stream and bind it to the user's session
  • authorize workflow access before replaying prior events
  • prevent event id collision and out-of-order patch corruption
  • cap event size and stream duration
  • avoid sending secrets, raw prompts, or sensitive tool output to the browser
  • sign or server-validate high-risk action requests
  • require user approval event to reference the exact payload being approved
  • log rejected protocol messages for abuse analysis without storing unnecessary sensitive content

For approval, avoid this weak pattern:

{ "event": "approve", "action": "send_email" }

Prefer this:

{
"event": "approval.resolved",
"workflowId": "wf_491",
"approvalId": "appr_22",
"decision": "approved",
"approvedPayloadHash": "sha256:...",
"editedByUser": false
}

Approval must bind to what the user actually saw.

Failure modes

  • A2UI as transport: teams put lifecycle, retries, cancellation, and tool progress inside the UI payload instead of a real interaction protocol.
  • AG-UI as UI schema: teams send vague events and expect the frontend to infer component behavior from prose.
  • No shared ids: events, traces, generated components, and backend logs cannot be correlated.
  • Unversioned schema: a prompt change emits props that older clients do not understand.
  • Protocol bypass: one feature uses the official event contract while another invents a private stream.

Verification checklist

  • The design explicitly states what AG-UI-style events carry.
  • The design explicitly states what A2UI-style payloads describe.
  • Generated component schemas are versioned.
  • Event streams support cancellation and terminal states.
  • Frontend and backend traces share workflow ids.
  • Invalid generated UI degrades without breaking the whole task.

Exercises

  1. Write ten event types needed for a realistic agentic workflow in your product.
  2. Design one A2UI-style payload for a generated table with filters and citations.
  3. Create a compatibility plan for mobile clients that do not support a new generated component.
  4. Decide which events should be visible to the user and which should remain trace-only.

Source lens

This chapter is based on Firecrawl research of the official AG-UI documentation, A2UI sources, and CopilotKit's developer guide to GenUI patterns. The AG-UI docs identify AG-UI as an event-based agent/user interaction protocol and distinguish it from A2UI as a generative UI specification.