@agentunion/fastaun-browser 0.5.19 → 0.5.21
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 +176 -78
- package/_packed_docs/CHANGELOG.md +176 -78
- package/_packed_docs/INDEX.md +288 -269
- package/_packed_docs/KITE_DOCS_GUIDE.md +101 -95
- package/_packed_docs/agent.md/SCHEMA.md +7 -7
- package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/344/270/216/346/215/242owner/347/274/226/346/216/222/346/226/271/346/241/210.md +530 -0
- package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/345/256/214/346/225/264/350/256/276/350/256/241/344/270/216/345/256/236/346/226/275/350/256/241/345/210/222.md +685 -0
- package/_packed_docs/agent.md/working/agent.md-schema/344/270/216/347/255/276/345/217/221/351/252/214/347/255/276/346/265/201/347/250/213/346/276/204/346/270/205.md +349 -0
- package/_packed_docs/agent.md/working//346/234/254/345/234/260Docker/346/265/213/350/257/225Bug/346/270/205/345/215/225.md +40 -0
- package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +11 -11
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +372 -331
- package/_packed_docs/protocol/08-AUN-E2EE.md +17 -12
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +676 -676
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +8 -12
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/211.md +445 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.0.md +161 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +666 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2113.0.md +233 -0
- package/_packed_docs/protocol/agent.md/SCHEMA.md +1 -1
- package/_packed_docs/sdk/0.5.21-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +368 -0
- package/_packed_docs/sdk/0.5.21-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +350 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +1 -1
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +5 -1
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +64 -64
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +70 -63
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +43 -40
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +179 -19
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +50 -49
- package/_packed_docs/sdk/09-group-rpc-manual.md +261 -254
- package/_packed_docs/sdk/09-message-rpc-manual.md +253 -160
- package/_packed_docs/sdk/09-storage-rpc-manual.md +18 -26
- package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +71 -0
- package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +88 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +105 -92
- package/_packed_docs/sdk/INDEX.md +197 -167
- package/_packed_docs/sdk/Ownership-SDK/345/256/236/347/216/260/346/214/207/345/215/227.md +169 -0
- package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/227.md +349 -0
- package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +930 -0
- package/_packed_docs/sdk/Ownership-SDK/351/233/206/346/210/220/346/214/207/345/215/227.md +270 -0
- package/_packed_docs/sdk/Ownership2.1-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +363 -0
- package/_packed_docs/sdk/Ownership2.1-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +553 -0
- package/_packed_docs/sdk/Ownership2.1-TDD/345/210/206/351/230/266/346/256/265/345/256/236/346/226/275/350/256/241/345/210/222.md +708 -0
- package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +480 -0
- package/_packed_docs/sdk/Ownership/347/256/241/347/220/206/344/270/223/351/242/230.md +559 -0
- package/_packed_docs/sdk/ProtectedHeaders/347/224/250/346/263/225/344/270/223/351/242/230.md +299 -0
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +173 -0
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +211 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273SDK/345/256/236/347/216/260/347/247/273/346/244/215/346/214/207/345/215/227.md +331 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273SDK/351/233/206/346/210/220/346/214/207/345/215/227.md +207 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/344/273/243/347/240/201/345/256/241/346/237/245/346/212/245/345/221/212.md +252 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/345/256/236/346/226/275/350/256/241/345/210/222.md +156 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/346/226/271/346/241/210.md +273 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/350/257/246/347/273/206/350/256/276/350/256/241.md +211 -0
- package/dist/agent-md-schema.d.ts +16 -4
- package/dist/agent-md-schema.d.ts.map +1 -1
- package/dist/agent-md-schema.js +65 -30
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.d.ts +35 -3
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +384 -150
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +59 -0
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +202 -16
- package/dist/aid-store.js.map +1 -1
- package/dist/aid.d.ts +4 -1
- package/dist/aid.d.ts.map +1 -1
- package/dist/aid.js +24 -42
- package/dist/aid.js.map +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +89 -18
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +6410 -1848
- package/dist/cert-utils.d.ts +50 -1
- package/dist/cert-utils.d.ts.map +1 -1
- package/dist/cert-utils.js +123 -56
- package/dist/cert-utils.js.map +1 -1
- package/dist/client/delivery.d.ts +108 -16
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +1411 -184
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +4 -1
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +203 -117
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +22 -3
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +1312 -684
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +23 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +419 -101
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +8 -6
- package/dist/crypto.js.map +1 -1
- package/dist/events.d.ts +24 -3
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +171 -29
- package/dist/events.js.map +1 -1
- package/dist/facades.d.ts +42 -1
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +368 -12
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +14 -1
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.d.ts +4 -0
- package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.js +30 -13
- package/dist/keystore/indexeddb-identity-store.js.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts +19 -2
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +193 -6
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +15 -2
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +308 -27
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/org-protocol.d.ts +45 -0
- package/dist/org-protocol.d.ts.map +1 -1
- package/dist/org-protocol.js +827 -21
- package/dist/org-protocol.js.map +1 -1
- package/dist/ownership-v21.d.ts +43 -9
- package/dist/ownership-v21.d.ts.map +1 -1
- package/dist/ownership-v21.js +183 -81
- package/dist/ownership-v21.js.map +1 -1
- package/dist/ownership-workflow.d.ts +36 -1
- package/dist/ownership-workflow.d.ts.map +1 -1
- package/dist/ownership-workflow.js +610 -89
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/seq-tracker.d.ts +2 -0
- package/dist/seq-tracker.d.ts.map +1 -1
- package/dist/seq-tracker.js +3 -2
- package/dist/seq-tracker.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +61 -3
- package/dist/tools/cross-sdk-agent.d.ts.map +1 -1
- package/dist/tools/cross-sdk-agent.js +524 -45
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +4 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +64 -30
- package/dist/transport.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
| `meta.*` | 核心 | 健康检查、状态查询、受信根证书 | meta 服务 | WebSocket |
|
|
21
21
|
| `storage.*` | 扩展 | 对象存储、大文件上传下载(详见 [11-Storage-子协议.md](11-Storage-子协议.md)) | storage 服务 | WebSocket + HTTP |
|
|
22
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
|
-
| `proxy.*` | 扩展 | Service Proxy 服务列表控制面 | Gateway 本地处理 / service_proxy 查询 | WebSocket |
|
|
26
|
-
| `search.*` | 扩展 | Agent 搜索与发现 | search 服务 | WebSocket |
|
|
27
|
-
| `relay.*` | 扩展 | NAT 穿透中继(详见 [05-Relay-子协议.md](05-Relay-子协议.md)) | relay 服务 | WebSocket |
|
|
28
|
-
| `peer.*` | 协议定义 | 点对点直连(详见 [04-Peer-子协议.md](04-Peer-子协议.md)) | 无对应服务 | WebSocket |
|
|
23
|
+
| `mail.*` | 扩展 | 邮件服务 | mail 服务 | WebSocket |
|
|
24
|
+
| `stream.*` | 扩展 | 实时流式传输(详见 [12-Stream-子协议.md](12-Stream-子协议.md)) | stream 服务 | WebSocket + HTTP SSE |
|
|
25
|
+
| `proxy.*` | 扩展 | Service Proxy 服务列表控制面 | Gateway 本地处理 / service_proxy 查询 | WebSocket |
|
|
26
|
+
| `search.*` | 扩展 | Agent 搜索与发现 | search 服务 | WebSocket |
|
|
27
|
+
| `relay.*` | 扩展 | NAT 穿透中继(详见 [05-Relay-子协议.md](05-Relay-子协议.md)) | relay 服务 | WebSocket |
|
|
28
|
+
| `peer.*` | 协议定义 | 点对点直连(详见 [04-Peer-子协议.md](04-Peer-子协议.md)) | 无对应服务 | WebSocket |
|
|
29
29
|
| `task.*` | 协议定义 | Agent 协作与任务执行 | 无对应服务 | WebSocket |
|
|
30
30
|
|
|
31
31
|
**控制面与数据面分离**:
|
|
@@ -36,215 +36,215 @@
|
|
|
36
36
|
- 大文件、二进制附件、长时流式内容不应直接嵌入 `message.*` 的 `payload`,应先经 `storage.*` 存储,再由 `message.*` 传递对象引用
|
|
37
37
|
- 实现应分别对 `message.*` 的消息体大小和 `storage.*` 的对象大小进行独立限制
|
|
38
38
|
|
|
39
|
-
**应用层扩展服务**本身也是 AID 持有者,通过核心协议(`message.*`)与客户端通信。客户端可以选择使用或不使用这些扩展服务。
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
### 6.2 Service Proxy 服务列表控制面 `proxy.*`
|
|
44
|
-
|
|
45
|
-
`proxy.*` 是 AUN Service Proxy 的控制面命名空间,用于 provider 通过 Gateway 长连接声明自己能够通过 Service Proxy 暴露哪些服务。它不承载 HTTP/WS 数据面流量;真实访问数据面由 `service_proxy` 模块的独立 proxy-server 隧道处理。
|
|
46
|
-
|
|
47
|
-
#### 控制面与数据面
|
|
48
|
-
|
|
49
|
-
- **Gateway 控制面**:provider 的 AUN 长连接调用 `proxy.register_services` / `proxy.unregister_services` / `proxy.list_services`。Gateway 记录每个 provider 长连接声明的服务摘要,供 `service_proxy` 模块判断 provider 是否在线、是否声明目标服务。
|
|
50
|
-
- **proxy-server 数据面**:service-proxy-client 连接 `service_proxy` 模块的 `/ws/client` 后,认证成功后必须再次发送隧道消息 `register_services`。proxy-server 只向已在本地数据面连接并注册目标服务的 provider 隧道转发请求。
|
|
51
|
-
- **服务列表生命周期**:Gateway 控制面服务列表绑定 Gateway 长连接;proxy-server 数据面服务列表绑定 proxy-server 隧道连接。连接断开后对应服务列表必须清理。
|
|
52
|
-
- **一致性要求**:同一 provider AID 的多个实例可以同时在线,但它们注册的服务列表必须一致。这里的一致性以清洗后的服务摘要为准,包括 `service_name`、`service_type`、`visibility` 和非敏感 `metadata`。
|
|
53
|
-
- **粘性路由**:同一 provider AID 的多个实例若提供相同服务,proxy-server 必须对同一访问亲和键保持稳定路由;亲和键可由 requester AID、客户端 IP、provider AID 和服务名组合得到。
|
|
54
|
-
|
|
55
|
-
#### 服务摘要
|
|
56
|
-
|
|
57
|
-
服务摘要不得包含内网 endpoint、token、cookie、私钥、证书等敏感字段。实现必须在 Gateway 控制面和 proxy-server 数据面分别清洗摘要,不能依赖共享代码。
|
|
58
|
-
|
|
59
|
-
```json
|
|
60
|
-
{
|
|
61
|
-
"service_name": "fileshare",
|
|
62
|
-
"service_type": "http",
|
|
63
|
-
"visibility": "public",
|
|
64
|
-
"metadata": {"label": "Files"}
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
| 字段 | 必需 | 说明 |
|
|
69
|
-
|------|:----:|------|
|
|
70
|
-
| `service_name` | ✅ | 服务名,只允许小写字母、数字、`_`、`-`;不得使用 `api`、`health`、`proxy`、`ws` 等保留名 |
|
|
71
|
-
| `service_type` | ❌ | 服务类型,默认 `http`;可用于提示 `http` / `sse` / `websocket` / `mcp` / `file` 等 |
|
|
72
|
-
| `visibility` | ❌ | 访问策略,默认 `private`;当前实现支持 `public`、`private`、`aun-auth` |
|
|
73
|
-
| `metadata` | ❌ | 非敏感元数据;实现必须过滤 endpoint、url、token、authorization、cookie、secret、private_key、cert 等敏感键 |
|
|
74
|
-
|
|
75
|
-
#### `proxy.register_services`
|
|
76
|
-
|
|
77
|
-
注册当前 Gateway 长连接提供的 Service Proxy 服务列表。服务端必须以连接认证得到的 AID 作为 provider AID;客户端传入的 `provider_aid` 只能作为兼容字段或诊断字段,不能覆盖认证身份。
|
|
78
|
-
|
|
79
|
-
**请求**:
|
|
80
|
-
```json
|
|
81
|
-
{
|
|
82
|
-
"jsonrpc": "2.0",
|
|
83
|
-
"id": "reg-1",
|
|
84
|
-
"method": "proxy.register_services",
|
|
85
|
-
"params": {
|
|
86
|
-
"provider_aid": "alice.agentid.pub",
|
|
87
|
-
"services": [{
|
|
88
|
-
"service_name": "fileshare",
|
|
89
|
-
"service_type": "http",
|
|
90
|
-
"visibility": "public",
|
|
91
|
-
"metadata": {"label": "Files"}
|
|
92
|
-
}]
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**响应**:
|
|
98
|
-
```json
|
|
99
|
-
{
|
|
100
|
-
"jsonrpc": "2.0",
|
|
101
|
-
"id": "reg-1",
|
|
102
|
-
"result": {
|
|
103
|
-
"ok": true,
|
|
104
|
-
"provider_aid": "alice.agentid.pub",
|
|
105
|
-
"connection_id": "conn-1",
|
|
106
|
-
"count": 1,
|
|
107
|
-
"services": [{
|
|
108
|
-
"service_name": "fileshare",
|
|
109
|
-
"service_type": "http",
|
|
110
|
-
"visibility": "public",
|
|
111
|
-
"metadata": {"label": "Files"}
|
|
112
|
-
}]
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
#### `proxy.unregister_services`
|
|
118
|
-
|
|
119
|
-
注销当前 Gateway 长连接上的部分或全部 Service Proxy 服务。省略 `service_names` 时注销该连接全部服务。
|
|
120
|
-
|
|
121
|
-
```json
|
|
122
|
-
{
|
|
123
|
-
"jsonrpc": "2.0",
|
|
124
|
-
"id": "unreg-1",
|
|
125
|
-
"method": "proxy.unregister_services",
|
|
126
|
-
"params": {"service_names": ["fileshare"]}
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
响应包含 `removed` 和剩余 `count`。如果同一 provider AID 还有其他连接,部分注销导致服务列表不一致时,服务端应拒绝该操作。
|
|
131
|
-
|
|
132
|
-
#### `proxy.list_services`
|
|
133
|
-
|
|
134
|
-
列出当前 Gateway 长连接已注册的服务摘要。
|
|
135
|
-
|
|
136
|
-
```json
|
|
137
|
-
{
|
|
138
|
-
"jsonrpc": "2.0",
|
|
139
|
-
"id": "list-1",
|
|
140
|
-
"method": "proxy.list_services",
|
|
141
|
-
"params": {}
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
#### 内部查询 `gateway.query_proxy_services`
|
|
146
|
-
|
|
147
|
-
`gateway.query_proxy_services` 是 service_proxy 模块调用 Gateway 的内部模块 RPC,不是普通客户端公开方法。调用方必须是 `service_proxy` 模块。
|
|
148
|
-
|
|
149
|
-
请求参数:
|
|
150
|
-
|
|
151
|
-
| 参数 | 必需 | 说明 |
|
|
152
|
-
|------|:----:|------|
|
|
153
|
-
| `provider_aid` | ✅ | 被访问 provider AID |
|
|
154
|
-
| `service_name` | ❌ | 目标服务名;为空时只查询 provider 在线和服务列表概览 |
|
|
155
|
-
|
|
156
|
-
响应字段:
|
|
157
|
-
|
|
158
|
-
| 字段 | 说明 |
|
|
159
|
-
|------|------|
|
|
160
|
-
| `provider_aid_exists` | Gateway 通过 CA 证书查询确认 provider AID 是否存在;查询失败时为 `null` |
|
|
161
|
-
| `provider_online` | provider 是否存在 Gateway 长连接 |
|
|
162
|
-
| `has_registered_services` | 在线连接中是否已有 proxy 服务列表注册 |
|
|
163
|
-
| `service_registered` | 指定 `service_name` 是否已由在线 provider 注册 |
|
|
164
|
-
| `service_names` | 当前 provider 声明的服务名集合 |
|
|
165
|
-
| `connections` | 已注册服务列表的 Gateway 长连接摘要 |
|
|
166
|
-
| `matched_connections` | 注册了指定服务的 Gateway 长连接摘要 |
|
|
167
|
-
|
|
168
|
-
#### proxy-server well-known 发现
|
|
169
|
-
|
|
170
|
-
proxy-client 不得由应用外部传入、配置或硬拼 proxy-server 地址。连接 proxy-server 前必须先执行发现:
|
|
171
|
-
|
|
172
|
-
1. 优先请求 `https://{provider_aid}/.well-known/aun-proxy`。
|
|
173
|
-
2. 请求失败时回退 `https://proxy.{issuer}/.well-known/aun-proxy`。
|
|
174
|
-
3. 发现结果可缓存到 provider AID 本地 SQLite metadata,缓存 TTL 为 1 小时。
|
|
175
|
-
|
|
176
|
-
响应示例:
|
|
177
|
-
|
|
178
|
-
```json
|
|
179
|
-
{
|
|
180
|
-
"issuer": "agentid.pub",
|
|
181
|
-
"provider_aid": "alice.agentid.pub",
|
|
182
|
-
"proxy_host": "proxy.agentid.pub",
|
|
183
|
-
"https_url": "https://proxy.agentid.pub:19890",
|
|
184
|
-
"ws_url": "wss://proxy.agentid.pub:19890/ws/client",
|
|
185
|
-
"proxy_servers": [{
|
|
186
|
-
"https_url": "https://proxy.agentid.pub:19890",
|
|
187
|
-
"ws_url": "wss://proxy.agentid.pub:19890/ws/client",
|
|
188
|
-
"priority": 1
|
|
189
|
-
}]
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
proxy-client 连接 `ws_url` 时必须带 `Authorization: Bearer <access_token>`。`access_token` 优先复用本地 cached token;缓存缺失或过期时,必须通过 AUNClient 向 Gateway 完成两步登录取得新 token。
|
|
194
|
-
|
|
195
|
-
#### proxy-server 隧道注册
|
|
196
|
-
|
|
197
|
-
service-proxy-client 连接 `service_proxy` 模块的 `/ws/client` 后,认证成功后必须发送:
|
|
198
|
-
|
|
199
|
-
```json
|
|
200
|
-
{
|
|
201
|
-
"type": "register_services",
|
|
202
|
-
"request_id": "reg-1",
|
|
203
|
-
"services": [{
|
|
204
|
-
"service_name": "fileshare",
|
|
205
|
-
"service_type": "http",
|
|
206
|
-
"visibility": "public",
|
|
207
|
-
"metadata": {"label": "Files"}
|
|
208
|
-
}]
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
成功响应:
|
|
213
|
-
|
|
214
|
-
```json
|
|
215
|
-
{"type": "register_services_ack", "request_id": "reg-1", "ok": true, "count": 1}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
若同一 provider AID 的另一条 proxy-server 隧道已注册不同服务列表,proxy-server 必须返回:
|
|
219
|
-
|
|
220
|
-
```json
|
|
221
|
-
{
|
|
222
|
-
"type": "service_proxy_error",
|
|
223
|
-
"request_id": "reg-1",
|
|
224
|
-
"error": {
|
|
225
|
-
"code": "proxy_services_inconsistent",
|
|
226
|
-
"message": "provider service list is inconsistent with existing connections"
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
#### 路由与 wakeup 策略
|
|
232
|
-
|
|
233
|
-
proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等价路由时,必须按以下顺序决策:
|
|
234
|
-
|
|
235
|
-
1. 本地 proxy-server 连接索引中存在 `(provider_aid, service_name)`:直接选择对应数据面连接;多连接时按亲和键稳定选择。
|
|
236
|
-
2. provider 已连接本 proxy-server 且已注册服务列表,但没有目标服务:返回 `service_not_registered`,不得 wakeup。
|
|
237
|
-
3. provider 未连接本 proxy-server 时,查询 Gateway 控制面:
|
|
238
|
-
- `provider_aid_exists=false`:返回 `provider_aid_not_found`。
|
|
239
|
-
- `provider_aid_exists=null`:返回 `provider_aid_check_failed`。
|
|
240
|
-
- `provider_online=false`:返回 `provider_offline`。
|
|
241
|
-
- `provider_online=true` 且 `service_registered=false`:返回 `service_not_registered`,不得 wakeup。
|
|
242
|
-
- `provider_online=true` 且 `service_registered=true`:通过 Gateway 向注册了目标服务的 provider 长连接发送 `app.service_proxy.wakeup`。
|
|
243
|
-
4. wakeup 已投递但本 proxy-server 仍未等到目标服务注册时,返回 `provider_wakeup_timeout`。
|
|
244
|
-
|
|
245
|
-
---
|
|
246
|
-
|
|
247
|
-
### 6.3 点对点消息 `message.*`
|
|
39
|
+
**应用层扩展服务**本身也是 AID 持有者,通过核心协议(`message.*`)与客户端通信。客户端可以选择使用或不使用这些扩展服务。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
### 6.2 Service Proxy 服务列表控制面 `proxy.*`
|
|
44
|
+
|
|
45
|
+
`proxy.*` 是 AUN Service Proxy 的控制面命名空间,用于 provider 通过 Gateway 长连接声明自己能够通过 Service Proxy 暴露哪些服务。它不承载 HTTP/WS 数据面流量;真实访问数据面由 `service_proxy` 模块的独立 proxy-server 隧道处理。
|
|
46
|
+
|
|
47
|
+
#### 控制面与数据面
|
|
48
|
+
|
|
49
|
+
- **Gateway 控制面**:provider 的 AUN 长连接调用 `proxy.register_services` / `proxy.unregister_services` / `proxy.list_services`。Gateway 记录每个 provider 长连接声明的服务摘要,供 `service_proxy` 模块判断 provider 是否在线、是否声明目标服务。
|
|
50
|
+
- **proxy-server 数据面**:service-proxy-client 连接 `service_proxy` 模块的 `/ws/client` 后,认证成功后必须再次发送隧道消息 `register_services`。proxy-server 只向已在本地数据面连接并注册目标服务的 provider 隧道转发请求。
|
|
51
|
+
- **服务列表生命周期**:Gateway 控制面服务列表绑定 Gateway 长连接;proxy-server 数据面服务列表绑定 proxy-server 隧道连接。连接断开后对应服务列表必须清理。
|
|
52
|
+
- **一致性要求**:同一 provider AID 的多个实例可以同时在线,但它们注册的服务列表必须一致。这里的一致性以清洗后的服务摘要为准,包括 `service_name`、`service_type`、`visibility` 和非敏感 `metadata`。
|
|
53
|
+
- **粘性路由**:同一 provider AID 的多个实例若提供相同服务,proxy-server 必须对同一访问亲和键保持稳定路由;亲和键可由 requester AID、客户端 IP、provider AID 和服务名组合得到。
|
|
54
|
+
|
|
55
|
+
#### 服务摘要
|
|
56
|
+
|
|
57
|
+
服务摘要不得包含内网 endpoint、token、cookie、私钥、证书等敏感字段。实现必须在 Gateway 控制面和 proxy-server 数据面分别清洗摘要,不能依赖共享代码。
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"service_name": "fileshare",
|
|
62
|
+
"service_type": "http",
|
|
63
|
+
"visibility": "public",
|
|
64
|
+
"metadata": {"label": "Files"}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| 字段 | 必需 | 说明 |
|
|
69
|
+
|------|:----:|------|
|
|
70
|
+
| `service_name` | ✅ | 服务名,只允许小写字母、数字、`_`、`-`;不得使用 `api`、`health`、`proxy`、`ws` 等保留名 |
|
|
71
|
+
| `service_type` | ❌ | 服务类型,默认 `http`;可用于提示 `http` / `sse` / `websocket` / `mcp` / `file` 等 |
|
|
72
|
+
| `visibility` | ❌ | 访问策略,默认 `private`;当前实现支持 `public`、`private`、`aun-auth` |
|
|
73
|
+
| `metadata` | ❌ | 非敏感元数据;实现必须过滤 endpoint、url、token、authorization、cookie、secret、private_key、cert 等敏感键 |
|
|
74
|
+
|
|
75
|
+
#### `proxy.register_services`
|
|
76
|
+
|
|
77
|
+
注册当前 Gateway 长连接提供的 Service Proxy 服务列表。服务端必须以连接认证得到的 AID 作为 provider AID;客户端传入的 `provider_aid` 只能作为兼容字段或诊断字段,不能覆盖认证身份。
|
|
78
|
+
|
|
79
|
+
**请求**:
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"jsonrpc": "2.0",
|
|
83
|
+
"id": "reg-1",
|
|
84
|
+
"method": "proxy.register_services",
|
|
85
|
+
"params": {
|
|
86
|
+
"provider_aid": "alice.agentid.pub",
|
|
87
|
+
"services": [{
|
|
88
|
+
"service_name": "fileshare",
|
|
89
|
+
"service_type": "http",
|
|
90
|
+
"visibility": "public",
|
|
91
|
+
"metadata": {"label": "Files"}
|
|
92
|
+
}]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**响应**:
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"jsonrpc": "2.0",
|
|
101
|
+
"id": "reg-1",
|
|
102
|
+
"result": {
|
|
103
|
+
"ok": true,
|
|
104
|
+
"provider_aid": "alice.agentid.pub",
|
|
105
|
+
"connection_id": "conn-1",
|
|
106
|
+
"count": 1,
|
|
107
|
+
"services": [{
|
|
108
|
+
"service_name": "fileshare",
|
|
109
|
+
"service_type": "http",
|
|
110
|
+
"visibility": "public",
|
|
111
|
+
"metadata": {"label": "Files"}
|
|
112
|
+
}]
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `proxy.unregister_services`
|
|
118
|
+
|
|
119
|
+
注销当前 Gateway 长连接上的部分或全部 Service Proxy 服务。省略 `service_names` 时注销该连接全部服务。
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"jsonrpc": "2.0",
|
|
124
|
+
"id": "unreg-1",
|
|
125
|
+
"method": "proxy.unregister_services",
|
|
126
|
+
"params": {"service_names": ["fileshare"]}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
响应包含 `removed` 和剩余 `count`。如果同一 provider AID 还有其他连接,部分注销导致服务列表不一致时,服务端应拒绝该操作。
|
|
131
|
+
|
|
132
|
+
#### `proxy.list_services`
|
|
133
|
+
|
|
134
|
+
列出当前 Gateway 长连接已注册的服务摘要。
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"jsonrpc": "2.0",
|
|
139
|
+
"id": "list-1",
|
|
140
|
+
"method": "proxy.list_services",
|
|
141
|
+
"params": {}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### 内部查询 `gateway.query_proxy_services`
|
|
146
|
+
|
|
147
|
+
`gateway.query_proxy_services` 是 service_proxy 模块调用 Gateway 的内部模块 RPC,不是普通客户端公开方法。调用方必须是 `service_proxy` 模块。
|
|
148
|
+
|
|
149
|
+
请求参数:
|
|
150
|
+
|
|
151
|
+
| 参数 | 必需 | 说明 |
|
|
152
|
+
|------|:----:|------|
|
|
153
|
+
| `provider_aid` | ✅ | 被访问 provider AID |
|
|
154
|
+
| `service_name` | ❌ | 目标服务名;为空时只查询 provider 在线和服务列表概览 |
|
|
155
|
+
|
|
156
|
+
响应字段:
|
|
157
|
+
|
|
158
|
+
| 字段 | 说明 |
|
|
159
|
+
|------|------|
|
|
160
|
+
| `provider_aid_exists` | Gateway 通过 CA 证书查询确认 provider AID 是否存在;查询失败时为 `null` |
|
|
161
|
+
| `provider_online` | provider 是否存在 Gateway 长连接 |
|
|
162
|
+
| `has_registered_services` | 在线连接中是否已有 proxy 服务列表注册 |
|
|
163
|
+
| `service_registered` | 指定 `service_name` 是否已由在线 provider 注册 |
|
|
164
|
+
| `service_names` | 当前 provider 声明的服务名集合 |
|
|
165
|
+
| `connections` | 已注册服务列表的 Gateway 长连接摘要 |
|
|
166
|
+
| `matched_connections` | 注册了指定服务的 Gateway 长连接摘要 |
|
|
167
|
+
|
|
168
|
+
#### proxy-server well-known 发现
|
|
169
|
+
|
|
170
|
+
proxy-client 不得由应用外部传入、配置或硬拼 proxy-server 地址。连接 proxy-server 前必须先执行发现:
|
|
171
|
+
|
|
172
|
+
1. 优先请求 `https://{provider_aid}/.well-known/aun-proxy`。
|
|
173
|
+
2. 请求失败时回退 `https://proxy.{issuer}/.well-known/aun-proxy`。
|
|
174
|
+
3. 发现结果可缓存到 provider AID 本地 SQLite metadata,缓存 TTL 为 1 小时。
|
|
175
|
+
|
|
176
|
+
响应示例:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"issuer": "agentid.pub",
|
|
181
|
+
"provider_aid": "alice.agentid.pub",
|
|
182
|
+
"proxy_host": "proxy.agentid.pub",
|
|
183
|
+
"https_url": "https://proxy.agentid.pub:19890",
|
|
184
|
+
"ws_url": "wss://proxy.agentid.pub:19890/ws/client",
|
|
185
|
+
"proxy_servers": [{
|
|
186
|
+
"https_url": "https://proxy.agentid.pub:19890",
|
|
187
|
+
"ws_url": "wss://proxy.agentid.pub:19890/ws/client",
|
|
188
|
+
"priority": 1
|
|
189
|
+
}]
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
proxy-client 连接 `ws_url` 时必须带 `Authorization: Bearer <access_token>`。`access_token` 优先复用本地 cached token;缓存缺失或过期时,必须通过 AUNClient 向 Gateway 完成两步登录取得新 token。
|
|
194
|
+
|
|
195
|
+
#### proxy-server 隧道注册
|
|
196
|
+
|
|
197
|
+
service-proxy-client 连接 `service_proxy` 模块的 `/ws/client` 后,认证成功后必须发送:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"type": "register_services",
|
|
202
|
+
"request_id": "reg-1",
|
|
203
|
+
"services": [{
|
|
204
|
+
"service_name": "fileshare",
|
|
205
|
+
"service_type": "http",
|
|
206
|
+
"visibility": "public",
|
|
207
|
+
"metadata": {"label": "Files"}
|
|
208
|
+
}]
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
成功响应:
|
|
213
|
+
|
|
214
|
+
```json
|
|
215
|
+
{"type": "register_services_ack", "request_id": "reg-1", "ok": true, "count": 1}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
若同一 provider AID 的另一条 proxy-server 隧道已注册不同服务列表,proxy-server 必须返回:
|
|
219
|
+
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"type": "service_proxy_error",
|
|
223
|
+
"request_id": "reg-1",
|
|
224
|
+
"error": {
|
|
225
|
+
"code": "proxy_services_inconsistent",
|
|
226
|
+
"message": "provider service list is inconsistent with existing connections"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### 路由与 wakeup 策略
|
|
232
|
+
|
|
233
|
+
proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等价路由时,必须按以下顺序决策:
|
|
234
|
+
|
|
235
|
+
1. 本地 proxy-server 连接索引中存在 `(provider_aid, service_name)`:直接选择对应数据面连接;多连接时按亲和键稳定选择。
|
|
236
|
+
2. provider 已连接本 proxy-server 且已注册服务列表,但没有目标服务:返回 `service_not_registered`,不得 wakeup。
|
|
237
|
+
3. provider 未连接本 proxy-server 时,查询 Gateway 控制面:
|
|
238
|
+
- `provider_aid_exists=false`:返回 `provider_aid_not_found`。
|
|
239
|
+
- `provider_aid_exists=null`:返回 `provider_aid_check_failed`。
|
|
240
|
+
- `provider_online=false`:返回 `provider_offline`。
|
|
241
|
+
- `provider_online=true` 且 `service_registered=false`:返回 `service_not_registered`,不得 wakeup。
|
|
242
|
+
- `provider_online=true` 且 `service_registered=true`:通过 Gateway 向注册了目标服务的 provider 长连接发送 `app.service_proxy.wakeup`。
|
|
243
|
+
4. wakeup 已投递但本 proxy-server 仍未等到目标服务注册时,返回 `provider_wakeup_timeout`。
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
### 6.3 点对点消息 `message.*`
|
|
248
248
|
|
|
249
249
|
**设计原则**:
|
|
250
250
|
|
|
@@ -261,12 +261,16 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
261
261
|
| `queue` | 单实例实时消费 | 内存环形缓冲 | 有限时间窗口(默认 5 分钟)+ 有限条数(默认 200 条/AID) | Worker/执行器消费、同一发送者尽量命中同一实例 |
|
|
262
262
|
| `fanout` | 广播到在线实例 | 数据库 + 文件存储 | TTL 过期前持久保存(默认 24 小时) | 离线送达、历史查询、多实例同步接收 |
|
|
263
263
|
|
|
264
|
-
**序列号机制**:
|
|
265
|
-
|
|
266
|
-
- `ttl <= 0` 的现有消息在收件人维度分配递增 `seq`
|
|
267
|
-
- `ttl > 0` 的 volatile 消息不分配持久 `seq`,使用独立 opaque `volatile_cursor`
|
|
268
|
-
- 客户端通过 `after_seq` 游标增量拉取,支持多设备各自维护进度
|
|
269
|
-
- `message.pull` 分别读取持久流与 volatile 流,并按服务端创建时间稳定合并
|
|
264
|
+
**序列号机制**:
|
|
265
|
+
|
|
266
|
+
- `ttl <= 0` 的现有消息在收件人维度分配递增 `seq`
|
|
267
|
+
- `ttl > 0` 的 volatile 消息不分配持久 `seq`,使用独立 opaque `volatile_cursor`
|
|
268
|
+
- 客户端通过 `after_seq` 游标增量拉取,支持多设备各自维护进度
|
|
269
|
+
- `message.pull` 分别读取持久流与 volatile 流,并按服务端创建时间稳定合并
|
|
270
|
+
|
|
271
|
+
**按对端隔离消费(`p2p_peer_pull_v1`)**:新 SDK 在 `auth.connect.capabilities` 中声明严格布尔值 `p2p_peer_pull_v1: true`。Gateway 将连接能力作为可信认证上下文传给 Message 服务,并在上线、重连后发送待同步提示;能力不由发送消息时的在线状态决定。旧 SDK 继续使用 global Pull/ACK。新 SDK 使用 `cursor_scope="peer"` 与完整 `sender_aid`,按接收方 AID、认证设备、内部消费 slot 和发送方隔离游标;原设备共享 `seq`、消息密文及群组 Pull/ACK 模型保持不变,不分配 `peer_seq`,不逐条回填历史。
|
|
272
|
+
|
|
273
|
+
首次进入 peer 模式时,服务端原子冻结同设备、同 slot 的旧 `server_acked_seq` 为 `bootstrap_floor_seq`;无旧记录为 0,已有 peer ACK 优先。每个新 peer 从该固定基线初始化,不能用后来变化的旧 global ACK 跳过历史。peer ACK 不推进旧 global ACK;同一设备降级到旧 SDK 可能重拉,应用必须幂等。当前 peer 模式只支持单 Message 服务实例,单实例内可有多个 writer shard;多实例支持留待 AUN 分布式 2.0。
|
|
270
274
|
|
|
271
275
|
#### `message.send`
|
|
272
276
|
|
|
@@ -278,11 +282,11 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
278
282
|
"jsonrpc": "2.0",
|
|
279
283
|
"id": 10,
|
|
280
284
|
"method": "message.send",
|
|
281
|
-
"params": {
|
|
282
|
-
"to": "bob.aid.pub",
|
|
283
|
-
"device_id": "bob-phone",
|
|
284
|
-
"ttl": 300,
|
|
285
|
-
"payload": {"type": "text", "text": "你好"}
|
|
285
|
+
"params": {
|
|
286
|
+
"to": "bob.aid.pub",
|
|
287
|
+
"device_id": "bob-phone",
|
|
288
|
+
"ttl": 300,
|
|
289
|
+
"payload": {"type": "text", "text": "你好"}
|
|
286
290
|
}
|
|
287
291
|
}
|
|
288
292
|
```
|
|
@@ -291,14 +295,15 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
291
295
|
|
|
292
296
|
| 参数 | 必需 | 说明 |
|
|
293
297
|
|------|:----:|------|
|
|
294
|
-
| `to` | ✅ | 接收者 AID |
|
|
295
|
-
| `device_id` | ❌ | 目标接收设备;指定后只投递该设备,不会降级为 AID 全设备投递 |
|
|
296
|
-
| `to_device_id` | ❌ | `device_id` 的兼容别名 |
|
|
297
|
-
| `ttl` | ❌ | 秒;缺省或 `<=0` 持久化,正数钳制到 1–3600 秒并进入 volatile 内存通道 |
|
|
298
|
-
| `payload` | ✅ | 消息载荷,对协议层透明,由应用层定义 |
|
|
298
|
+
| `to` | ✅ | 接收者 AID |
|
|
299
|
+
| `device_id` | ❌ | 目标接收设备;指定后只投递该设备,不会降级为 AID 全设备投递 |
|
|
300
|
+
| `to_device_id` | ❌ | `device_id` 的兼容别名 |
|
|
301
|
+
| `ttl` | ❌ | 秒;缺省或 `<=0` 持久化,正数钳制到 1–3600 秒并进入 volatile 内存通道 |
|
|
302
|
+
| `payload` | ✅ | 消息载荷,对协议层透明,由应用层定义 |
|
|
299
303
|
| `type` | ❌ | 信封/封装类型,普通业务消息无需填写;SDK 加密发送时自动使用 `e2ee.encrypted` |
|
|
300
304
|
| `encrypted` | ❌ | E2EE 标记(默认 `false`) |
|
|
301
|
-
| `message_id` | ❌ |
|
|
305
|
+
| `message_id` | ❌ | 持久 P2P 的逻辑消息幂等键;新消息使用新的唯一 ID,重试复用原 ID,sender 隔离不扩大复用范围;客户端提供或服务端生成 UUID。volatile 保留原 sender+ID 隔离 |
|
|
306
|
+
| `need_render` | ❌ | 布尔值,默认 `true`;表示消息是否需要应用渲染,不改变拉取顺序或 ACK 规则 |
|
|
302
307
|
| `timestamp` | ❌ | 客户端时间戳(毫秒),服务端忽略此字段,始终使用服务端时间 |
|
|
303
308
|
|
|
304
309
|
**响应**:
|
|
@@ -313,10 +318,12 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
313
318
|
"status": "sent",
|
|
314
319
|
"delivery_mode": "queue"
|
|
315
320
|
}
|
|
316
|
-
}
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
正 TTL 消息不写数据库或 WAL、不分配持久 `seq`,响应包含 `storage="volatile"`、`volatile_cursor`(多设备时可含 `volatile_cursors`)、`created_at`、`expires_at` 和 `status="accepted"`。`delivery_mode` 继续控制在线投递方式,不改变 TTL 存储语义。跨域只传递剩余 TTL,目标域不得重新应用 1 秒下限。
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
正 TTL 消息不写数据库或 WAL、不分配持久 `seq`,响应包含 `storage="volatile"`、`volatile_cursor`(多设备时可含 `volatile_cursors`)、`created_at`、`expires_at` 和 `status="accepted"`。`delivery_mode` 继续控制在线投递方式,不改变 TTL 存储语义。跨域只传递剩余 TTL,目标域不得重新应用 1 秒下限。
|
|
325
|
+
|
|
326
|
+
`need_render` 同样适用于 `group.send`。SDK 提取后放入明文信封,接收端同时可读取消息顶层该字段;历史缺字段或数据库 NULL 按 `true`。它不进入 E2EE AAD、`protected_headers`、消息保护签名或元数据 HMAC;RPC `client_signature` 仍按既有业务参数签名规则覆盖该参数,不新增 canonical 排除项。
|
|
320
327
|
|
|
321
328
|
##### Payload 参考约定
|
|
322
329
|
|
|
@@ -366,9 +373,27 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
366
373
|
- 旧通道在 `peer.switch` 完成前 **MUST** 保持可用
|
|
367
374
|
- 升级失败或超时时双方 **MUST** 回退到原通道
|
|
368
375
|
|
|
376
|
+
#### `message.peers`
|
|
377
|
+
|
|
378
|
+
返回当前认证设备、消费 slot 的消息对端目录,不是联系人服务。要求连接已声明 `p2p_peer_pull_v1: true`。
|
|
379
|
+
|
|
380
|
+
| 参数 | 必需 | 说明 |
|
|
381
|
+
|------|:----:|------|
|
|
382
|
+
| `filter` | ❌ | 默认 `pending`;只返回有持久待拉取消息或可用 volatile 消息的对端。`all` 返回仍有消息状态的全部对端 |
|
|
383
|
+
| `limit` | ❌ | 仅 `all` 可用,默认 100,范围 1–200 |
|
|
384
|
+
| `page_token` | ❌ | 仅 `all` 可用,复用响应的 `next_page_token` |
|
|
385
|
+
|
|
386
|
+
`pending` 一次完整返回,不分页、不截断到 200 个 peer,传入分页参数会拒绝。响应包含 `cursor_scope="peer"`、`receiver_aid`、`device_id`、固定的 `bootstrap_floor_seq`、`catalog_ready`、`catalog_revision` 和 `peers`;`all` 另含 `has_more`、`next_page_token`。`catalog_ready=false` 表示目录尚未覆盖可靠读取边界,不能把其空列表当作已同步完成,SDK 保留后台重试。
|
|
387
|
+
|
|
388
|
+
每个 peer 包含 `sender_aid`、`head_seq`、`server_ack_seq`、`initial_after_seq`、`initialization_source`、`retention_floor_seq`、`earliest_available_seq` 和 `volatile_has_more`。正常 `pending` 直接从同一游标表的 peer A/H 筛选持久候选:内部 `peer_H>A` 且 `peer_H>R`,再合并可用 volatile sender;不扫描消息积压、不逐 peer seek,也不执行 COUNT/SUM。候选可以保守偏大,完成仍由 Forward 覆盖证明及 ACK 确认;不返回每 peer 或整体的 `pending_count`、`need_render_pending_count`、`non_render_pending_count` 三项精确计数。
|
|
389
|
+
|
|
390
|
+
`peers[].next_pending_seq` 是可选排序近似;正常 `pending` 的持久候选直接返回该 peer 的 `server_ack_seq`(A),包含 0,`all` 或 volatile-only 允许省略。它不是首条未确认投递的真实 seq,无需额外查询或 SQL 往返;仅用于 SDK 调度,不是覆盖证明、可提交游标或完成依据,不能由它推进 A/H,也不能用 `covered_through_seq+1` 推导下一提示。公共 S 不用于抬高某个 peer 的 Forward 扫描起点,仍按该 peer ACK 与永久保留边界校验。
|
|
391
|
+
|
|
392
|
+
响应顶层可选 `pending_count_estimate=max(0,H-max(R,S_used))`:H 是当前设备已知可靠 Head,R 是已证明永久不可取得的前缀,S_used 是当前消费 slot 的有效公共安全前缀;S 缺失或 S>H 时按 0 使用,H 未知时省略字段。它是整体持久 seq 跨度上界,可含空号及 S 后已 ACK 的消息,不含 volatile,不是精确条数、未读数或 all 单页数量。SDK 仅透传给应用,不能缺省填 0、对 peer 求和或据此调度/推进游标/判断同步完成。volatile-only peer 在估计为 0 或缺省时仍须返回与同步。
|
|
393
|
+
|
|
369
394
|
#### `message.pull`
|
|
370
395
|
|
|
371
|
-
|
|
396
|
+
按持久和 volatile 两个独立游标拉取消息。以下请求/响应示例表示旧 global 路径;peer 路径增加 `cursor_scope="peer"`、`sender_aid`,持久页默认及最大 200 条,volatile 游标同样按 peer 隔离。
|
|
372
397
|
|
|
373
398
|
**请求**:
|
|
374
399
|
```json
|
|
@@ -376,11 +401,11 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
376
401
|
"jsonrpc": "2.0",
|
|
377
402
|
"id": 11,
|
|
378
403
|
"method": "message.pull",
|
|
379
|
-
"params": {
|
|
380
|
-
"after_seq": 0,
|
|
381
|
-
"after_volatile_cursor": "v1:i1:7:20",
|
|
382
|
-
"limit": 50,
|
|
383
|
-
"device_id": "device-001"
|
|
404
|
+
"params": {
|
|
405
|
+
"after_seq": 0,
|
|
406
|
+
"after_volatile_cursor": "v1:i1:7:20",
|
|
407
|
+
"limit": 50,
|
|
408
|
+
"device_id": "device-001"
|
|
384
409
|
}
|
|
385
410
|
}
|
|
386
411
|
```
|
|
@@ -389,11 +414,19 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
389
414
|
|
|
390
415
|
| 参数 | 必需 | 说明 |
|
|
391
416
|
|------|:----:|------|
|
|
392
|
-
| `after_seq` | ❌ | 起始序列号(默认 0),返回 `seq > after_seq` 的消息 |
|
|
393
|
-
| `after_volatile_cursor` | ❌ | opaque volatile 游标;四个 SDK 自动维护,应用通常无需传入 |
|
|
394
|
-
| `limit` | ❌ | 单次返回上限(默认 50,最大 50) |
|
|
395
|
-
| `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
|
|
396
|
-
| `window_mode` | ❌ | 可选 Pull 模式;`tail` 表示读取以安全 Head 结尾的最新一页 |
|
|
417
|
+
| `after_seq` | ❌ | 起始序列号(默认 0),返回 `seq > after_seq` 的消息 |
|
|
418
|
+
| `after_volatile_cursor` | ❌ | opaque volatile 游标;四个 SDK 自动维护,应用通常无需传入 |
|
|
419
|
+
| `limit` | ❌ | 单次返回上限(默认 50,最大 50) |
|
|
420
|
+
| `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
|
|
421
|
+
| `window_mode` | ❌ | 可选 Pull 模式;`tail` 表示读取以安全 Head 结尾的最新一页 |
|
|
422
|
+
| `cursor_scope` | ❌ | 旧请求缺省 `global`;新 SDK 使用 `peer`,须有连接能力声明 |
|
|
423
|
+
| `sender_aid` | peer 必需 | 完整发送方 AID,只返回该对端消息;global 请求不得携带此字段 |
|
|
424
|
+
|
|
425
|
+
peer Forward 响应另含 `cursor_scope`、`sender_aid`、`scan_after_seq`、`covered_through_seq`、`next_after_seq`、`head_seq`、`server_ack_seq`、`persistent_has_more`、`volatile_has_more`、`has_more`、可选 `next_pending_seq`、`page_need_render_count` 和 `page_non_render_count`。固定可靠 Head 后,扫描 `(scan_after_seq, covered_through_seq]`,下一页使用 `next_after_seq=covered_through_seq`;原 seq 在不同 sender 之间共享,peer 页可稀疏,不能由相邻数字或返回条数推断缺消息。三个 `has_more` 必须为布尔值,且 `has_more = persistent_has_more OR volatile_has_more`。`count` 与两类页内数量按最终返回消息在内存计算,包含本页 volatile,不扫描全部积压;计数不改变扫描范围,不优先过滤可渲染消息。
|
|
426
|
+
|
|
427
|
+
`next_pending_seq` 是 peer Forward(含 force)的可选调度提示:`persistent_has_more=true` 时,返回本页最终边界之后首条未返回持久投递的原 seq,满足 `covered_through_seq < seq <= head_seq`;无持久更多时省略,only-volatile 仍按 `volatile_has_more` 继续。它直接复用原 `limit+1` 查询和去重合并结果:200 条页取第 201 条,字节截断取第一条未返回持久消息,volatile 混排挤掉持久消息时修正为最终第一条未返回持久 seq,不新增 SQL。Tail/History/旧 global 不增加此字段。正常 Forward 在消息页可靠 commit 后即可将页提示用于排序,不等待 ACK;仅收到响应或 commit 失败不能采用,ACK 未完成或失败保留独立确认责任,拒绝旧/迟到页回退;Tail/force/History 不更新正常调度。非法或缺失的可选提示不使合法消息页失败,不能用 `covered_through_seq+1` 推导,也不参与覆盖、ACK 或完成判断。
|
|
428
|
+
|
|
429
|
+
`server_ack_seq` 只可用于首次 peer 初始化,运行中的 SDK 不得据此跳过本地未交付区间;合法 `retention_floor_seq` 才能解释已经永久不可取得的前缀。peer 内解密或应用交付未完成时,不得仅凭扫描覆盖证明推进 A/ACK。
|
|
397
430
|
|
|
398
431
|
**响应**:
|
|
399
432
|
```json
|
|
@@ -424,69 +457,70 @@ proxy-server 处理 `https://proxy.{issuer}/{user_name}/{svc_name}/...` 或等
|
|
|
424
457
|
|------|------|------|
|
|
425
458
|
| `messages` | array | 消息列表(临时 + 持久化合并,按 `seq` 排序) |
|
|
426
459
|
| `count` | integer | 本次返回的消息条数 |
|
|
427
|
-
| `latest_seq` | integer | 本次返回的最大 `seq` |
|
|
428
|
-
| `latest_volatile_cursor` | string\|null | 本页最后一个 volatile 游标;不改变 `latest_seq` |
|
|
429
|
-
| `volatile_has_more` | boolean | 是否仍有未返回的 volatile 消息;SDK 在 volatile 游标前进时据此继续分页 |
|
|
430
|
-
| `volatile_earliest_cursor` | string\|null | 当前 boot epoch 内仍可读取的最早 volatile 游标 |
|
|
431
|
-
| `volatile_dropped_count` | integer | 当前 boot epoch 内因过期或容量淘汰而不可读的累计数 |
|
|
460
|
+
| `latest_seq` | integer | 本次返回的最大 `seq` |
|
|
461
|
+
| `latest_volatile_cursor` | string\|null | 本页最后一个 volatile 游标;不改变 `latest_seq` |
|
|
462
|
+
| `volatile_has_more` | boolean | 是否仍有未返回的 volatile 消息;SDK 在 volatile 游标前进时据此继续分页 |
|
|
463
|
+
| `volatile_earliest_cursor` | string\|null | 当前 boot epoch 内仍可读取的最早 volatile 游标 |
|
|
464
|
+
| `volatile_dropped_count` | integer | 当前 boot epoch 内因过期或容量淘汰而不可读的累计数 |
|
|
432
465
|
| `ephemeral_earliest_available_seq` | integer\|null | 当前临时缓冲中最早可用的 `seq`,`null` 表示无临时消息 |
|
|
433
466
|
| `ephemeral_dropped_count` | integer | 因缓冲淘汰而丢弃的临时消息计数 |
|
|
434
467
|
|
|
435
|
-
> 客户端可通过 `ephemeral_earliest_available_seq` 判断是否有临时消息丢失:若 `after_seq < ephemeral_earliest_available_seq`,说明存在已被淘汰的消息。
|
|
436
|
-
|
|
437
|
-
**说明**:持久游标与 volatile 游标独立推进。SDK 只把含正 `seq` 的消息送入持久 tracker;volatile push/pull 按发送方和 `message_id` 去重,交付成功后自动 ACK。SDK 在传输层注入内部 slot,应用不得传入或读取,任何消息、响应和事件都不得包含该字段。epoch 不匹配时 SDK 清空 volatile 游标并重试一次。`message.history` 不返回 volatile 消息。
|
|
438
|
-
|
|
439
|
-
**Tail 模式**:`window_mode="tail"` 时,服务端固定安全 `head_seq
|
|
440
|
-
|
|
441
|
-
| 字段 | 说明 |
|
|
442
|
-
|------|------|
|
|
443
|
-
| `window_mode` | 固定为 `tail` |
|
|
444
|
-
| `window_start_seq` | 已扫描窗口的包含式左边界 |
|
|
445
|
-
| `head_seq` | 本次请求固定的安全 Head |
|
|
446
|
-
| `covered_through_seq` | 覆盖终点,正常等于 `head_seq` |
|
|
447
|
-
|
|
448
|
-
Tail 不推进 ACK、retention/visibility floor、Pull activity 或 catch-up 状态,不接受 `ack_up_to_seq` 或 `force=true`。seq band
|
|
449
|
-
|
|
450
|
-
#### `message.history`
|
|
451
|
-
|
|
452
|
-
按 `before_seq` 排他上界向前只读翻页,不修改 ACK、cursor、floor 或 Pull activity。
|
|
453
|
-
|
|
454
|
-
**参数**:
|
|
455
|
-
|
|
456
|
-
| 参数 | 必需 | 说明 |
|
|
457
|
-
|------|:----:|------|
|
|
458
|
-
| `before_seq` | ✅ | 正整数排他上界,只返回 `seq < before_seq` 的消息 |
|
|
459
|
-
| `limit` | ❌ | 单页上限(默认 50,最大 50) |
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
| `
|
|
467
|
-
| `
|
|
468
|
-
| `
|
|
469
|
-
| `
|
|
470
|
-
| `
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
468
|
+
> 客户端可通过 `ephemeral_earliest_available_seq` 判断是否有临时消息丢失:若 `after_seq < ephemeral_earliest_available_seq`,说明存在已被淘汰的消息。
|
|
469
|
+
|
|
470
|
+
**说明**:持久游标与 volatile 游标独立推进。SDK 只把含正 `seq` 的消息送入持久 tracker;volatile push/pull 按发送方和 `message_id` 去重,交付成功后自动 ACK。SDK 在传输层注入内部 slot,应用不得传入或读取,任何消息、响应和事件都不得包含该字段。epoch 不匹配时 SDK 清空 volatile 游标并重试一次。`message.history` 不返回 volatile 消息。
|
|
471
|
+
|
|
472
|
+
**Tail 模式**:`window_mode="tail"` 时,服务端固定安全 `head_seq`;global 返回跨度不超过 `limit` 的最新 seq band,peer 按该 sender 最新消息条数取页,seq 跨度可大于 `limit`。额外返回:
|
|
473
|
+
|
|
474
|
+
| 字段 | 说明 |
|
|
475
|
+
|------|------|
|
|
476
|
+
| `window_mode` | 固定为 `tail` |
|
|
477
|
+
| `window_start_seq` | 已扫描窗口的包含式左边界 |
|
|
478
|
+
| `head_seq` | 本次请求固定的安全 Head |
|
|
479
|
+
| `covered_through_seq` | 覆盖终点,正常等于 `head_seq` |
|
|
480
|
+
|
|
481
|
+
Tail 不推进 ACK、retention/visibility floor、Pull activity 或 catch-up 状态,不接受 `ack_up_to_seq` 或 `force=true`。Tail 使用窗口证明,不要求 Forward 的三个 `has_more` 字段。global seq band 内未返回的序号视为服务端永久空号;peer 仅按服务端覆盖证明合并窗口,不能套用 dense seq 校验。新 SDK 仅在已验证自身 `agent.md.type=human` 时自动优先 Tail 再 Forward;其他或未知类型直接 Forward。无 `window_mode` 的旧 global 请求保持原副作用语义。
|
|
482
|
+
|
|
483
|
+
#### `message.history`
|
|
484
|
+
|
|
485
|
+
按 `before_seq` 排他上界向前只读翻页,不修改 ACK、cursor、floor 或 Pull activity。
|
|
486
|
+
|
|
487
|
+
**参数**:
|
|
488
|
+
|
|
489
|
+
| 参数 | 必需 | 说明 |
|
|
490
|
+
|------|:----:|------|
|
|
491
|
+
| `before_seq` | ✅ | 正整数排他上界,只返回 `seq < before_seq` 的消息 |
|
|
492
|
+
| `limit` | ❌ | 单页上限(默认 50,最大 50) |
|
|
493
|
+
| `cursor_scope` / `sender_aid` | peer 必需 | 与 Pull 相同;peer 页默认及最大 200 条,隔离读取该 sender 历史 |
|
|
494
|
+
|
|
495
|
+
**响应字段**:
|
|
496
|
+
|
|
497
|
+
| 字段 | 说明 |
|
|
498
|
+
|------|------|
|
|
499
|
+
| `messages` | 页内按 seq 升序 |
|
|
500
|
+
| `window_start_seq` | 本页最小边界;空页为 `null` |
|
|
501
|
+
| `next_before_seq` | 下一页直接使用的排他上界;无更早消息为 `null` |
|
|
502
|
+
| `has_older` | 是否仍有更早的可见消息 |
|
|
503
|
+
| `retention_floor_seq` | 已实际删除、不可恢复的 seq 下界 |
|
|
504
|
+
| `earliest_available_seq` | 当前最早可拉取边界 |
|
|
505
|
+
|
|
506
|
+
History 不触发实时消息事件。客户端解密 History 结果时不得修改实时 A/T/H 或发送 ACK。
|
|
507
|
+
|
|
508
|
+
**客户端发布语义**:peer 页内按 seq 升序处理;SDK 在当前运行实例内协调并发交付,并以最多 50,000 条的内存成功绑定去重,按接收 AID、设备、消费 slot、事件类别和原正 delivery seq 识别投递,校验 sender 与 `message_id`,不因 namespace 或 Push/Pull/Tail 来源另造身份。消息热路径不逐条读写耐久 receipt,自定义 store 不要求提供 receipt 能力。应用 handler 成功后才完成内存标记,peer 持久消息 Forward 页依据有效 proof 提交页 A/T/H 后发送本页新增累计 ACK;使用持久化 store 时保存页状态。内存淘汰、重建 client、崩溃或版本切换后允许重放,应用须在业务事务中按消息身份持久幂等;多个 client/进程不提供跨实例首次回调原子 claim。跨 peer 不承诺全局回调顺序,显式 History/force/Tail 列表不因内存去重删行;History 不进入实时发布流。
|
|
509
|
+
|
|
510
|
+
#### `message.ack`
|
|
511
|
+
|
|
512
|
+
确认已收到消息。持久 ACK 与 volatile ACK 可以单独提交,也可以在同一请求中提交。
|
|
479
513
|
|
|
480
514
|
**请求**:
|
|
481
515
|
```json
|
|
482
516
|
{
|
|
483
517
|
"jsonrpc": "2.0",
|
|
484
518
|
"id": 12,
|
|
485
|
-
"method": "message.ack",
|
|
486
|
-
"params": {
|
|
487
|
-
"seq": 43,
|
|
488
|
-
"volatile_cursors": ["v1:i1:7:21"],
|
|
489
|
-
"device_id": "device-001"
|
|
519
|
+
"method": "message.ack",
|
|
520
|
+
"params": {
|
|
521
|
+
"seq": 43,
|
|
522
|
+
"volatile_cursors": ["v1:i1:7:21"],
|
|
523
|
+
"device_id": "device-001"
|
|
490
524
|
}
|
|
491
525
|
}
|
|
492
526
|
```
|
|
@@ -495,11 +529,12 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
|
|
|
495
529
|
|
|
496
530
|
| 参数 | 必需 | 说明 |
|
|
497
531
|
|------|:----:|------|
|
|
498
|
-
| `seq` | ❌ | 确认到的持久序列号(含);未提交 volatile ACK 时必填 |
|
|
499
|
-
| `volatile_cursor` | ❌ | 单个 volatile 游标的兼容形式 |
|
|
500
|
-
| `volatile_cursors` | ❌ | 要确认的 volatile 游标数组 |
|
|
501
|
-
| `volatile_ids` | ❌ | 要按 `message_id` 确认的 volatile 消息数组 |
|
|
502
|
-
| `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
|
|
532
|
+
| `seq` | ❌ | 确认到的持久序列号(含);未提交 volatile ACK 时必填 |
|
|
533
|
+
| `volatile_cursor` | ❌ | 单个 volatile 游标的兼容形式 |
|
|
534
|
+
| `volatile_cursors` | ❌ | 要确认的 volatile 游标数组 |
|
|
535
|
+
| `volatile_ids` | ❌ | 要按 `message_id` 确认的 volatile 消息数组 |
|
|
536
|
+
| `device_id` | ❌ | 多实例消费上下文中的设备标识;缺省时使用连接认证上下文 |
|
|
537
|
+
| `cursor_scope` / `sender_aid` | peer 必需 | 按 peer 确认;持久水位使用 `up_to_seq`,兼容 `seq` / `ack_seq` |
|
|
503
538
|
|
|
504
539
|
**响应**:
|
|
505
540
|
```json
|
|
@@ -510,7 +545,9 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
|
|
|
510
545
|
}
|
|
511
546
|
```
|
|
512
547
|
|
|
513
|
-
**说明**:`ack_seq` 仅增不减;volatile 结果通过 `volatile_ack` 返回 `accepted`、`expired` 等幂等计数。服务端内部按消费 slot 隔离 lease,但 slot 不属于对外协议对象。
|
|
548
|
+
**说明**:`ack_seq` 仅增不减;volatile 结果通过 `volatile_ack` 返回 `accepted`、`expired` 等幂等计数。服务端内部按消费 slot 隔离 lease,但 slot 不属于对外协议对象。
|
|
549
|
+
|
|
550
|
+
peer 响应以 `peer_ack_seq` / `effective_ack_seq` 表示该 sender 的确认水位,不能把 `ack_seq` 当作 peer ACK。可选 `legacy_safe_ack_seq` 与 `previous_legacy_safe_ack_seq` 表示当前消费 slot 的公共安全前缀 S 及原值,不写回旧 global ACK。服务端在同一 `message_peer_slot_cursor` 表以真实 sender 行保存 peer ACK Ap、内部 `sender_aid='*'` 行保存同 owner/device/slot 的 S,与 ACK 同 RR 事务原子持久,单调且不得超过可靠 H;`*` 不对外接受或枚举。bootstrap G 独立冻结,不用 S 替代;来源或潜在 legacy 低位迁入不明时不提高 S。本期不新增设备级聚合游标行;缺完整持久设备 slot 名册时 `device_safe_ack_seq` 可省略,SDK 不得由单 peer 或单 slot 的水位推断设备全部旧密钥可销毁。
|
|
514
551
|
|
|
515
552
|
#### `message.recall`
|
|
516
553
|
|
|
@@ -603,9 +640,9 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
|
|
|
603
640
|
{
|
|
604
641
|
"jsonrpc": "2.0",
|
|
605
642
|
"method": "event/message.received",
|
|
606
|
-
"params": {
|
|
607
|
-
"from": "bob.aid.pub",
|
|
608
|
-
"sender_device_id": "bob-phone",
|
|
643
|
+
"params": {
|
|
644
|
+
"from": "bob.aid.pub",
|
|
645
|
+
"sender_device_id": "bob-phone",
|
|
609
646
|
"to": "alice.aid.pub",
|
|
610
647
|
"message_id": "550e8400-...",
|
|
611
648
|
"seq": 42,
|
|
@@ -614,10 +651,12 @@ History 不触发实时消息事件。客户端解密 History 结果时不得修
|
|
|
614
651
|
"delivery_mode": "queue",
|
|
615
652
|
"encrypted": false
|
|
616
653
|
}
|
|
617
|
-
}
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
volatile 事件包含 `storage="volatile"`、`volatile_cursor`、`created_at`、`expires_at`,不含持久 `seq` 或内部 slot。`sender_device_id` 始终表示发送方设备,可用于下一次定向发送。
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
volatile 事件包含 `storage="volatile"`、`volatile_cursor`、`created_at`、`expires_at`,不含持久 `seq` 或内部 slot。`sender_device_id` 始终表示发送方设备,可用于下一次定向发送。
|
|
658
|
+
|
|
659
|
+
peer 连接按接收 AID、设备及 sender 折叠待拉取通知;上线恢复可以只发 `cursor_scope="peer"` 的同步提示,由 SDK 调用完整 pending `message.peers` 后并行拉取,不能把提示的 0 seq 当作消息水位。可信消息元数据可携带 `prev_peer_seq`,表示同接收设备、同 sender 的前一条原 seq;未知时省略,只有可证明为首条才返回 0。若本地 A=103 收到 seq=105,前驱为103时可确认相接,前驱大于103则需要补拉;缺前驱时保守交由 peer Forward 覆盖证明判断,不能仅由105−103认定 Gap。
|
|
621
660
|
|
|
622
661
|
#### `event/message.ack`
|
|
623
662
|
|
|
@@ -628,17 +667,19 @@ volatile 事件包含 `storage="volatile"`、`volatile_cursor`、`created_at`、
|
|
|
628
667
|
"jsonrpc": "2.0",
|
|
629
668
|
"method": "event/message.ack",
|
|
630
669
|
"params": {
|
|
631
|
-
"to": "bob.aid.pub",
|
|
632
|
-
"device_id": "device-001",
|
|
633
|
-
"ack_seq": 43,
|
|
670
|
+
"to": "bob.aid.pub",
|
|
671
|
+
"device_id": "device-001",
|
|
672
|
+
"ack_seq": 43,
|
|
634
673
|
"timestamp": 1709712003
|
|
635
674
|
}
|
|
636
675
|
}
|
|
637
676
|
```
|
|
638
677
|
|
|
639
|
-
- `to`:确认方 AID
|
|
640
|
-
- `device_id`:触发 ack 的设备标识;legacy 客户端为空字符串
|
|
641
|
-
- `ack_seq`:确认到的序列号(含该 seq 及之前的所有消息)
|
|
678
|
+
- `to`:确认方 AID
|
|
679
|
+
- `device_id`:触发 ack 的设备标识;legacy 客户端为空字符串
|
|
680
|
+
- `ack_seq`:确认到的序列号(含该 seq 及之前的所有消息)
|
|
681
|
+
|
|
682
|
+
peer 能力连接收到的 peer ACK 通知使用 `cursor_scope="peer"`、`sender_aid` 和 `peer_ack_seq`,不得用它推进旧 global 游标或其他 peer。旧 ACK 通知不能替代新 SDK 的本地交付证明;投递 ACK 不表示应用业务已读。
|
|
642
683
|
|
|
643
684
|
#### `event/message.recalled`
|
|
644
685
|
|
|
@@ -664,7 +705,7 @@ volatile 事件包含 `storage="volatile"`、`volatile_cursor`、`created_at`、
|
|
|
664
705
|
|
|
665
706
|
---
|
|
666
707
|
|
|
667
|
-
### 6.4 元协议 `meta.*`
|
|
708
|
+
### 6.4 元协议 `meta.*`
|
|
668
709
|
|
|
669
710
|
#### `meta.ping`
|
|
670
711
|
|
|
@@ -800,7 +841,7 @@ Issuer 必须通过 `https://ct.{issuer}` 提供证书透明日志(CT)的公
|
|
|
800
841
|
|
|
801
842
|
---
|
|
802
843
|
|
|
803
|
-
### 6.5 搜索与发现 `search.*`
|
|
844
|
+
### 6.5 搜索与发现 `search.*`
|
|
804
845
|
|
|
805
846
|
`search.*` 定义 AUN 中 Agent 的公开发现机制,围绕 `agent.md` 工作:
|
|
806
847
|
|
|
@@ -1048,7 +1089,7 @@ tags:
|
|
|
1048
1089
|
|
|
1049
1090
|
---
|
|
1050
1091
|
|
|
1051
|
-
### 6.6 Agent 协作与任务 `task.*`
|
|
1092
|
+
### 6.6 Agent 协作与任务 `task.*`
|
|
1052
1093
|
|
|
1053
1094
|
`task.*` 用于表达 Agent 之间的长生命周期协作任务,参考 A2A 的 task 机制,对齐 AUN 特点:
|
|
1054
1095
|
|
|
@@ -1339,27 +1380,27 @@ event/task.delegated # 已创建子任务
|
|
|
1339
1380
|
|
|
1340
1381
|
---
|
|
1341
1382
|
|
|
1342
|
-
### 6.7 端到端加密(E2EE)摘要
|
|
1383
|
+
### 6.7 端到端加密(E2EE)摘要
|
|
1343
1384
|
|
|
1344
|
-
>
|
|
1385
|
+
> 当前 V2 主路径见 [E2EE V2 消息通信时序图](../sdk/E2EE_V2消息通信时序图.md);群组规范见 [08-AUN-E2EE-Group](08-AUN-E2EE-Group.md)。[08-AUN-E2EE](08-AUN-E2EE.md) 仅说明 Legacy 信封。
|
|
1345
1386
|
|
|
1346
1387
|
**核心原则**:
|
|
1347
1388
|
|
|
1348
1389
|
- E2EE 加解密**完全由客户端实现**,无需在线协商
|
|
1349
1390
|
- 服务端只做消息中转和 prekey 存储,对加密内容完全透明
|
|
1350
|
-
-
|
|
1351
|
-
-
|
|
1391
|
+
- 当前 P2P 使用 `message.send` 承载 `e2ee.p2p_encrypted` 信封,群组使用 `group.v2.send` 承载 `e2ee.group_encrypted` 信封
|
|
1392
|
+
- 当前默认每消息独立密钥,按设备使用 `3DH` / `1DH` wrap;`prekey_ecdh_v2` / `long_term_key` 仅用于 Legacy 兼容
|
|
1352
1393
|
|
|
1353
1394
|
**服务端兼容性要求**:
|
|
1354
1395
|
|
|
1355
|
-
-
|
|
1396
|
+
- 接受并转发当前 V2 加密信封及 Legacy `encrypted: true` 消息
|
|
1356
1397
|
- 在离线队列和历史消息中存储密文 payload
|
|
1357
1398
|
- 不对密文 payload 施加额外的语义解析要求
|
|
1358
|
-
-
|
|
1399
|
+
- 当前 P2P 设备 SPK 使用 `message.v2.put_peer_pk` / `message.v2.bootstrap`;`message.e2ee.put_prekey` / `message.e2ee.get_prekey` 仅为 Legacy 兼容
|
|
1359
1400
|
|
|
1360
1401
|
**互操作要求**:
|
|
1361
1402
|
|
|
1362
|
-
跨语言、跨平台 SDK
|
|
1403
|
+
跨语言、跨平台 SDK 必须按当前 V2 路径保持算法、信封、AAD 与 recipient proof 一致;旧格式才适用 [Legacy E2EE 规范](08-AUN-E2EE.md),不得用旧信封替代默认 V2 发送格式。
|
|
1363
1404
|
|
|
1364
1405
|
**错误码**:
|
|
1365
1406
|
|
|
@@ -1369,7 +1410,7 @@ event/task.delegated # 已创建子任务
|
|
|
1369
1410
|
|
|
1370
1411
|
---
|
|
1371
1412
|
|
|
1372
|
-
### 6.8 跨域消息路由
|
|
1413
|
+
### 6.8 跨域消息路由
|
|
1373
1414
|
|
|
1374
1415
|
**当前实现事实**:
|
|
1375
1416
|
|