Skip to main content
The Agent-to-User Interface (A2UI) is a specialized protocol and rendering engine designed to allow agents to push structured, interactive UI updates to the user’s Canvas. Unlike standard text-based chat, A2UI enables agents to build and update complex interfaces—such as forms, tables, and charts—using incremental JSON Patches.

Protocol and Data Flow

The A2UI system operates on a state-synchronization model. The agent maintains a logical UI state (the A2uiDocument), and instead of re-sending the entire UI on every change, it emits PatchDocument payloads containing specific operations (add, replace, remove).

A2UI State Machine

The following diagram illustrates the flow from an agent’s patch generation to the React component rendering in the Web Console. Diagram: A2UI Update Lifecycle Sources: apps/web/src/a2ui/patch.ts#47-89, apps/web/src/a2ui/renderer.tsx#33-59, apps/web/src/a2ui/tests/renderer.snapshot.test.tsx#23-51

Patch Processing and Security

A2UI relies on a robust JSON Patch implementation that prioritizes security and performance. Because patches are generated by agents (which may be executing untrusted code or processing untrusted LLM output), the renderer enforces strict “budget” and “sanitization” rules.

Security Constraints

  1. Prototype Pollution Guard: The applyPatchDocument function explicitly forbids pointer tokens like __proto__, prototype, and constructor to prevent attackers from corrupting the JavaScript runtime apps/web/src/a2ui/patch.ts#16-16, apps/web/src/a2ui/tests/patch.security.test.tsx#9-30.
  2. Processing Budgets: To prevent Denial of Service (DoS) via complex patches, the system enforces a PatchProcessingBudget. This includes limits on the number of operations per patch (maxOpsPerPatch), path length (maxPathLength), and total execution time per tick (maxApplyMsPerTick) apps/web/src/a2ui/patch.ts#18-45.
  3. Sanitization: All incoming values are cloned using cloneJsonValue before being integrated into the state to ensure no references to external mutable objects are maintained apps/web/src/a2ui/patch.ts#66-66, apps/web/src/a2ui/patch.ts#200-207.

Content Security Policy (CSP)

The Web Console enforces a strict CSP via meta tags in index.html to ensure that even if a malicious UI component is rendered, it cannot execute inline scripts or exfiltrate data to unauthorized origins apps/web/index.html#9-11. This is verified by automated tests in securityPolicy.test.ts apps/web/src/securityPolicy.test.ts#11-28. Sources: apps/web/src/a2ui/patch.ts#16-16, apps/web/src/a2ui/patch.ts#18-45, apps/web/src/a2ui/tests/patch.security.test.tsx#9-30, apps/web/index.html#9-11, apps/web/src/securityPolicy.test.ts#11-28

Renderer Implementation

The A2uiRenderer component in renderer.tsx is the primary entry point for displaying A2UI documents. It iterates through a list of components and dispatches them to specialized sub-renderers.

Supported Component Types

TypeComponentDescription
textpRenders simple text with semantic “tones” (e.g., success, error) apps/web/src/a2ui/renderer.tsx#68-71.
markdownSanitizedMarkdownRenders markdown content through a sanitization layer apps/web/src/a2ui/renderer.tsx#72-73.
listol / ulStandard ordered or unordered lists apps/web/src/a2ui/renderer.tsx#74-87.
tableEntityTableInteractive data grids with sortable columns apps/web/src/a2ui/renderer.tsx#88-89, apps/web/src/a2ui/renderer.tsx#99-123.
formAppFormDynamic forms including TextInputField, CheckboxField, and SelectField apps/web/src/a2ui/renderer.tsx#90-91, apps/web/src/a2ui/renderer.tsx#130-177.
chartA2uiBarChartVisual representation of numeric series apps/web/src/a2ui/renderer.tsx#92-93.

Code-to-Entity Mapping

The following diagram maps React components to their A2UI protocol definitions. Diagram: A2UI Component Mapping Sources: apps/web/src/a2ui/renderer.tsx#33-59, apps/web/src/a2ui/renderer.tsx#66-97, apps/web/src/a2ui/renderer.tsx#130-177

Form Handling and User Interaction

Interaction in A2UI is primarily handled through the form component. When a user interacts with form fields (e.g., CheckboxField or SelectField), the internal state of the A2uiForm component is updated apps/web/src/a2ui/renderer.tsx#135-146. Upon submission, the handleSubmit function prevents the default browser behavior and invokes the onFormSubmit callback, passing an A2uiFormSubmitEvent which includes the componentId and the current values apps/web/src/a2ui/renderer.tsx#148-154. This event is typically routed back to the agent via the gRPC/HTTP control plane, allowing the agent to react to user input. Sources: apps/web/src/a2ui/renderer.tsx#135-146, apps/web/src/a2ui/renderer.tsx#148-154, apps/web/src/a2ui/renderer.tsx#186-234

Styling and Layout

The A2UI renderer uses a grid-based layout defined in the global styles.css. Components are wrapped in .a2ui-component containers and the main renderer uses the .a2ui-renderer class, which applies a standard gap and layout rules apps/web/src/styles.css#146-153. Specific styling for A2UI elements: Sources: apps/web/src/styles.css#146-153, apps/web/src/main.tsx#4-7