Skip to content

Commit 79df6e0

Browse files
authored
Make A2UI v0.9 an A2A Extension and Unify Catalogs (google#452)
1 parent b22fd59 commit 79df6e0

20 files changed

Lines changed: 794 additions & 573 deletions
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# A2UI (Agent-to-Agent UI) Extension Spec v0.9
2+
3+
## Overview
4+
5+
This extension implements the A2UI (Agent-to-Agent UI) spec v0.9, a format for agents to send streaming, interactive user interfaces to clients.
6+
7+
## Extension URI
8+
9+
The URI of this extension is https://a2ui.org/a2a-extension/a2ui/v0.9
10+
11+
This is the only URI accepted for this extension.
12+
13+
## Core Concepts
14+
15+
The A2UI extension is built on the following main concepts:
16+
17+
Surfaces: A "Surface" is a distinct, controllable region of the client's UI. The spec uses a surfaceId to direct updates to specific surfaces (e.g., a main content area, a side panel, or a new chat bubble). This allows a single agent stream to manage multiple UI areas independently.
18+
19+
Catalog Definition Document: The a2ui extension is catalog-agnostic. All UI components (e.g., Text, Row, Button) and functions (e.g., required, email) are defined in a separate Catalog Definition Schema. This allows clients and servers to negotiate which catalog to use.
20+
21+
Schemas: The a2ui extension is defined by several primary JSON schemas:
22+
23+
- 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).
26+
- Client Capabilities Schema: The schema for the `a2uiClientCapabilities` object.
27+
28+
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.
29+
30+
## Agent Card details
31+
32+
Agents advertise their A2UI capabilities in their AgentCard within the `AgentCapabilities.extensions` list. The `params` object defines the agent's specific UI support.
33+
34+
Example AgentExtension block:
35+
36+
```json
37+
{
38+
"uri": "https://a2ui.org/a2a-extension/a2ui/v0.9",
39+
"description": "Ability to render A2UI v0.9",
40+
"required": false,
41+
"params": {
42+
"supportedCatalogIds": [
43+
"https://a2ui.dev/specification/0.9/standard_catalog.json",
44+
"https://my-company.com/a2ui/v0.9/my_custom_catalog.json"
45+
],
46+
"acceptsInlineCatalogs": true
47+
}
48+
}
49+
```
50+
51+
### Parameter Definitions
52+
- `params.supportedCatalogIds`: (OPTIONAL) An array of strings, where each string is a URI pointing to a Catalog Definition Schema that the agent can generate.
53+
- `params.acceptsInlineCatalogs`: (OPTIONAL) A boolean indicating if the agent can accept an `inlineCatalogs` array in the client's `a2uiClientCapabilities`. If omitted, this defaults to `false`.
54+
55+
## Extension Activation
56+
Clients indicate their desire to use the A2UI extension by specifying it via the transport-defined A2A extension activation mechanism.
57+
58+
For JSON-RPC and HTTP transports, this is indicated via the X-A2A-Extensions HTTP header.
59+
60+
For gRPC, this is indicated via the X-A2A-Extensions metadata value.
61+
62+
Activating this extension implies that the server can send A2UI-specific messages (like updateComponents) and the client is expected to send A2UI-specific events (like action).
63+
64+
## Data Encoding
65+
66+
A2UI messages are encoded as an A2A `DataPart`.
67+
68+
To identify a `DataPart` as containing A2UI data, it must have the following metadata:
69+
70+
- `mimeType`: `application/json+a2ui`
71+
72+
The `data` field of the `DataPart` contains the A2UI JSON message (e.g., `updateComponents`, `action`).
73+
74+
Example A2UI DataPart:
75+
76+
```json
77+
{
78+
"data": {
79+
"createSurface": {
80+
"surfaceId": "user_profile_surface",
81+
"catalogId": "https://a2ui.dev/specification/0.9/standard_catalog.json"
82+
}
83+
},
84+
"kind": "data",
85+
"metadata": {
86+
"mimeType": "application/json+a2ui"
87+
}
88+
}
89+
```

specification/0.9/docs/a2ui_protocol.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Version 0.9 of the A2UI protocol represents a philosophical shift from previous
3535
This "prompt-first" approach offers several advantages:
3636

3737
1. **Richer Schema:** The protocol is no longer limited by the constraints of structured output formats. This allows for more readable, complex, and expressive component catalogs.
38-
2. **Modularity:** The schema is now refactored into separate, more manageable components (e.g., [`common_types.json`], [`standard_catalog_definition.json`], [`server_to_client.json`]), improving maintainability and modularity.
38+
2. **Modularity:** The schema is now refactored into separate, more manageable components (e.g., [`common_types.json`], [`standard_catalog.json`], [`server_to_client.json`]), improving maintainability and modularity.
3939

4040
The main disadvantage of this approach is that it requires more complex post-generation validation, as the LLM is not strictly constrained by the schema. This requires robust error handling and correction, so the system can identify discrepancies and attempt to fix them before rendering, or request a retry or correction from the LLM.
4141

@@ -100,7 +100,7 @@ The [`server_to_client.json`] schema is the top-level entry point. Every line st
100100

101101
### The Standard Catalog
102102

103-
The [`standard_catalog_definition.json`] schema contains the definitions for all specific UI components (e.g., `Text`, `Button`, `Row`). By separating this from the envelope, developers can easily swap in custom catalogs (e.g., `material_catalog.json` or `cupertino_catalog.json`) without rewriting the core protocol parser.
103+
The [`standard_catalog.json`] schema contains the definitions for all specific UI components (e.g., `Text`, `Button`, `Row`) and functions (e.g., `required`, `email`). By separating this from the envelope, developers can easily swap in custom catalogs (e.g., `material_catalog.json` or `cupertino_catalog.json`) without rewriting the core protocol parser.
104104

105105
Custom catalogs can be used to define additional UI components or modify the behavior of existing components. To use a custom catalog, simply include it in the prompt in place of the standard catalog. It should have the same form as the standard catalog, and use common elements in the [`common_types.json`] schema.
106106

@@ -115,15 +115,15 @@ This message signals the client to create a new surface and begin rendering it.
115115
**Properties:**
116116

117117
- `surfaceId` (string, required): The unique identifier for the UI surface to be rendered.
118-
- `catalogId` (string, required): A string that uniquely identifies the component catalog used for this surface. It is recommended to prefix this with an internet domain that you own, to avoid conflicts (e.g., `https://mycompany.com/1.0/somecatalog`).
118+
- `catalogId` (string, required): A string that uniquely identifies the catalog (components and functions) used for this surface. It is recommended to prefix this with an internet domain that you own, to avoid conflicts (e.g., `https://mycompany.com/1.0/somecatalog`).
119119

120120
**Example:**
121121

122122
```json
123123
{
124124
"createSurface": {
125125
"surfaceId": "user_profile_card",
126-
"catalogId": "https://a2ui.dev/specification/0.9/standard_catalog_definition.json"
126+
"catalogId": "https://a2ui.dev/specification/0.9/standard_catalog.json"
127127
}
128128
}
129129
```
@@ -212,9 +212,9 @@ This message instructs the client to remove a surface and all its associated com
212212
The following example demonstrates a complete interaction to render a Contact Form, expressed as a JSONL stream.
213213

214214
```jsonl
215-
{"createSurface":{"surfaceId":"contact_form_1","catalogId":"https://a2ui.dev/specification/0.9/standard_catalog_definition.json"}}
216-
{"updateComponents":{"surfaceId":"contact_form_1","components":[{"id":"root","component":"Column","children":["first_name_label","first_name_field","last_name_label","last_name_field","email_label","email_field","phone_label","phone_field","notes_label","notes_field","submit_button"]},{"id":"first_name_label","component":"Text","text":"First Name"},{"id":"first_name_field","component":"TextField","label":"First Name","value":{"path":"/contact/firstName"},"variant":"shortText"},{"id":"last_name_label","component":"Text","text":"Last Name"},{"id":"last_name_field","component":"TextField","label":"Last Name","value":{"path":"/contact/lastName"},"variant":"shortText"},{"id":"email_label","component":"Text","text":"Email"},{"id":"email_field","component":"TextField","label":"Email","value":{"path":"/contact/email"},"variant":"shortText","checks":[{"call":"email","message":"Please enter a valid email address."}]},{"id":"phone_label","component":"Text","text":"Phone"},{"id":"phone_field","component":"TextField","label":"Phone","value":{"path":"/contact/phone"},"variant":"shortText"},{"id":"notes_label","component":"Text","text":"Notes"},{"id":"notes_field","component":"TextField","label":"Notes","value":{"path":"/contact/notes"},"variant":"longText"},{"id":"submit_button_label","component":"Text","text":"Submit"},{"id":"submit_button","component":"Button","child":"submit_button_label","action":{"name":"submitContactForm"}}]}}
217-
{"updateDataModel": {"surfaceId": "contact_form_1", "path": "/contact", "value": {"firstName": "John", "lastName": "Doe", "email": "john.doe@example.com"}}}
215+
{"createSurface":{"surfaceId":"contact_form_1","catalogId":"https://a2ui.dev/specification/0.9/standard_catalog.json"}}
216+
{"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","message":"Email is required."},{"call":"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":{"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","primary":true,"action":{"name":"submitContactForm","context":{"formId":"contact_form_1","clientTime":{"call":"now","returnType":"string"},"isNewsletterSubscribed":{"path":"/contact/subscribe"}}}}]}}
217+
{"updateDataModel":{"surfaceId":"contact_form_1","path":"/contact","value":{"firstName":"John","lastName":"Doe","email":"john.doe@example.com","phone":"1234567890","preference":["email"],"subscribe":true}}}
218218
```
219219

220220
## Component Model
@@ -234,7 +234,7 @@ This structure is designed to be both flexible and strictly validated.
234234

235235
### The Component Catalog
236236

237-
The set of available UI components and their properties is defined in a **Component Catalog**. The standard catalog is defined in [`standard_catalog_definition.json`]. This allows for different clients to support different sets of components, including custom ones. The server must generate `updateComponents` messages that conform to the component catalog understood by the client.
237+
The set of available UI components and functions is defined in a **Catalog**. The standard catalog is defined in [`standard_catalog.json`]. This allows for different clients to support different sets of components and functions, including custom ones. The server must generate messages that conform to the catalog understood by the client.
238238

239239
### UI Composition: The Adjacency List Model
240240

@@ -495,7 +495,7 @@ Buttons can also define `checks`. If any check fails, the button is automaticall
495495

496496
## Standard Component Catalog
497497

498-
The [`standard_catalog_definition.json`] provides the baseline set of components.
498+
The [`standard_catalog.json`] provides the baseline set of components and functions.
499499

500500
| Component | Description |
501501
| :---------------- | :------------------------------------------------------------------------------------- |
@@ -572,24 +572,25 @@ This message is sent when the user interacts with a component that has an `actio
572572
- `timestamp` (string, required): An ISO 8601 timestamp.
573573
- `context` (object, required): A JSON object containing any context provided in the component's `action` property.
574574

575-
### `capabilities`
575+
### Client Capabilities
576576

577-
This message is sent by the client upon connection to inform the server of its capabilities, including supported component catalogs and validation catalogs.
577+
Client capabilities are sent by the client to inform the server of its capabilities, including supported catalogs (components and functions). In A2UI v0.9, these are sent as part of the **A2A metadata** envelope in every message, rather than as a first-class A2UI message. This ensures the server always has the client's latest capabilities without needing a separate handshake.
578+
579+
The `a2uiClientCapabilities` object in the metadata follows the [`a2ui_client_capabilities_schema.json`] schema.
578580

579581
**Properties:**
580582

581-
- `supportedCatalogIds` (array of strings, required): URIs of supported component catalogs.
582-
- `supportedFunctionCatalogIds`: A list of URIs for the function catalogs supported by the client.
583-
- `inlineCatalogs`: An array of inline component catalog definitions provided directly by the client (useful for custom or ad-hoc components).
584-
- `inlineFunctionCatalogs`: An array of function catalog definitions provided directly by the client (useful for custom or ad-hoc functions).
583+
- `supportedCatalogIds` (array of strings, required): URIs of supported catalogs.
584+
- `inlineCatalogs`: An array of inline catalog definitions provided directly by the client (useful for custom or ad-hoc components and functions).
585585

586586
### `error`
587587

588588
This message is used to report a client-side error to the server.
589589

590-
[`standard_catalog_definition.json`]: ../json/standard_catalog_definition.json
590+
[`standard_catalog.json`]: ../json/standard_catalog.json
591591
[`common_types.json`]: ../json/common_types.json
592592
[`server_to_client.json`]: ../json/server_to_client.json
593593
[`client_to_server.json`]: ../json/client_to_server.json
594+
[`a2ui_client_capabilities_schema.json`]: ../json/a2ui_client_capabilities_schema.json
594595
[JSON Pointer]: https://datatracker.ietf.org/doc/html/rfc6901
595596
[RFC 6901]: https://datatracker.ietf.org/doc/html/rfc6901

specification/0.9/docs/evolution_guide.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Version 0.9 represents a fundamental philosophical shift from "Structured Output
2020
| **Data Model Update** | Array of Key-Value Pairs | Standard JSON Object |
2121
| **Data Binding** | `dataBinding` / `literalString` | `path` / Native JSON types |
2222
| **Button Context** | Array of Key-Value pairs | Standard JSON Object |
23+
| **Catalog** | Separate component and function catalogs | Unified Catalog (`standard_catalog.json`) |
2324
| **Auxiliary Rules** | N/A | `standard_catalog_rules.txt` |
2425
| **Validation** | Basic Schema | Strict `ValidationFailed` feedback loop |
2526
| **Interpolation** | N/A (Object wrappers only) | Native `${expression}` syntax |
@@ -36,10 +37,11 @@ Version 0.9 represents a fundamental philosophical shift from "Structured Output
3637
**v0.9:**
3738

3839
- **Modularization**: The schema is strictly split into:
39-
- `common_types.json`: Reusable primitives (IDs, paths, weights).
40+
- `common_types.json`: Reusable primitives (IDs, paths, weights) and logic/expression types.
4041
- `server_to_client.json`: The "envelope" defining the message types.
41-
- `standard_catalog_definition.json`: The specific UI components.
42-
- **Benefit**: This allows developers to swap out the `standard_catalog_definition.json` for a `custom_catalog.json` without touching the core protocol envelope.
42+
- `standard_catalog.json`: The unified catalog of UI components and functions.
43+
- **Benefit**: This allows developers to swap out the `standard_catalog.json` for a `custom_catalog.json` without touching the core protocol envelope.
44+
- **Unification**: Components and functions are now part of the same catalog object, simplifying capability negotiation and inline definitions.
4345

4446
### 2.2. Strict Message Typing
4547

@@ -78,7 +80,7 @@ Version 0.9 represents a fundamental philosophical shift from "Structured Output
7880
- **Purpose**: `createSurface` signals the client to create a new surface and prepare for rendering.
7981
- **Style Information Removed**: `createSurface` does **NOT** contain style information. Theming is now handled via the client styles, decoupling it from the message stream.
8082
- **Root Rule**: The rule is: "There must be exactly one component with the ID `root`." The "root" attribute that `beginRendering` had has been removed. The client is expected to render as soon as it has a valid tree with a root component.
81-
- **New Requirement**: `createSurface` now requires a **`catalogId`** (URI) to explicitly state which component set is being used.
83+
- **New Requirement**: `createSurface` now requires a **`catalogId`** (URI) to explicitly state which unified catalog (components and functions) is being used.
8284

8385
**Example:**
8486

@@ -102,7 +104,7 @@ Version 0.9 represents a fundamental philosophical shift from "Structured Output
102104
{
103105
"createSurface": {
104106
"surfaceId": "user_profile_card",
105-
"catalogId": "https://a2ui.dev/specification/0.9/standard_catalog_definition.json"
107+
"catalogId": "https://a2ui.dev/specification/0.9/standard_catalog.json"
106108
}
107109
}
108110
```
@@ -310,5 +312,4 @@ For developers migrating from earlier versions, here is a quick reference of pro
310312
| **TextField** | `text` | `value` |
311313
| **Many** | `usageHint` | `variant` |
312314
| **Client Message** | `userAction` | `action` |
313-
| **Client Message** | `clientUiCapabilities` | `capabilities` |
314315
| **Common Type** | `childrenProperty` | `ChildList` |

0 commit comments

Comments
 (0)