@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.
- package/CHANGELOG.md +26 -0
- package/_packed_docs/CHANGELOG.md +26 -0
- package/_packed_docs/agent.md/SCHEMA.md +173 -0
- package/_packed_docs/agent.md/examples/codeagent-claudecode.md +61 -0
- package/_packed_docs/agent.md/examples/human-developer.md +60 -0
- package/_packed_docs/agent.md/examples/openclaw-lobster.md +52 -0
- package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +43 -0
- package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +205 -0
- 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
- 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
- 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
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +262 -0
- package/_packed_docs/protocol/04-Peer-/345/255/220/345/215/217/350/256/256.md +180 -0
- package/_packed_docs/protocol/05-Relay-/345/255/220/345/215/217/350/256/256.md +164 -0
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1135 -0
- 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
- package/_packed_docs/protocol/08-AUN-E2EE-Group.md +900 -0
- package/_packed_docs/protocol/08-AUN-E2EE.md +413 -0
- package/_packed_docs/protocol/09-/345/256/211/345/205/250/350/200/203/350/231/221.md +316 -0
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +804 -0
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +271 -0
- package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +329 -0
- package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +141 -0
- 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
- package/_packed_docs/protocol/README.md +71 -0
- package/_packed_docs/protocol/agent.md/SCHEMA.md +118 -0
- package/_packed_docs/protocol/agent.md/examples/codeagent-claudecode.md +61 -0
- package/_packed_docs/protocol/agent.md/examples/human-developer.md +60 -0
- package/_packed_docs/protocol/agent.md/examples/openclaw-lobster.md +52 -0
- package/_packed_docs/protocol/aun-docs-guide.md +49 -0
- package/_packed_docs/protocol/index.md +114 -0
- 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
- 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
- package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +337 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +223 -0
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +354 -0
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +172 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +373 -0
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +611 -0
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +1152 -0
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +150 -0
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +89 -0
- package/_packed_docs/sdk/09-custody-api-manual.md +445 -0
- package/_packed_docs/sdk/09-group-rpc-manual.md +1895 -0
- package/_packed_docs/sdk/09-message-rpc-manual.md +597 -0
- package/_packed_docs/sdk/09-meta-rpc-manual.md +142 -0
- package/_packed_docs/sdk/09-payload-reference.md +702 -0
- package/_packed_docs/sdk/09-storage-rpc-manual.md +408 -0
- package/_packed_docs/sdk/09-stream-rpc-manual.md +275 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +72 -0
- package/_packed_docs/sdk/INDEX.md +131 -0
- package/_packed_docs/sdk/README.md +307 -0
- package/dist/auth.d.ts +2 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +13 -11
- package/dist/auth.js.map +1 -1
- package/dist/client.d.ts +38 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +179 -97
- package/dist/client.js.map +1 -1
- package/dist/namespaces/auth.d.ts +1 -0
- package/dist/namespaces/auth.d.ts.map +1 -1
- package/dist/namespaces/auth.js +20 -6
- package/dist/namespaces/auth.js.map +1 -1
- package/dist/transport.d.ts +9 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +24 -0
- package/dist/transport.js.map +1 -1
- package/package.json +40 -37
|
@@ -0,0 +1,1135 @@
|
|
|
1
|
+
## 6. 服务协议(业务层)
|
|
2
|
+
|
|
3
|
+
> 本文描述认证完成后的业务层方法。连接与身份认证见对应子协议文档:
|
|
4
|
+
> - 身份与凭证:[01-身份与凭证协议-auth.md](01-身份与凭证协议-auth.md)
|
|
5
|
+
> - Gateway 连接:[03-Gateway-连接模式.md](03-Gateway-连接模式.md)
|
|
6
|
+
> - Peer 对等认证:[04-Peer-子协议.md](04-Peer-子协议.md)
|
|
7
|
+
> - Relay 中继:[05-Relay-子协议.md](05-Relay-子协议.md)
|
|
8
|
+
>
|
|
9
|
+
> 业务层方法与连接拓扑无关。无论使用 gateway、peer 或 relay 模式,认证完成后都可调用以下方法。
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### 6.1 命名空间概览
|
|
14
|
+
|
|
15
|
+
| 命名空间 | 分类 | 功能 | 对应服务 | 传输方式 |
|
|
16
|
+
|---------|------|------|---------|---------|
|
|
17
|
+
| `auth.*` | 核心 | AID 注册、认证、令牌管理 | auth 服务 | WebSocket |
|
|
18
|
+
| `ca.*` | 核心 | 证书签发、续期、吊销 | ca 服务 | WebSocket / HTTP |
|
|
19
|
+
| `message.*` | 核心 | 点对点消息路由、E2EE prekey 管理 | message 服务 | WebSocket |
|
|
20
|
+
| `meta.*` | 核心 | 健康检查、状态查询、受信根证书 | meta 服务 | WebSocket |
|
|
21
|
+
| `storage.*` | 扩展 | 对象存储、大文件上传下载(详见 [11-Storage-子协议.md](11-Storage-子协议.md)) | storage 服务 | WebSocket + HTTP |
|
|
22
|
+
| `group.*` | 扩展 | 群组管理、群消息、资源共享(详见 [10-Group-子协议.md](10-Group-子协议.md)) | group 服务 | WebSocket |
|
|
23
|
+
| `mail.*` | 扩展 | 邮件服务 | mail 服务 | WebSocket |
|
|
24
|
+
| `stream.*` | 扩展 | 实时流式传输(详见 [12-Stream-子协议.md](12-Stream-子协议.md)) | stream 服务 | WebSocket + HTTP SSE |
|
|
25
|
+
| `search.*` | 扩展 | Agent 搜索与发现 | search 服务 | WebSocket |
|
|
26
|
+
| `relay.*` | 扩展 | NAT 穿透中继(详见 [05-Relay-子协议.md](05-Relay-子协议.md)) | relay 服务 | WebSocket |
|
|
27
|
+
| `peer.*` | 协议定义 | 点对点直连(详见 [04-Peer-子协议.md](04-Peer-子协议.md)) | 无对应服务 | WebSocket |
|
|
28
|
+
| `task.*` | 协议定义 | Agent 协作与任务执行 | 无对应服务 | WebSocket |
|
|
29
|
+
|
|
30
|
+
**控制面与数据面分离**:
|
|
31
|
+
|
|
32
|
+
- `message.*` 用于传递消息语义、小型结构化负载和控制信息,不承担大对象传输职责
|
|
33
|
+
- `storage.*` 用于承载大文件、大对象及附件内容的上传、下载与持久保存
|
|
34
|
+
- `stream.*` 用于实时流式传输(LLM 输出、数据推送等),控制面通过 RPC 管理流生命周期,数据面通过独立端口的 WebSocket(推流)和 HTTP SSE(拉流)传输
|
|
35
|
+
- 大文件、二进制附件、长时流式内容不应直接嵌入 `message.*` 的 `payload`,应先经 `storage.*` 存储,再由 `message.*` 传递对象引用
|
|
36
|
+
- 实现应分别对 `message.*` 的消息体大小和 `storage.*` 的对象大小进行独立限制
|
|
37
|
+
|
|
38
|
+
**应用层扩展服务**本身也是 AID 持有者,通过核心协议(`message.*`)与客户端通信。客户端可以选择使用或不使用这些扩展服务。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### 6.2 点对点消息 `message.*`
|
|
43
|
+
|
|
44
|
+
**设计原则**:
|
|
45
|
+
|
|
46
|
+
- **无会话生命周期**:不需要 create/invite/join/close 流程,直接发送即可
|
|
47
|
+
- **投递语义由 `delivery_mode` 决定**:`fanout` 会进入离线历史并广播到同一 AID 的在线实例;`queue` 只做实时单实例投递,不进入历史存储
|
|
48
|
+
- **控制面与数据面分离**:`message.*` 承载消息语义和小型结构化数据;附件、大对象应通过 `storage.*` 传输,消息中只保留引用
|
|
49
|
+
|
|
50
|
+
> 本节仅适用于 P2P `message.*`。`group.send` 不支持 `queue`,群消息始终是 fanout 语义。
|
|
51
|
+
|
|
52
|
+
**消息存储模型**:
|
|
53
|
+
|
|
54
|
+
| `delivery_mode.mode` | 投递方式 | 存储位置 | 生命周期 | 适用场景 |
|
|
55
|
+
|----------------------|----------|---------|---------|---------|
|
|
56
|
+
| `queue` | 单实例实时消费 | 内存环形缓冲 | 有限时间窗口(默认 5 分钟)+ 有限条数(默认 200 条/AID) | Worker/执行器消费、同一发送者尽量命中同一实例 |
|
|
57
|
+
| `fanout` | 广播到在线实例 | 数据库 + 文件存储 | TTL 过期前持久保存(默认 24 小时) | 离线送达、历史查询、多实例同步接收 |
|
|
58
|
+
|
|
59
|
+
**序列号机制**:
|
|
60
|
+
|
|
61
|
+
- 每条消息(无论临时或持久化)在收件人维度分配一个递增 `seq`
|
|
62
|
+
- 客户端通过 `after_seq` 游标增量拉取,支持多设备各自维护进度
|
|
63
|
+
- `message.pull` 合并返回临时消息和持久化消息,按 `seq` 排序
|
|
64
|
+
|
|
65
|
+
#### `message.send`
|
|
66
|
+
|
|
67
|
+
发送 P2P 消息。
|
|
68
|
+
|
|
69
|
+
**请求**:
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"jsonrpc": "2.0",
|
|
73
|
+
"id": 10,
|
|
74
|
+
"method": "message.send",
|
|
75
|
+
"params": {
|
|
76
|
+
"to": "bob.aid.pub",
|
|
77
|
+
"payload": {"type": "text", "text": "你好"}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**参数**:
|
|
83
|
+
|
|
84
|
+
| 参数 | 必需 | 说明 |
|
|
85
|
+
|------|:----:|------|
|
|
86
|
+
| `to` | ✅ | 接收者 AID |
|
|
87
|
+
| `payload` | ✅ | 消息载荷,对协议层透明,由应用层定义 |
|
|
88
|
+
| `type` | ❌ | 信封/封装类型,普通业务消息无需填写;SDK 加密发送时自动使用 `e2ee.encrypted` |
|
|
89
|
+
| `encrypted` | ❌ | E2EE 标记(默认 `false`) |
|
|
90
|
+
| `message_id` | ❌ | 幂等键(客户端提供或服务端生成 UUID) |
|
|
91
|
+
| `timestamp` | ❌ | 客户端时间戳(毫秒),服务端忽略此字段,始终使用服务端时间 |
|
|
92
|
+
|
|
93
|
+
**响应**:
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"jsonrpc": "2.0",
|
|
97
|
+
"id": 10,
|
|
98
|
+
"result": {
|
|
99
|
+
"message_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
100
|
+
"seq": 42,
|
|
101
|
+
"timestamp": 1709712000,
|
|
102
|
+
"status": "sent",
|
|
103
|
+
"delivery_mode": "queue"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
##### Payload 参考约定
|
|
109
|
+
|
|
110
|
+
`message.send.params.payload` 的统一业务负载格式见 [消息Payload参考约定](../sdk/消息Payload参考约定.md)。完整 P2P 请求仍在 `payload` 同级传入 `to`;业务类型放在 `payload.type`,不要与 `message.send.params.type` 信封/封装类型混用。
|
|
111
|
+
|
|
112
|
+
协议层只要求 `payload` 是 JSON 对象,并按服务端配置做大小限制;字段语义由应用层约定,接收端应对未知 `payload.type`、未知 `kind` 和缺失展示字段做降级处理。
|
|
113
|
+
|
|
114
|
+
#### 连接升级控制消息
|
|
115
|
+
|
|
116
|
+
`peer.offer` / `peer.accept` / `peer.reject` / `peer.switch` 不是独立 JSON-RPC 方法,而是通过普通 `message.send` 发送的**协议控制负载**。三种连接模式在业务层复用统一的 `message.*`。
|
|
117
|
+
|
|
118
|
+
**用途**:
|
|
119
|
+
|
|
120
|
+
- `gateway → peer`:通过 Gateway 交换直连地址,尝试升级到 Peer
|
|
121
|
+
- `relay → peer`:已通过 Relay 联通的双方尝试升级到直连
|
|
122
|
+
- 失败时可回退到原有通道,不影响业务层 API
|
|
123
|
+
|
|
124
|
+
**`peer.offer` 示例**:
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"method": "message.send",
|
|
128
|
+
"params": {
|
|
129
|
+
"to": "bob.company.com",
|
|
130
|
+
"payload": {
|
|
131
|
+
"type": "peer.offer",
|
|
132
|
+
"session_id": "upgrade-550e8400",
|
|
133
|
+
"from_mode": "gateway",
|
|
134
|
+
"preferred_mode": "peer",
|
|
135
|
+
"endpoints": [{"url": "wss://alice.company.com:9900/acp", "priority": 1}],
|
|
136
|
+
"expires_in": 30
|
|
137
|
+
},
|
|
138
|
+
"delivery_mode": {"mode": "queue"}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**`peer.accept` 负载**:`{ "type": "peer.accept", "session_id": "...", "selected_endpoint": "wss://..." }`
|
|
144
|
+
|
|
145
|
+
**`peer.reject` 负载**:`{ "type": "peer.reject", "session_id": "...", "reason": "policy_denied" }`
|
|
146
|
+
|
|
147
|
+
**`peer.switch` 负载**:`{ "type": "peer.switch", "session_id": "...", "new_mode": "peer", "keep_fallback": true }`
|
|
148
|
+
|
|
149
|
+
**规范要求**:
|
|
150
|
+
|
|
151
|
+
- 接收方 **MAY** 接受或拒绝 `peer.offer`
|
|
152
|
+
- 接受后,双方 **MUST** 在新通道上重新执行完整 `initialize(mode=peer)` 与 `peer.*` 认证流程
|
|
153
|
+
- 旧通道在 `peer.switch` 完成前 **MUST** 保持可用
|
|
154
|
+
- 升级失败或超时时双方 **MUST** 回退到原通道
|
|
155
|
+
|
|
156
|
+
#### `message.pull`
|
|
157
|
+
|
|
158
|
+
按游标拉取新消息。合并返回临时消息和持久化消息,按 `seq` 排序。
|
|
159
|
+
|
|
160
|
+
**请求**:
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"jsonrpc": "2.0",
|
|
164
|
+
"id": 11,
|
|
165
|
+
"method": "message.pull",
|
|
166
|
+
"params": {
|
|
167
|
+
"after_seq": 0,
|
|
168
|
+
"limit": 100,
|
|
169
|
+
"device_id": "device-001",
|
|
170
|
+
"slot_id": "slot-a"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**参数**:
|
|
176
|
+
|
|
177
|
+
| 参数 | 必需 | 说明 |
|
|
178
|
+
|------|:----:|------|
|
|
179
|
+
| `after_seq` | ❌ | 起始序列号(默认 0),返回 `seq > after_seq` 的消息 |
|
|
180
|
+
| `limit` | ❌ | 单次返回上限(默认 100,最大 200) |
|
|
181
|
+
| `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
|
|
182
|
+
| `slot_id` | ❌ | 同一设备下的消费槽位;空字符串表示设备单实例模式 |
|
|
183
|
+
| `limit` | ❌ | 返回条数(默认 100,最大 200) |
|
|
184
|
+
|
|
185
|
+
**响应**:
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"jsonrpc": "2.0",
|
|
189
|
+
"id": 11,
|
|
190
|
+
"result": {
|
|
191
|
+
"messages": [{
|
|
192
|
+
"message_id": "550e8400-...",
|
|
193
|
+
"seq": 43,
|
|
194
|
+
"from": "alice.aid.pub",
|
|
195
|
+
"to": "bob.aid.pub",
|
|
196
|
+
"timestamp": 1709712000,
|
|
197
|
+
"payload": {"type": "text", "text": "你好"},
|
|
198
|
+
"delivery_mode": "fanout"
|
|
199
|
+
}],
|
|
200
|
+
"count": 1,
|
|
201
|
+
"latest_seq": 43,
|
|
202
|
+
"ephemeral_earliest_available_seq": 38,
|
|
203
|
+
"ephemeral_dropped_count": 5
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**响应字段**:
|
|
209
|
+
|
|
210
|
+
| 字段 | 类型 | 说明 |
|
|
211
|
+
|------|------|------|
|
|
212
|
+
| `messages` | array | 消息列表(临时 + 持久化合并,按 `seq` 排序) |
|
|
213
|
+
| `count` | integer | 本次返回的消息条数 |
|
|
214
|
+
| `latest_seq` | integer | 本次返回的最大 `seq` |
|
|
215
|
+
| `ephemeral_earliest_available_seq` | integer\|null | 当前临时缓冲中最早可用的 `seq`,`null` 表示无临时消息 |
|
|
216
|
+
| `ephemeral_dropped_count` | integer | 因缓冲淘汰而丢弃的临时消息计数 |
|
|
217
|
+
|
|
218
|
+
> 客户端可通过 `ephemeral_earliest_available_seq` 判断是否有临时消息丢失:若 `after_seq < ephemeral_earliest_available_seq`,说明存在已被淘汰的消息。
|
|
219
|
+
|
|
220
|
+
**说明**:不修改消息状态,多设备安全(各 `(aid, device_id, slot_id)` 维护各自的 `after_seq`),同一 `after_seq` 多次调用返回相同结果(幂等)。显式传入的 `device_id` / `slot_id` 若与连接认证上下文不一致,服务端 **MUST** 拒绝请求。
|
|
221
|
+
|
|
222
|
+
#### `message.ack`
|
|
223
|
+
|
|
224
|
+
确认已收到消息,推进服务端 ack 游标。
|
|
225
|
+
|
|
226
|
+
**请求**:
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"jsonrpc": "2.0",
|
|
230
|
+
"id": 12,
|
|
231
|
+
"method": "message.ack",
|
|
232
|
+
"params": {
|
|
233
|
+
"seq": 43,
|
|
234
|
+
"device_id": "device-001",
|
|
235
|
+
"slot_id": "slot-a"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**参数**:
|
|
241
|
+
|
|
242
|
+
| 参数 | 必需 | 说明 |
|
|
243
|
+
|------|:----:|------|
|
|
244
|
+
| `seq` | ✅ | 确认到的序列号(含),表示该 seq 及之前的所有消息已收到 |
|
|
245
|
+
| `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
|
|
246
|
+
| `slot_id` | ❌ | 同一设备下的消费槽位;空字符串表示设备单实例模式 |
|
|
247
|
+
|
|
248
|
+
**响应**:
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"jsonrpc": "2.0",
|
|
252
|
+
"id": 12,
|
|
253
|
+
"result": {"success": true, "ack_seq": 43}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**说明**:`ack_seq` 仅增不减。现代连接按 `(aid, device_id, slot_id)` 维护 ack 游标;未携带 `device_id` 的 legacy 连接继续走 per-AID 兼容路径。显式传入的 `device_id` / `slot_id` 若与连接认证上下文不一致,服务端 **MUST** 拒绝请求。
|
|
258
|
+
|
|
259
|
+
#### `message.recall`
|
|
260
|
+
|
|
261
|
+
撤回消息。仅发送方可撤回,受时间窗口限制(默认 2 分钟)。
|
|
262
|
+
|
|
263
|
+
**请求**:
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"jsonrpc": "2.0",
|
|
267
|
+
"id": 13,
|
|
268
|
+
"method": "message.recall",
|
|
269
|
+
"params": {"message_ids": ["uuid-1", "uuid-2"]}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**参数**:
|
|
274
|
+
|
|
275
|
+
| 参数 | 必需 | 说明 |
|
|
276
|
+
|------|:----:|------|
|
|
277
|
+
| `message_ids` | ✅ | 要撤回的消息 ID 列表(最多 100 个) |
|
|
278
|
+
|
|
279
|
+
**响应**:
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"jsonrpc": "2.0",
|
|
283
|
+
"id": 13,
|
|
284
|
+
"result": {
|
|
285
|
+
"success": true,
|
|
286
|
+
"accepted": 2,
|
|
287
|
+
"recalled": 1,
|
|
288
|
+
"errors": [{"message_id": "uuid-2", "error": "expired"}]
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
| 字段 | 类型 | 说明 |
|
|
294
|
+
|------|------|------|
|
|
295
|
+
| `success` | boolean | 操作是否执行 |
|
|
296
|
+
| `accepted` | integer | 接收的 message_id 数 |
|
|
297
|
+
| `recalled` | integer | 实际撤回数 |
|
|
298
|
+
| `errors` | array\|null | 失败项,错误码:`not_found` / `not_sender` / `already_recalled` / `expired` |
|
|
299
|
+
|
|
300
|
+
**说明**:撤回成功后向接收方推送 `event/message.recalled` 事件。仅 `delivery_mode.mode = "fanout"` 的消息支持撤回;`queue` 消息不进入历史,无法可靠追溯。
|
|
301
|
+
|
|
302
|
+
#### `message.query_online`
|
|
303
|
+
|
|
304
|
+
批量查询 AID 在线状态。
|
|
305
|
+
|
|
306
|
+
**请求**:
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"jsonrpc": "2.0",
|
|
310
|
+
"id": 14,
|
|
311
|
+
"method": "message.query_online",
|
|
312
|
+
"params": {"aids": ["alice.aid.pub", "bob.example.com"]}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**参数**:
|
|
317
|
+
|
|
318
|
+
| 参数 | 必需 | 说明 |
|
|
319
|
+
|------|:----:|------|
|
|
320
|
+
| `aids` | ✅ | 要查询的 AID 列表(最多 100 个) |
|
|
321
|
+
|
|
322
|
+
**响应**:
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"jsonrpc": "2.0",
|
|
326
|
+
"id": 14,
|
|
327
|
+
"result": {
|
|
328
|
+
"online": {
|
|
329
|
+
"alice.aid.pub": true,
|
|
330
|
+
"bob.example.com": false
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**当前实现说明**:
|
|
337
|
+
|
|
338
|
+
- 本域 AID 直接由 message 服务本地在线跟踪器返回
|
|
339
|
+
- 外域 AID 通过 `gateway.forward_federation` 转发到目标域查询
|
|
340
|
+
- 当前实现中,若某个外域查询失败,该域内 AID 会回落为 `false`
|
|
341
|
+
|
|
342
|
+
#### `event/message.received`
|
|
343
|
+
|
|
344
|
+
收到 P2P 消息事件。
|
|
345
|
+
|
|
346
|
+
```json
|
|
347
|
+
{
|
|
348
|
+
"jsonrpc": "2.0",
|
|
349
|
+
"method": "event/message.received",
|
|
350
|
+
"params": {
|
|
351
|
+
"from": "bob.aid.pub",
|
|
352
|
+
"to": "alice.aid.pub",
|
|
353
|
+
"message_id": "550e8400-...",
|
|
354
|
+
"seq": 42,
|
|
355
|
+
"payload": {"type": "text", "text": "你好"},
|
|
356
|
+
"timestamp": 1709712005,
|
|
357
|
+
"delivery_mode": "queue",
|
|
358
|
+
"encrypted": false
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### `event/message.ack`
|
|
364
|
+
|
|
365
|
+
消息确认事件(通知发送方消息已被接收方确认)。
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"jsonrpc": "2.0",
|
|
370
|
+
"method": "event/message.ack",
|
|
371
|
+
"params": {
|
|
372
|
+
"to": "bob.aid.pub",
|
|
373
|
+
"device_id": "device-001",
|
|
374
|
+
"slot_id": "slot-a",
|
|
375
|
+
"ack_seq": 43,
|
|
376
|
+
"timestamp": 1709712003
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
- `to`:确认方 AID
|
|
382
|
+
- `device_id`:触发 ack 的设备标识;legacy 客户端为空字符串
|
|
383
|
+
- `slot_id`:触发 ack 的消费槽位;空字符串表示设备单实例或 legacy 路径
|
|
384
|
+
- `ack_seq`:确认到的序列号(含该 seq 及之前的所有消息)
|
|
385
|
+
|
|
386
|
+
#### `event/message.recalled`
|
|
387
|
+
|
|
388
|
+
消息被撤回事件(通知接收方消息已被发送方撤回)。
|
|
389
|
+
|
|
390
|
+
```json
|
|
391
|
+
{
|
|
392
|
+
"jsonrpc": "2.0",
|
|
393
|
+
"method": "event/message.recalled",
|
|
394
|
+
"params": {
|
|
395
|
+
"from": "alice.aid.pub",
|
|
396
|
+
"to": "bob.aid.pub",
|
|
397
|
+
"message_ids": ["uuid-1"],
|
|
398
|
+
"timestamp": 1709712000
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
- `from`:发送方(撤回者)AID
|
|
404
|
+
- `to`:接收方 AID
|
|
405
|
+
- `message_ids`:被撤回的消息 ID 列表
|
|
406
|
+
- `timestamp`:服务端时间戳(毫秒)
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
### 6.3 元协议 `meta.*`
|
|
411
|
+
|
|
412
|
+
#### `meta.ping`
|
|
413
|
+
|
|
414
|
+
健康检查。
|
|
415
|
+
|
|
416
|
+
**请求**:
|
|
417
|
+
```json
|
|
418
|
+
{"jsonrpc": "2.0", "id": 30, "method": "meta.ping"}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**响应**:
|
|
422
|
+
```json
|
|
423
|
+
{"jsonrpc": "2.0", "id": 30, "result": {"pong": true, "timestamp": 1709712000}}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### `meta.status`
|
|
427
|
+
|
|
428
|
+
查询当前连接状态。
|
|
429
|
+
|
|
430
|
+
**当前实现事实**:
|
|
431
|
+
|
|
432
|
+
- `meta.status` 由 Gateway 本地处理,不转发到独立 `meta` 服务
|
|
433
|
+
- 当前 Gateway 返回的是简化状态对象,不是完整的 peer / relay 拓扑诊断结构
|
|
434
|
+
- Python SDK 当前也只实现 Gateway 拓扑;`peer` 和 `relay` 拓扑在 Python SDK 中尚未实现
|
|
435
|
+
|
|
436
|
+
**当前返回字段**:
|
|
437
|
+
|
|
438
|
+
| 字段 | 说明 |
|
|
439
|
+
|------|------|
|
|
440
|
+
| `mode` | 当前连接模式。现实现固定为 `gateway` |
|
|
441
|
+
| `aid` | 当前会话 AID |
|
|
442
|
+
| `role` | 当前会话角色 |
|
|
443
|
+
| `connected_at` | 会话建立时间戳(毫秒) |
|
|
444
|
+
| `protocol_version` | 协议版本,当前为 `1.0` |
|
|
445
|
+
|
|
446
|
+
**当前实现示例**:
|
|
447
|
+
```json
|
|
448
|
+
{
|
|
449
|
+
"jsonrpc": "2.0",
|
|
450
|
+
"id": 31,
|
|
451
|
+
"result": {
|
|
452
|
+
"mode": "gateway",
|
|
453
|
+
"aid": "alice.aid.pub",
|
|
454
|
+
"role": "user",
|
|
455
|
+
"connected_at": 1709712000000,
|
|
456
|
+
"protocol_version": "1.0"
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**协议演进约束**:
|
|
462
|
+
|
|
463
|
+
- 客户端 **MUST** 容忍未知字段,以便未来扩展更完整的连接诊断结构
|
|
464
|
+
- 文档中关于 peer / relay 诊断字段的 richer 结构,目前应视为未来扩展方向,而非当前稳定返回契约
|
|
465
|
+
|
|
466
|
+
#### `meta.trust_roots`
|
|
467
|
+
|
|
468
|
+
查询当前 AUN 受信根证书列表。Gateway 内部转发给 CA 模块处理。
|
|
469
|
+
|
|
470
|
+
该 RPC 适合已连接客户端查询服务端缓存列表。首次信任根更新应优先使用公开 HTTP 端点:
|
|
471
|
+
|
|
472
|
+
- `GET https://trust.aun.network/.well-known/aun/trust-roots.json`
|
|
473
|
+
- `GET https://pki.{issuer}/trust-root.json`
|
|
474
|
+
- `GET https://gateway.{issuer}/pki/trust-roots.json`
|
|
475
|
+
|
|
476
|
+
Issuer PKI 泛域名服务还必须提供 `GET https://pki.{issuer}/root.crt`,用于下载该 issuer 证书链锚定的 Root CA PEM。客户端导入前必须验证受信根列表的 `authority_signature`,并确认 `root.crt` 的 SHA-256 指纹存在于已验签列表中。
|
|
477
|
+
|
|
478
|
+
**请求**:
|
|
479
|
+
```json
|
|
480
|
+
{"jsonrpc": "2.0", "id": 32, "method": "meta.trust_roots"}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
**参数**:无。
|
|
484
|
+
|
|
485
|
+
**响应**:
|
|
486
|
+
```json
|
|
487
|
+
{
|
|
488
|
+
"jsonrpc": "2.0",
|
|
489
|
+
"id": 32,
|
|
490
|
+
"result": {
|
|
491
|
+
"version": 2,
|
|
492
|
+
"issued_at": "2026-03-15T10:00:00Z",
|
|
493
|
+
"next_update": "2026-03-16T10:00:00Z",
|
|
494
|
+
"authority_signature": "MEUCIQDx...",
|
|
495
|
+
"root_cas": [
|
|
496
|
+
{
|
|
497
|
+
"id": "root-ca-001",
|
|
498
|
+
"name": "AUN Root CA A",
|
|
499
|
+
"organization": "Organization A",
|
|
500
|
+
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
|
|
501
|
+
"fingerprint_sha256": "a1b2c3d4...",
|
|
502
|
+
"status": "active",
|
|
503
|
+
"crl_url": "http://crl.rootca-a.example/root.crl",
|
|
504
|
+
"ocsp_url": "http://ocsp.rootca-a.example"
|
|
505
|
+
}
|
|
506
|
+
]
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**响应字段**:
|
|
512
|
+
|
|
513
|
+
| 字段 | 类型 | 说明 |
|
|
514
|
+
|------|------|------|
|
|
515
|
+
| `version` | integer | 受信根列表版本,单调递增 |
|
|
516
|
+
| `issued_at` | string | 列表签发时间 |
|
|
517
|
+
| `next_update` | string | 建议下次更新时间 |
|
|
518
|
+
| `authority_signature` | string | 管理局对规范化列表内容的签名 |
|
|
519
|
+
| `root_cas` | array | Root CA 列表 |
|
|
520
|
+
| `root_cas[].certificate` | string | PEM 格式 Root CA 证书 |
|
|
521
|
+
| `root_cas[].fingerprint_sha256` | string | Root CA 证书 DER SHA-256 指纹 |
|
|
522
|
+
| `root_cas[].status` | string | `active` / `retired` / `revoked` 等状态 |
|
|
523
|
+
|
|
524
|
+
> **兼容说明**:早期服务可能仍返回 `roots/count` 简化结构。客户端可以查询该结构,但默认不得将未签名列表导入本地信任根。客户端仍应容忍未知字段。
|
|
525
|
+
|
|
526
|
+
#### CT 公开 HTTP 端点
|
|
527
|
+
|
|
528
|
+
Issuer 必须通过 `https://ct.{issuer}` 提供证书透明日志(CT)的公开只读查询入口。该入口不属于 SDK RPC 命名空间,不通过 `AUNClient` 暴露专用方法;审计方和客户端可直接使用 HTTP 查询。
|
|
529
|
+
|
|
530
|
+
`ct.{issuer}` 是稳定的公开访问面,CA 服务本身不得直接暴露公网 HTTP 端点。服务端对外只能暴露公开只读查询路径,CT 写入接口不得通过 `ct.{issuer}` 暴露。
|
|
531
|
+
|
|
532
|
+
规范端点:
|
|
533
|
+
|
|
534
|
+
| 方法 | URL | 说明 |
|
|
535
|
+
|------|-----|------|
|
|
536
|
+
| GET | `https://ct.{issuer}/sth` | 获取最新签名树头(STH) |
|
|
537
|
+
| GET | `https://ct.{issuer}/entries?start=0&limit=100` | 分页查询公开 CT 条目 |
|
|
538
|
+
| GET | `https://ct.{issuer}/entries/{log_id}` | 按日志 ID 查询单条公开 CT 条目 |
|
|
539
|
+
| GET | `https://ct.{issuer}/certs/{serial}` | 按证书序列号查询对应 CT 条目 |
|
|
540
|
+
| GET | `https://ct.{issuer}/proof/{tree_size}/{log_id}` | 获取指定树大小下的 Merkle inclusion proof |
|
|
541
|
+
|
|
542
|
+
完整日志范围、字段定义、SCT/STH 格式和 Issuer CA 写入要求见 [附录D D.8](附录D-Root_CA_治理机制.md) 与 [附录F](附录F-Issuer_CA_申请流程.md)。
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
### 6.4 搜索与发现 `search.*`
|
|
547
|
+
|
|
548
|
+
`search.*` 定义 AUN 中 Agent 的公开发现机制,围绕 `agent.md` 工作:
|
|
549
|
+
|
|
550
|
+
- `agent.md` 是 Agent 的标准公开描述文档,对标 A2A 的 Agent Card
|
|
551
|
+
- AP 内部通过 `search.*` 为本 AP 托管或索引的公开 `agent.md` 提供检索服务
|
|
552
|
+
- 整个 AUN 网络可通过公开 AP 之间的同步,聚合形成跨 AP、跨 Issuer 的全网 Agent 搜索与发现能力
|
|
553
|
+
|
|
554
|
+
#### 6.4.1 `agent.md` 规范
|
|
555
|
+
|
|
556
|
+
`agent.md` **MUST** 采用 `YAML frontmatter + Markdown 正文` 结构。
|
|
557
|
+
|
|
558
|
+
**必填字段**:
|
|
559
|
+
|
|
560
|
+
| 字段 | 说明 |
|
|
561
|
+
|------|------|
|
|
562
|
+
| `aid` | Agent 的唯一身份标识,必须为合法 AID |
|
|
563
|
+
| `name` | Agent 显示名称 |
|
|
564
|
+
| `type` | Agent 类型,如 `human`、`assistant`、`avatar`、`codeagent` |
|
|
565
|
+
| `version` | 该公开描述文档自身的版本号 |
|
|
566
|
+
| `description` | 一句话简介 |
|
|
567
|
+
|
|
568
|
+
**可选字段**:`tags`、`visibility`(`public`/`unlisted`/`private`)、`updated_at`、`skills`、`input_modes`、`output_modes`、`service_endpoints`、`provider`、`contact`、`license`、`signature`
|
|
569
|
+
|
|
570
|
+
**最小格式示例**:
|
|
571
|
+
|
|
572
|
+
```markdown
|
|
573
|
+
---
|
|
574
|
+
aid: "agent-name.aid.pub"
|
|
575
|
+
name: "Agent Name"
|
|
576
|
+
type: "assistant"
|
|
577
|
+
version: "1.0.0"
|
|
578
|
+
description: "一句话描述"
|
|
579
|
+
visibility: "public"
|
|
580
|
+
tags:
|
|
581
|
+
- tag1
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
# Markdown 正文
|
|
585
|
+
详细说明、Skills、使用示���等...
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
- `visibility=private` 的记录 **MUST NOT** 进入公开索引
|
|
589
|
+
- `agent.md` **MUST NOT** 包含私钥或敏感凭据
|
|
590
|
+
|
|
591
|
+
#### 6.4.2 发现模型
|
|
592
|
+
|
|
593
|
+
**AP 内发现**:
|
|
594
|
+
|
|
595
|
+
- AP **MUST** 能索引其服务范围内公开可见的 `agent.md`
|
|
596
|
+
- `search.query`、`search.get_agent`、`search.suggest` 返回的是该 AP 当前索引视图
|
|
597
|
+
|
|
598
|
+
**全网发现**:
|
|
599
|
+
|
|
600
|
+
- 公开 AP **SHOULD** 从其他公开 AP 同步公开的 `agent.md`
|
|
601
|
+
- 同步模型推荐"增量追加日志 + 周期性快照"
|
|
602
|
+
- 客户端 **MUST** 把搜索结果视为"最终一致",而不是强事务视图
|
|
603
|
+
|
|
604
|
+
#### `search.ap_info`
|
|
605
|
+
|
|
606
|
+
查询公开 AP 的同步能力与当前索引状态。
|
|
607
|
+
|
|
608
|
+
**请求**:
|
|
609
|
+
```json
|
|
610
|
+
{"jsonrpc": "2.0", "id": 40, "method": "search.ap_info"}
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
**响应**:
|
|
614
|
+
```json
|
|
615
|
+
{
|
|
616
|
+
"jsonrpc": "2.0",
|
|
617
|
+
"id": 40,
|
|
618
|
+
"result": {
|
|
619
|
+
"ap_id": "search.aid.pub",
|
|
620
|
+
"public": true,
|
|
621
|
+
"capabilities": {"query": true, "suggest": true, "snapshot": true, "changes": true},
|
|
622
|
+
"current_snapshot_version": "2026-03-21T00:00:00Z",
|
|
623
|
+
"change_cursor_head": "chg_00000991",
|
|
624
|
+
"updated_at": "2026-03-21T08:00:00Z"
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
#### `search.snapshot`
|
|
630
|
+
|
|
631
|
+
获取公开 AP 的全量快照,用于冷启动或游标失效后重建。
|
|
632
|
+
|
|
633
|
+
**请求**:
|
|
634
|
+
```json
|
|
635
|
+
{
|
|
636
|
+
"jsonrpc": "2.0",
|
|
637
|
+
"id": 41,
|
|
638
|
+
"method": "search.snapshot",
|
|
639
|
+
"params": {"version": "2026-03-21T00:00:00Z", "cursor": null, "limit": 500}
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
**响应**:
|
|
644
|
+
```json
|
|
645
|
+
{
|
|
646
|
+
"jsonrpc": "2.0",
|
|
647
|
+
"id": 41,
|
|
648
|
+
"result": {
|
|
649
|
+
"snapshot_version": "2026-03-21T00:00:00Z",
|
|
650
|
+
"items": [{
|
|
651
|
+
"aid": "reviewer.aid.pub",
|
|
652
|
+
"agent_md_url": "https://reviewer.aid.pub/agent.md",
|
|
653
|
+
"agent_md_sha256": "6f4c...9a",
|
|
654
|
+
"source_ap": "search.aid.pub",
|
|
655
|
+
"updated_at": "2026-03-20T12:00:00Z"
|
|
656
|
+
}],
|
|
657
|
+
"next_cursor": "snap_0002",
|
|
658
|
+
"has_more": true
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
#### `search.changes`
|
|
664
|
+
|
|
665
|
+
获取某个游标之后的增量变更,用于持续同步。
|
|
666
|
+
|
|
667
|
+
**请求**:
|
|
668
|
+
```json
|
|
669
|
+
{
|
|
670
|
+
"jsonrpc": "2.0",
|
|
671
|
+
"id": 42,
|
|
672
|
+
"method": "search.changes",
|
|
673
|
+
"params": {"cursor": "chg_00000920", "limit": 200}
|
|
674
|
+
}
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
**响应**:
|
|
678
|
+
```json
|
|
679
|
+
{
|
|
680
|
+
"jsonrpc": "2.0",
|
|
681
|
+
"id": 42,
|
|
682
|
+
"result": {
|
|
683
|
+
"from_cursor": "chg_00000920",
|
|
684
|
+
"next_cursor": "chg_00000991",
|
|
685
|
+
"changes": [
|
|
686
|
+
{"sequence": 921, "op": "upsert", "aid": "reviewer.aid.pub", "updated_at": "2026-03-21T07:55:00Z"},
|
|
687
|
+
{"sequence": 922, "op": "delete", "aid": "oldbot.aid.pub", "updated_at": "2026-03-21T07:56:00Z"}
|
|
688
|
+
],
|
|
689
|
+
"has_more": false
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
- `op` 至少支持 `upsert` 与 `delete`
|
|
695
|
+
- 若游标已过期,服务端 **SHOULD** 返回错误,要求下游重新拉取 `search.snapshot`
|
|
696
|
+
|
|
697
|
+
#### `search.query`
|
|
698
|
+
|
|
699
|
+
搜索公开 Agent。
|
|
700
|
+
|
|
701
|
+
**请求**:
|
|
702
|
+
```json
|
|
703
|
+
{
|
|
704
|
+
"jsonrpc": "2.0",
|
|
705
|
+
"id": 43,
|
|
706
|
+
"method": "search.query",
|
|
707
|
+
"params": {"q": "code review assistant", "tags": ["coding"], "limit": 10}
|
|
708
|
+
}
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
**响应**:
|
|
712
|
+
```json
|
|
713
|
+
{
|
|
714
|
+
"jsonrpc": "2.0",
|
|
715
|
+
"id": 43,
|
|
716
|
+
"result": {
|
|
717
|
+
"items": [{
|
|
718
|
+
"aid": "reviewer.aid.pub",
|
|
719
|
+
"name": "Reviewer",
|
|
720
|
+
"description": "面向工程团队的代码审查 Agent",
|
|
721
|
+
"tags": ["coding", "review"],
|
|
722
|
+
"agent_md_url": "https://reviewer.aid.pub/agent.md"
|
|
723
|
+
}],
|
|
724
|
+
"next_cursor": "cur_abc123"
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
#### `search.get_agent`
|
|
730
|
+
|
|
731
|
+
获取单个 Agent 的公开描述。
|
|
732
|
+
|
|
733
|
+
**请求**:
|
|
734
|
+
```json
|
|
735
|
+
{
|
|
736
|
+
"jsonrpc": "2.0",
|
|
737
|
+
"id": 44,
|
|
738
|
+
"method": "search.get_agent",
|
|
739
|
+
"params": {"aid": "reviewer.aid.pub"}
|
|
740
|
+
}
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
**响应**:
|
|
744
|
+
```json
|
|
745
|
+
{
|
|
746
|
+
"jsonrpc": "2.0",
|
|
747
|
+
"id": 44,
|
|
748
|
+
"result": {
|
|
749
|
+
"aid": "reviewer.aid.pub",
|
|
750
|
+
"agent_md": "---\naid: \"reviewer.aid.pub\"\nname: \"Reviewer\"\n...\n---\n# Reviewer\n",
|
|
751
|
+
"content_type": "text/markdown",
|
|
752
|
+
"agent_md_url": "https://reviewer.aid.pub/agent.md",
|
|
753
|
+
"updated_at": "2026-03-20T12:00:00Z"
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
#### `search.suggest`
|
|
759
|
+
|
|
760
|
+
返回搜索建议、热门标签或前缀匹配结果。
|
|
761
|
+
|
|
762
|
+
**请求**:
|
|
763
|
+
```json
|
|
764
|
+
{"jsonrpc": "2.0", "id": 45, "method": "search.suggest", "params": {"prefix": "code"}}
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
**响应**:
|
|
768
|
+
```json
|
|
769
|
+
{
|
|
770
|
+
"jsonrpc": "2.0",
|
|
771
|
+
"id": 45,
|
|
772
|
+
"result": {
|
|
773
|
+
"suggestions": [
|
|
774
|
+
{"type": "query", "value": "code review"},
|
|
775
|
+
{"type": "tag", "value": "coding"},
|
|
776
|
+
{"type": "aid", "value": "reviewer.aid.pub"}
|
|
777
|
+
]
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
#### 错误码
|
|
783
|
+
|
|
784
|
+
| 错误码 | 名称 | 说明 |
|
|
785
|
+
|-------:|------|------|
|
|
786
|
+
| `-32160` | Search unavailable | 当前 AP 未启用搜索服务 |
|
|
787
|
+
| `-32161` | Agent not found | 指定 AID 的公开 `agent.md` 不存在 |
|
|
788
|
+
| `-32162` | Invalid search query | 查询参数非法 |
|
|
789
|
+
| `-32163` | Snapshot stale | 当前结果基于过期快照 |
|
|
790
|
+
| `-32164` | Change cursor expired | 增量游标已超出保留窗口 |
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
### 6.5 Agent 协作与任务 `task.*`
|
|
795
|
+
|
|
796
|
+
`task.*` 用于表达 Agent 之间的长生命周期协作任务,参考 A2A 的 task 机制,对齐 AUN 特点:
|
|
797
|
+
|
|
798
|
+
- 任务对象通过 `task.*` 暴露统一的状态、输入、产物和事件
|
|
799
|
+
- 大对象、附件 **SHOULD** 通过 `storage.*` 承载,`task.*` 仅传递元数据与引用
|
|
800
|
+
|
|
801
|
+
**任务对象核心字段**:
|
|
802
|
+
|
|
803
|
+
| 字段 | 说明 |
|
|
804
|
+
|------|------|
|
|
805
|
+
| `task_id` | 任务唯一标识 |
|
|
806
|
+
| `status` | 任务状态 |
|
|
807
|
+
| `owner` | 发起方 AID |
|
|
808
|
+
| `assignee` | 执行方 AID |
|
|
809
|
+
| `participants` | 参与方列表 |
|
|
810
|
+
| `visibility` | 任务可见性(`private`/`shared`/`public`) |
|
|
811
|
+
| `parent_task_id` | 父任务标识(如有) |
|
|
812
|
+
| `input` | 初始输入 |
|
|
813
|
+
| `artifacts` | 任务产物 |
|
|
814
|
+
| `messages` | 上下文消息 |
|
|
815
|
+
|
|
816
|
+
**状态机**:
|
|
817
|
+
|
|
818
|
+
| 状态 | 说明 |
|
|
819
|
+
|------|------|
|
|
820
|
+
| `submitted` | 已创建,等待接收方受理 |
|
|
821
|
+
| `rejected` | 接收方明确拒绝受理(终态) |
|
|
822
|
+
| `working` | 正在执行 |
|
|
823
|
+
| `input_required` | 需要发起方补充信息 |
|
|
824
|
+
| `completed` | 正常完成(终态) |
|
|
825
|
+
| `failed` | 执行失败(终态) |
|
|
826
|
+
| `canceled` | 被取消(终态) |
|
|
827
|
+
|
|
828
|
+
终态任务 **MAY** 允许读取历史,但 **MUST NOT** 再接受新的执行输入。
|
|
829
|
+
|
|
830
|
+
#### `task.create`
|
|
831
|
+
|
|
832
|
+
**请求**:
|
|
833
|
+
```json
|
|
834
|
+
{
|
|
835
|
+
"jsonrpc": "2.0",
|
|
836
|
+
"id": 50,
|
|
837
|
+
"method": "task.create",
|
|
838
|
+
"params": {
|
|
839
|
+
"to": "reviewer.aid.pub",
|
|
840
|
+
"input": {"type": "text", "content": "请审查这个 PR 的风险点"},
|
|
841
|
+
"visibility": "private"
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
**响应**:
|
|
847
|
+
```json
|
|
848
|
+
{
|
|
849
|
+
"jsonrpc": "2.0",
|
|
850
|
+
"id": 50,
|
|
851
|
+
"result": {
|
|
852
|
+
"task_id": "task_01HV7J6N8F",
|
|
853
|
+
"status": "submitted",
|
|
854
|
+
"owner": "alice.aid.pub",
|
|
855
|
+
"assignee": "reviewer.aid.pub",
|
|
856
|
+
"created_at": "2026-03-21T13:00:00Z"
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
#### `task.get`
|
|
862
|
+
|
|
863
|
+
**请求**:
|
|
864
|
+
```json
|
|
865
|
+
{"jsonrpc": "2.0", "id": 51, "method": "task.get", "params": {"task_id": "task_01HV7J6N8F"}}
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
**响应**:返回完整任务对象(含 `status`、`participants`、`children`、`messages`、`artifacts` 等)。
|
|
869
|
+
|
|
870
|
+
#### `task.accept`
|
|
871
|
+
|
|
872
|
+
接收方显式受理任务,把 `submitted` 推进到 `working`。
|
|
873
|
+
|
|
874
|
+
**请求**:
|
|
875
|
+
```json
|
|
876
|
+
{"jsonrpc": "2.0", "id": 52, "method": "task.accept", "params": {"task_id": "task_01HV7J6N8F"}}
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
**响应**:
|
|
880
|
+
```json
|
|
881
|
+
{"jsonrpc": "2.0", "id": 52, "result": {"task_id": "task_01HV7J6N8F", "status": "working"}}
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
#### `task.reject`
|
|
885
|
+
|
|
886
|
+
接收方显式拒绝受理任务。
|
|
887
|
+
|
|
888
|
+
**请求**:
|
|
889
|
+
```json
|
|
890
|
+
{"jsonrpc": "2.0", "id": 53, "method": "task.reject", "params": {"task_id": "task_01HV7J6N8F", "reason": "unsupported_scope"}}
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
**响应**:
|
|
894
|
+
```json
|
|
895
|
+
{"jsonrpc": "2.0", "id": 53, "result": {"task_id": "task_01HV7J6N8F", "status": "rejected"}}
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
#### `task.send_input`
|
|
899
|
+
|
|
900
|
+
向任务追加新的输入,用于继续协作或响应 `input_required`。
|
|
901
|
+
|
|
902
|
+
**请求**:
|
|
903
|
+
```json
|
|
904
|
+
{
|
|
905
|
+
"jsonrpc": "2.0",
|
|
906
|
+
"id": 54,
|
|
907
|
+
"method": "task.send_input",
|
|
908
|
+
"params": {
|
|
909
|
+
"task_id": "task_01HV7J6N8F",
|
|
910
|
+
"input": {"type": "text", "content": "补充说明:重点检查数据库迁移部分"}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
```
|
|
914
|
+
|
|
915
|
+
**响应**:
|
|
916
|
+
```json
|
|
917
|
+
{"jsonrpc": "2.0", "id": 54, "result": {"task_id": "task_01HV7J6N8F", "status": "working"}}
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
#### `task.delegate`
|
|
921
|
+
|
|
922
|
+
把当前任务的一个子问题委派给另一个 Agent,创建子任务。
|
|
923
|
+
|
|
924
|
+
**请求**:
|
|
925
|
+
```json
|
|
926
|
+
{
|
|
927
|
+
"jsonrpc": "2.0",
|
|
928
|
+
"id": 55,
|
|
929
|
+
"method": "task.delegate",
|
|
930
|
+
"params": {
|
|
931
|
+
"task_id": "task_01HV7J6N8F",
|
|
932
|
+
"to": "db-reviewer.aid.pub",
|
|
933
|
+
"input": {"type": "text", "content": "请专门检查数据库迁移风险"}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
**响应**:
|
|
939
|
+
```json
|
|
940
|
+
{
|
|
941
|
+
"jsonrpc": "2.0",
|
|
942
|
+
"id": 55,
|
|
943
|
+
"result": {
|
|
944
|
+
"task_id": "task_child_01",
|
|
945
|
+
"parent_task_id": "task_01HV7J6N8F",
|
|
946
|
+
"status": "submitted",
|
|
947
|
+
"assignee": "db-reviewer.aid.pub"
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
- 服务端 **SHOULD** 限制递归委派深度和扇出数量,避免任务风暴
|
|
953
|
+
|
|
954
|
+
#### `task.complete`
|
|
955
|
+
|
|
956
|
+
将任务标记为完成,附带最终产物。
|
|
957
|
+
|
|
958
|
+
**请求**:
|
|
959
|
+
```json
|
|
960
|
+
{
|
|
961
|
+
"jsonrpc": "2.0",
|
|
962
|
+
"id": 56,
|
|
963
|
+
"method": "task.complete",
|
|
964
|
+
"params": {
|
|
965
|
+
"task_id": "task_01HV7J6N8F",
|
|
966
|
+
"artifacts": [{
|
|
967
|
+
"id": "artifact-1",
|
|
968
|
+
"type": "text",
|
|
969
|
+
"name": "summary",
|
|
970
|
+
"mime_type": "text/markdown",
|
|
971
|
+
"content": "数据库迁移存在锁表风险"
|
|
972
|
+
}]
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
#### `task.fail`
|
|
978
|
+
|
|
979
|
+
将任务标记为失败。
|
|
980
|
+
|
|
981
|
+
**请求**:
|
|
982
|
+
```json
|
|
983
|
+
{"jsonrpc": "2.0", "id": 57, "method": "task.fail", "params": {"task_id": "task_01HV7J6N8F", "reason": "missing_required_context"}}
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
#### `task.cancel`
|
|
987
|
+
|
|
988
|
+
取消未完成任务。
|
|
989
|
+
|
|
990
|
+
**请求**:
|
|
991
|
+
```json
|
|
992
|
+
{"jsonrpc": "2.0", "id": 58, "method": "task.cancel", "params": {"task_id": "task_01HV7J6N8F", "reason": "user_abort"}}
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
**响应**:
|
|
996
|
+
```json
|
|
997
|
+
{"jsonrpc": "2.0", "id": 58, "result": {"task_id": "task_01HV7J6N8F", "status": "canceled"}}
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
#### `task.children`
|
|
1001
|
+
|
|
1002
|
+
列出指定任务的子任务摘要。
|
|
1003
|
+
|
|
1004
|
+
**请求**:
|
|
1005
|
+
```json
|
|
1006
|
+
{"jsonrpc": "2.0", "id": 59, "method": "task.children", "params": {"task_id": "task_01HV7J6N8F"}}
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
#### `task.list`
|
|
1010
|
+
|
|
1011
|
+
分页列出任务。
|
|
1012
|
+
|
|
1013
|
+
**请求**:
|
|
1014
|
+
```json
|
|
1015
|
+
{"jsonrpc": "2.0", "id": 60, "method": "task.list", "params": {"status": "working", "limit": 20, "cursor": null}}
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
- 返回结果 **MUST** 受调用方身份约束,**MUST NOT** 泄露无权访问的任务
|
|
1019
|
+
|
|
1020
|
+
#### `task.subscribe`
|
|
1021
|
+
|
|
1022
|
+
订阅任务后续事件。
|
|
1023
|
+
|
|
1024
|
+
**请求**:
|
|
1025
|
+
```json
|
|
1026
|
+
{
|
|
1027
|
+
"jsonrpc": "2.0",
|
|
1028
|
+
"id": 61,
|
|
1029
|
+
"method": "task.subscribe",
|
|
1030
|
+
"params": {"task_ids": ["task_01HV7J6N8F"], "events": ["updated", "completed", "artifact"]}
|
|
1031
|
+
}
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
**响应**:
|
|
1035
|
+
```json
|
|
1036
|
+
{"jsonrpc": "2.0", "id": 61, "result": {"subscribed": ["task_01HV7J6N8F"]}}
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
- 服务端 **MUST NOT** 为无访问权限的任务建立订阅
|
|
1040
|
+
- 服务端 **MAY** 在连接断开后丢失订阅状态,客户端应负责重订阅
|
|
1041
|
+
|
|
1042
|
+
#### 任务事件
|
|
1043
|
+
|
|
1044
|
+
```text
|
|
1045
|
+
event/task.updated # 任务状态更新
|
|
1046
|
+
event/task.completed # 任务完成
|
|
1047
|
+
event/task.failed # 任务失败
|
|
1048
|
+
event/task.artifact # 任务产物可用
|
|
1049
|
+
event/task.delegated # 已创建子任务
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
**`event/task.updated` 示例**:
|
|
1053
|
+
```json
|
|
1054
|
+
{
|
|
1055
|
+
"jsonrpc": "2.0",
|
|
1056
|
+
"method": "event/task.updated",
|
|
1057
|
+
"params": {
|
|
1058
|
+
"task_id": "task_01HV7J6N8F",
|
|
1059
|
+
"status": "input_required",
|
|
1060
|
+
"updated_at": "2026-03-21T13:01:00Z",
|
|
1061
|
+
"message": {"type": "text", "content": "请提供 PR 链接"}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
#### 错误码
|
|
1067
|
+
|
|
1068
|
+
| 错误码 | 名称 | 说明 |
|
|
1069
|
+
|-------:|------|------|
|
|
1070
|
+
| `-32170` | Task not found | 指定任务不存在 |
|
|
1071
|
+
| `-32171` | Task state invalid | 当前状态不允许该操作 |
|
|
1072
|
+
| `-32172` | Task input required | 需要补充输入 |
|
|
1073
|
+
| `-32173` | Task canceled | 任务已取消 |
|
|
1074
|
+
| `-32174` | Task output too large | 输出过大,应改用 `storage.*` 引用 |
|
|
1075
|
+
| `-32175` | Task access denied | 无权访问该任务 |
|
|
1076
|
+
| `-32176` | Task already accepted | 不能重复 accept |
|
|
1077
|
+
| `-32177` | Task rejected | 任务已被拒绝 |
|
|
1078
|
+
| `-32178` | Task delegation denied | 无权创建子任务 |
|
|
1079
|
+
| `-32179` | Task child limit exceeded | 子任务数量或深度超限 |
|
|
1080
|
+
| `-32185` | Task completion blocked | 存在未完成的必需子任务 |
|
|
1081
|
+
| `-32186` | Task failure recorded | 任务已进入失败终态 |
|
|
1082
|
+
|
|
1083
|
+
---
|
|
1084
|
+
|
|
1085
|
+
### 6.6 端到端加密(E2EE)摘要
|
|
1086
|
+
|
|
1087
|
+
> 规范性定义见 [08-AUN-E2EE.md](08-AUN-E2EE.md)。本节仅保留摘要。
|
|
1088
|
+
|
|
1089
|
+
**核心原则**:
|
|
1090
|
+
|
|
1091
|
+
- E2EE 加解密**完全由客户端实现**,无需在线协商
|
|
1092
|
+
- 服务端只做消息中转和 prekey 存储,对加密内容完全透明
|
|
1093
|
+
- 加密消息通过 `message.send` 的 `encrypted: true` 标志标识
|
|
1094
|
+
- 两级降级:prekey_ecdh_v2(优先,四路 ECDH)→ long_term_key(降级)
|
|
1095
|
+
|
|
1096
|
+
**服务端兼容性要求**:
|
|
1097
|
+
|
|
1098
|
+
- 接受并转发 `encrypted: true` 的消息
|
|
1099
|
+
- 在离线队列和历史消息中存储密文 payload
|
|
1100
|
+
- 不对密文 payload 施加额外的语义解析要求
|
|
1101
|
+
- 提供 `message.e2ee.put_prekey` / `message.e2ee.get_prekey` RPC
|
|
1102
|
+
|
|
1103
|
+
**互操作要求**:
|
|
1104
|
+
|
|
1105
|
+
跨语言、跨平台 SDK 的互操作必须以 [08-AUN-E2EE.md](08-AUN-E2EE.md) 中定义的算法套件、密文 payload 格式、AAD 字段、重放保护规则为准。
|
|
1106
|
+
|
|
1107
|
+
**错误码**:
|
|
1108
|
+
|
|
1109
|
+
| 错误码 | 名称 | 说明 |
|
|
1110
|
+
|-------:|------|------|
|
|
1111
|
+
| `-32604` | E2EE capability required | 客户端不支持群组 E2EE(无法加入群组) |
|
|
1112
|
+
|
|
1113
|
+
---
|
|
1114
|
+
|
|
1115
|
+
### 6.7 跨域消息路由
|
|
1116
|
+
|
|
1117
|
+
**当前实现事实**:
|
|
1118
|
+
|
|
1119
|
+
- 跨域消息路由已落地在 Gateway federation 通道上
|
|
1120
|
+
- 本域服务通过 `gateway.forward_federation` / `gateway.forward_federation_batch` 发起跨域 RPC 中继
|
|
1121
|
+
- Gateway federation client 当前通过 `https://{issuer}/.well-known/aun-gateway` 发现远端 Gateway 地址
|
|
1122
|
+
- 远端 Gateway 通过 `federation.hello` 完成双向认证后,接收 `federation.relay` / `federation.relay_batch`
|
|
1123
|
+
- `message.send`、`message.query_online`、`storage.*`、`group.*` 等服务当前都已复用该通道进行跨域转发
|
|
1124
|
+
|
|
1125
|
+
**当前约束**:
|
|
1126
|
+
|
|
1127
|
+
- 这是一条 Gateway 级 federation 中继通道,不是独立的 `message.*` 子协议扩展
|
|
1128
|
+
- 跨域转发的具体可用 namespace 受 Gateway 白名单控制
|
|
1129
|
+
- 服务端会向被中继的 RPC 注入 `_federation` 上下文,并校验调用方 AID 的 issuer 与来源 issuer 一致
|
|
1130
|
+
|
|
1131
|
+
**错误语义**:
|
|
1132
|
+
|
|
1133
|
+
- `gateway.forward_federation` 当前在连接失败时返回 `-32010`
|
|
1134
|
+
- 超时时返回 `-32011`
|
|
1135
|
+
- 运行时拒绝或协议错误返回 `-32012`
|