Protocol Architecture
The A2UI protocol is built on three core pillars:- State Synchronization: The UI maintains an
A2uiDocumentwhich represents the current view state. - Incremental Patching: Instead of re-sending the entire UI state, the agent sends
PatchOperationobjects (based on JSON Patch RFC 6902) to modify the existing document. - Security Isolation: The renderer enforces strict sanitization, ensuring that agents cannot execute arbitrary JavaScript or bypass Content Security Policy (CSP) via the UI layer.
Data Flow Diagram
This diagram illustrates how an agent’s intent is transformed into a UI update through the A2UI pipeline. A2UI Update Pipeline Sources: apps/web/src/a2ui/renderer.tsx#36-63, apps/web/src/a2ui/normalize.ts#33-77, apps/web/src/a2ui/tests/renderer.snapshot.test.tsx#26-54Document Structure and Components
AnA2uiDocument consists of a surface identifier, an optional experimental governance block, and an array of components.
Supported Components
The renderer supports a specific set of primitive components defined in theA2uiComponent union type:
| Component Type | Purpose | Key Props |
|---|---|---|
text | Simple status or labels | tone (normal, success, danger), value |
markdown | Rich text content | value (sanitized markdown) |
list | Ordered or unordered lists | items, ordered (boolean) |
table | Structured data grids | columns, rows |
form | Interactive data entry | fields, submitLabel, title |
chart | Data visualization | series (label/value pairs), title |
Implementation Mapping
This diagram bridges the conceptual UI components to their specific TypeScript implementation entities. Component Implementation Map Sources: apps/web/src/a2ui/renderer.tsx#116-147, apps/web/src/a2ui/normalize.ts#160-194, apps/web/src/a2ui/types.ts#1-24Patching and Normalization
The A2UI system uses a strict normalization phase before rendering to ensure that incoming JSON from the agent (which may be untrusted or malformed) adheres to safety constraints.Normalization Logic
ThenormalizeA2uiDocument function performs the following checks:
- Version Check: Validates that
v: 1is present apps/web/src/a2ui/normalize.ts#41-43. - Surface Validation: Ensures the
surfacestring is non-empty and within length limits apps/web/src/a2ui/normalize.ts#45-48. - Component Deduplication: Assigns unique IDs to components and sanitizes them to prevent DOM ID collisions apps/web/src/a2ui/normalize.ts#54-67.
- Experimental Governance: If an
experimentalblock is present, it validates feature flags and rollout stages apps/web/src/a2ui/normalize.ts#79-158.
Patch Application
Agents sendPatchOperation objects to modify the document. Common operations include:
add: Appending items to a list or adding a new component.replace: Updating a status message or chart value.remove: Deleting a component after a task is finished.
applyPatchDocument function applies these operations to the current state before passing the result through the normalization and rendering pipeline apps/web/src/a2ui/tests/renderer.snapshot.test.tsx#47-49.
Security and Sanitization
Security is enforced at the protocol boundary to prevent Cross-Site Scripting (XSS) and unauthorized data exfiltration.Sanitization Strategies
- No Direct HTML: The renderer does not use
dangerouslySetInnerHTML. Markdown is rendered via aSanitizedMarkdowncomponent that strips dangerous tags and attributes apps/web/src/a2ui/renderer.tsx#12-12. - Input Coercion: Values are strictly coerced using functions like
coerceString,coerceBoolean, andcoerceFiniteNumberapps/web/src/a2ui/normalize.ts#4-9. - Identifier Sanitization: Component and field IDs are sanitized to ensure they only contain safe characters for DOM attributes apps/web/src/a2ui/normalize.ts#149-150.
- Experimental Consent: Any “ambient” experiment (e.g.,
push_to_talk) requires explicitconsent_required: truein the document, or the normalization will fail apps/web/src/a2ui/normalize.ts#123-128.
Governance Validation
The protocol includes anexperimental block that tracks features under development. This block requires:
- A
trackIdandfeatureFlagapps/web/src/a2ui/normalize.ts#90-103. - A
securityReviewchecklist of strings apps/web/src/a2ui/normalize.ts#130-139. exitCriteriathat define when the experiment should be retired or promoted apps/web/src/a2ui/normalize.ts#140-146.
Interaction and Forms
The A2UI protocol supports bi-directional communication through theform component.
- Rendering:
A2uiFormrenders a set ofA2uiFormFieldentries (text, select, checkbox) apps/web/src/a2ui/renderer.tsx#180-227. - State Management: The form maintains local React state for all field values apps/web/src/a2ui/renderer.tsx#185-196.
- Submission: When a user clicks the submit button, an
onFormSubmitcallback is triggered with thecomponentIdand the collectedvaluesapps/web/src/a2ui/renderer.tsx#198-205. - Handoff: These values are typically sent back to the agent via the gRPC
RunStreamor an HTTP POST to the daemon’s console API.