A2UI Schema
The @threadplane/a2ui schema is a TypeScript model of the protocol shapes the framework uses. It's a contract for agent output and custom integrations, but it's not a runtime validator.
#Dynamic values
Dynamic values are wrapped objects. A value can be literal or resolved from the surface data model by path.
Absolute paths start with / and are resolved from the model root. Relative paths are resolved from an optional A2uiScope.
#Children
Layout components use either explicit child IDs or a template declaration.
The protocol layer only types this shape. Template expansion is renderer behavior.
#Actions
An action has a name and optional context entries. Context values use the same dynamic wrappers as component props.
@threadplane/a2ui does not execute actions. It only describes the payload that chat/render code can turn into an outbound A2uiActionMessage.
#Components
Every component has an id, optional weight, and a single-key component union.
The exported component definitions are:
| Definition | Main fields |
|---|---|
Text | text, usageHint |
Image | url, alt, width, height |
Icon | icon, size |
Video | url, autoPlay, controls |
AudioPlayer | url, autoPlay, controls |
Row | children, gap, alignment, distribution |
Column | children, gap, alignment |
List | children, direction |
Card | child |
Tabs | tabItems |
Divider | direction |
Modal | entryPointChild, contentChild, title |
Button | child, primary, action |
CheckBox | label, checked, action |
TextField | label, text, textFieldType, validationRegexp |
DateTimeInput | label, value, enableDate, enableTime |
MultipleChoice | selections, options, maxAllowedSelections, label |
Slider | value, minValue, maxValue, step, label |
Several of these fields are constrained to a fixed enum. Emit one of the listed values — an unknown value isn't validated at the protocol layer, but a renderer may ignore it or fall back to a default:
| Field | On | Allowed values |
|---|---|---|
usageHint | Text | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'caption' | 'body' |
textFieldType | TextField | 'date' | 'longText' | 'number' | 'shortText' | 'obscured' |
alignment | Row, Column | 'start' | 'center' | 'end' | 'stretch' |
distribution | Row | 'start' | 'center' | 'end' | 'space-between' | 'space-around' |
direction | List | 'vertical' | 'horizontal' |
direction | Divider | 'horizontal' | 'vertical' |
Tabs is the one container that doesn't use A2uiChildren. Its tabItems is an array of A2uiTabItem, each pairing a title (a DynamicString) with a single child id:
The schema exposes validationRegexp on TextField, but validation execution is not implemented in this package. Treat schema fields as protocol data until a renderer wires behavior.
#Message envelopes
The parser recognizes four top-level envelopes:
#surfaceUpdate
Adds or replaces components for a surface.
#dataModelUpdate
Carries nested data-model entries. path is optional.
Each A2uiDataModelEntry has a key plus one of valueString, valueNumber, valueBoolean, or valueMap.
#beginRendering
Identifies the root component to render for a surface.
The source comments describe styles.font and styles.primaryColor as the canonical style fields.
#deleteSurface
Removes a surface by ID.
#Internal surface model
A2uiSurface is an internal model used after messages are applied:
A2uiTheme carries optional, agent-supplied presentation hints:
This shape is not constrained to the wire format. Do not assume an agent sends it directly.
#Outbound action messages
When a rendered surface sends an action back to the agent, the typed outbound shape is:
The outbound action version is v1. The optional label is a human-readable label derived from the source component's text (for example, a Button's child Text), used to describe the action in transcripts; backends may ignore it.