Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions specification/v0_10/docs/a2ui_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Validators determine which fields represent structural links by looking for thes

## Envelope message structure

The envelope defines four primary message types, and every message streamed by the server must be a JSON object containing exactly one of the following keys: `createSurface`, `updateComponents`, `updateDataModel`, or `deleteSurface`. The key indicates the type of message, and these are the messages that make up each message in the protocol stream.
The envelope defines several message types, and every message streamed by the server must be a JSON object containing exactly one of the following keys: `createSurface`, `updateComponents`, `updateDataModel`, `deleteSurface`, or `actionResponse`. The key indicates the type of message, and these are the messages that make up each message in the protocol stream.

### `createSurface`

Expand Down Expand Up @@ -275,6 +275,51 @@ This message instructs the client to remove a surface and all its associated com
}
```

### `actionResponse`

This message is sent by the server to respond to a client-initiated `action` that requested a response via `wantResponse: true`.

**Properties:**

- `actionId` (string, required): The unique ID of the action call this response belongs to. MUST match the `actionId` sent by the client.
- `actionResponse` (object, required): The payload containing the response.
- `value` (any): The return value of the action. Present on success.
- `error` (object): Error details if the action failed.
- `code` (string): Error code.
- `message` (string): Description of the error.

Exactly one of `value` or `error` must be present.

**Example:**

Client sends this to the server:
```json
{
"version": "v0.10",
"action": {
"name": "get_typeahead_suggestions",
"surfaceId": "mysurface",
"sourceComponentId": "myinput",
"context": {
"prefix": "app"
},
"wantResponse": true,
"actionId": "get_typeahead_suggestions_1"
}
}
```

Server responds with:
```json
{
"version": "v0.10",
"actionId": "get_typeahead_suggestions_1",
"actionResponse": {
"value": ["apple", "application", "approved"]
}
}
```

## Example Stream

The following example demonstrates a complete interaction to render a Contact Form, expressed as a JSONL stream.
Expand Down Expand Up @@ -343,7 +388,10 @@ Interactive components (like `Button`) use an `action` property to define what h

#### Server actions

To send an event to the server, use the `event` property within the `action` object. It requires a `name` and an optional `context`.
To send an event to the server, use the `event` property within the `action` object. It requires a `name` and supports an optional `context`, `wantResponse`, and `responsePath`.

- `wantResponse` (boolean, optional): If true, the client expects an `actionResponse` from the server. Defaults to false.
- `responsePath` (string, optional): A JSON Pointer path in the local data model where the response `value` should be saved.

```json
{
Expand Down Expand Up @@ -813,6 +861,7 @@ This message is sent when the user interacts with a component that has an `actio
- `sourceComponentId` (string, required): The ID of the component that triggered the action.
- `timestamp` (string, required): An ISO 8601 timestamp.
- `context` (object, required): A JSON object containing any context provided in the component's `action` property.
- `actionId` (string, optional): A unique ID for this action call, generated by the client if `wantResponse` is true.

### Capabilities & metadata

Expand Down
6 changes: 6 additions & 0 deletions specification/v0_10/docs/evolution_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This document serves as a comprehensive guide to the changes between A2UI versio

Version 0.10 differs from 0.9 in the following ways:

- **Client-to-Server RPC**: Introduced `actionResponse` enabling synchronous responses to client-initiated actions. Added `actionId` for response correlation.
- <TBD>

## 2. Changes
Expand All @@ -16,10 +17,12 @@ Version 0.10 differs from 0.9 in the following ways:

### 2.2. Server-to-Client Message List Schema

- Added `ActionResponseMessage` to allow the server to respond to a specific action call using an `actionId`.
- <TBD>

### 2.3. Client-to-Server Message List Schema

- Added `actionId` to the `action` message properties, which the client generates if a response is expected (`wantResponse: true`).
- <TBD>

### 2.4. Client Capabilities Schema
Expand All @@ -40,10 +43,13 @@ Version 0.10 differs from 0.9 in the following ways:

### 2.8. Server-to-Client Messages

- Added `actionResponse` message structure to support synchronous responses with a `value` or `error`.
- <TBD>

### 2.9. Client-to-Server Events

- Updated `action` message to include `actionId`.
- Updated `Action` type in `common_types.json` to include `wantResponse` and `responsePath` on event triggers.
- <TBD>

## 3. Migration Guide
Expand Down
9 changes: 9 additions & 0 deletions specification/v0_10/json/client_to_server.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
"type": "object",
"description": "A JSON object containing the key-value pairs from the component's action.event.context, after resolving all data bindings.",
"additionalProperties": true
},
"wantResponse": {
"type": "boolean",
"description": "If true, the client expects an actionResponse from the server.",
"default": false
},
"actionId": {
"type": "string",
"description": "Unique ID for this action call. Only needed if wantResponse is true."
}
},
"required": [
Expand Down
9 changes: 9 additions & 0 deletions specification/v0_10/json/common_types.json
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,15 @@
"additionalProperties": {
"$ref": "#/$defs/DynamicValue"
}
},
"wantResponse": {
"type": "boolean",
"description": "If true, the client expects an actionResponse from the server.",
"default": false
},
"responsePath": {
"type": "string",
"description": "Optional JSON Pointer path where the client should save the response value in its local data model."
}
},
"required": ["name"],
Expand Down
41 changes: 40 additions & 1 deletion specification/v0_10/json/server_to_client.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
{ "$ref": "#/$defs/UpdateComponentsMessage" },
{ "$ref": "#/$defs/UpdateDataModelMessage" },
{ "$ref": "#/$defs/DeleteSurfaceMessage" },
{ "$ref": "#/$defs/CallFunctionMessage" }
{ "$ref": "#/$defs/CallFunctionMessage" },
{ "$ref": "#/$defs/ActionResponseMessage" }
],
"$defs": {
"CreateSurfaceMessage": {
Expand Down Expand Up @@ -166,6 +167,44 @@
},
"required": ["version", "callFunction", "functionCallId"],
"additionalProperties": false
},
"ActionResponseMessage": {
"type": "object",
"description": "A response to a client-initiated action.",
"properties": {
"version": {
"const": "v0.10"
},
"actionId": {
"type": "string",
"description": "The ID of the action call this response belongs to."
},
"actionResponse": {
"type": "object",
"properties": {
"value": {
"description": "The return value of the action.",
"type": [ "string", "number", "boolean", "array", "object", "null" ]
},
"error": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" }
},
"required": [ "code", "message" ],
"additionalProperties": false
}
},
"oneOf": [
{ "required": [ "value" ] },
{ "required": [ "error" ] }
],
"additionalProperties": false
}
},
"required": [ "version", "actionResponse", "actionId" ],
"additionalProperties": false
}
}
}
Loading