A2UI v0.9.1 消息模板
以下示例展示小型 A2UI v0.9.1 消息流的结构与顺序,适合学习和测试,并不是可以不经检查直接上线的通用载荷。组件属性取决于渲染器选用的 Catalog,协议也可能继续演进。请固定版本、仅使用宿主批准的 Catalog,并在渲染前按准确的官方 v0.9.1 Schema校验每一行。
A2UI 消息通常以 JSON Lines 流式传输:每一行是一个完整 JSON 对象。除非传输层明确要求,否则不要把多行包成数组。v0.9 生命周期使用 createSurface、updateComponents、updateDataModel 和 deleteSurface,不得与 v0.8 的 beginRendering、surfaceUpdate 或 dataModelUpdate 混用。
模板一:静态状态卡片
下面的最小消息序列会创建 Surface,并添加一个包含标题和状态文本的根列。请把示例 Catalog URL 替换成宿主认可的标识;不得允许 Agent 通过任意 Catalog URL 加载可执行代码。
{"version":"v0.9.1","createSurface":{"surfaceId":"service-status","catalogId":"https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"}}
{"version":"v0.9.1","updateComponents":{"surfaceId":"service-status","components":[{"id":"root","component":"Column","children":["title","status"]},{"id":"title","component":"Text","text":"服务状态","variant":"h2"},{"id":"status","component":"Text","text":"全部系统运行正常"}]}}
组件列表是扁平结构:根组件引用子组件 ID,而不是嵌套完整组件对象,因此可以增量替换。组件名称和属性仍必须存在于所选 Catalog 中;若 Catalog 使用不同的文本或布局字段,应按其定义调整并重新校验。
同一 Surface 内应使用稳定组件 ID。相同 ID 的更新会替换已有定义;随机 ID 会让定向更新更困难,还可能在内存中留下过期组件。
模板二:数据绑定内容
持续变化的业务值应存入数据模型,不必每次重新生成整个组件图。下面的订单摘要从数据路径读取文本。绑定语法仍需按当前 Catalog 和渲染器版本确认。
{"version":"v0.9.1","createSurface":{"surfaceId":"order-summary","catalogId":"https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"}}
{"version":"v0.9.1","updateComponents":{"surfaceId":"order-summary","components":[{"id":"root","component":"Column","children":["heading","order-id","state"]},{"id":"heading","component":"Text","text":"订单摘要","variant":"h2"},{"id":"order-id","component":"Text","text":{"path":"/order/id"}},{"id":"state","component":"Text","text":{"path":"/order/status"}}]}}
{"version":"v0.9.1","updateDataModel":{"surfaceId":"order-summary","path":"/","value":{"order":{"id":"A-1042","status":"等待审核"}}}}
后续只更新发生变化的值:
{"version":"v0.9.1","updateDataModel":{"surfaceId":"order-summary","path":"/order/status","value":"已批准"}}
宿主应限制可写路径。合法 JSON Pointer 不等于已授权的数据目的地。还要限制数据模型大小和文本长度,并拒绝不符合应用预期类型的值。
模板三:由宿主授权的 Action
交互组件可以请求 Action,但载荷本身不授予权限。下例添加一个请求宿主刷新订单的按钮。按钮和 Action 字段由 Catalog 定义,因此需要使用与应用一致的 Catalog,在 A2UI Composer 中校验。
{"version":"v0.9.1","updateComponents":{"surfaceId":"order-summary","components":[{"id":"root","component":"Column","children":["heading","order-id","state","refresh"]},{"id":"refresh","component":"Button","child":"refresh-label","action":{"event":{"name":"refreshOrder","context":{"orderId":{"path":"/order/id"}}}}},{"id":"refresh-label","component":"Text","text":"刷新状态"}]}}
宿主应把 refreshOrder 映射到自己的函数,在服务端检查用户权限,并在请求前校验 orderId。付款、披露数据、发送消息或不可逆操作需要明确确认和防重复提交。禁止把 Action 名称或参数中的内容当作代码执行。
替换根组件时,要包含所有仍需显示的子组件。相同 ID 的增量更新会替换已有定义,不会根据省略字段猜测合并意图。
模板四:确定性清理
当对话、弹窗、路由或任务不再需要 Surface 时,应主动删除:
{"version":"v0.9.1","deleteSurface":{"surfaceId":"order-summary"}}
渲染器应释放对应的组件状态、绑定、待处理回调、媒体和订阅。删除后收到的更新必须失败,不能静默重建 Surface。旧 Surface 完成删除和清理后,surfaceId 才能复用。
校验流程
每次改造模板时执行以下流程:
- 选定一个协议版本和一个 Catalog 版本。
- 按匹配的官方 Schema 校验每个 JSON 对象。
- 在宿主边界拒绝未知组件、属性、路径、URL 和 Action。
- 在 Composer 或渲染器测试工具中预览正常、空值、超长、错误和增量数据。
- 测试重复、乱序、截断以及删除后到达的消息。
- 测试键盘操作、焦点、标签、窄屏和安全失败状态。
- 将已校验载荷保存为 Fixture,使依赖升级产生可见差异。
常见改造错误
复制消息时不要删除 version。v0.9.1 Schema 接受当前补丁版本标识;旧文章可能仍展示 v0.9,或结构完全不同的 v0.8 格式。消息版本与 Catalog 版本必须对应。
不要重命名 root,不要重新把组件属性包在类型对象下,也不要把固定 children 数组改回 explicitList;这些都来自旧版结构。Button 事件应放在 action.event 内,渲染器解析允许的上下文绑定后,再把结果发送到服务端。
示例还省略了产品约束。真实订单 Surface 应定义文本长度、允许状态、URL 策略、权限、本地化、空状态和无障碍播报。可以替换示例标识与内容,但除非匹配的官方 Schema 有变化,不应破坏已验证的消息信封结构。
把模板作为测试 Fixture
在应用测试中保存少量已知有效和已知无效的消息流,并使用与生产环境相同的校验器和渲染器执行。提示词可以包含简化 Schema 指引,但模型是否遵守不能作为安全边界。即使同一模板长期正常,运行时校验仍然必需。
协议生命周期以官方消息参考为准;宿主职责见渲染器开发指南。本站示例与官方分版本 Schema 不一致时,应以官方资料为准。