消息类型¶
本参考文档提供了所有 A2UI 消息类型的详细文档。
消息格式¶
所有 A2UI 消息都是作为 JSON Lines (JSONL) 发送的 JSON 对象。每行只包含一条消息,每条消息只包含以下四个键之一:
beginRenderingsurfaceUpdatedataModelUpdatedeleteSurface
beginRendering¶
向客户端发出信号,表明它有足够的信息来执行 Surface 的初始渲染。
Schema¶
{
beginRendering: {
surfaceId: string; // Required: Unique surface identifier
root: string; // Required: The ID of the root component to render
catalogId?: string; // Optional: URL of component catalog
styles?: object; // Optional: Styling information
}
}
属性¶
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
surfaceId |
string | ✅ | 此 Surface 的唯一标识符。 |
root |
string | ✅ | 此 Surface 的 UI 树根组件的 id。 |
catalogId |
string | ❌ | 组件目录的标识符。如果省略,默认为 v0.8 标准目录。 |
styles |
object | ❌ | 目录定义的 UI 样式信息。 |
示例¶
基本渲染信号:
带有自定义目录:
{
"beginRendering": {
"surfaceId": "custom-ui",
"root": "root-custom",
"catalogId": "https://my-company.com/a2ui/v0.8/my_custom_catalog.json"
}
}
使用说明¶
- 必须在客户端接收到根组件及其初始子组件的组件定义后发送。
- 客户端应缓冲
surfaceUpdate和dataModelUpdate消息,并在收到相应的beginRendering消息后才渲染 Surface 的 UI。
surfaceUpdate¶
在 Surface 中添加或更新组件。
Schema¶
{
surfaceUpdate: {
surfaceId: string; // Required: Target surface
components: Array<{ // Required: List of components
id: string; // Required: Component ID
component: { // Required: Wrapper for component data
[ComponentType]: { // Required: Exactly one component type
...properties // Component-specific properties
}
}
}>
}
}
属性¶
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
surfaceId |
string | ✅ | 要更新的 Surface ID |
components |
array | ✅ | 组件定义数组 |
组件对象¶
components 数组中的每个对象必须具有:
id(string, 必需): Surface 内的唯一标识符component(object, 必需): 包含且仅包含一个键(组件类型,例如Text,Button)的包装对象。
示例¶
单个组件:
{
"surfaceUpdate": {
"surfaceId": "main",
"components": [
{
"id": "greeting",
"component": {
"Text": {
"text": {"literalString": "Hello, World!"},
"usageHint": "h1"
}
}
}
]
}
}
多个组件(邻接表):
{
"surfaceUpdate": {
"surfaceId": "main",
"components": [
{
"id": "root",
"component": {
"Column": {
"children": {"explicitList": ["header", "body"]}
}
}
},
{
"id": "header",
"component": {
"Text": {
"text": {"literalString": "Welcome"}
}
}
},
{
"id": "body",
"component": {
"Card": {
"child": "content"
}
}
},
{
"id": "content",
"component": {
"Text": {
"text": {"path": "/message"}
}
}
}
]
}
}
更新现有组件:
{
"surfaceUpdate": {
"surfaceId": "main",
"components": [
{
"id": "greeting",
"component": {
"Text": {
"text": {"literalString": "Hello, Alice!"},
"usageHint": "h1"
}
}
}
]
}
}
具有 id: "greeting" 的组件被更新(而不是复制)。
使用说明¶
- 必须在
beginRendering消息中指定一个组件作为root,作为树的根。 - 组件形成邻接表(带有 ID 引用的扁平结构)。
- 发送具有现有 ID 的组件会更新该组件。
- 子组件通过 ID 引用。
- 组件可以增量添加(流式传输)。
错误¶
| 错误 | 原因 | 解决方案 |
|---|---|---|
| Surface 未找到 | surfaceId 不存在 |
确保对给定 Surface 始终使用唯一的 surfaceId。Surface 在首次更新时隐式创建。 |
| 无效的组件类型 | 未知的组件类型 | 检查协商的目录中是否存在该组件类型。 |
| 无效的属性 | 该类型不存在此属性 | 对照目录 Schema 进行验证。 |
| 循环引用 | 组件引用自身作为子组件 | 修复组件层次结构。 |
dataModelUpdate¶
更新组件绑定的数据模型。
Schema¶
{
dataModelUpdate: {
surfaceId: string; // Required: Target surface
path?: string; // Optional: Path to a location in the model
contents: Array<{ // Required: Data entries
key: string;
valueString?: string;
valueNumber?: number;
valueBoolean?: boolean;
valueMap?: Array<{...}>;
}>
}
}
属性¶
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
surfaceId |
string | ✅ | 要更新的 Surface ID。 |
path |
string | ❌ | 数据模型中位置的路径(例如 'user')。如果省略,则更新应用于根。 |
contents |
array | ✅ | 作为邻接表的数据条目数组。每个条目都有一个 key 和一个类型的 value* 属性。 |
contents 邻接表¶
contents 数组是键值对列表。数组中的每个对象必须有一个 key 和且仅有一个 value* 属性(valueString, valueNumber, valueBoolean, 或 valueMap)。这种结构对 LLM 友好,避免了从泛型 value 字段推断类型的问题。
示例¶
初始化整个模型:
如果省略 path,contents 将替换 Surface 的整个数据模型。
{
"dataModelUpdate": {
"surfaceId": "main",
"contents": [
{
"key": "user",
"valueMap": [
{ "key": "name", "valueString": "Alice" },
{ "key": "email", "valueString": "alice@example.com" }
]
},
{ "key": "items", "valueMap": [] }
]
}
}
更新嵌套属性:
如果提供了 path,contents 将更新该位置的数据。
{
"dataModelUpdate": {
"surfaceId": "main",
"path": "user",
"contents": [
{ "key": "email", "valueString": "alice@newdomain.com" }
]
}
}
这将更改 /user/email 而不影响 /user/name。
使用说明¶
- 数据模型是每个 Surface 独有的。
- 组件在其绑定的数据更改时自动重新渲染。
- 优先更新特定路径,而不是替换整个模型。
- 数据模型是一个纯 JSON 对象。
- 任何数据转换(例如,格式化日期)必须在发送
dataModelUpdate消息之前由服务器完成。
deleteSurface¶
删除 Surface 及其所有组件和数据。
Schema¶
属性¶
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
surfaceId |
string | ✅ | 要删除的 Surface ID |
示例¶
删除一个 Surface:
删除多个 Surface:
使用说明¶
- 删除与 Surface 关联的所有组件
- 清除 Surface 的数据模型
- 客户端应从 UI 中移除 Surface
- 删除不存在的 Surface 是安全的(无操作)
- 在关闭模态框、对话框或导航离开时使用
错误¶
| 错误 | 原因 | 解决方案 |
|---|---|---|
| (无 - 删除是幂等的) |
消息顺序¶
要求¶
beginRendering必须在该 Surface 的初始surfaceUpdate消息之后。surfaceUpdate可以在dataModelUpdate之前或之后。- 不同 Surface 的消息是独立的。
- 多条消息可以增量更新同一个 Surface。
推荐顺序¶
{"surfaceUpdate": {"surfaceId": "main", "components": [...]}}
{"dataModelUpdate": {"surfaceId": "main", "contents": {...}}}
{"beginRendering": {"surfaceId": "main", "root": "root-id"}}
渐进式构建¶
{"surfaceUpdate": {"surfaceId": "main", "components": [...]}} // Header
{"surfaceUpdate": {"surfaceId": "main", "components": [...]}} // Body
{"beginRendering": {"surfaceId": "main", "root": "root-id"}} // Initial render
{"surfaceUpdate": {"surfaceId": "main", "components": [...]}} // Footer (after initial render)
{"dataModelUpdate": {"surfaceId": "main", "contents": {...}}} // Populate data
验证¶
所有消息都应根据以下内容进行验证:
- server_to_client.json: 消息信封 Schema
- standard_catalog_definition.json: 组件 Schema
延伸阅读¶
- 组件库: 所有可用的组件类型
- 数据绑定指南: 数据绑定如何工作
- Agent 开发指南: 生成有效消息