Skip to content

Commit f243ba1

Browse files
Merge branch 'main' into fix/lit-multiple-choice-binding
2 parents bfda784 + 9c35418 commit f243ba1

17 files changed

+158
-50
lines changed

.geminiignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Ignore large lock files that aren't useful for context
2+
**/pnpm-lock.yaml
3+
**/package-lock.json
4+
**/uv.lock

specification/v0_9/docs/a2ui_extension_specification.md

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ Catalog Definition Document: The a2ui extension is catalog-agnostic. All UI comp
2121
Schemas: The a2ui extension is defined by several primary JSON schemas:
2222

2323
- Catalog Definition Schema: A standard format for defining a library of components and functions.
24-
- Server-to-Client Message Schema: The core wire format for messages sent from the agent to the client (e.g., updateComponents, updateDataModel).
25-
- Client-to-Server Event Schema: The core wire format for messages sent from the client to the agent (e.g., action).
24+
- Server-to-Client Message List Schema: The core wire format for messages sent from the agent to the client (e.g., updateComponents, updateDataModel).
25+
- Client-to-Server Message List Schema: The core wire format for messages sent from the client to the agent (e.g., action).
2626
- Client Capabilities Schema: The schema for the `a2uiClientCapabilities` object.
2727

2828
Client Capabilities: The client sends its capabilities to the server in an `a2uiClientCapabilities` object. This object is included in the `metadata` field of every A2A `Message` sent from the client to the server. This object allows the client to declare which catalogs it supports.
@@ -69,28 +69,47 @@ To identify a `DataPart` as containing A2UI data, it must have the following met
6969

7070
- `mimeType`: `application/json+a2ui`
7171

72-
The `data` field of the `DataPart` contains a **single** A2UI JSON message (e.g., `createSurface`, `updateComponents`, `action`). It MUST NOT be an array of messages.
72+
The `data` field of the `DataPart` contains a **list** of A2UI JSON messages (e.g., `createSurface`, `updateComponents`, `action`). It MUST be an array of messages.
7373

74-
### Atomicity and multiple messages
74+
### Processing Rules
7575

76-
To send multiple A2UI messages that should be processed atomically (e.g., creating a surface and immediately populating it), the sender MUST include multiple `DataPart`s within a single A2A `Message`.
76+
The `data` field contains a list of messages. This list is **NOT** a transactional unit. Receivers (both Clients and Agents) MUST process messages in the list sequentially.
7777

78-
Receivers (both Clients and Agents) MUST process all A2UI `DataPart`s within a single A2A `Message` sequentially and atomically. For a renderer, this means the UI should not be repainted until all parts in the message have been applied.
78+
If a single message in the list fails to validate or apply (e.g., due to a schema violation or invalid reference), the receiver SHOULD report/log the error for that specific message and MUST continue processing the remaining messages in the list.
79+
80+
Atomicity is guaranteed only at the **individual message** level. However, for a better user experience, a renderer SHOULD NOT repaint the UI until all messages in the list have been processed. This prevents intermediate states from flickering to the user.
7981

8082
### Server-to-client messages
8183

82-
When an agent sends a message to a client (or another agent acting as a client/renderer), the `data` payload must validate against the **Server-to-Client Message Schema**.
84+
When an agent sends a message to a client (or another agent acting as a client/renderer), the `data` payload must validate against the **Server-to-Client Message List Schema**.
8385

84-
Example `createSurface` DataPart:
86+
Example DataPart:
8587

8688
```json
8789
{
88-
"data": {
89-
"createSurface": {
90-
"surfaceId": "user_profile_surface",
91-
"catalogId": "https://a2ui.org/specification/v0_9/standard_catalog.json"
90+
"data": [
91+
{
92+
"version": "v0.9",
93+
"createSurface": {
94+
"surfaceId": "example_surface",
95+
"catalogId": "https://a2ui.org/specification/v0_9/standard_catalog.json"
96+
}
97+
},
98+
{
99+
"version": "v0.9",
100+
"updateComponents": {
101+
"surfaceId": "example_surface",
102+
"components": [
103+
{
104+
"Text": {
105+
"id": "root",
106+
"text": "Hello!"
107+
}
108+
}
109+
]
110+
}
92111
}
93-
},
112+
],
94113
"kind": "data",
95114
"metadata": {
96115
"mimeType": "application/json+a2ui"
@@ -100,23 +119,26 @@ Example `createSurface` DataPart:
100119

101120
### Client-to-server events
102121

103-
When a client (or an agent forwarding an event) sends a message to an agent, it also uses a `DataPart` with the same `application/json+a2ui` MIME type. However, the `data` payload must validate against the **Client-to-Server Event Schema**.
122+
When a client (or an agent forwarding an event) sends a message to an agent, it also uses a `DataPart` with the same `application/json+a2ui` MIME type. However, the `data` payload must validate against the **Client-to-Server Message List Schema**.
104123

105124
Example `action` DataPart:
106125

107126
```json
108127
{
109-
"data": {
110-
"action": {
111-
"name": "submit_form",
112-
"surfaceId": "contact_form_1",
113-
"sourceComponentId": "submit_button",
114-
"timestamp": "2026-01-15T12:00:00Z",
115-
"context": {
116-
"email": "user@example.com"
128+
"data": [
129+
{
130+
"version": "v0.9",
131+
"action": {
132+
"name": "submit_form",
133+
"surfaceId": "contact_form_1",
134+
"sourceComponentId": "submit_button",
135+
"timestamp": "2026-01-15T12:00:00Z",
136+
"context": {
137+
"email": "user@example.com"
138+
}
117139
}
118140
}
119-
},
141+
],
120142
"kind": "data",
121143
"metadata": {
122144
"mimeType": "application/json+a2ui"

specification/v0_9/docs/a2ui_protocol.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ This message signals the client to create a new surface and begin rendering it.
189189

190190
```json
191191
{
192+
"version": "v0.9",
192193
"createSurface": {
193194
"surfaceId": "user_profile_card",
194195
"catalogId": "https://a2ui.org/specification/v0_9/standard_catalog.json",
@@ -213,6 +214,7 @@ This message provides a list of UI components to be added to or updated within a
213214

214215
```json
215216
{
217+
"version": "v0.9",
216218
"updateComponents": {
217219
"surfaceId": "user_profile_card",
218220
"components": [
@@ -250,6 +252,7 @@ This message is used to send or update the data that populates the UI components
250252

251253
```json
252254
{
255+
"version": "v0.9",
253256
"updateDataModel": {
254257
"surfaceId": "user_profile_card",
255258
"path": "/user/name",
@@ -270,6 +273,7 @@ This message instructs the client to remove a surface and all its associated com
270273

271274
```json
272275
{
276+
"version": "v0.9",
273277
"deleteSurface": {
274278
"surfaceId": "user_profile_card"
275279
}
@@ -281,10 +285,10 @@ This message instructs the client to remove a surface and all its associated com
281285
The following example demonstrates a complete interaction to render a Contact Form, expressed as a JSONL stream.
282286

283287
```jsonl
284-
{"createSurface":{"surfaceId":"contact_form_1","catalogId":"https://a2ui.org/specification/v0_9/standard_catalog.json"}}
285-
{"updateComponents":{"surfaceId":"contact_form_1","components":[{"id":"root","component":"Card","child":"form_container"},{"id":"form_container","component":"Column","children":["header_row","name_row","email_group","phone_group","pref_group","divider_1","newsletter_checkbox","submit_button"],"justify":"start","align":"stretch"},{"id":"header_row","component":"Row","children":["header_icon","header_text"],"align":"center"},{"id":"header_icon","component":"Icon","name":"mail"},{"id":"header_text","component":"Text","text":"# Contact Us","variant":"h2"},{"id":"name_row","component":"Row","children":["first_name_group","last_name_group"],"justify":"spaceBetween"},{"id":"first_name_group","component":"Column","children":["first_name_label","first_name_field"],"weight":1},{"id":"first_name_label","component":"Text","text":"First Name","variant":"caption"},{"id":"first_name_field","component":"TextField","label":"First Name","value":{"path":"/contact/firstName"},"variant":"shortText"},{"id":"last_name_group","component":"Column","children":["last_name_label","last_name_field"],"weight":1},{"id":"last_name_label","component":"Text","text":"Last Name","variant":"caption"},{"id":"last_name_field","component":"TextField","label":"Last Name","value":{"path":"/contact/lastName"},"variant":"shortText"},{"id":"email_group","component":"Column","children":["email_label","email_field"]},{"id":"email_label","component":"Text","text":"Email Address","variant":"caption"},{"id":"email_field","component":"TextField","label":"Email","value":{"path":"/contact/email"},"variant":"shortText","checks":[{"call":"required","args":{"value":{"path":"/contact/email"}},"message":"Email is required."},{"call":"email","args":{"value":{"path":"/contact/email"}},"message":"Please enter a valid email address."}]},{"id":"phone_group","component":"Column","children":["phone_label","phone_field"]},{"id":"phone_label","component":"Text","text":"Phone Number","variant":"caption"},{"id":"phone_field","component":"TextField","label":"Phone","value":{"path":"/contact/phone"},"variant":"shortText","checks":[{"call":"regex","args":{"value":{"path":"/contact/phone"},"pattern":"^\\d{10}$"},"message":"Phone number must be 10 digits."}]},{"id":"pref_group","component":"Column","children":["pref_label","pref_picker"]},{"id":"pref_label","component":"Text","text":"Preferred Contact Method","variant":"caption"},{"id":"pref_picker","component":"ChoicePicker","variant":"mutuallyExclusive","options":[{"label":"Email","value":"email"},{"label":"Phone","value":"phone"},{"label":"SMS","value":"sms"}],"value":{"path":"/contact/preference"}},{"id":"divider_1","component":"Divider","axis":"horizontal"},{"id":"newsletter_checkbox","component":"CheckBox","label":"Subscribe to our newsletter","value":{"path":"/contact/subscribe"}},{"id":"submit_button_label","component":"Text","text":"Send Message"},{"id":"submit_button","component":"Button","child":"submit_button_label","variant":"primary","action":{"event":{"name":"submitContactForm","context":{"formId":"contact_form_1","clientTime":{"call":"now","args":{},"returnType":"string"},"isNewsletterSubscribed":{"path":"/contact/subscribe"}}}}}]}}
286-
{"updateDataModel":{"surfaceId":"contact_form_1","path":"/contact","value":{"firstName":"John","lastName":"Doe","email":"john.doe@example.com","phone":"1234567890","preference":["email"],"subscribe":true}}}
287-
{"deleteSurface":{"surfaceId":"contact_form_1"}}
288+
{"version": "v0.9", "createSurface":{"surfaceId":"contact_form_1","catalogId":"https://a2ui.org/specification/v0_9/standard_catalog.json"}}
289+
{"version": "v0.9", "updateComponents":{"surfaceId":"contact_form_1","components":[{"id":"root","component":"Card","child":"form_container"},{"id":"form_container","component":"Column","children":["header_row","name_row","email_group","phone_group","pref_group","divider_1","newsletter_checkbox","submit_button"],"justify":"start","align":"stretch"},{"id":"header_row","component":"Row","children":["header_icon","header_text"],"align":"center"},{"id":"header_icon","component":"Icon","name":"mail"},{"id":"header_text","component":"Text","text":"# Contact Us","variant":"h2"},{"id":"name_row","component":"Row","children":["first_name_group","last_name_group"],"justify":"spaceBetween"},{"id":"first_name_group","component":"Column","children":["first_name_label","first_name_field"],"weight":1},{"id":"first_name_label","component":"Text","text":"First Name","variant":"caption"},{"id":"first_name_field","component":"TextField","label":"First Name","value":{"path":"/contact/firstName"},"variant":"shortText"},{"id":"last_name_group","component":"Column","children":["last_name_label","last_name_field"],"weight":1},{"id":"last_name_label","component":"Text","text":"Last Name","variant":"caption"},{"id":"last_name_field","component":"TextField","label":"Last Name","value":{"path":"/contact/lastName"},"variant":"shortText"},{"id":"email_group","component":"Column","children":["email_label","email_field"]},{"id":"email_label","component":"Text","text":"Email Address","variant":"caption"},{"id":"email_field","component":"TextField","label":"Email","value":{"path":"/contact/email"},"variant":"shortText","checks":[{"call":"required","args":{"value":{"path":"/contact/email"}},"message":"Email is required."},{"call":"email","args":{"value":{"path":"/contact/email"}},"message":"Please enter a valid email address."}]},{"id":"phone_group","component":"Column","children":["phone_label","phone_field"]},{"id":"phone_label","component":"Text","text":"Phone Number","variant":"caption"},{"id":"phone_field","component":"TextField","label":"Phone","value":{"path":"/contact/phone"},"variant":"shortText","checks":[{"call":"regex","args":{"value":{"path":"/contact/phone"},"pattern":"^\\d{10}$"},"message":"Phone number must be 10 digits."}]},{"id":"pref_group","component":"Column","children":["pref_label","pref_picker"]},{"id":"pref_label","component":"Text","text":"Preferred Contact Method","variant":"caption"},{"id":"pref_picker","component":"ChoicePicker","variant":"mutuallyExclusive","options":[{"label":"Email","value":"email"},{"label":"Phone","value":"phone"},{"label":"SMS","value":"sms"}],"value":{"path":"/contact/preference"}},{"id":"divider_1","component":"Divider","axis":"horizontal"},{"id":"newsletter_checkbox","component":"CheckBox","label":"Subscribe to our newsletter","value":{"path":"/contact/subscribe"}},{"id":"submit_button_label","component":"Text","text":"Send Message"},{"id":"submit_button","component":"Button","child":"submit_button_label","variant":"primary","action":{"event":{"name":"submitContactForm","context":{"formId":"contact_form_1","clientTime":{"call":"now","args":{},"returnType":"string"},"isNewsletterSubscribed":{"path":"/contact/subscribe"}}}}}]}}
290+
{"version": "v0.9", "updateDataModel":{"surfaceId":"contact_form_1","path":"/contact","value":{"firstName":"John","lastName":"Doe","email":"john.doe@example.com","phone":"1234567890","preference":["email"],"subscribe":true}}}
291+
{"version": "v0.9", "deleteSurface":{"surfaceId":"contact_form_1"}}
288292
```
289293

290294
## Component model
@@ -531,6 +535,7 @@ _Update a specific field:_
531535

532536
```json
533537
{
538+
"version": "v0.9",
534539
"updateDataModel": {
535540
"surfaceId": "surface_123",
536541
"path": "/user/firstName",
@@ -543,6 +548,7 @@ _Remove a field:_
543548

544549
```json
545550
{
551+
"version": "v0.9",
546552
"updateDataModel": {
547553
"surfaceId": "surface_123",
548554
"path": "/user/tempData"
@@ -554,6 +560,7 @@ _Replace the entire data model:_
554560

555561
```json
556562
{
563+
"version": "v0.9",
557564
"updateDataModel": {
558565
"surfaceId": "surface_123",
559566
"value": {

specification/v0_9/docs/evolution_guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Version 0.9 represents a fundamental philosophical shift from "Structured Output
103103

104104
```json
105105
{
106+
"version": "v0.9",
106107
"createSurface": {
107108
"surfaceId": "user_profile_card",
108109
"catalogId": "https://a2ui.org/specification/v0_9/standard_catalog.json",
@@ -155,6 +156,7 @@ Specifying an unknown surfaceId will cause an error. It is recommended that clie
155156

156157
```json
157158
{
159+
"version": "v0.9",
158160
"updateComponents": {
159161
"surfaceId": "main",
160162
"components": [

specification/v0_9/eval/src/generation_flow.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Standard Instructions:
5656
13. Do NOT use a 'style' property. Use standard properties like 'align', 'justify', 'variant', etc.
5757
14. Do NOT invent properties that are not in the schema. Check the 'properties' list for each component type.
5858
15. Use 'checks' property for validation rules if required.
59+
16. EVERY message object MUST include the property "version": "v0.9" at the top level.
5960
${catalogRules ? `\nInstructions specific to this catalog:\n${catalogRules}` : ""}
6061
6162
Schemas:

specification/v0_9/json/a2ui_client_capabilities.json

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,25 @@
55
"description": "A schema for the a2uiClientCapabilities object, which is sent from the client to the server as part of the A2A metadata to describe the client's UI rendering capabilities.",
66
"type": "object",
77
"properties": {
8-
"supportedCatalogIds": {
9-
"type": "array",
10-
"description": "The URI of each of the component and function catalogs that is supported by the client.",
11-
"items": { "type": "string" }
12-
},
13-
"inlineCatalogs": {
14-
"type": "array",
15-
"description": "An array of inline catalog definitions, which can contain both components and functions. This should only be provided if the agent declares 'acceptsInlineCatalogs: true' in its capabilities.",
16-
"items": { "$ref": "#/$defs/Catalog" }
8+
"v0.9": {
9+
"type": "object",
10+
"description": "The capabilities structure for version 0.9 of the A2UI protocol.",
11+
"properties": {
12+
"supportedCatalogIds": {
13+
"type": "array",
14+
"description": "The URI of each of the component and function catalogs that is supported by the client.",
15+
"items": { "type": "string" }
16+
},
17+
"inlineCatalogs": {
18+
"type": "array",
19+
"description": "An array of inline catalog definitions, which can contain both components and functions. This should only be provided if the agent declares 'acceptsInlineCatalogs: true' in its capabilities.",
20+
"items": { "$ref": "#/$defs/Catalog" }
21+
}
22+
},
23+
"required": ["supportedCatalogIds"]
1724
}
1825
},
19-
"required": ["supportedCatalogIds"],
26+
"required": ["v0.9"],
2027
"$defs": {
2128
"FunctionDefinition": {
2229
"type": "object",

specification/v0_9/json/a2ui_client_data_model.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
"description": "Schema for attaching the client data model to A2A message metadata. This object should be placed in the `a2uiClientDataModel` field of the metadata.",
66
"type": "object",
77
"properties": {
8+
"version": {
9+
"const": "v0.9"
10+
},
811
"surfaces": {
912
"type": "object",
1013
"description": "A map of surface IDs to their current data models.",
@@ -14,6 +17,6 @@
1417
}
1518
}
1619
},
17-
"required": ["surfaces"],
20+
"required": ["version", "surfaces"],
1821
"additionalProperties": false
1922
}

specification/v0_9/json/client_to_server.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
"title": "A2UI (Agent to UI) Client-to-Server Event Schema",
33
"description": "Describes a JSON payload for a client-to-server event message.",
44
"type": "object",
5-
"minProperties": 1,
6-
"maxProperties": 1,
5+
"minProperties": 2,
6+
"maxProperties": 2,
77
"properties": {
8+
"version": {
9+
"const": "v0.9"
10+
},
811
"action": {
912
"type": "object",
1013
"description": "Reports a user-initiated action from a component.",
@@ -92,10 +95,10 @@
9295
},
9396
"oneOf": [
9497
{
95-
"required": ["action"]
98+
"required": ["action", "version"]
9699
},
97100
{
98-
"required": ["error"]
101+
"required": ["error", "version"]
99102
}
100103
]
101104
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://a2ui.org/specification/v0_9/client_to_server_list.json",
4+
"title": "A2UI Client-to-Server Message List",
5+
"description": "A list of A2UI Client-to-Server messages.",
6+
"type": "array",
7+
"items": {
8+
"$ref": "client_to_server.json"
9+
}
10+
}

0 commit comments

Comments
 (0)