@agentunion/fastaun-browser 0.5.4 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/CHANGELOG.md +177 -67
  2. package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/216/245/345/205/245/344/270/216/346/274/224/347/244/272/346/214/207/345/215/227.md +290 -0
  3. package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/346/236/266/346/236/204/344/270/216/350/257/246/347/273/206/345/256/236/347/216/260/350/256/241/345/210/222-codex.md +994 -0
  4. package/_packed_docs/AUN/347/246/273/347/272/277/346/216/250/351/200/201/346/234/215/345/212/241/350/277/220/347/273/264/344/270/216/345/217/221/345/270/203/346/214/207/345/215/227.md +144 -0
  5. package/_packed_docs/CHANGELOG.md +177 -67
  6. package/_packed_docs/INDEX.md +124 -65
  7. package/_packed_docs/KITE_DOCS_GUIDE.md +65 -30
  8. package/_packed_docs/agent.md/SCHEMA.md +83 -58
  9. package/_packed_docs/agent.md/examples/codeagent-claudecode.md +1 -1
  10. package/_packed_docs/agent.md/examples/openclaw-lobster.md +1 -1
  11. package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +1 -1
  12. package/_packed_docs/audit/AUN/346/234/215/345/212/241Go/345/214/226/351/207/215/346/236/204/347/262/276/347/273/206/345/214/226/346/272/220/347/240/201/345/256/241/346/237/245-20260718.md +366 -0
  13. package/_packed_docs/aun/345/205/254/347/275/221/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +234 -0
  14. package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1095 -0
  15. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +1199 -0
  16. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +6 -4
  17. package/_packed_docs/group-message-rpc-alignment-gaps.md +741 -0
  18. package/_packed_docs/message-online-push-alignment.md +572 -0
  19. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +58 -20
  20. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +219 -247
  21. package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +14 -14
  22. package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +3 -3
  23. package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +165 -421
  24. package/_packed_docs/protocol/README.md +1 -0
  25. package/_packed_docs/protocol/aun-docs-guide.md +7 -4
  26. package/_packed_docs/protocol/index.md +25 -19
  27. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +63 -18
  28. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +22 -0
  29. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +93 -84
  30. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +6 -2
  31. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +73 -34
  32. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +3 -3
  33. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +21 -9
  34. package/_packed_docs/sdk/09-group-rpc-manual.md +319 -285
  35. package/_packed_docs/sdk/09-message-rpc-manual.md +144 -103
  36. package/_packed_docs/sdk/09-payload-reference.md +1 -1
  37. package/_packed_docs/sdk/09-storage-rpc-manual.md +14 -3
  38. package/_packed_docs/sdk/09-stream-rpc-manual.md +8 -8
  39. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +34 -23
  40. package/_packed_docs/sdk/CHANGELOG-0.5.6.md +73 -0
  41. package/_packed_docs/sdk/INDEX.md +45 -37
  42. package/_packed_docs/sdk/README.md +11 -9
  43. package/_packed_docs//345/217/221/345/270/203/346/212/245/345/221/212-0.5.6.md +260 -0
  44. package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/344/273/243/347/240/201/345/256/241/346/237/245/351/227/256/351/242/230/346/270/205/345/215/225.md +229 -0
  45. package/_packed_docs//346/266/210/346/201/257/345/220/214/346/255/245/344/270/216/345/216/206/345/217/262/346/213/211/345/217/226/346/224/271/351/200/240/346/226/271/346/241/210.md +750 -0
  46. package/dist/agent-md-schema.d.ts +14 -0
  47. package/dist/agent-md-schema.d.ts.map +1 -0
  48. package/dist/agent-md-schema.js +103 -0
  49. package/dist/agent-md-schema.js.map +1 -0
  50. package/dist/agent-md.d.ts +11 -5
  51. package/dist/agent-md.d.ts.map +1 -1
  52. package/dist/agent-md.js +295 -53
  53. package/dist/agent-md.js.map +1 -1
  54. package/dist/aid-store.d.ts +7 -7
  55. package/dist/aid-store.d.ts.map +1 -1
  56. package/dist/aid-store.js +46 -18
  57. package/dist/aid-store.js.map +1 -1
  58. package/dist/aid.d.ts +2 -0
  59. package/dist/aid.d.ts.map +1 -1
  60. package/dist/aid.js +29 -7
  61. package/dist/aid.js.map +1 -1
  62. package/dist/auth.d.ts.map +1 -1
  63. package/dist/auth.js +31 -11
  64. package/dist/auth.js.map +1 -1
  65. package/dist/bundle.js +29920 -19719
  66. package/dist/cert-utils.d.ts +1 -0
  67. package/dist/cert-utils.d.ts.map +1 -1
  68. package/dist/cert-utils.js +36 -16
  69. package/dist/cert-utils.js.map +1 -1
  70. package/dist/client/delivery.d.ts +106 -11
  71. package/dist/client/delivery.d.ts.map +1 -1
  72. package/dist/client/delivery.js +1925 -374
  73. package/dist/client/delivery.js.map +1 -1
  74. package/dist/client/group-state.d.ts.map +1 -1
  75. package/dist/client/group-state.js +27 -24
  76. package/dist/client/group-state.js.map +1 -1
  77. package/dist/client/lifecycle.d.ts +15 -1
  78. package/dist/client/lifecycle.d.ts.map +1 -1
  79. package/dist/client/lifecycle.js +477 -132
  80. package/dist/client/lifecycle.js.map +1 -1
  81. package/dist/client/mention-mode.d.ts +7 -0
  82. package/dist/client/mention-mode.d.ts.map +1 -0
  83. package/dist/client/mention-mode.js +184 -0
  84. package/dist/client/mention-mode.js.map +1 -0
  85. package/dist/client/peers.d.ts +1 -1
  86. package/dist/client/peers.d.ts.map +1 -1
  87. package/dist/client/peers.js +26 -3
  88. package/dist/client/peers.js.map +1 -1
  89. package/dist/client/rpc-pipeline.d.ts +34 -2
  90. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  91. package/dist/client/rpc-pipeline.js +503 -99
  92. package/dist/client/rpc-pipeline.js.map +1 -1
  93. package/dist/client/runtime.d.ts +1 -3
  94. package/dist/client/runtime.d.ts.map +1 -1
  95. package/dist/client/runtime.js +4 -7
  96. package/dist/client/runtime.js.map +1 -1
  97. package/dist/client/v2-e2ee.d.ts +43 -2
  98. package/dist/client/v2-e2ee.d.ts.map +1 -1
  99. package/dist/client/v2-e2ee.js +931 -138
  100. package/dist/client/v2-e2ee.js.map +1 -1
  101. package/dist/client.d.ts +46 -15
  102. package/dist/client.d.ts.map +1 -1
  103. package/dist/client.js +785 -304
  104. package/dist/client.js.map +1 -1
  105. package/dist/errors.d.ts.map +1 -1
  106. package/dist/errors.js +4 -1
  107. package/dist/errors.js.map +1 -1
  108. package/dist/facades.d.ts +26 -1
  109. package/dist/facades.d.ts.map +1 -1
  110. package/dist/facades.js +142 -60
  111. package/dist/facades.js.map +1 -1
  112. package/dist/group-id.d.ts.map +1 -1
  113. package/dist/group-id.js +2 -17
  114. package/dist/group-id.js.map +1 -1
  115. package/dist/group-index.d.ts +6 -1
  116. package/dist/group-index.d.ts.map +1 -1
  117. package/dist/group-index.js +44 -25
  118. package/dist/group-index.js.map +1 -1
  119. package/dist/index.d.ts +5 -4
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +3 -2
  122. package/dist/index.js.map +1 -1
  123. package/dist/keystore/index.d.ts +10 -5
  124. package/dist/keystore/index.d.ts.map +1 -1
  125. package/dist/keystore/indexeddb-identity-store.d.ts +0 -12
  126. package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
  127. package/dist/keystore/indexeddb-identity-store.js +0 -60
  128. package/dist/keystore/indexeddb-identity-store.js.map +1 -1
  129. package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
  130. package/dist/keystore/indexeddb-shared.js +9 -5
  131. package/dist/keystore/indexeddb-shared.js.map +1 -1
  132. package/dist/keystore/indexeddb-token-store.d.ts +3 -1
  133. package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
  134. package/dist/keystore/indexeddb-token-store.js +47 -2
  135. package/dist/keystore/indexeddb-token-store.js.map +1 -1
  136. package/dist/register-flow.d.ts.map +1 -1
  137. package/dist/register-flow.js +28 -3
  138. package/dist/register-flow.js.map +1 -1
  139. package/dist/seq-tracker.d.ts +28 -8
  140. package/dist/seq-tracker.d.ts.map +1 -1
  141. package/dist/seq-tracker.js +224 -61
  142. package/dist/seq-tracker.js.map +1 -1
  143. package/dist/storage/vfs.d.ts +1 -0
  144. package/dist/storage/vfs.d.ts.map +1 -1
  145. package/dist/storage/vfs.js +26 -2
  146. package/dist/storage/vfs.js.map +1 -1
  147. package/dist/tools/cross-sdk-agent.js +399 -11
  148. package/dist/tools/cross-sdk-agent.js.map +1 -1
  149. package/dist/transport.d.ts +12 -0
  150. package/dist/transport.d.ts.map +1 -1
  151. package/dist/transport.js +226 -102
  152. package/dist/transport.js.map +1 -1
  153. package/dist/v2/session/session.d.ts.map +1 -1
  154. package/dist/v2/session/session.js +3 -4
  155. package/dist/v2/session/session.js.map +1 -1
  156. package/dist/v2/state/commitment.d.ts.map +1 -1
  157. package/dist/v2/state/commitment.js +1 -2
  158. package/dist/v2/state/commitment.js.map +1 -1
  159. package/dist/validators.d.ts.map +1 -1
  160. package/dist/validators.js +8 -14
  161. package/dist/validators.js.map +1 -1
  162. package/dist/version.d.ts +1 -1
  163. package/dist/version.js +1 -1
  164. package/package.json +11 -9
  165. package/dist/group-resources.d.ts +0 -98
  166. package/dist/group-resources.d.ts.map +0 -1
  167. package/dist/group-resources.js +0 -635
  168. package/dist/group-resources.js.map +0 -1
  169. package/dist/keystore/indexeddb.d.ts +0 -179
  170. package/dist/keystore/indexeddb.d.ts.map +0 -1
  171. package/dist/keystore/indexeddb.js +0 -2031
  172. package/dist/keystore/indexeddb.js.map +0 -1
  173. package/dist/namespaces/auth.d.ts +0 -98
  174. package/dist/namespaces/auth.d.ts.map +0 -1
  175. package/dist/namespaces/auth.js +0 -992
  176. package/dist/namespaces/auth.js.map +0 -1
  177. package/dist/namespaces/custody.d.ts +0 -51
  178. package/dist/namespaces/custody.d.ts.map +0 -1
  179. package/dist/namespaces/custody.js +0 -302
  180. package/dist/namespaces/custody.js.map +0 -1
  181. package/dist/namespaces/meta.d.ts +0 -109
  182. package/dist/namespaces/meta.d.ts.map +0 -1
  183. package/dist/namespaces/meta.js +0 -549
  184. package/dist/namespaces/meta.js.map +0 -1
@@ -152,8 +152,8 @@ AID 由 `AIDStore.load()` 返回,应用层不直接构造。
152
152
  | `is_private_key_valid()` | `isPrivateKeyValid()` | `IsPrivateKeyValid()` | 私钥是否可用 |
153
153
  | `sign(data)` | `sign(data)` | `Sign(data)` | 签名 bytes |
154
154
  | `verify(data, signature)` | `verify(data, signature)` | `Verify(data, signature)` | 验签 |
155
- | `sign_agent_md(content)` | `signAgentMd(content)` | `SignAgentMd(content)` | agent.md 签名 |
156
- | `verify_agent_md(content)` | `verifyAgentMd(content)` | `VerifyAgentMd(content)` | agent.md 验签 |
155
+ | `sign_agent_md(content)` | `signAgentMd(content)` | `SignAgentMd(content)` | agent.md 签名 |
156
+ | `verify_agent_md(content)` | `verifyAgentMd(content)` | `VerifyAgentMd(content)` | agent.md 验签 |
157
157
 
158
158
  ---
159
159
 
@@ -193,17 +193,20 @@ client := aun.NewAUNClient(aid)
193
193
 
194
194
  | Python | TS/JS | Go | 说明 |
195
195
  |--------|-------|----|------|
196
- | `load_identity(aid)` | `loadIdentity(aid)` | `LoadIdentity(aid)` | 在 `no_identity` / `closed` 状态加载身份 |
197
- | `state` | `state` | `ConnectionState()` | 九态公开状态 |
198
- | `gateway_url` | `gatewayUrl` | `GetGatewayURL()` | 当前连接的 Gateway URL(只读,自动发现,连接前为空) |
199
- | `current_aid` | `currentAid` | `CurrentAID()` | 当前 AID 对象 |
196
+ | `load_identity(aid)` | `loadIdentity(aid)` | `LoadIdentity(aid)` | 在 `no_identity` / `closed` 状态加载身份 |
197
+ | `state` | `state` | `ConnectionState()` | 九态公开状态 |
198
+ | `gateway_url` | `gatewayUrl` | `GetGatewayURL()` | 当前连接的 Gateway URL(只读,自动发现,连接前为空) |
199
+ | `get_access_token()` | `getAccessToken()` | `GetAccessToken()` | 同步读取后台刷新任务维护的当前 access token;不发起认证、刷新或网络请求;无 token 时分别返回 `None` / `null` / 空字符串 |
200
+ | `current_aid` | `currentAid` | `CurrentAID()` | 当前 AID 对象 |
200
201
  | `aid` | `aid` | `AID()` | 当前 AID 字符串 |
201
202
  | `has_identity` | `hasIdentity` | `HasIdentity()` | 是否已加载身份 |
202
203
  | `can_sign` | `canSign` | `CanSign()` | 是否可签名 |
203
204
  | `can_connect` | `canConnect` | `CanConnect()` | 是否可连接 |
204
205
  | `can_send` / `is_ready` | `canSend` / `isReady` | `CanSend()` / `IsReady()` | 是否可发送 |
205
- | `is_online` | `isOnline` | `IsOnline()` | 是否处于在线或重连相关状态 |
206
- | `is_closed` | `isClosed` | `IsClosed()` | 是否已关闭 |
206
+ | `is_online` | `isOnline` | `IsOnline()` | 是否处于在线或重连相关状态 |
207
+ | `is_closed` | `isClosed` | `IsClosed()` | 是否已关闭 |
208
+
209
+ `get_access_token()` / `getAccessToken()` / `GetAccessToken()` 面向需要自行发起 HTTP 数据面请求的应用。返回值是调用时刻的缓存快照,不是可长期持有的凭据:应在每次需要 AID Bearer 的请求前重新读取,不能持续复用 `authenticate()` 首次返回的字符串。getter 本身不会主动刷新,也不独立检查 token 是否临近过期;其有效性依赖客户端后台刷新任务正常运行。返回空值时应先完成身份加载和认证/连接,且不得发送空的 `Authorization` 头。Storage VFS 和 Group FS 等 SDK 门面会自行编排其数据面请求,普通应用优先使用门面。Bearer、资源域 ticket、跨 issuer 下载和 401/403 重试边界见 [Storage RPC 手册:数据面 HTTP 下载流程](09-storage-rpc-manual.md#数据面-http-下载流程)。
207
210
 
208
211
  状态值:
209
212
 
@@ -217,18 +220,18 @@ retry_backoff / reconnecting / connection_failed / closed
217
220
  Python:
218
221
 
219
222
  ```python
220
- auth = await client.authenticate()
221
- await client.connect({"slot_id": "main", "auto_reconnect": True})
223
+ auth = await client.authenticate()
224
+ await client.connect({"auto_reconnect": True})
222
225
  await client.disconnect()
223
226
  await client.close()
224
227
  ```
225
228
 
226
229
  说明:
227
230
 
228
- - `authenticate()` 只取 token,不建立业务会话。
229
- - `connect()` 可从 `standby` 自动认证并进入 `ready`。
230
- - `disconnect()` 断开当前传输连接,对象仍可重新连接。
231
- - `close()` 关闭连接和后台任务;之后只能重新加载身份再复用。
231
+ - `authenticate()` 只取 token,不建立业务会话。
232
+ - `connect()` 可从 `standby` 自动认证并进入 `ready`。
233
+ - `disconnect()` 断开当前传输连接,对象仍可重新连接。
234
+ - `close()` 关闭连接和后台任务;之后只能重新加载身份再复用。
232
235
 
233
236
  四个 SDK 的公开构造入口均已对齐为“无参或 AID 对象”。调试、TLS、根证书、device_id、slot_id 等配置由 `AIDStore` 传递到 AID,再由 `AUNClient` 继承;连接级选项只传给 `connect()`。
234
237
 
@@ -304,14 +307,14 @@ headers = client.get_protected_headers()
304
307
  | Python | TS/JS | Go | 说明 |
305
308
  |--------|-------|----|------|
306
309
  | `AIDStore.upload_agent_md(aid, content=None)` | `store.uploadAgentMd(aid, content?)` | `store.UploadAgentMD(ctx, aid, content...)` | 发布指定本地 AID 的 agent.md |
307
- | `AIDStore.download_agent_md(aid)` | `store.downloadAgentMd(aid)` | `store.DownloadAgentMD(ctx, aid)` | 下载并验签 |
308
- | `AIDStore.check_agent_md(aid)` | `store.checkAgentMd(aid)` | `store.CheckAgentMD(ctx, aid, maxUnsyncedDays...)` | 检查一致性 |
309
-
310
- 说明:
311
-
312
- - agent.md 上传、下载和检查入口都在 `AIDStore`;`AUNClient` 不再暴露上传入口。
313
- - 上传要求目标 AID 已在本地加载且私钥有效;SDK 会对正文签名,并通过 `AuthFlow` 获取或复用该 AID 的 access_token。
314
- - SDK 发起 GET 时只发送 `Accept: text/markdown`,不主动发送 `If-None-Match` / `If-Modified-Since`。如果服务端异常返回 304,本地有内容则复用;无内容时再发一次无条件 GET。
310
+ | `AIDStore.download_agent_md(aid)` | `store.downloadAgentMd(aid)` | `store.DownloadAgentMD(ctx, aid)` | 下载并验签 |
311
+ | `AIDStore.check_agent_md(aid)` | `store.checkAgentMd(aid)` | `store.CheckAgentMD(ctx, aid, maxUnsyncedDays...)` | 检查一致性 |
312
+
313
+ 说明:
314
+
315
+ - agent.md 上传、下载和检查入口都在 `AIDStore`;`AUNClient` 不再暴露上传入口。
316
+ - 上传要求目标 AID 已在本地加载且私钥有效;SDK 会对正文签名,并通过 `AuthFlow` 获取或复用该 AID 的 access_token。
317
+ - SDK 发起 GET 时只发送 `Accept: text/markdown`,不主动发送 `If-None-Match` / `If-Modified-Since`。如果服务端异常返回 304,本地有内容则复用;无内容时再发一次无条件 GET。
315
318
  - SDK 会自动从 Gateway `_meta.agent_md_etags` 和信封 `agent_md` 观察远端版本;`requester`、`peer`、`group` 是标准角色键,`receiver`、`target`、`to`、`sender`、`from` 是兼容别名。
316
319
  - `Accept: text/markdown` 与 agent.md 的 YAML frontmatter + Markdown 格式兼容;agent.md 仍是 Markdown 媒体类型上的结构化约定。
317
320
 
@@ -335,11 +338,16 @@ headers = client.get_protected_headers()
335
338
 
336
339
  | 能力 | Python | TS/JS | Go | 说明 |
337
340
  |------|--------|-------|----|------|
338
- | Message | `client.message` | `client.message` | `client.Message()` | 消息便利方法:`send()`、`pull()`、`ack()`、`recall()`、`queryOnline()` |
341
+ | Message | `client.message` | `client.message` | `client.Message()` | 消息便利方法:`send()`、`pull()`、`history()`、`ack()`、`recall()`、`queryOnline()` |
339
342
  | Message Thought | `client.message.thought` | `client.message.thought` | `client.Message().Thought()` | P2P 思考内容:`put()`、`get()`(不持久化、不分配 seq、强制 E2EE) |
340
- | Group | `client.group` | `client.group` | `client.Group()` | 群组便利方法:`create()`、`send()`、`pull()`、`ack()`、群管理方法、群查询方法、群设置便利方法 |
341
- | Group Thought | `client.group.thought` | `client.group.thought` | `client.Group().Thought()` | 群思考内容:`put()`、`get()`(不持久化、不分配 seq、强制 E2EE) |
342
- | Stream | `client.stream` | `client.stream` | — | 流式数据:`createStream()`、`sendChunk()`、`endStream()`、`subscribeStream()` |
343
+ | Group | `client.group` | `client.group` | `client.Group()` | 群组便利方法:`create()`、`send()`、`pull()`、`history()`、`ack()`、群管理方法、群查询方法、群设置便利方法 |
344
+ | Group Thought | `client.group.thought` | `client.group.thought` | `client.Group().Thought()` | 群思考内容:`put()`、`get()`(不持久化、不分配 seq、强制 E2EE) |
345
+ | Offline Push | `client.push` | | — | Python SDK:登记/注销当前安装的 `push_notify_aid`,Push Server 处理批次后 ACK |
346
+ | Stream | `client.stream` | `client.stream` | — | 流式数据:`createStream()`、`sendChunk()`、`endStream()`、`subscribeStream()` |
347
+
348
+ `message.history` 和 `group.history` 使用 `before_seq` 排他上界向左翻页,下一页直接使用响应的 `next_before_seq`。History 只读,不推进实时 A/T/H、不 ACK、不触发实时消息事件。实时 Push 的最新页同步完全由 SDK 内部自动执行,再按 A/T/H 决定是否补一页 Forward;没有需要应用调用的 Tail 方法或参数。
349
+
350
+ 消息回调只提供页级语义:单个 Tail/Forward 响应页内按 seq 升序、同 seq 最多一次;跨 Push/Tail/Forward 页可能重复或乱序。A/T/H 不能用于判断某条消息是否已经回调。全局去重与排序不是 SDK 业务逻辑保证;应用仓库应以 `(namespace, message_id)` 做唯一键,并按 `seq` 排序。SDK 的进程内折叠仅是 best-effort 优化。
343
351
 
344
352
  **群查询方法**:`GroupFacade` 提供三个查询方法,适用不同场景:
345
353
 
@@ -631,8 +639,37 @@ fmt.Printf("推送成功\n")
631
639
  5. **附件字段只存引用**:`updateRules` / `updateAnnouncement` / `updateSettingWithIndex` 传入 `content` 和 `attachments` 元数据引用;`updateJoinRequirements` 传入结构化入群字段和 `attachments` 元数据引用。附件实体先上传到群自有区,推荐路径为 `group_aid:/.group/attachments/{rules|announcement|join|<keyName>}/...`。群自有区默认允许 `owner/admin` 写入,`member` 默认不可写;`.group/` 不允许授予 `role:member` 写权限。
632
640
 
633
641
  ---
634
-
635
- ## ServiceProxyClient
642
+
643
+ ### 离线推送门面(Python)
644
+
645
+ 应用启动时推荐把推送代理和 opaque token 交给 `connect()`:
646
+
647
+ ```python
648
+ await client.connect({
649
+ "push_notify_aid": "push.example.com",
650
+ "push_token": token,
651
+ })
652
+ ```
653
+
654
+ SDK 先建立 AUN 会话,再调用 `push.register` 登记当前安装。`push_notify_aid` 是 SDK 公共名称,线上 RPC 字段仍是冻结契约中的 `push_server_aid`;它不会被透传给 `auth.connect`。
655
+
656
+ 运行期间更换 token 或停止推送时使用 facade:
657
+
658
+ ```python
659
+ await client.push.register(push_notify_aid="push.example.com", push_token=new_token)
660
+ await client.push.unregister()
661
+ ```
662
+
663
+ - `register()` 可附带 `provider`、`app_id`;身份范围始终由 Gateway 注入的当前 `aid/device_id/slot_id` 决定,调用方不能伪造。
664
+ - `unregister()` 幂等禁用当前安装,不删除历史 delivery。
665
+ - `ack(batch_id, status)` 只供 Push Server 实现使用;V1 status 仅允许 `accepted`、`retryable_failure`、`permanent_failure`。
666
+ - 本轮只修改 Python SDK;Go、TypeScript、JavaScript 尚无专用 Push facade。
667
+
668
+ 协议与可靠性边界见 `docs/protocol/15-离线推送通知协议.md`。
669
+
670
+ ---
671
+
672
+ ## ServiceProxyClient
636
673
 
637
674
  Service Proxy 用于 provider 通过 AUN 身份暴露本地 HTTP / WebSocket 服务。当前公开封装在 Python SDK 的 `ServiceProxyClient` 中;其它语言可以按 [09-proxy-rpc-manual.md](09-proxy-rpc-manual.md) 直接实现同等控制面和隧道消息。
638
675
 
@@ -701,8 +738,9 @@ sub.unsubscribe()
701
738
  | `message.ack` | 消息 ack |
702
739
  | `message.undecryptable` | P2P E2EE 解密失败 |
703
740
  | `group.changed` | 群组事件 |
704
- | `group.message_undecryptable` | 群 E2EE 解密失败 |
705
- | `storage.object_changed` | Storage 对象变更事件透传 |
741
+ | `group.message_undecryptable` | 群 E2EE 解密失败 |
742
+ | `push.offline_message` | Push Server 收到离线唤醒批次;普通终端无需订阅 |
743
+ | `storage.object_changed` | Storage 对象变更事件透传 |
706
744
 
707
745
  ---
708
746
 
@@ -728,13 +766,14 @@ sub.unsubscribe()
728
766
 
729
767
  | 领域 | 手册 | 关键方法 |
730
768
  |------|------|----------|
731
- | 消息 | [09-message-rpc-manual.md](09-message-rpc-manual.md) | `message.send` / `message.pull` / `message.ack` / `message.thought.*` |
732
- | 群组 | [09-group-rpc-manual.md](09-group-rpc-manual.md) | `group.create` / `group.send` / `group.v2.*` / `group.fs.*` |
769
+ | 消息 | [09-message-rpc-manual.md](09-message-rpc-manual.md) | `message.send` / `message.pull` / `message.history` / `message.ack` / `message.thought.*` |
770
+ | 群组 | [09-group-rpc-manual.md](09-group-rpc-manual.md) | `group.create` / `group.send` / `group.pull` / `group.history` / `group.v2.*` / `group.fs.*` |
733
771
  | 存储 | [09-storage-rpc-manual.md](09-storage-rpc-manual.md) | `storage.put_object` / `storage.fs.*` / `storage.volume.*` / ACL / token / share link |
734
772
  | 协作 | [09-collab-rpc-manual.md](09-collab-rpc-manual.md) | `collab.ls-files` / `collab.show` / `collab.commit` / `collab.merge` / `collab.log` / `collab.diff` / `collab.clone` / `collab.prune` / `collab.gc` / `collab.reflog` / `collab.revert` / `collab.tag.*` / `collab.ls-remote` / `collab.unregister` |
735
773
  | 元信息 | [09-meta-rpc-manual.md](09-meta-rpc-manual.md) | `meta.ping` / `meta.status` / `meta.trust_roots` |
736
- | Stream | [09-stream-rpc-manual.md](09-stream-rpc-manual.md) | `stream.create` / `stream.close` / `stream.list_active` |
737
- | Service Proxy | [09-proxy-rpc-manual.md](09-proxy-rpc-manual.md) | `proxy.register_services` / `proxy.unregister_services` / `proxy.list_services` |
774
+ | Stream | [09-stream-rpc-manual.md](09-stream-rpc-manual.md) | `stream.create` / `stream.close` / `stream.list_active` |
775
+ | Offline Push | `docs/protocol/15-离线推送通知协议.md` | `push.register` / `push.unregister` / `push.ack` / `push.offline_message` |
776
+ | Service Proxy | [09-proxy-rpc-manual.md](09-proxy-rpc-manual.md) | `proxy.register_services` / `proxy.unregister_services` / `proxy.list_services` |
738
777
 
739
778
  ---
740
779
 
@@ -68,7 +68,7 @@ except AUNError as e:
68
68
  | -32602 且消息包含 `group.index` 签名/schema/hash/etag 错误 | group.index 校验失败 | 检查 signer、canonical JSONL、`body_hash`、`etag` 和 `signature` |
69
69
  | -32040 ~ -32044 | E2EE 群组错误 | `E2EEError` 子类 |
70
70
  | 4090 | 身份冲突 | `IdentityConflictError` |
71
- | -32050 | 证书已吊销 | `CertificateRevokedError` |
71
+ | -32050 | 证书已吊销 | `CertificateRevokedError` |
72
72
  | -33001 | 群组不存在 | `GroupNotFoundError` |
73
73
  | -33002 / -33003 | 群组状态错误 | `GroupStateError` |
74
74
  | -33004 ~ -33009 | 其他群组错误 | `GroupError` 子类 |
@@ -136,7 +136,7 @@ if not registered["ok"] and registered["error"]["code"] == "IDENTITY_CONFLICT":
136
136
 
137
137
  不要通过删除本地 `AIDs/` 目录解决冲突;私钥丢失后无法证明原 AID 所有权。
138
138
 
139
- ### 连接状态错误
139
+ ### 连接状态错误
140
140
 
141
141
  ```python
142
142
  await client.call("message.send", params) # 非 ready 状态会抛 ConnectionError / StateError
@@ -144,7 +144,7 @@ await client.call("message.send", params) # 非 ready 状态会抛 ConnectionEr
144
144
 
145
145
  发送前检查:
146
146
 
147
- ```python
147
+ ```python
148
148
  if not client.can_send:
149
149
  await client.connect({"auto_reconnect": True})
150
150
  ```
@@ -92,16 +92,28 @@ SDK 内部自动管理 RPC 并发,应用层无需配置:
92
92
 
93
93
  | 机制 | 说明 |
94
94
  |------|------|
95
- | RPC 并发上限 | 全局最多 16 个并发 RPC 请求 |
96
- | 后台 RPC 限制 | 后台任务额外限制为 8 个 |
97
- | Pull Gate | 同一 namespace/group pull 操作自动序列化 |
98
- | 队列超时 | 排队超过 timeout `TimeoutError` |
99
-
100
- 应用层保持普通 `await client.call(...)` 即可。
95
+ | RPC 并发上限 | 全局最多 16 个并发 RPC 请求 |
96
+ | 后台 RPC 限制 | 后台任务额外限制为 8 个 |
97
+ | Pull Gate | 每个 `AUNClient` 一个客户端级 Gate;P2P Message、Group Message、Group Event Pull 共享该 Gate,始终 single-inflight |
98
+ | 队列优先级 | Tail/History 前台 FIFO 优先于 Forward/Gap Fill 后台 FIFO;Group Event Pull 为后台;同 key 自动折叠 |
99
+
100
+ Gate 内始终保持单飞;相同 key 的调用共享同一结果,不同 key 按前台优先、队列顺序执行。应用层保持普通 `await client.call(...)` 即可,不应自行实现重复并发控制。
101
+
102
+ ---
103
+
104
+ ## 7. 消息同步与历史读取
105
+
106
+ - V2 Push 只作为服务端 Head 通知。只要本地 H 落后,就先 Tail;Tail 后仍有未扫描 Gap 才执行一页后台 Forward。
107
+ - 不要把回调成功当作 ACK 条件。SDK 按服务端原始页最大 seq 推进 Forward 水位;坏密文通过 `message.undecryptable` / `group.message_undecryptable` 单独处理。
108
+ - 冷启动缺 sender IK 时允许 SDK 最多同步等待 3 秒 bootstrap;同发送端并发请求自动合并。成功后当前消息立即重试解密,失败或超时才 pending,不要在应用层并发重复拉取 IK。
109
+ - SDK 只保证单个 Tail/Forward 响应页内按 seq 升序、同 seq 最多发布一次;A/T/H 只是扫描水位,不是发布账本。
110
+ - 实时消息可能从 Push、Tail、Forward 重复到达,跨页、跨通道都不保证全局回调顺序。全局去重与排序由应用业务仓库负责,不属于 SDK 业务逻辑保证;业务仓库必须按 `(namespace, message_id)` 幂等,并按 seq 排序展示。SDK 进程内折叠只能作为 best-effort 优化。
111
+ - 用 `message.history(before_seq=..., limit=...)` 或 `group.history(group_id=..., before_seq=..., limit=...)` 向左翻页;下一页直接复用响应的 `next_before_seq`。History 不影响实时游标和 ACK。
112
+ - Forward Piggy ACK 保留:有待提交 ACK 时,非满页仍会再拉一页并携带 ACK,拉到空页后停止。
101
113
 
102
114
  ---
103
115
 
104
- ## 7. Group Index 更新流程
116
+ ## 8. Group Index 更新流程
105
117
 
106
118
  公告、规则、入群要求属于 indexed settings。owner/admin 修改这些内容时,不要直接裸调 `group.set_settings` 写单个 key,应使用 SDK facade 的 `updateGroupIndex` 语义。
107
119
 
@@ -113,11 +125,11 @@ SDK 内部自动管理 RPC 并发,应用层无需配置:
113
125
  4. 调用 `updateGroupIndex`。SDK 会读取当前服务端 index、生成新签名 index,并带 `expected_index_etag` 调用 `group.set_settings`。
114
126
  5. 如果服务端返回 `group.index etag conflict`,说明提交基线已变化;应用层需要重新决定 pull、merge 或保留本地修改后再提交。
115
127
 
116
- `getAnnouncement`、`getRules`、`getJoinRequirements` 只读 SDK 本地缓存;本地没有对应值时才读取相应 settings 初始化缓存,不会因为 etag 不一致自动 pull 远端。`updateAnnouncement`、`updateRules`、`updateJoinRequirements` 已内置 indexed 写入路径。普通不进入 index 的设置,例如 `dispatch_mode`,仍可直接使用 `setSettings` / `set_settings` / `SetSettings`。
128
+ `getAnnouncement`、`getRules`、`getJoinRequirements` 只读 SDK 本地缓存;本地没有对应值时才读取相应 settings 初始化缓存,不会因为 etag 不一致自动 pull 远端。`updateAnnouncement`、`updateRules`、`updateJoinRequirements` 已内置 indexed 写入路径。普通不进入 index 的设置,例如 `mention_mode`,仍可直接使用 `setSettings` / `set_settings` / `SetSettings`。
117
129
 
118
130
  ---
119
131
 
120
- ## 8. 测试数据保护
132
+ ## 9. 测试数据保护
121
133
 
122
134
  - 不要删除 `AIDs/` 下的私钥、证书、seed、数据库或 token 文件。
123
135
  - 不要并行跑共享同一身份材料的集成 / E2E / 跨域测试。