@agentunion/fastaun-browser 0.2.19 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/_packed_docs/CHANGELOG.md +26 -0
  3. package/_packed_docs/agent.md/SCHEMA.md +173 -0
  4. package/_packed_docs/agent.md/examples/codeagent-claudecode.md +61 -0
  5. package/_packed_docs/agent.md/examples/human-developer.md +60 -0
  6. package/_packed_docs/agent.md/examples/openclaw-lobster.md +52 -0
  7. package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +43 -0
  8. package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +205 -0
  9. package/_packed_docs/protocol/00A-/350/256/276/350/256/241/345/216/237/345/210/231-/344/270/272Agent/350/200/214/347/224/237.md +197 -0
  10. package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +549 -0
  11. package/_packed_docs/protocol/02-/350/257/201/344/271/246/344/270/216/344/277/241/344/273/273/344/275/223/347/263/273.md +810 -0
  12. package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +262 -0
  13. package/_packed_docs/protocol/04-Peer-/345/255/220/345/215/217/350/256/256.md +180 -0
  14. package/_packed_docs/protocol/05-Relay-/345/255/220/345/215/217/350/256/256.md +164 -0
  15. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1135 -0
  16. package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +234 -0
  17. package/_packed_docs/protocol/08-AUN-E2EE-Group.md +900 -0
  18. package/_packed_docs/protocol/08-AUN-E2EE.md +413 -0
  19. package/_packed_docs/protocol/09-/345/256/211/345/205/250/350/200/203/350/231/221.md +316 -0
  20. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +804 -0
  21. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +271 -0
  22. package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +329 -0
  23. package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +141 -0
  24. package/_packed_docs/protocol/14-/344/272/244/344/272/222/346/234/272/345/210/266-/345/223/215/345/272/224/346/250/241/345/274/217/344/270/216/350/207/252/344/270/273/346/250/241/345/274/217.md +170 -0
  25. package/_packed_docs/protocol/README.md +71 -0
  26. package/_packed_docs/protocol/agent.md/SCHEMA.md +118 -0
  27. package/_packed_docs/protocol/agent.md/examples/codeagent-claudecode.md +61 -0
  28. package/_packed_docs/protocol/agent.md/examples/human-developer.md +60 -0
  29. package/_packed_docs/protocol/agent.md/examples/openclaw-lobster.md +52 -0
  30. package/_packed_docs/protocol/aun-docs-guide.md +49 -0
  31. package/_packed_docs/protocol/index.md +114 -0
  32. package/_packed_docs/protocol//350/215/211/346/241/210-agent.md/347/255/276/345/220/215/345/215/217/350/256/256.md +205 -0
  33. package/_packed_docs/protocol//350/215/211/346/241/210-/346/213/222/347/273/235/344/277/241/345/217/267/345/215/217/350/256/256.md +249 -0
  34. package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +337 -0
  35. package/_packed_docs/protocol//351/231/204/345/275/225B-/346/211/251/345/261/225/346/200/247/346/214/207/345/215/227.md +80 -0
  36. package/_packed_docs/protocol//351/231/204/345/275/225C-/347/247/201/351/222/245/347/256/241/347/220/206/344/270/216/350/272/253/344/273/275/346/201/242/345/244/215.md +704 -0
  37. package/_packed_docs/protocol//351/231/204/345/275/225D-Root_CA_/346/262/273/347/220/206/346/234/272/345/210/266.md +620 -0
  38. package/_packed_docs/protocol//351/231/204/345/275/225E-Root_CA_/345/207/206/345/205/245/346/265/201/347/250/213.md +605 -0
  39. package/_packed_docs/protocol//351/231/204/345/275/225F-Issuer_CA_/347/224/263/350/257/267/346/265/201/347/250/213.md +548 -0
  40. package/_packed_docs/protocol//351/231/204/345/275/225G-AID_/345/255/244/345/204/277/351/242/204/351/230/262/344/270/216/346/225/221/346/217/264/346/234/272/345/210/266.md +513 -0
  41. package/_packed_docs/protocol//351/231/204/345/275/225H-Identity/346/234/215/345/212/241/345/256/236/347/216/260/346/214/207/345/215/227.md +619 -0
  42. package/_packed_docs/protocol//351/231/204/345/275/225I-/350/267/250/345/237/237/346/266/210/346/201/257/350/267/257/347/224/261/345/256/236/347/216/260/346/214/207/345/215/227.md +492 -0
  43. package/_packed_docs/protocol//351/231/204/345/275/225J-/345/256/242/346/210/267/347/253/257/346/216/245/345/205/245/347/244/272/344/276/213.md +402 -0
  44. package/_packed_docs/protocol//351/231/204/345/275/225K-Agent_Web/345/217/221/347/216/260/345/215/217/350/256/256.md +130 -0
  45. package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +267 -0
  46. package/_packed_docs/protocol//351/231/204/345/275/225M-JWT/350/256/244/350/257/201/345/256/236/347/216/260/346/214/207/345/215/227.md +367 -0
  47. package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +223 -0
  48. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +354 -0
  49. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +172 -0
  50. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +373 -0
  51. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +611 -0
  52. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +1152 -0
  53. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +150 -0
  54. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +89 -0
  55. package/_packed_docs/sdk/09-custody-api-manual.md +445 -0
  56. package/_packed_docs/sdk/09-group-rpc-manual.md +1895 -0
  57. package/_packed_docs/sdk/09-message-rpc-manual.md +597 -0
  58. package/_packed_docs/sdk/09-meta-rpc-manual.md +142 -0
  59. package/_packed_docs/sdk/09-payload-reference.md +702 -0
  60. package/_packed_docs/sdk/09-storage-rpc-manual.md +408 -0
  61. package/_packed_docs/sdk/09-stream-rpc-manual.md +275 -0
  62. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +72 -0
  63. package/_packed_docs/sdk/INDEX.md +131 -0
  64. package/_packed_docs/sdk/README.md +307 -0
  65. package/dist/auth.d.ts +2 -1
  66. package/dist/auth.d.ts.map +1 -1
  67. package/dist/auth.js +13 -11
  68. package/dist/auth.js.map +1 -1
  69. package/dist/client.d.ts +38 -8
  70. package/dist/client.d.ts.map +1 -1
  71. package/dist/client.js +179 -97
  72. package/dist/client.js.map +1 -1
  73. package/dist/namespaces/auth.d.ts +1 -0
  74. package/dist/namespaces/auth.d.ts.map +1 -1
  75. package/dist/namespaces/auth.js +20 -6
  76. package/dist/namespaces/auth.js.map +1 -1
  77. package/dist/transport.d.ts +9 -1
  78. package/dist/transport.d.ts.map +1 -1
  79. package/dist/transport.js +24 -0
  80. package/dist/transport.js.map +1 -1
  81. package/package.json +40 -37
@@ -0,0 +1,702 @@
1
+ # 消息 Payload 参考约定
2
+
3
+ `message.send.params.payload`、`message.thought.put.params.payload`、`group.send.params.payload` 和 `group.thought.put.params.payload` 使用同一套业务负载约定。`payload` 是应用层 JSON 对象,服务端只做大小、JSON 可序列化、信封/封装类型和加密相关的必要检查;业务字段由发送端和接收端协商,服务端不按本文字段做强制校验。
4
+
5
+ 示例展示的是 `payload` 片段:P2P 完整请求仍需要在同级传入 `to`;群消息完整请求仍需要在同级传入 `group_id`;思考内容需要在顶层通过 `context.type + context.id` 指定 selector。文本、图片、文件、思考内容等业务消息类型只能放在 `payload.type`;`message.send.params.type` / `message.thought.put.params.type` / `group.send.params.type` / `group.thought.put.params.type` 是信封或封装类型,例如 SDK 加密发送时自动填充的 `e2ee.encrypted` / `e2ee.group_encrypted`。
6
+
7
+ ## 类型总览
8
+
9
+ | 类型标识 | 作用 | 常见场景 |
10
+ |----------|------|----------|
11
+ | `text` | 纯文本或 Markdown 文本 | 普通对话、任务说明、通知正文 |
12
+ | `quote` | 带引用摘要的回复 | 回复某条消息、保留上下文 |
13
+ | `thought` | 思考过程片段 | Agent 针对某个 P2P 或群上下文的非广播思考内容 |
14
+ | `voice` | 语音文件引用及转写信息 | 语音消息、语音备忘 |
15
+ | `image` | 图片对象引用及展示信息 | 截图、流程图、图片分享 |
16
+ | `video` | 视频对象引用及封面信息 | 录屏、演示视频 |
17
+ | `file` | 通用文件对象引用 | 文档、压缩包、日志附件 |
18
+ | `location` | 地理位置 | 位置共享、地点卡片 |
19
+ | `link` | 链接预览卡片 | 网页、文档、外部资源分享 |
20
+ | `action_card` | 交互卡片 | 选择项、简单确认、任务审批 |
21
+ | `action_card_reply` | 交互卡片回复 | 按钮选择、取消/拒绝、自由输入回复 |
22
+ | `merge` | 合并转发摘要 | 多条消息记录转发 |
23
+ | `personal_card` | 个人或 Agent 名片 | 推荐联系人、介绍 Agent |
24
+ | `status` | 状态更新 | 输入中、处理中、任务进度、错误状态 |
25
+ | `event` | 应用层事件通知 | 任务完成、流程节点变化、异步回调 |
26
+ | `json` | 结构化业务数据 | 参数、配置、计划、表单数据 |
27
+ | `json` + `kind: "poll"` | 投票或表单 | 群内投票、选项收集 |
28
+ | `tool_call` | Agent 工具调用过程标注(请求段) | 发送方标注自身正在调用的本地工具,供查看端渲染 |
29
+ | `tool_result` | Agent 工具调用过程标注(结果段) | 同一发送方标注本地工具执行结果,供查看端渲染 |
30
+ | `custom` | 应用自定义消息 | 私有卡片、业务专用对象 |
31
+
32
+ 接收端应对未知 `payload.type`、未知 `kind` 和缺失展示字段做降级处理,优先使用 `text` / `fallback_text` 展示。
33
+
34
+ ## 信封字段不进入 payload
35
+
36
+ `payload` 只描述业务内容,不重复传输层、投递层或群消息信封已经提供的字段。
37
+
38
+ | 字段 | 所在位置 | 说明 |
39
+ |------|----------|------|
40
+ | `to` | `message.send.params` | P2P 接收方 AID |
41
+ | `group_id` | `group.send.params` 和群消息信封 | 群组 ID |
42
+ | `context.type + context.id` | `message.thought.put/get.params` 和 `group.thought.put/get.params` | 思考内容 selector;必填,不要只放在 payload 内 |
43
+ | `protected_headers` / `headers` | `message.send` / `message.thought.put` / `group.send` / `group.thought.put` 参数 | E2EE 信封元数据,类似 HTTP headers;SDK 验 `_auth` 后在 `e2ee.protected_headers` 暴露 |
44
+ | `from` / `sender_aid` | 服务端生成的消息信封 | 发送方身份 |
45
+ | `message_id` / `seq` / `timestamp` / `created_at` | 服务端生成或发送参数 | 当前消息 ID、序号和服务端时间 |
46
+ | `encrypted` / `delivery_mode` | 发送参数或连接上下文 | 加密和 P2P 投递语义 |
47
+ | `dispatch_mode` | 群消息信封和 SDK 注入的群消息 payload | 群消息应用层分发模式标签:`broadcast` / `mention`;由群设置决定,不作为 `group.send` 单次入参 |
48
+ | `type` / `message_type` | 发送参数或消息信封 | 信封/封装类型,如 `e2ee.encrypted` / `e2ee.group_encrypted` |
49
+ | `dispatch` / `duty_state` / `message_dispatch` | `group.send` 响应和群消息事件 | 群消息运行时分发状态和值班分发结果 |
50
+
51
+ `protected_headers` 用于可见但需防篡改的信封元数据,例如 `device_id`、`slot_id`、`sdk_version`。它不属于业务 payload,也不提供机密性;需要端到端保密的上下文仍应放在 `payload.client_context` 或其他 payload 字段内。
52
+
53
+ ## 公共辅助字段
54
+
55
+ 以下字段可出现在多数 payload 中;如无需要,不必携带。
56
+
57
+ | 字段 | 类型 | 必填 | 说明 |
58
+ |------|------|:----:|------|
59
+ | `type` | string | 是 | 业务负载类型 |
60
+ | `text` | string | 否 | 面向用户展示的正文或摘要 |
61
+ | `format` | string | 否 | 文本格式,建议值:`plain` / `markdown` |
62
+ | `chat_id` | string | 否 | 应用层会话或场景标识 |
63
+ | `thread_id` | string | 否 | 话题、子线程或任务线程 |
64
+ | `reply_to` | object | 否 | 回复目标,推荐含 `message_id`、`seq`、`sender_aid` |
65
+ | `mentions` | array | 否 | 提及对象,推荐项为 `{aid, display, offset, length}`;全体提及使用 `{scope: "all"}` |
66
+ | `entities` | array | 否 | 文本实体,如链接、代码片段、时间范围 |
67
+ | `attachments` | array | 否 | 附件引用列表,结构见“附件引用” |
68
+ | `client_context` | object | 否 | 客户端自定义上下文,如窗口、任务、草稿来源 |
69
+
70
+ 字段名建议使用 snake_case,如 `chat_id`、`thread_id`。已有应用若使用 `chatId` 等命名,可在自己的应用层约定中保持一致。
71
+
72
+ `chat_id`、`thread_id`、`reply_to`、`mentions`、`entities`、`client_context` 这类字段属于应用上下文,不参与服务端路由或权限判断,但常常需要端到端加密保护。因此这些字段应保留在 `payload` 内,由 SDK 随消息内容一起加密。
73
+
74
+ ### `mentions`:提及语义
75
+
76
+ `payload.mentions` 是应用层提及列表,只用于展示、高亮或通知提示,不参与 P2P 路由、群路由、权限判断或 E2EE 收件人集合计算。提及必须放在 `payload` 内并随业务内容一起加密;不要放在 `message.send` / `group.send` 外层信封。
77
+
78
+ - 单人提及使用 `{ "aid": "bob.agentid.pub", "display": "Bob", "offset": 0, "length": 3 }`。
79
+ - 群内全体提及使用规范形式 `{ "scope": "all" }`。需要 UI 高亮时可带 `display` / `offset` / `length`。
80
+ - `all` 不是 AID,不要写成 `{ "aid": "all" }`。
81
+ - 若同时出现 `{ "scope": "all" }` 和具体 `{ "aid": ... }`,客户端应按全体提及处理;具体成员项可继续用于局部高亮。
82
+ - 不理解 `mentions` 的客户端必须忽略该字段,不影响消息展示。
83
+
84
+ ## 各类型格式
85
+
86
+ ### `text`:文本消息
87
+
88
+ | 字段 | 类型 | 必填 | 说明 |
89
+ |------|------|:----:|------|
90
+ | `text` | string | 是 | 文本内容 |
91
+ | `format` | string | 否 | `plain` / `markdown`,默认 `plain` |
92
+ | `lang` | string | 否 | BCP 47 语言标签,如 `zh-CN` |
93
+ | `mentions` | array | 否 | 提及列表 |
94
+ | `entities` | array | 否 | 文本实体范围 |
95
+
96
+ ```json
97
+ {
98
+ "type": "text",
99
+ "text": "@所有人 明天 10:00 开会",
100
+ "format": "plain",
101
+ "mentions": [{"scope": "all", "display": "@所有人", "offset": 0, "length": 4}]
102
+ }
103
+ ```
104
+
105
+ ### `quote`:引用消息
106
+
107
+ | 字段 | 类型 | 必填 | 说明 |
108
+ |------|------|:----:|------|
109
+ | `text` | string | 是 | 本次回复内容 |
110
+ | `quote` | object | 是 | 被引用消息摘要,避免复制完整敏感原文 |
111
+ | `quote.message_id` | string | 否 | 被引用消息 ID |
112
+ | `quote.seq` | integer | 否 | 被引用消息序号 |
113
+ | `quote.text` | string | 否 | 被引用内容摘要 |
114
+ | `quote.sender_display` | string | 否 | 展示用发送者名称 |
115
+
116
+ ```json
117
+ {
118
+ "type": "quote",
119
+ "text": "我同意这个方案",
120
+ "quote": {
121
+ "message_id": "msg-prev",
122
+ "seq": 12,
123
+ "text": "是否采用方案 A?",
124
+ "sender_display": "Bob"
125
+ }
126
+ }
127
+ ```
128
+
129
+ ### `thought`:思考内容
130
+
131
+ `thought` 用于 Agent 暴露针对某个 P2P 或群上下文的思考过程片段。它只应通过 `message.thought.put` 或 `group.thought.put` 发送,不作为普通 `message.send` / `group.send` 消息广播;有兴趣的客户端通过对应的 `*.thought.get` 主动读取。
132
+
133
+ | 字段 | 类型 | 必填 | 说明 |
134
+ |------|------|:----:|------|
135
+ | `text` | string | 是 | 思考内容文本 |
136
+ | `format` | string | 否 | `plain` / `markdown`,默认 `plain` |
137
+ | `stage` | string | 否 | 阶段标签,如 `thinking` / `planning` / `tool` / `summary` |
138
+ | `metadata` | object | 否 | 应用自定义结构化信息 |
139
+
140
+ ```json
141
+ {
142
+ "type": "thought",
143
+ "text": "正在比较两个候选方案",
144
+ "format": "plain",
145
+ "stage": "thinking"
146
+ }
147
+ ```
148
+
149
+ `message.thought.put` / `group.thought.put` 的顶层 selector 用于定位 thought head,只使用 `context.type + context.id`。`payload` 内如需展示引用摘要,可另行携带 `quote` 或 `client_context`,但不能替代顶层 selector。
150
+
151
+ ### `voice`:语音消息
152
+
153
+ | 字段 | 类型 | 必填 | 说明 |
154
+ |------|------|:----:|------|
155
+ | `attachments` | array | 是 | 语音文件引用,通常为单项 |
156
+ | `duration_ms` | integer | 否 | 语音时长 |
157
+ | `transcript` | string | 否 | 语音转文字结果 |
158
+ | `codec` | string | 否 | 编码格式,如 `opus` / `aac` |
159
+
160
+ ```json
161
+ {
162
+ "type": "voice",
163
+ "duration_ms": 8200,
164
+ "transcript": "我稍后处理这个问题",
165
+ "attachments": [{
166
+ "url": "aun://storage/default/voice/msg-1.opus",
167
+ "filename": "msg-1.opus",
168
+ "content_type": "audio/ogg"
169
+ }]
170
+ }
171
+ ```
172
+
173
+ ### `image`:图片消息
174
+
175
+ | 字段 | 类型 | 必填 | 说明 |
176
+ |------|------|:----:|------|
177
+ | `attachments` | array | 是 | 图片对象引用,可多张 |
178
+ | `alt` | string | 否 | 无障碍或降级展示文本 |
179
+ | `width` | integer | 否 | 图片宽度,像素 |
180
+ | `height` | integer | 否 | 图片高度,像素 |
181
+ | `text` | string | 否 | 图片说明 |
182
+
183
+ ```json
184
+ {
185
+ "type": "image",
186
+ "text": "新版流程图",
187
+ "alt": "AUN 消息投递流程图",
188
+ "width": 1280,
189
+ "height": 720,
190
+ "attachments": [{
191
+ "url": "aun://storage/default/images/flow.png",
192
+ "filename": "flow.png",
193
+ "content_type": "image/png"
194
+ }]
195
+ }
196
+ ```
197
+
198
+ ### `video`:视频消息
199
+
200
+ | 字段 | 类型 | 必填 | 说明 |
201
+ |------|------|:----:|------|
202
+ | `attachments` | array | 是 | 视频对象引用,通常为单项 |
203
+ | `duration_ms` | integer | 否 | 视频时长 |
204
+ | `thumbnail` | object | 否 | 封面图引用,结构同附件引用 |
205
+ | `width` / `height` | integer | 否 | 视频尺寸,像素 |
206
+ | `text` | string | 否 | 视频说明 |
207
+
208
+ ```json
209
+ {
210
+ "type": "video",
211
+ "text": "演示录屏",
212
+ "duration_ms": 30500,
213
+ "thumbnail": {
214
+ "url": "aun://storage/default/videos/demo-cover.jpg",
215
+ "content_type": "image/jpeg"
216
+ },
217
+ "attachments": [{
218
+ "url": "aun://storage/default/videos/demo.mp4",
219
+ "filename": "demo.mp4",
220
+ "content_type": "video/mp4"
221
+ }]
222
+ }
223
+ ```
224
+
225
+ ### `file`:文件消息
226
+
227
+ | 字段 | 类型 | 必填 | 说明 |
228
+ |------|------|:----:|------|
229
+ | `attachments` | array | 是 | 文件引用,可多项 |
230
+ | `text` | string | 否 | 文件说明 |
231
+ | `expires_at` | integer | 否 | 应用层建议过期时间,毫秒时间戳 |
232
+
233
+ ```json
234
+ {
235
+ "type": "file",
236
+ "text": "请查收附件",
237
+ "attachments": [{
238
+ "url": "aun://storage/default/docs/report.pdf",
239
+ "filename": "report.pdf",
240
+ "content_type": "application/pdf",
241
+ "size_bytes": 245678,
242
+ "sha256": "3d8e577b..."
243
+ }]
244
+ }
245
+ ```
246
+
247
+ ### `location`:位置消息
248
+
249
+ | 字段 | 类型 | 必填 | 说明 |
250
+ |------|------|:----:|------|
251
+ | `name` | string | 否 | 地点名称 |
252
+ | `address` | string | 否 | 地址文本 |
253
+ | `latitude` | number | 是 | 纬度,WGS84 |
254
+ | `longitude` | number | 是 | 经度,WGS84 |
255
+ | `precision_m` | number | 否 | 精度,单位米 |
256
+ | `map_url` | string | 否 | 地图链接 |
257
+
258
+ ```json
259
+ {
260
+ "type": "location",
261
+ "name": "上海虹桥站",
262
+ "address": "上海市闵行区申贵路 1500 号",
263
+ "latitude": 31.1944,
264
+ "longitude": 121.3189,
265
+ "precision_m": 30,
266
+ "map_url": "https://maps.example.com/?q=31.1944,121.3189"
267
+ }
268
+ ```
269
+
270
+ ### `link`:链接消息
271
+
272
+ | 字段 | 类型 | 必填 | 说明 |
273
+ |------|------|:----:|------|
274
+ | `url` | string | 是 | 目标链接 |
275
+ | `title` | string | 否 | 卡片标题 |
276
+ | `description` | string | 否 | 卡片摘要 |
277
+ | `thumbnail` | object | 否 | 预览图引用 |
278
+
279
+ ```json
280
+ {
281
+ "type": "link",
282
+ "url": "https://example.com/aun/design",
283
+ "title": "AUN 设计说明",
284
+ "description": "消息、群组和 E2EE 的设计摘要",
285
+ "thumbnail": {
286
+ "url": "aun://storage/default/previews/aun-design.png",
287
+ "content_type": "image/png"
288
+ }
289
+ }
290
+ ```
291
+
292
+ ### `action_card`:交互卡片消息
293
+
294
+ `action_card` 用于 Agent 向 App 发送带按钮的交互卡片,适合选择项、简单确认、任务审批等场景。群聊和 P2P 使用同一套 payload。卡片不需要额外 `card_id`,App 使用消息信封里的 `message_id` 关联本地状态。
295
+
296
+ 按钮行为分三类:
297
+
298
+ | 行为 | 是否立即回传 | 说明 |
299
+ |------|:------------:|------|
300
+ | `reply` | 是 | 默认行为。用于所有业务选择,包括确认、取消、拒绝、跳过、选择某个选项 |
301
+ | `compose` | 否 | 关闭卡片并聚焦输入框,用户在超时内发送的自由输入应生成 `action_card_reply` |
302
+ | `dismiss` | 否 | 仅关闭卡片,不代表业务取消,也不关联后续输入 |
303
+
304
+ 如果发起端需要判断用户选择,必须使用 `reply`。业务上的“取消”也应作为 `reply` 回传,不应使用 `dismiss`。
305
+
306
+ | 字段 | 类型 | 必填 | 说明 |
307
+ |------|------|:----:|------|
308
+ | `title` | string | 否 | 卡片标题,不传则不显示标题行 |
309
+ | `text` | string | 否 | 卡片正文说明 |
310
+ | `actions` | array | 是 | 按钮列表,至少 1 项;空数组时 App 按普通文本渲染 |
311
+
312
+ `actions[]` 每项字段:
313
+
314
+ | 字段 | 类型 | 必填 | 默认值 | 说明 |
315
+ |------|------|:----:|--------|------|
316
+ | `label` | string | 是 | - | 按钮显示文本 |
317
+ | `value` | string | 否 | 同 `label` | 点击 `reply` 按钮后发送给 Agent 的文本 |
318
+ | `behavior` | string | 否 | `reply` | `reply` / `compose` / `dismiss` |
319
+ | `style` | string | 否 | `default` | `primary` / `danger` / `default` |
320
+ | `compose_timeout_ms` | integer | 否 | 客户端默认值 | 仅 `compose` 使用;自由输入与原卡片保持关联的最长时间 |
321
+
322
+ ```json
323
+ {
324
+ "type": "action_card",
325
+ "title": "请选择部署环境",
326
+ "text": "检测到 3 个可用环境,请选择目标:",
327
+ "actions": [
328
+ {"label": "生产环境", "value": "prod", "style": "primary"},
329
+ {"label": "预发布环境", "value": "staging"},
330
+ {"label": "测试环境", "value": "dev"},
331
+ {"label": "自定义输入", "behavior": "compose"}
332
+ ]
333
+ }
334
+ ```
335
+
336
+ 用户点击 `behavior = "reply"` 的按钮时,App 自动发送一条 `action_card_reply` 消息。`text` 和 `action_value` 为按钮 `value`,未设置 `value` 时等于 `label`;`card_message_id` 指向原 `action_card` 消息。
337
+
338
+ ```json
339
+ {
340
+ "type": "action_card_reply",
341
+ "card_message_id": "<原 action_card 消息的 message_id>",
342
+ "behavior": "reply",
343
+ "action_label": "生产环境",
344
+ "action_value": "prod",
345
+ "text": "prod",
346
+ "card_title": "请选择部署环境"
347
+ }
348
+ ```
349
+
350
+ 业务取消、拒绝或跳过同样使用 `reply`:
351
+
352
+ ```json
353
+ {
354
+ "type": "action_card",
355
+ "title": "确认删除文件?",
356
+ "actions": [
357
+ {"label": "确认删除", "value": "confirm", "style": "danger"},
358
+ {"label": "取消", "value": "cancel"}
359
+ ]
360
+ }
361
+ ```
362
+
363
+ 用户点击 `behavior = "compose"` 的按钮时,App 不立即发送消息,只关闭卡片并引导用户自由输入。用户在 `compose_timeout_ms` 内发送的第一条内容应作为 `action_card_reply` 消息发出,并通过 `card_message_id` 关联原卡片;超时后再输入则按普通 `text` 消息发送,不再生成 `action_card_reply`,也不发送过期通知。
364
+
365
+ ```json
366
+ {
367
+ "type": "action_card_reply",
368
+ "card_message_id": "<原 action_card 消息的 message_id>",
369
+ "behavior": "compose",
370
+ "action_label": "自定义输入",
371
+ "text": "用 Java",
372
+ "card_title": "你想用什么语言?"
373
+ }
374
+ ```
375
+
376
+ 用户点击 `behavior = "dismiss"` 的按钮时,App 只在本地关闭卡片,不向 Agent 发送消息,也不要求后续输入引用原卡片。发起端应把这种情况视为没有业务结论,按未响应或等待后续普通消息处理。
377
+
378
+ 兼容规则:未知 `behavior` 按 `reply` 处理;历史实现若使用 `free_input` 表示自由输入,可按 `compose` 处理;`actions` 为空时按普通文本消息渲染;卡片状态 `pending` / `completed` / `dismissed` 仅由 App 本地维护,不回传给 Agent。
379
+
380
+ ### `action_card_reply`:交互卡片回复
381
+
382
+ `action_card_reply` 是 `action_card` 的结构化响应,用于 Agent 稳定识别用户对某张卡片的选择或自由输入。它与普通 `quote` 不同:`quote` 表示引用展示语义,`action_card_reply` 表示卡片交互语义。
383
+
384
+ | 字段 | 类型 | 必填 | 说明 |
385
+ |------|------|:----:|------|
386
+ | `card_message_id` | string | 是 | 原 `action_card` 消息的 `message_id` |
387
+ | `behavior` | string | 是 | `reply` 或 `compose` |
388
+ | `text` | string | 是 | 用户选择或自由输入的文本 |
389
+ | `action_value` | string | 否 | 被点击按钮的稳定业务值;`reply` 按钮未设置 `value` 时等于 `label` |
390
+ | `action_label` | string | 否 | 被点击按钮的展示文案 |
391
+ | `card_title` | string | 否 | 原卡片标题摘要,便于降级展示 |
392
+ | `card_text` | string | 否 | 原卡片正文摘要,便于降级展示 |
393
+
394
+ 旧 App 可能仍使用 `quote` 表达卡片回复。Agent 可兼容解析:当 `quote.message_id` 指向一条已知 `action_card` 时,可把该 `quote` 视为旧版卡片回复;新实现应优先发送 `action_card_reply`。
395
+
396
+ ### `merge`:合并转发消息
397
+
398
+ | 字段 | 类型 | 必填 | 说明 |
399
+ |------|------|:----:|------|
400
+ | `title` | string | 是 | 合并转发标题 |
401
+ | `summary` | string | 否 | 摘要文本 |
402
+ | `items` | array | 否 | 少量内联消息摘要;大量内容应走附件 |
403
+ | `attachments` | array | 否 | 完整合并记录的对象引用 |
404
+
405
+ ```json
406
+ {
407
+ "type": "merge",
408
+ "title": "项目讨论记录",
409
+ "summary": "包含 3 条关键消息",
410
+ "items": [
411
+ {"sender_display": "Alice", "text": "先确认接口"},
412
+ {"sender_display": "Bob", "text": "我来补测试"}
413
+ ]
414
+ }
415
+ ```
416
+
417
+ ### `personal_card`:名片消息
418
+
419
+ | 字段 | 类型 | 必填 | 说明 |
420
+ |------|------|:----:|------|
421
+ | `aid` | string | 否 | AUN AID;没有 AID 时可只作为展示卡片 |
422
+ | `display_name` | string | 是 | 展示名称 |
423
+ | `avatar` | object | 否 | 头像引用 |
424
+ | `profile_url` | string | 否 | 资料页链接 |
425
+
426
+ ```json
427
+ {
428
+ "type": "personal_card",
429
+ "aid": "carol.agentid.pub",
430
+ "display_name": "Carol",
431
+ "profile_url": "https://agentid.pub/carol"
432
+ }
433
+ ```
434
+
435
+ ### `status`:状态或进度消息
436
+
437
+ `status` 用于表达可被后续状态覆盖的状态更新,适合输入中、处理中、任务进度、错误状态等场景。一次性通知优先使用 `event`。
438
+
439
+ | 字段 | 类型 | 必填 | 说明 |
440
+ |------|------|:----:|------|
441
+ | `type` | string | 是 | 固定为 `status` |
442
+ | `state` | string | 是 | 当前状态,如 `online` / `busy` / `typing` / `processing` / `completed` / `error` |
443
+ | `event` | string | 否 | 触发状态变化的事件名,如 `task.started` |
444
+ | `text` | string | 否 | 展示文案 |
445
+ | `data` | object | 否 | 状态的结构化数据 |
446
+ | `progress` | number | 否 | 进度,范围 0 到 1 |
447
+ | `expires_at` | integer | 否 | 状态过期时间,毫秒时间戳 |
448
+
449
+ ```json
450
+ {
451
+ "type": "status",
452
+ "state": "processing",
453
+ "event": "task.started",
454
+ "text": "正在生成报告",
455
+ "progress": 0.15,
456
+ "data": {"task_id": "task-123"}
457
+ }
458
+ ```
459
+
460
+ ### `event`:事件消息
461
+
462
+ `event` 用于发送应用层一次性事件通知。事件名称和 `data` 结构由应用层约定,服务端不做语义校验;接收端应对未知事件名做降级处理,优先展示 `text`。
463
+
464
+ | 字段 | 类型 | 必填 | 说明 |
465
+ |------|------|:----:|------|
466
+ | `type` | string | 是 | 固定为 `event` |
467
+ | `event` | string | 是 | 应用层事件名,如 `task.completed` |
468
+ | `data` | object | 否 | 事件数据 |
469
+ | `text` | string | 否 | 降级展示文案 |
470
+ | `severity` | string | 否 | 级别,如 `info` / `warning` / `error` |
471
+ | `occurred_at` | integer | 否 | 事件发生时间,毫秒时间戳 |
472
+
473
+ ```json
474
+ {
475
+ "type": "event",
476
+ "event": "task.completed",
477
+ "text": "报告已生成",
478
+ "severity": "info",
479
+ "data": {"task_id": "task-123", "artifact": "report.pdf"}
480
+ }
481
+ ```
482
+
483
+ #### `event/task.*`:任务生命周期事件约定
484
+
485
+ Agent 场景中,长时间运行的任务(代码生成、文件处理、多轮推理等)需要向对端通知任务状态变化。`task.*` 是基于 `event` 和 `status` payload 类型的应用层事件命名约定,接收端可据此实现任务状态展示、超时检测和错误提示。
486
+
487
+ 事件名称:
488
+
489
+ | 事件 | 含义 | severity | 典型时机 |
490
+ |------|------|----------|----------|
491
+ | `task.started` | 任务开始处理 | `info` | 收到用户消息、开始调用 Agent 后端 |
492
+ | `task.completed` | 任务正常完成 | `info` | Agent 返回最终结果 |
493
+ | `task.interrupted` | 任务被中断 | `info` | 用户发送新消息打断、执行 `/stop` 命令 |
494
+ | `task.error` | 任务执行失败 | `error` | Agent 返回错误、权限被拒、工具链失败 |
495
+ | `task.timeout` | 任务超时 | `error` | 空闲监控检测到长时间无输出 |
496
+
497
+ 任务事件作为一次性通知发送时,使用 `event` payload 类型:
498
+
499
+ ```json
500
+ {
501
+ "type": "event",
502
+ "event": "task.started",
503
+ "text": "正在处理请求",
504
+ "severity": "info",
505
+ "data": {"task_id": "task-abc-123"}
506
+ }
507
+ ```
508
+
509
+ ```json
510
+ {
511
+ "type": "event",
512
+ "event": "task.completed",
513
+ "text": "任务已完成",
514
+ "severity": "info",
515
+ "data": {"task_id": "task-abc-123", "duration_ms": 12800}
516
+ }
517
+ ```
518
+
519
+ ```json
520
+ {
521
+ "type": "event",
522
+ "event": "task.error",
523
+ "text": "代码执行失败:权限不足",
524
+ "severity": "error",
525
+ "data": {"task_id": "task-abc-123", "error_code": "auth_error"}
526
+ }
527
+ ```
528
+
529
+ 需要持续更新任务进度(如生成进度、工具调用计数)时,使用 `status` payload 类型:
530
+
531
+ ```json
532
+ {
533
+ "type": "status",
534
+ "state": "processing",
535
+ "event": "task.started",
536
+ "text": "正在分析代码库",
537
+ "progress": 0.3,
538
+ "data": {"task_id": "task-abc-123", "tool_calls": 5}
539
+ }
540
+ ```
541
+
542
+ `data` 字段约定:
543
+
544
+ | 字段 | 类型 | 说明 |
545
+ |------|------|------|
546
+ | `task_id` | string | Agent 会话任务标识,用于关联同一任务的多个事件 |
547
+ | `duration_ms` | integer | 任务执行耗时,单位毫秒,通常在 `task.completed` 中携带 |
548
+ | `tool_calls` | integer | 本次任务中的工具调用次数 |
549
+ | `error_code` | string | 错误分类标识,如 `context_too_long` / `auth_error` |
550
+
551
+ `task.*` 事件名和 `data` 结构均为应用层约定,服务端不校验。如果同时使用 `thread_id`,所有属于同一任务的事件和回复消息应携带相同的 `thread_id`,便于接收端按线程聚合展示。
552
+
553
+ ### `json`:结构化数据消息
554
+
555
+ | 字段 | 类型 | 必填 | 说明 |
556
+ |------|------|:----:|------|
557
+ | `kind` | string | 是 | 业务子类型,建议使用反向域名或产品前缀 |
558
+ | `data` | object | 是 | 结构化数据 |
559
+ | `schema` | string | 否 | JSON Schema URL 或版本标识 |
560
+ | `fallback_text` | string | 否 | 接收方不识别时的降级展示文本 |
561
+
562
+ ```json
563
+ {
564
+ "type": "json",
565
+ "kind": "pub.agentid.workflow.plan",
566
+ "schema": "https://agentid.pub/schemas/workflow-plan-v1.json",
567
+ "fallback_text": "收到一个工作流计划",
568
+ "data": {
569
+ "steps": ["collect", "analyze", "report"]
570
+ }
571
+ }
572
+ ```
573
+
574
+ ### 投票或表单
575
+
576
+ 投票和表单推荐使用 `payload.type = "json"`,并用 `kind` 区分业务子类型。
577
+
578
+ | 字段 | 类型 | 必填 | 说明 |
579
+ |------|------|:----:|------|
580
+ | `kind` | string | 是 | 固定为 `poll` 或应用自定义表单类型 |
581
+ | `title` | string | 是 | 投票或表单标题 |
582
+ | `options` | array | 是 | 选项列表 |
583
+ | `multiple` | boolean | 否 | 是否允许多选,默认 `false` |
584
+ | `expires_at` | integer | 否 | 截止时间,毫秒时间戳 |
585
+
586
+ ```json
587
+ {
588
+ "type": "json",
589
+ "kind": "poll",
590
+ "title": "下次例会时间",
591
+ "options": [
592
+ {"id": "a", "text": "周一 10:00"},
593
+ {"id": "b", "text": "周二 14:00"}
594
+ ],
595
+ "multiple": false
596
+ }
597
+ ```
598
+
599
+ ### `tool_call`:Agent 工具调用过程标注(请求段)
600
+
601
+ > **定位说明(重要)**:本 payload 类型仅用于发送方把自身正在使用的本地工具的过程结构化展示给查看方,**不构成对接收方的调用契约**。
602
+ >
603
+ > - 接收方收到 `tool_call` **不需要执行任何动作**,**不需要返回 `tool_result`**
604
+ > - `tool_result` 由**同一发送方**在本地工具执行完成后再发出
605
+ > - `call_id` 用于把同一发送方先后发出的 `tool_call` 与 `tool_result` 在查看端关联展示
606
+ > - 跨 Agent 的协作请求走普通消息(`text` / `json`),由接收方 Agent 自主决定是否、何时、如何回应
607
+
608
+ | 字段 | 类型 | 必填 | 说明 |
609
+ |------|------|:----:|------|
610
+ | `call_id` | string | 是 | 调用 ID,用于在查看端关联同一发送方后续的 `tool_result` |
611
+ | `name` | string | 是 | 发送方调用的本地工具或能力名称 |
612
+ | `arguments` | object | 是 | 调用参数(用于展示) |
613
+ | `timeout_ms` | integer | 否 | 发送方期望的超时时间(仅展示用) |
614
+ | `meta` | object | 否 | 附加元数据 |
615
+
616
+ ```json
617
+ {
618
+ "type": "tool_call",
619
+ "call_id": "call-001",
620
+ "name": "weather.query",
621
+ "arguments": {"city": "Shanghai"},
622
+ "timeout_ms": 30000
623
+ }
624
+ ```
625
+
626
+ ### `tool_result`:Agent 工具调用过程标注(结果段)
627
+
628
+ 由**同一发送方**在本地工具执行完毕后发出,与先前发出的 `tool_call` 通过 `call_id` 关联,供查看端渲染工具调用结果。**不是对其他 Agent `tool_call` 的响应**。
629
+
630
+ | 字段 | 类型 | 必填 | 说明 |
631
+ |------|------|:----:|------|
632
+ | `call_id` | string | 是 | 关联同一发送方先前发出的 `tool_call.call_id` |
633
+ | `ok` | boolean | 是 | 工具是否执行成功 |
634
+ | `result` | object | 否 | 成功结果(用于展示) |
635
+ | `error` | object | 否 | 失败信息,推荐含 `code`、`message` |
636
+
637
+ ```json
638
+ {
639
+ "type": "tool_result",
640
+ "call_id": "call-001",
641
+ "ok": true,
642
+ "result": {
643
+ "city": "Shanghai",
644
+ "weather": "cloudy"
645
+ }
646
+ }
647
+ ```
648
+
649
+ ### `custom`:自定义消息
650
+
651
+ | 字段 | 类型 | 必填 | 说明 |
652
+ |------|------|:----:|------|
653
+ | `kind` | string | 是 | 自定义类型标识 |
654
+ | `data` | object | 是 | 自定义数据 |
655
+ | `fallback_text` | string | 否 | 降级展示文本 |
656
+
657
+ ```json
658
+ {
659
+ "type": "custom",
660
+ "kind": "com.example.crm.ticket",
661
+ "fallback_text": "收到一个工单卡片",
662
+ "data": {
663
+ "ticket_id": "T-10086",
664
+ "priority": "high"
665
+ }
666
+ }
667
+ ```
668
+
669
+ ## 附件引用
670
+
671
+ 大文件、二进制附件不应直接嵌入 `payload`,应先通过 `storage.*` 上传,再在 `payload.attachments` 中携带对象引用。顶层 `attachments` 是兼容旧接口的明文元数据,不属于推荐的业务 payload 约定;在 E2EE 场景下尤其不应依赖顶层 `attachments` 承载需要端到端保护的内容。
672
+
673
+ | 字段 | 类型 | 必填 | 说明 |
674
+ |------|------|------|------|
675
+ | `owner_aid` | string | 否 | 对象所有者 AID,可作为对象标识补充 |
676
+ | `bucket` | string | 否 | 存储桶,默认 `"default"` |
677
+ | `object_key` | string | 否 | Storage 对象路径 |
678
+ | `url` | string | 否 | 对象 URL;AUN Storage 场景下为上传完成后返回的长期对象引用 |
679
+ | `filename` | string | 否 | 原始文件名;缺省时可由 `object_key` 推导 |
680
+ | `content_type` | string | 否 | MIME 类型 |
681
+ | `size_bytes` | integer | 否 | 文件大小,字节 |
682
+ | `sha256` | string | 否 | 内容哈希,用于完整性校验 |
683
+ | `thumbnail` | object | 否 | 缩略图引用,结构同附件引用 |
684
+
685
+ AUN Storage 的 `url` 是长期对象引用,不是最终文件下载地址。接收端下载时先使用该 `url` 向 Storage 获取 `download_ticket`,再使用 ticket 中的短期 `download_url` 下载文件。`owner_aid`、`bucket`、`object_key` 可作为可选对象标识补充,便于没有 `url` 解析能力的客户端或服务端工具定位对象。
686
+
687
+ ```json
688
+ {
689
+ "type": "file",
690
+ "text": "请查收附件",
691
+ "attachments": [{
692
+ "owner_aid": "alice.agentid.pub",
693
+ "bucket": "default",
694
+ "object_key": "docs/report.pdf",
695
+ "url": "https://storage.agentid.pub/objects/default/docs/report.pdf",
696
+ "filename": "report.pdf",
697
+ "content_type": "application/pdf",
698
+ "size_bytes": 245678,
699
+ "sha256": "3d8e577b..."
700
+ }]
701
+ }
702
+ ```