@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
@@ -58,7 +58,7 @@
58
58
 
59
59
  | 方法 | 说明 |
60
60
  |------|------|
61
- | [group.set_settings](#groupset_settings) | 统一设置群参数,含 `dispatch_mode` |
61
+ | [group.set_settings](#groupset_settings) | 统一设置群参数,含 `mention_mode` |
62
62
  | [group.get_settings](#groupget_settings) | 统一读取群参数 |
63
63
 
64
64
  ### 消息
@@ -70,6 +70,7 @@
70
70
  | [group.thought.put](#groupthoughtput) | 写入某个群上下文的思考内容 |
71
71
  | [group.thought.get](#groupthoughtget) | 获取某个群上下文的思考内容 |
72
72
  | [group.pull](#grouppull) | 增量拉取消息 |
73
+ | [group.history](#grouphistory) | 向前只读翻页群消息 |
73
74
  | [group.pull_events](#grouppull_events) | 增量拉取事件 |
74
75
  | [group.ack](#groupack) | 确认已读(旧接口,等同 ack_messages) |
75
76
  | [group.ack_messages](#groupack_messages) | 确认消息游标 |
@@ -100,10 +101,10 @@
100
101
 
101
102
  | 方法 | 说明 |
102
103
  |------|------|
103
- | [group.set_settings](#groupset_settings) | 统一设置群参数(含公告、规则、入群要求、dispatch_mode 等) |
104
+ | [group.set_settings](#groupset_settings) | 统一设置群参数(含公告、规则、入群要求、mention_mode 等) |
104
105
  | [group.get_settings](#groupget_settings) | 统一读取群参数 |
105
106
 
106
- **便利方法**:SDK 提供向后兼容的便利方法(`getAnnouncement`/`updateAnnouncement`/`getRules`/`updateRules`/`getJoinRequirements`/`updateJoinRequirements`),并提供通用文档型方法(`getSettingWithIndex`/`updateSettingWithIndex`,Python 为 `get_setting_with_index`/`update_setting_with_index`,Go 为 `GetSettingWithIndex`/`UpdateSettingWithIndex`)。读取方法优先返回 SDK 本地缓存,本地没有对应值时才调用 `get_settings` 初始化;即使观察到远端 etag 不一致也不会自动 pull 远端。indexed 写入方法内部调用 `updateGroupIndex` 生成签名 `group.index` 并通过 `set_settings` CAS 提交。
107
+ **便利方法**:SDK 提供向后兼容的便利方法(`getAnnouncement`/`updateAnnouncement`/`getRules`/`updateRules`/`getJoinRequirements`/`updateJoinRequirements`),并提供通用文档型方法(`getSettingWithIndex`/`updateSettingWithIndex`,Python 为 `get_setting_with_index`/`update_setting_with_index`,Go 为 `GetSettingWithIndex`/`UpdateSettingWithIndex`)。读取方法优先返回 SDK 本地缓存,本地没有对应值时才调用 `get_settings` 初始化;即使观察到远端 etag 不一致也不会自动 pull 远端。indexed 写入方法内部调用 `updateGroupIndex` 生成签名 `group.index` 并通过 `set_settings` CAS 提交。
107
108
 
108
109
  ### 群文件系统
109
110
 
@@ -137,17 +138,17 @@
137
138
 
138
139
  ---
139
140
 
140
- ## Group AID / Group ID 兼容规范
141
-
142
- 目标态群组主标识是 `group_aid`,canonical 形式为 `{base}.{issuer-domain}`,例如 `10042.agentid.pub`、`team01.agentid.pub`、`g-abc123.agentid.pub`。新建群以 `group_aid` 为准;新群的兼容 `group_id` 列值也使用同一个 `group_aid` 字符串。历史 `group_id` 字段名和 RPC 参数名继续保留,但语义上只是兼容字段。
143
-
144
- SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_aid` / `groupAid` 统一规范化为 `group_aid`。裸客户端也应使用同一 `group_aid` 生成签名材料和 E2EE AAD,避免同一群的历史别名产生不同材料。服务端响应可能同时返回 `group_id` 和 `group_aid`;新代码应优先读取 `group_aid`,仅兼容旧版本或历史数据时回退读取 `group_id`。
145
-
146
- 兼容输入包括目标态 `{base}.{issuer-domain}`、本域简写 `{base}` / `g-{slug}`,以及旧格式 `group.{issuer-domain}/{base}`、`{base}@issuer-domain`、`g-{slug}@issuer-domain`、`g-{slug}.{issuer-domain}`。带域的旧输入会转换为 `{base}.{issuer-domain}`;本域简写会在服务端或 SDK 有本域 issuer 配置时补成本域 `group_aid`。`base` 支持 5 位及以上小写字母或数字,或 4 到 64 位 `[a-z0-9_-]` 风格名称;旧 `g-` 前缀形式继续兼容,`g-` 后为 4 到 32 位小写字母或数字。命名群使用 `group_name` 作为 base,规则见 `group.create` 参数说明。
147
-
148
- `group.create` 的新建语义以 `group_aid` 为准:命名群由 `group_name + issuer` 生成 `group_aid`,自动群由服务端群号生成 `{number}.{issuer}`。`group_id` 参数只作为旧客户端兼容别名;传入时不能是纯数字(纯数字群号保留给服务端自动分配),且规范化后的 `group_aid` 未被占用。如果已被占用或与历史别名碰撞会返回错误。
149
-
150
- 在 `https://group.issuer-domain/...` 这类群链接中,path 使用单段 `group_aid`,例如 `https://group.agentid.pub/10042.agentid.pub/invite/ic-xxx`、`https://group.agentid.pub/g-abc123.agentid.pub/invite/ic-xxx`。历史 base 简写链接可继续由服务端兼容解析。
141
+ ## Group AID / Group ID 兼容规范
142
+
143
+ 目标态群组主标识是 `group_aid`,canonical 形式为 `{base}.{issuer-domain}`,例如 `10042.agentid.pub`、`team01.agentid.pub`、`g-abc123.agentid.pub`。新建群以 `group_aid` 为准;新群的兼容 `group_id` 列值也使用同一个 `group_aid` 字符串。历史 `group_id` 字段名和 RPC 参数名继续保留,但语义上只是兼容字段。
144
+
145
+ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_aid` / `groupAid` 统一规范化为 `group_aid`。裸客户端也应使用同一 `group_aid` 生成签名材料和 E2EE AAD,避免同一群的历史别名产生不同材料。服务端响应可能同时返回 `group_id` 和 `group_aid`;新代码应优先读取 `group_aid`,仅兼容旧版本或历史数据时回退读取 `group_id`。
146
+
147
+ 兼容输入包括目标态 `{base}.{issuer-domain}`、本域简写 `{base}` / `g-{slug}`,以及旧格式 `group.{issuer-domain}/{base}`、`{base}@issuer-domain`、`g-{slug}@issuer-domain`、`g-{slug}.{issuer-domain}`。带域的旧输入会转换为 `{base}.{issuer-domain}`;本域简写会在服务端或 SDK 有本域 issuer 配置时补成本域 `group_aid`。`base` 支持 5 位及以上小写字母或数字,或 4 到 64 位 `[a-z0-9_-]` 风格名称;旧 `g-` 前缀形式继续兼容,`g-` 后为 4 到 32 位小写字母或数字。命名群使用 `group_name` 作为 base,规则见 `group.create` 参数说明。
148
+
149
+ `group.create` 的新建语义以 `group_aid` 为准:命名群由 `group_name + issuer` 生成 `group_aid`,自动群由服务端群号生成 `{number}.{issuer}`。`group_id` 参数只作为旧客户端兼容别名;传入时不能是纯数字(纯数字群号保留给服务端自动分配),且规范化后的 `group_aid` 未被占用。如果已被占用或与历史别名碰撞会返回错误。
150
+
151
+ 在 `https://group.issuer-domain/...` 这类群链接中,path 使用单段 `group_aid`,例如 `https://group.agentid.pub/10042.agentid.pub/invite/ic-xxx`、`https://group.agentid.pub/g-abc123.agentid.pub/invite/ic-xxx`。历史 base 简写链接可继续由服务端兼容解析。
151
152
 
152
153
  ---
153
154
 
@@ -155,16 +156,16 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
155
156
 
156
157
  ### group.create
157
158
 
158
- 创建群组。调用者自动成为 owner。支持创建命名群(传入 `group_name` + `public_key`)。新建群主标识以 `group_aid` 为准;`group_id` 仅作为兼容字段保留。
159
+ 创建群组。调用者自动成为 owner。支持创建命名群(传入 `group_name` + `public_key`)。新建群主标识以 `group_aid` 为准;`group_id` 仅作为兼容字段保留。
159
160
 
160
161
  **参数**:
161
162
 
162
163
  | 参数 | 类型 | 必填 | 说明 |
163
164
  |------|------|------|------|
164
165
  | `name` | string | 是 | 群组显示名称 |
165
- | `group_aid` | string | 否 | 目标态群 AID;新代码优先使用。传入时会规范化为 `{base}.{issuer-domain}`,不能是纯数字 |
166
- | `group_id` | string | 否 | 兼容旧客户端的别名;值语义同 `group_aid`,不再推荐新代码使用 |
167
- | `group_name` | string | 否 | 命名群标识,4-64 字符,`[a-z0-9_-]+`,不以 `guest`/`g-` 开头。与 `public_key` 同时提供时创建命名群,并生成 `{group_name}.{issuer-domain}` |
166
+ | `group_aid` | string | 否 | 目标态群 AID;新代码优先使用。传入时会规范化为 `{base}.{issuer-domain}`,不能是纯数字 |
167
+ | `group_id` | string | 否 | 兼容旧客户端的别名;值语义同 `group_aid`,不再推荐新代码使用 |
168
+ | `group_name` | string | 否 | 命名群标识,4-64 字符,`[a-z0-9_-]+`,不以 `guest`/`g-` 开头。与 `public_key` 同时提供时创建命名群,并生成 `{group_name}.{issuer-domain}` |
168
169
  | `public_key` | string | 否 | 命名群公钥(base64 编码),与 `group_name` 同时提供 |
169
170
  | `curve` | string | 否 | 密钥曲线,默认 `"P-256"` |
170
171
  | `visibility` | string | 否 | `"public"` / `"private"`,默认由配置决定 |
@@ -181,8 +182,8 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
181
182
  ```json
182
183
  {
183
184
  "group": {
184
- "group_id": "my-team.agentid.pub",
185
- "group_aid": "my-team.agentid.pub",
185
+ "group_id": "my-team.agentid.pub",
186
+ "group_aid": "my-team.agentid.pub",
186
187
  "name": "测试群",
187
188
  "owner_aid": "alice.agentid.pub",
188
189
  "creator_aid": "alice.agentid.pub",
@@ -193,9 +194,9 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
193
194
  "member_count": 1,
194
195
  "message_seq": 0,
195
196
  "event_seq": 0,
196
- "group_url": "https://group.agentid.pub/my-team.agentid.pub",
197
- "created_at": 1234567890000,
198
- "updated_at": 1234567890000
197
+ "group_url": "https://group.agentid.pub/my-team.agentid.pub",
198
+ "created_at": 1234567890000,
199
+ "updated_at": 1234567890000
199
200
  },
200
201
  "aid_cert": {
201
202
  "cert": "-----BEGIN CERTIFICATE-----...",
@@ -207,9 +208,9 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
207
208
  }
208
209
  ```
209
210
 
210
- > `aid_cert` 仅在命名群创建时返回。`group_aid` 是新代码应使用的主标识;`group_id` 为兼容字段,新群通常与 `group_aid` 相同,历史群可能保留旧存储值。
211
-
212
- **标识格式**:目标态为 `{base}.{issuer-domain}`。旧格式 `group.{issuer-domain}/{base}`、`{base}@{issuer-domain}` 会在 API 边界转换为目标态 `group_aid`。
211
+ > `aid_cert` 仅在命名群创建时返回。`group_aid` 是新代码应使用的主标识;`group_id` 为兼容字段,新群通常与 `group_aid` 相同,历史群可能保留旧存储值。
212
+
213
+ **标识格式**:目标态为 `{base}.{issuer-domain}`。旧格式 `group.{issuer-domain}/{base}`、`{base}@{issuer-domain}` 会在 API 边界转换为目标态 `group_aid`。
213
214
 
214
215
  ### group.bind_aid
215
216
 
@@ -219,7 +220,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
219
220
 
220
221
  | 参数 | 类型 | 必填 | 说明 |
221
222
  |------|------|------|------|
222
- | `group_id` | string | 是 | 群组标识;兼容参数名,值使用目标态 `group_aid` |
223
+ | `group_id` | string | 是 | 群组标识;兼容参数名,值使用目标态 `group_aid` |
223
224
  | `group_name` | string | 是 | 命名群标识,4-64 字符,`[a-z0-9_-]+` |
224
225
  | `public_key` | string | 是 | 群公钥(base64 编码) |
225
226
  | `curve` | string | 否 | 密钥曲线,默认 `"P-256"` |
@@ -241,7 +242,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
241
242
 
242
243
  | 参数 | 类型 | 必填 | 说明 |
243
244
  |------|------|------|------|
244
- | `group_id` | string | 是 | 群组标识;兼容参数名,值使用目标态 `group_aid` |
245
+ | `group_id` | string | 是 | 群组标识;兼容参数名,值使用目标态 `group_aid` |
245
246
  | `required` | string[] | 否 | 受限字段声明:`member`、`state`、`e2ee`、`avatar` |
246
247
 
247
248
  **默认响应**:
@@ -256,7 +257,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
256
257
  "status": "active",
257
258
  "description": "技术讨论群",
258
259
  "member_count": 42,
259
- "created_at": 1234567890000
260
+ "created_at": 1234567890000
260
261
  }
261
262
  ```
262
263
 
@@ -272,7 +273,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
272
273
 
273
274
  | 参数 | 类型 | 必填 | 说明 |
274
275
  |------|------|------|------|
275
- | `group_id` | string | 是 | 群组标识;兼容参数名,值使用目标态 `group_aid` |
276
+ | `group_id` | string | 是 | 群组标识;兼容参数名,值使用目标态 `group_aid` |
276
277
  | `name` | string | 否 | 新名称 |
277
278
  | `visibility` | string | 否 | 新可见性 |
278
279
  | `description` | string | 否 | 新描述 |
@@ -301,7 +302,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
301
302
  "name": "项目讨论",
302
303
  "visibility": "private",
303
304
  "member_count": 5,
304
- "updated_at": 1234567890000,
305
+ "updated_at": 1234567890000,
305
306
  "role": "owner"
306
307
  }
307
308
  ],
@@ -343,7 +344,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
343
344
 
344
345
  暂停群组。暂停期间不能发送消息。需要 **admin 及以上**权限。
345
346
 
346
- **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
347
+ **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
347
348
 
348
349
  **响应**:
349
350
 
@@ -360,7 +361,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
360
361
 
361
362
  恢复暂停的群组。需要 **admin 及以上**权限。
362
363
 
363
- **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
364
+ **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
364
365
 
365
366
  **响应**:
366
367
 
@@ -377,7 +378,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
377
378
 
378
379
  永久解散群组。不可恢复。需要 **owner** 权限。
379
380
 
380
- **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
381
+ **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
381
382
 
382
383
  **响应**:
383
384
 
@@ -401,7 +402,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
401
402
 
402
403
  | 参数 | 类型 | 必填 | 说明 |
403
404
  |------|------|------|------|
404
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
405
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
405
406
  | `aid` | string | 是 | 要添加的 AID |
406
407
  | `role` | string | 否 | `"admin"` / `"member"`,默认 `"member"` |
407
408
  | `member_type` | string | 否 | `"human"` / `"ai"`,默认 `"human"` |
@@ -415,7 +416,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
415
416
  "aid": "bob.agentid.pub",
416
417
  "role": "member",
417
418
  "member_type": "human",
418
- "joined_at": 1234567890000
419
+ "joined_at": 1234567890000
419
420
  }
420
421
  }
421
422
  ```
@@ -428,7 +429,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
428
429
 
429
430
  | 参数 | 类型 | 必填 | 默认值 | 说明 |
430
431
  |------|------|------|--------|------|
431
- | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
432
+ | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
432
433
  | `page` | integer | 否 | 1 | 页码 |
433
434
  | `size` | integer | 否 | 50 | 每页条数(最大 200) |
434
435
  | `role` | string | 否 | — | 按角色过滤(owner/admin/member) |
@@ -444,9 +445,9 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
444
445
  "aid": "alice.agentid.pub",
445
446
  "role": "owner",
446
447
  "member_type": "human",
447
- "joined_at": 1234567890000,
448
+ "joined_at": 1234567890000,
448
449
  "last_ack_seq": 100,
449
- "last_pull_at": 1234567890000
450
+ "last_pull_at": 1234567890000
450
451
  }
451
452
  ],
452
453
  "total": 1,
@@ -464,7 +465,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
464
465
 
465
466
  | 参数 | 类型 | 必填 | 说明 |
466
467
  |------|------|------|------|
467
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
468
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
468
469
  | `aid` | string | 是 | 要踢出的 AID |
469
470
 
470
471
  **响应**:
@@ -480,7 +481,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
480
481
 
481
482
  主动退出群组。owner 不能直接退群,需先转让群主。
482
483
 
483
- **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
484
+ **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
484
485
 
485
486
  **响应**:
486
487
 
@@ -493,13 +494,13 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
493
494
 
494
495
  ### group.set_role
495
496
 
496
- 设置成员角色。`owner` 可将普通成员设为 `admin`,也可将 `admin` 设回 `member`;`admin` 不能修改其它成员角色,只能将自己的角色降为 `member`。不能通过 `group.set_role` 改变 `owner` 角色;群主只在建群或 `group.transfer_owner` 中变更。该 RPC 改变 membership 中的角色事实;`owner/admin` 默认拥有群自有区写权限,`member` 默认没有写权限。成员级群协作目录应通过 `group.fs.set_acl` 显式授予 `role:member` 的 `rw` 权限。
497
+ 设置成员角色。`owner` 可将普通成员设为 `admin`,也可将 `admin` 设回 `member`;`admin` 不能修改其它成员角色,只能将自己的角色降为 `member`。不能通过 `group.set_role` 改变 `owner` 角色;群主只在建群或 `group.transfer_owner` 中变更。该 RPC 改变 membership 中的角色事实;`owner/admin` 默认拥有群自有区写权限,`member` 默认没有写权限。成员级群协作目录应通过 `group.fs.set_acl` 显式授予 `role:member` 的 `rw` 权限。
497
498
 
498
499
  **参数**:
499
500
 
500
501
  | 参数 | 类型 | 必填 | 说明 |
501
502
  |------|------|------|------|
502
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
503
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
503
504
  | `aid` | string | 是 | 目标 AID |
504
505
  | `role` | string | 是 | `"admin"` / `"member"` |
505
506
 
@@ -513,7 +514,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
513
514
  "aid": "bob.agentid.pub",
514
515
  "role": "admin",
515
516
  "member_type": "human",
516
- "joined_at": 1234567890000,
517
+ "joined_at": 1234567890000,
517
518
  "last_ack_seq": 0,
518
519
  "last_pull_at": 0
519
520
  },
@@ -532,7 +533,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
532
533
 
533
534
  | 参数 | 类型 | 必填 | 说明 |
534
535
  |------|------|------|------|
535
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
536
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
536
537
  | `new_owner` | string | 是 | 新群主 AID(也接受 `aid`) |
537
538
 
538
539
  **响应**:
@@ -558,7 +559,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
558
559
 
559
560
  | 参数 | 类型 | 必填 | 说明 |
560
561
  |------|------|------|------|
561
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
562
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
562
563
  | `public_key` | string | 是 | 公钥 DER base64(SPKI 格式) |
563
564
  | `curve` | string | 否 | 曲线名称(默认 P-256) |
564
565
 
@@ -567,7 +568,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
567
568
  ```json
568
569
  {
569
570
  "group": {
570
- "group_id": "my-team.agentid.pub",
571
+ "group_id": "my-team.agentid.pub",
571
572
  "group_aid": "my-team.agentid.pub",
572
573
  ...
573
574
  },
@@ -602,7 +603,7 @@ SDK 发起 `group.*` 调用时会把传入的 `group_id` / `groupId` / `group_ai
602
603
 
603
604
  | 参数 | 类型 | 必填 | 说明 |
604
605
  |------|------|------|------|
605
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
606
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
606
607
  | `group_aid` | string | 否 | 群身份 AID(可选,服务端可推导) |
607
608
  | `old_public_key` | string | 是 | 旧公钥 DER base64 |
608
609
  | `new_public_key` | string | 是 | 新公钥 DER base64 |
@@ -632,7 +633,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
632
633
  ```json
633
634
  {
634
635
  "group": {
635
- "group_id": "my-team.agentid.pub",
636
+ "group_id": "my-team.agentid.pub",
636
637
  "group_aid": "my-team.agentid.pub",
637
638
  ...
638
639
  },
@@ -660,7 +661,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
660
661
 
661
662
  | 参数 | 类型 | 必填 | 说明 |
662
663
  |------|------|------|------|
663
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
664
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
664
665
  | `subject` | string | 是 | 要封禁的 AID(也接受 `aid`) |
665
666
  | `reason` | string | 否 | 封禁原因 |
666
667
  | `expires_at` | integer | 否 | 过期时间戳(0 = 永久) |
@@ -677,7 +678,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
677
678
  "banned_by": "alice.agentid.pub",
678
679
  "reason": "垃圾消息",
679
680
  "expires_at": 0,
680
- "created_at": 1234567890000
681
+ "created_at": 1234567890000
681
682
  }
682
683
  }
683
684
  ```
@@ -686,7 +687,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
686
687
 
687
688
  解除封禁。需要 **admin 及以上**权限。
688
689
 
689
- **参数**:`group_id`(string,兼容字段,值使用目标态 `group_aid`),`subject` 或 `aid` (string)
690
+ **参数**:`group_id`(string,兼容字段,值使用目标态 `group_aid`),`subject` 或 `aid` (string)
690
691
 
691
692
  **响应**:
692
693
 
@@ -702,7 +703,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
702
703
 
703
704
  获取封禁列表。需要 **admin 及以上**权限。
704
705
 
705
- **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
706
+ **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
706
707
 
707
708
  **响应**:
708
709
 
@@ -716,7 +717,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
716
717
  "banned_by": "alice.agentid.pub",
717
718
  "reason": "垃圾消息",
718
719
  "expires_at": 0,
719
- "created_at": 1234567890000
720
+ "created_at": 1234567890000
720
721
  }
721
722
  ],
722
723
  "total": 1,
@@ -737,7 +738,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
737
738
 
738
739
  | 参数 | 类型 | 必填 | 说明 |
739
740
  |------|------|------|------|
740
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
741
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
741
742
  | `message` | string | 否 | 申请留言 |
742
743
  | `answer` | string | 否 | 入群问题的答案 |
743
744
 
@@ -773,8 +774,8 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
773
774
  "message": "请加我",
774
775
  "answer": "...",
775
776
  "status": "pending",
776
- "created_at": 1234567890000,
777
- "updated_at": 1234567890000,
777
+ "created_at": 1234567890000,
778
+ "updated_at": 1234567890000,
778
779
  "expires_at": 1234654290,
779
780
  "reviewed_by": null,
780
781
  "rejection_reason": null
@@ -790,7 +791,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
790
791
 
791
792
  | 参数 | 类型 | 必填 | 默认值 | 说明 |
792
793
  |------|------|------|--------|------|
793
- | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
794
+ | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
794
795
  | `status` | string | 否 | `"pending"` | `"pending"` / `"approved"` / `"rejected"` |
795
796
  | `page` | integer | 否 | 1 | 页码 |
796
797
  | `size` | integer | 否 | — | 每页数量 |
@@ -806,8 +807,8 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
806
807
  "aid": "carol.agentid.pub",
807
808
  "message": "请加我",
808
809
  "status": "pending",
809
- "created_at": 1234567890000,
810
- "updated_at": 1234567890000
810
+ "created_at": 1234567890000,
811
+ "updated_at": 1234567890000
811
812
  }
812
813
  ],
813
814
  "total": 1,
@@ -824,7 +825,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
824
825
 
825
826
  | 参数 | 类型 | 必填 | 说明 |
826
827
  |------|------|------|------|
827
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
828
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
828
829
  | `aid` | string | 是 | 申请人 AID |
829
830
  | `approve` | boolean | 否 | 批准或拒绝,默认 `true` |
830
831
  | `reason` | string | 否 | 拒绝原因 |
@@ -862,7 +863,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
862
863
 
863
864
  | 参数 | 类型 | 必填 | 说明 |
864
865
  |------|------|------|------|
865
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
866
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
866
867
  | `requests` | array | 是 | 审批列表 |
867
868
 
868
869
  `requests` 数组每项:
@@ -894,7 +895,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
894
895
 
895
896
  | 参数 | 类型 | 必填 | 说明 |
896
897
  |------|------|------|------|
897
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
898
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
898
899
  | `code` | string | 否 | 自定义邀请码(不提供则自动生成) |
899
900
  | `max_uses` | integer | 否 | 最大使用次数,默认 1,必须 > 0 |
900
901
  | `expires_in_seconds` | integer | 否 | 有效期(秒),默认由 invite_code_ttl_days 配置(7 天) |
@@ -912,7 +913,7 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
912
913
  "max_uses": 10,
913
914
  "used_count": 0,
914
915
  "status": "active",
915
- "created_at": 1234567890000
916
+ "created_at": 1234567890000
916
917
  }
917
918
  }
918
919
  ```
@@ -937,13 +938,13 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
937
938
 
938
939
  列出群组的邀请码。需要 admin 权限。
939
940
 
940
- **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
941
+ **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
941
942
 
942
943
  ### group.revoke_invite_code
943
944
 
944
945
  撤销邀请码。需要 admin 权限。
945
946
 
946
- **参数**:`group_id`(string,兼容字段,值使用目标态 `group_aid`),`code` (string)
947
+ **参数**:`group_id`(string,兼容字段,值使用目标态 `group_aid`),`code` (string)
947
948
 
948
949
  ---
949
950
 
@@ -951,28 +952,28 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
951
952
 
952
953
  ### group.set_settings
953
954
 
954
- 统一写入群参数。需要 admin 及以上权限。`dispatch_mode` 是群消息的应用层分发模式标签,会随 `group.send` 生成的消息持久化,并由 SDK 在解密后注入到消息顶层和 `payload.dispatch_mode`。
955
-
956
- `group.index` 是保留设置 key,用于保存 owner/admin SDK 生成并签名的群索引。更新 indexed settings 时必须同包提交新的签名 `group.index`,并通过 `expected_index_etag` 做 CAS。
955
+ 统一写入群参数。需要 admin 及以上权限。`mention_mode` 是群消息的应用层提及过滤模式标签,会随 `group.send` 生成的消息持久化,并由 SDK 在解密后注入到消息顶层和对象 `payload.mention_mode`。
956
+
957
+ `group.index` 是保留设置 key,用于保存 owner/admin SDK 生成并签名的群索引。更新 indexed settings 时必须同包提交新的签名 `group.index`,并通过 `expected_index_etag` 做 CAS。
957
958
 
958
- `dispatch_mode` 不是 `group.send` 的单次入参;要修改后续消息的模式,请通过 `group.set_settings` 更新群设置。
959
+ `mention_mode` 不是 `group.send` 的单次入参;要修改后续消息的模式,请通过 `group.set_settings` 更新群设置。
959
960
 
960
961
  **参数**:
961
962
 
962
963
  | 参数 | 类型 | 必填 | 说明 |
963
964
  |------|------|------|------|
964
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
965
- | `settings` | object | 是 | 要写入的设置键值 |
966
- | `expected_index_etag` | string | 写 `group.index` 时必填 | CAS 期望旧 etag;空字符串表示只允许创建首个 `group.index` |
967
- | `settings["dispatch_mode"]` | string | 否 | `"broadcast"` / `"mention"`,默认 `"broadcast"` |
968
- | `settings["rules.content"]` | string | 否 | 群规则正文 |
969
- | `settings["rules.attachments"]` | array | 否 | 群规则附件稳定引用 |
970
- | `settings["announcement.content"]` | string | 否 | 群公告正文 |
971
- | `settings["announcement.attachments"]` | array | 否 | 群公告附件稳定引用 |
972
- | `settings["join.attachments"]` | array | 否 | 入群要求附件稳定引用 |
973
- | `settings["{keyName}.content"]` | string | 否 | 通用文档型 indexed setting 正文;`keyName` 需满足受控命名规则 |
974
- | `settings["{keyName}.attachments"]` | array | 否 | 通用文档型 indexed setting 附件稳定引用 |
975
- | `settings["group.index"]` | object | 更新 indexed settings 时必填 | 签名 group index,当前结构至少包含 `body` |
965
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
966
+ | `settings` | object | 是 | 要写入的设置键值 |
967
+ | `expected_index_etag` | string | 写 `group.index` 时必填 | CAS 期望旧 etag;空字符串表示只允许创建首个 `group.index` |
968
+ | `settings["mention_mode"]` | string | 否 | `"disabled"` / `"mention-only"`,默认 `"disabled"`;服务端兼容旧名和值 |
969
+ | `settings["rules.content"]` | string | 否 | 群规则正文 |
970
+ | `settings["rules.attachments"]` | array | 否 | 群规则附件稳定引用 |
971
+ | `settings["announcement.content"]` | string | 否 | 群公告正文 |
972
+ | `settings["announcement.attachments"]` | array | 否 | 群公告附件稳定引用 |
973
+ | `settings["join.attachments"]` | array | 否 | 入群要求附件稳定引用 |
974
+ | `settings["{keyName}.content"]` | string | 否 | 通用文档型 indexed setting 正文;`keyName` 需满足受控命名规则 |
975
+ | `settings["{keyName}.attachments"]` | array | 否 | 通用文档型 indexed setting 附件稳定引用 |
976
+ | `settings["group.index"]` | object | 更新 indexed settings 时必填 | 签名 group index,当前结构至少包含 `body` |
976
977
 
977
978
  **预定义群级参数**:
978
979
 
@@ -986,122 +987,122 @@ aun-group-aid-renew-v1|{group_id}|{group_aid}|{sha256(old_public_key)}|{sha256(n
986
987
  | `announcement.content` | string | `""` | 群公告正文 |
987
988
  | `announcement.attachments` | array | `[]` | 群公告附件 |
988
989
  | `join.mode` | string | 按 `visibility` 推导:`public -> open`,`private -> approval` | 入群模式:`"open"` / `"approval"` / `"invite_only"` / `"closed"` |
989
- | `join.question` | string | `""` | 入群问题 |
990
- | `join.auto_approve_patterns` | array | `[]` | 自动批准 AID 匹配规则 |
991
- | `join.max_pending` | integer | `100` | 最大待审批入群申请数 |
992
- | `join.attachments` | array | `[]` | 入群材料附件稳定引用 |
993
- | `dispatch_mode` | string | `"broadcast"` | 群消息分发标签:`"broadcast"` / `"mention"`;未显式设置时 `get_settings` 仍返回默认值 |
994
- | `group.index` | object | — | 保留 key;签名 JSONL 群索引,由 SDK 生成,服务端只校验、CAS 保存和返回 |
995
-
996
- **indexed settings**:
997
-
998
- | key | 说明 |
999
- |-----|------|
1000
- | `rules.content` / `rules.attachments` | 群规则正文与附件稳定引用 |
1001
- | `announcement.content` / `announcement.attachments` | 群公告正文与附件稳定引用 |
1002
- | `join.mode` / `join.question` / `join.auto_approve_patterns` / `join.max_pending` / `join.attachments` | 入群要求配置与附件稳定引用 |
1003
- | `{keyName}.content` / `{keyName}.attachments` | 通用文档型设置正文与附件稳定引用 |
1004
-
1005
- 写入规则:
1006
-
1007
- - 只更新非 indexed settings 时,继续直接调用 `set_settings`,不需要 `group.index`。
1008
- - 更新任意 indexed setting 时,必须在同一次 `settings` 中携带签名 `group.index`。
1009
- - 服务端只接受受控动态文档 key:`{keyName}.content` / `{keyName}.attachments`,其中 `keyName` 匹配 `^[A-Za-z][A-Za-z0-9_-]{0,63}$`,且不能使用 `join` 等保留前缀。调用方不能用该机制写任意 settings key。
1010
- - 写入 `group.index` 时必须传 `expected_index_etag`。
1011
- - 服务端在同一事务内比较当前 `group.index` etag、写 indexed settings、写 `group.index`。
1012
- - CAS 失败时错误消息包含 `group.index etag conflict`;SDK 的 `updateGroupIndex` 会重新读取当前 index、重建签名并按 `max_attempts` 重试。
1013
- - `rules.attachments`、`announcement.attachments`、`join.attachments` 和 `{keyName}.attachments` 只保存附件引用;附件实体应先写入群自有区,推荐路径为 `group_aid:/.group/attachments/{rules|announcement|join|<keyName>}/...`。群自有区默认允许 `owner/admin` 写入,`member` 默认不可写;`.group/` 是系统控制目录,不允许授予 `role:member` 写权限。
1014
-
1015
- ```python
1016
- await client.call("group.set_settings", {
990
+ | `join.question` | string | `""` | 入群问题 |
991
+ | `join.auto_approve_patterns` | array | `[]` | 自动批准 AID 匹配规则 |
992
+ | `join.max_pending` | integer | `100` | 最大待审批入群申请数 |
993
+ | `join.attachments` | array | `[]` | 入群材料附件稳定引用 |
994
+ | `mention_mode` | string | `"disabled"` | 群消息提及过滤标签:`"disabled"` / `"mention-only"`;未显式设置时 `get_settings` 仍返回默认值 |
995
+ | `group.index` | object | — | 保留 key;签名 JSONL 群索引,由 SDK 生成,服务端只校验、CAS 保存和返回 |
996
+
997
+ **indexed settings**:
998
+
999
+ | key | 说明 |
1000
+ |-----|------|
1001
+ | `rules.content` / `rules.attachments` | 群规则正文与附件稳定引用 |
1002
+ | `announcement.content` / `announcement.attachments` | 群公告正文与附件稳定引用 |
1003
+ | `join.mode` / `join.question` / `join.auto_approve_patterns` / `join.max_pending` / `join.attachments` | 入群要求配置与附件稳定引用 |
1004
+ | `{keyName}.content` / `{keyName}.attachments` | 通用文档型设置正文与附件稳定引用 |
1005
+
1006
+ 写入规则:
1007
+
1008
+ - 只更新非 indexed settings 时,继续直接调用 `set_settings`,不需要 `group.index`。
1009
+ - 更新任意 indexed setting 时,必须在同一次 `settings` 中携带签名 `group.index`。
1010
+ - 服务端只接受受控动态文档 key:`{keyName}.content` / `{keyName}.attachments`,其中 `keyName` 匹配 `^[A-Za-z][A-Za-z0-9_-]{0,63}$`,且不能使用 `join` 等保留前缀。调用方不能用该机制写任意 settings key。
1011
+ - 写入 `group.index` 时必须传 `expected_index_etag`。
1012
+ - 服务端在同一事务内比较当前 `group.index` etag、写 indexed settings、写 `group.index`。
1013
+ - CAS 失败时错误消息包含 `group.index etag conflict`;SDK 的 `updateGroupIndex` 会重新读取当前 index、重建签名并按 `max_attempts` 重试。
1014
+ - `rules.attachments`、`announcement.attachments`、`join.attachments` 和 `{keyName}.attachments` 只保存附件引用;附件实体应先写入群自有区,推荐路径为 `group_aid:/.group/attachments/{rules|announcement|join|<keyName>}/...`。群自有区默认允许 `owner/admin` 写入,`member` 默认不可写;`.group/` 是系统控制目录,不允许授予 `role:member` 写权限。
1015
+
1016
+ ```python
1017
+ await client.call("group.set_settings", {
1017
1018
  "group_id": "g-abc123.agentid.pub",
1018
- "settings": {"dispatch_mode": "mention"},
1019
+ "settings": {"mention_mode": "mention-only"},
1019
1020
  })
1020
1021
  ```
1021
1022
 
1022
1023
  **响应**:
1023
1024
 
1024
1025
  ```json
1025
- {
1026
- "group_id": "g-abc123.agentid.pub",
1027
- "group_aid": "g-abc123.agentid.pub",
1028
- "updated_keys": ["dispatch_mode"]
1029
- }
1030
- ```
1031
-
1032
- 写入 `group.index` 成功时,响应顶层会强制携带 `_meta.group_indexes`:
1033
-
1034
- ```json
1035
- {
1036
- "group_id": "g-abc123.agentid.pub",
1037
- "group_aid": "g-abc123.agentid.pub",
1038
- "updated_keys": ["announcement.content", "group.index"],
1039
- "_meta": {
1040
- "group_indexes": {
1041
- "g-abc123.agentid.pub": {
1042
- "etag": "\"sha256:...\"",
1043
- "last_modified": 1780000000000,
1044
- "schema": "aun.group.index.v1"
1045
- }
1046
- }
1047
- }
1048
- }
1049
- ```
1050
-
1051
- `group.index` 的正文格式:
1052
-
1053
- ```jsonl
1054
- {"type":"index_meta","group_aid":"g-abc123.agentid.pub","etag":"\"sha256:...\"","last_modified":1780000000000,"schema":"aun.group.index.v1","body_hash":"sha256:...","signed_by":"alice.agentid.pub","sig_alg":"ECDSA-P256-SHA256","signature":"base64..."}
1055
- {"key":"announcement.content","source":"db","etag":"\"sha256:...\"","last_modified":1780000000000}
1056
- ```
1057
-
1058
- `etag` 和 `body_hash` 都由 index 条目的 canonical JSONL bytes 计算。`signature` 覆盖去掉 `signature` 字段后的 `index_meta` 和正文条目,`signed_by` 必须等于本次 RPC actor AID。服务端不会根据 DB 状态生成 `group.index`。
1059
-
1060
- ### group.get_settings
1061
-
1062
- 统一读取群参数。成员可读;不传 `keys` 时返回核心群资料和 settings 表中的全部设置。未显式设置 `dispatch_mode` 时,服务端仍返回默认值 `"broadcast"`。读取 `keys=["group.index"]` 可从服务端摘取当前签名 `group.index`。
1026
+ {
1027
+ "group_id": "g-abc123.agentid.pub",
1028
+ "group_aid": "g-abc123.agentid.pub",
1029
+ "updated_keys": ["mention_mode"]
1030
+ }
1031
+ ```
1032
+
1033
+ 写入 `group.index` 成功时,响应顶层会强制携带 `_meta.group_indexes`:
1034
+
1035
+ ```json
1036
+ {
1037
+ "group_id": "g-abc123.agentid.pub",
1038
+ "group_aid": "g-abc123.agentid.pub",
1039
+ "updated_keys": ["announcement.content", "group.index"],
1040
+ "_meta": {
1041
+ "group_indexes": {
1042
+ "g-abc123.agentid.pub": {
1043
+ "etag": "\"sha256:...\"",
1044
+ "last_modified": 1780000000000,
1045
+ "schema": "aun.group.index.v1"
1046
+ }
1047
+ }
1048
+ }
1049
+ }
1050
+ ```
1051
+
1052
+ `group.index` 的正文格式:
1053
+
1054
+ ```jsonl
1055
+ {"type":"index_meta","group_aid":"g-abc123.agentid.pub","etag":"\"sha256:...\"","last_modified":1780000000000,"schema":"aun.group.index.v1","body_hash":"sha256:...","signed_by":"alice.agentid.pub","sig_alg":"ECDSA-P256-SHA256","signature":"base64..."}
1056
+ {"key":"announcement.content","source":"db","etag":"\"sha256:...\"","last_modified":1780000000000}
1057
+ ```
1058
+
1059
+ `etag` 和 `body_hash` 都由 index 条目的 canonical JSONL bytes 计算。`signature` 覆盖去掉 `signature` 字段后的 `index_meta` 和正文条目,`signed_by` 必须等于本次 RPC actor AID。服务端不会根据 DB 状态生成 `group.index`。
1060
+
1061
+ ### group.get_settings
1062
+
1063
+ 统一读取群参数。成员可读;不传 `keys` 时返回核心群资料和 settings 表中的全部设置。未显式设置 `mention_mode` 时,服务端仍返回默认值 `"disabled"`。读取 `keys=["group.index"]` 可从服务端摘取当前签名 `group.index`。
1063
1064
 
1064
1065
  **参数**:
1065
1066
 
1066
1067
  | 参数 | 类型 | 必填 | 说明 |
1067
1068
  |------|------|------|------|
1068
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1069
- | `keys` | array | 否 | 只读取指定 key,如 `["dispatch_mode", "rules.content"]`;读取 `["group.index"]` 时强制返回 `_meta.group_indexes` |
1069
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1070
+ | `keys` | array | 否 | 只读取指定 key,如 `["mention_mode", "rules.content"]`;读取 `["group.index"]` 时强制返回 `_meta.group_indexes` |
1070
1071
 
1071
1072
  **响应**:
1072
1073
 
1073
1074
  ```json
1074
- {
1075
- "group_id": "g-abc123.agentid.pub",
1076
- "group_aid": "g-abc123.agentid.pub",
1077
- "settings": [
1078
- {"key": "dispatch_mode", "value": "broadcast", "updated_at": 1234567890000}
1079
- ]
1080
- }
1081
- ```
1082
-
1083
- 如果服务端已保存 `group.index`,普通 settings 读取可能在顶层返回 `_meta.group_indexes`。该 meta 受服务端注入频率控制;显式读取 `group.index` 时会强制返回:
1084
-
1085
- ```json
1086
- {
1087
- "group_id": "g-abc123.agentid.pub",
1088
- "group_aid": "g-abc123.agentid.pub",
1089
- "settings": [
1090
- {"key": "group.index", "value": {"body": "..."}, "updated_by": "alice.agentid.pub", "updated_at": 1780000000000}
1091
- ],
1092
- "_meta": {
1093
- "group_indexes": {
1094
- "g-abc123.agentid.pub": {
1095
- "etag": "\"sha256:...\"",
1096
- "last_modified": 1780000000000,
1097
- "schema": "aun.group.index.v1"
1098
- }
1099
- }
1100
- }
1101
- }
1102
- ```
1103
-
1104
- SDK 观察到 `_meta.group_indexes` 只记录远端 etag,不会自动覆盖本地 index 或业务缓存。etag 不一致只表示本地与观察到的远端版本不同,方向由应用层决定:`checkGroupIndex` 用于检查是否不同步,`getGroupIndex` 用于显式 pull 远端 manifest 并同步本地缓存,`updateGroupIndex` 用于显式 CAS push 本地 indexed settings。
1075
+ {
1076
+ "group_id": "g-abc123.agentid.pub",
1077
+ "group_aid": "g-abc123.agentid.pub",
1078
+ "settings": [
1079
+ {"key": "mention_mode", "value": "disabled", "updated_at": 1234567890000}
1080
+ ]
1081
+ }
1082
+ ```
1083
+
1084
+ 如果服务端已保存 `group.index`,普通 settings 读取可能在顶层返回 `_meta.group_indexes`。该 meta 受服务端注入频率控制;显式读取 `group.index` 时会强制返回:
1085
+
1086
+ ```json
1087
+ {
1088
+ "group_id": "g-abc123.agentid.pub",
1089
+ "group_aid": "g-abc123.agentid.pub",
1090
+ "settings": [
1091
+ {"key": "group.index", "value": {"body": "..."}, "updated_by": "alice.agentid.pub", "updated_at": 1780000000000}
1092
+ ],
1093
+ "_meta": {
1094
+ "group_indexes": {
1095
+ "g-abc123.agentid.pub": {
1096
+ "etag": "\"sha256:...\"",
1097
+ "last_modified": 1780000000000,
1098
+ "schema": "aun.group.index.v1"
1099
+ }
1100
+ }
1101
+ }
1102
+ }
1103
+ ```
1104
+
1105
+ SDK 观察到 `_meta.group_indexes` 只记录远端 etag,不会自动覆盖本地 index 或业务缓存。etag 不一致只表示本地与观察到的远端版本不同,方向由应用层决定:`checkGroupIndex` 用于检查是否不同步,`getGroupIndex` 用于显式 pull 远端 manifest 并同步本地缓存,`updateGroupIndex` 用于显式 CAS push 本地 indexed settings。
1105
1106
 
1106
1107
  ## 消息
1107
1108
 
@@ -1109,13 +1110,13 @@ SDK 观察到 `_meta.group_indexes` 只记录远端 etag,不会自动覆盖本
1109
1110
 
1110
1111
  发送群消息。需要 member 权限。
1111
1112
 
1112
- 群消息的持久化 `dispatch_mode` 来自群设置,取值为 `"broadcast"` / `"mention"`;服务端会写入消息对象并在 pull / push 中返回。运行时是否广播全员或分发给值班 Agent,由响应中的 `dispatch` / `message_dispatch` 描述。
1113
+ 群消息的持久化 `mention_mode` 来自群设置,取值为 `"disabled"` / `"mention-only"`;服务端会写入消息对象并在 pull / push 中返回。运行时是否广播全员或分发给值班 Agent,由响应中的 `dispatch` / `message_dispatch` 描述。V2 加密消息把快照放在既有 `envelope_json` 元数据中,不改变 `per_device` 投递列。
1113
1114
 
1114
1115
  **参数**:
1115
1116
 
1116
1117
  | 参数 | 类型 | 必填 | 说明 |
1117
1118
  |------|------|------|------|
1118
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1119
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1119
1120
  | `payload` | object | 否 | 消息内容 |
1120
1121
  | `type` | string | 否 | 信封/封装类型,普通业务消息无需填写;SDK 加密群消息时自动使用 `e2ee.group_encrypted` |
1121
1122
  | `attachments` | array | 否 | 兼容旧接口的顶层附件元数据;推荐把业务附件放入 `payload.attachments` |
@@ -1123,7 +1124,7 @@ SDK 观察到 `_meta.group_indexes` 只记录远端 etag,不会自动覆盖本
1123
1124
 
1124
1125
  ### Payload 参考约定
1125
1126
 
1126
- `group.send.params.payload` 的统一业务负载格式见 [09-payload-reference](09-payload-reference.md)。完整群消息请求仍在 `payload` 同级传入 `group_id`(兼容参数名,值使用目标态 `group_aid`);业务类型放在 `payload.type`,不要与 `group.send.params.type` 信封/封装类型混用。
1127
+ `group.send.params.payload` 的统一业务负载格式见 [09-payload-reference](09-payload-reference.md)。完整群消息请求仍在 `payload` 同级传入 `group_id`(兼容参数名,值使用目标态 `group_aid`);业务类型放在 `payload.type`,不要与 `group.send.params.type` 信封/封装类型混用。
1127
1128
 
1128
1129
  `protected_headers` 只在 SDK 加密路径生效;裸 RPC 发送明文或已加密信封时,调用方需自行遵守 [05-E2EE加密通信](05-E2EE加密通信.md#protectedheaders-与可验证上下文) 的格式和校验规则。
1129
1130
 
@@ -1138,52 +1139,52 @@ SDK 观察到 `_meta.group_indexes` 只记录远端 etag,不会自动覆盖本
1138
1139
  "message_id": "uuid",
1139
1140
  "sender_aid": "alice.agentid.pub",
1140
1141
  "message_type": "e2ee.group_encrypted",
1141
- "dispatch_mode": "broadcast",
1142
+ "mention_mode": "disabled",
1142
1143
  "payload": {"type": "e2ee.group_encrypted", "...": "..."},
1143
1144
  "attachments": [],
1144
1145
  "created_at": 1234567890000
1145
1146
  },
1146
1147
  "event": { ... },
1147
- "dispatch_mode": "broadcast",
1148
- "dispatch": {"mode": "broadcast", "reason": "duty_disabled"},
1149
- "message_dispatch": { ... },
1150
- "envelope": {
1151
- "from": "alice.agentid.pub",
1152
- "group_id": "g-abc123.agentid.pub",
1153
- "type": "text",
1154
- "timestamp": 1234567890000,
1155
- "encrypted": true,
1156
- "payload_type": "text"
1157
- },
1158
- "payload": {"type": "text", "text": "Hello"}
1159
- }
1160
- ```
1148
+ "mention_mode": "disabled",
1149
+ "dispatch": {"mode": "broadcast", "reason": "duty_disabled"},
1150
+ "message_dispatch": { ... },
1151
+ "envelope": {
1152
+ "from": "alice.agentid.pub",
1153
+ "group_id": "g-abc123.agentid.pub",
1154
+ "type": "text",
1155
+ "timestamp": 1234567890000,
1156
+ "encrypted": true,
1157
+ "payload_type": "text"
1158
+ },
1159
+ "payload": {"type": "text", "text": "Hello"}
1160
+ }
1161
+ ```
1161
1162
 
1162
1163
  | 字段 | 类型 | 说明 |
1163
1164
  |------|------|------|
1164
- | `group_id` | string | 兼容字段,值语义为目标态 `group_aid` |
1165
+ | `group_id` | string | 兼容字段,值语义为目标态 `group_aid` |
1165
1166
  | `message` | object | 消息对象(含 seq、message_id、sender_aid 等) |
1166
1167
  | `event` | object | 关联的群事件对象 |
1167
- | `dispatch_mode` | string | 群消息持久化分发模式标签:`"broadcast"` / `"mention"`;SDK 解密后也会注入到 `payload.dispatch_mode` |
1168
- | `dispatch` | object | 分发策略:`mode` 为 `"broadcast"`(广播全员)或 `"duty"`(值班分发);`reason` 说明原因(如 `"duty_disabled"` / `"active_duty"` / `"no_duty_candidate"` 等) |
1169
- | `duty_state` | object | 可选,值班模式下的当前状态 |
1170
- | `message_dispatch` | object | 运行时分发结果;常见 `status` 包括 `"broadcast"`、`"sent"`、`"queued_batch"`、`"debounced"`、`"skipped"`、`"failed"` |
1171
- | `envelope` | object | SDK 回填的发送结果信封,包含发送方、群标识、业务类型、时间戳、加密标志、protected headers 等可转发元数据 |
1172
- | `payload` | object | SDK 回填的应用层业务 payload;裸 RPC 或内部 `_skip_send_result_envelope` 路径可能没有该字段 |
1168
+ | `mention_mode` | string | 群消息提及过滤模式标签:`"disabled"` / `"mention-only"`;SDK 解密后也会注入到对象 `payload.mention_mode` |
1169
+ | `dispatch` | object | 分发策略:`mode` 为 `"broadcast"`(广播全员)或 `"duty"`(值班分发);`reason` 说明原因(如 `"duty_disabled"` / `"active_duty"` / `"no_duty_candidate"` 等) |
1170
+ | `duty_state` | object | 可选,值班模式下的当前状态 |
1171
+ | `message_dispatch` | object | 运行时分发结果;常见 `status` 包括 `"broadcast"`、`"sent"`、`"queued_batch"`、`"debounced"`、`"skipped"`、`"failed"` |
1172
+ | `envelope` | object | SDK 回填的发送结果信封,包含发送方、群标识、业务类型、时间戳、加密标志、protected headers 等可转发元数据 |
1173
+ | `payload` | object | SDK 回填的应用层业务 payload;裸 RPC 或内部 `_skip_send_result_envelope` 路径可能没有该字段 |
1173
1174
 
1174
1175
  ### group.thought.put
1175
1176
 
1176
1177
  写入某个发送者针对一个群上下文的思考内容。该内容不是普通群消息:服务端不分配消息 `seq`,不广播,不进入 `group.pull`,不需要 ack,也不持久化;只在内存中保留当前 head。
1177
1178
 
1178
- SDK 调用时必须走群组 E2EE。应用层传入明文 `payload`,SDK 会加密成 V2 `e2ee.group_encrypted` 信封、补齐 `thought_id` / `timestamp`,并附加 `client_signature`。裸 WebSocket 客户端若绕过 SDK,至少必须自行完成 V2 envelope、`sender_signature`、AAD 和 state commitment 生成;`client_signature` 按 Gateway 连接级身份语义携带。
1179
+ SDK 调用时必须走群组 E2EE。应用层传入明文 `payload`,SDK 会加密成 V2 `e2ee.group_encrypted` 信封、补齐 `thought_id` / `timestamp`,并附加 `client_signature`。裸 WebSocket 客户端若绕过 SDK,至少必须自行完成 V2 envelope、`sender_signature`、AAD 和 state commitment 生成;`client_signature` 按 Gateway 连接级身份语义携带。
1179
1180
 
1180
- 存储键为规范化后的 `group_aid + sender_aid + context.type + context.id`。RPC 字段名仍为 `group_id` 以兼容旧客户端,但服务端会先规范化为目标态群标识;`sender_aid` 由服务端认证态派生,不能由客户端指定;`context` 是 thought head 的唯一 selector,推荐使用 `{"type": "run", "id": "run-xxx"}`。同一 `(group_aid, sender_aid)` 保留最近 N 个 context 对应的 head,N 由群服务配置 `max_thought_heads_per_sender` 控制,当前默认值为 100;同一个 head 下可追加多条 thought item。
1181
+ 存储键为规范化后的 `group_aid + sender_aid + context.type + context.id`。RPC 字段名仍为 `group_id` 以兼容旧客户端,但服务端会先规范化为目标态群标识;`sender_aid` 由服务端认证态派生,不能由客户端指定;`context` 是 thought head 的唯一 selector,推荐使用 `{"type": "run", "id": "run-xxx"}`。同一 `(group_aid, sender_aid)` 保留最近 N 个 context 对应的 head,N 由群服务配置 `max_thought_heads_per_sender` 控制,当前默认值为 100;同一个 head 下可追加多条 thought item。
1181
1182
 
1182
1183
  **参数**:
1183
1184
 
1184
1185
  | 参数 | 类型 | 必填 | 说明 |
1185
1186
  |------|------|------|------|
1186
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1187
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1187
1188
  | `context.type` | string | 是 | 思考的上下文类型,推荐 `run` |
1188
1189
  | `context.id` | string | 是 | 思考的上下文 ID,如 `run_id` |
1189
1190
  | `payload` | object | 是 | SDK 加密前的思考内容;推荐格式见 [09-payload-reference](09-payload-reference.md#thought思考内容) |
@@ -1211,7 +1212,7 @@ await client.call("group.thought.put", {
1211
1212
  "thought_id": "gt-...",
1212
1213
  "type": "e2ee.group_encrypted",
1213
1214
  "encrypted": true,
1214
- "payload": {"type": "e2ee.group_encrypted", "version": "v2", "...": "..."},
1215
+ "payload": {"type": "e2ee.group_encrypted", "version": "v2", "...": "..."},
1215
1216
  "client_signature": { "...": "..." }
1216
1217
  }
1217
1218
  ```
@@ -1237,7 +1238,7 @@ await client.call("group.thought.put", {
1237
1238
 
1238
1239
  | 参数 | 类型 | 必填 | 说明 |
1239
1240
  |------|------|------|------|
1240
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1241
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1241
1242
  | `sender_aid` | string | 是 | thought 作者 AID |
1242
1243
  | `context.type` | string | 是 | 思考的上下文类型,推荐 `run` |
1243
1244
  | `context.id` | string | 是 | 思考的上下文 ID,如 `run_id` |
@@ -1286,9 +1287,9 @@ result = await client.call("group.thought.get", {
1286
1287
 
1287
1288
  | 参数 | 类型 | 必填 | 默认值 | 说明 |
1288
1289
  |------|------|------|--------|------|
1289
- | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1290
+ | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1290
1291
  | `after_message_seq` | integer | 否 | 0 | 从该消息 seq 之后拉取 |
1291
- | `limit` | integer | 否 | 50 | 最大条数(最大 50;`pull_max_limit` 配置只能进一步收紧) |
1292
+ | `limit` | integer | 否 | 50 | 最大条数(最大 50;`pull_max_limit` 配置只能进一步收紧) |
1292
1293
  | `device_id` | string | 否 | — | 设备 ID(多设备模式) |
1293
1294
 
1294
1295
  **响应**:
@@ -1299,13 +1300,37 @@ result = await client.call("group.thought.get", {
1299
1300
  "messages": [ ... ],
1300
1301
  "latest_message_seq": 42,
1301
1302
  "has_more": false,
1302
- "limit": 50
1303
+ "limit": 50,
1304
+ "retention_floor_message_seq": 20,
1305
+ "earliest_available_message_seq": 31
1303
1306
  }
1304
1307
  ```
1305
1308
 
1306
1309
  多设备模式时额外返回 `cursor` 对象(含 `current_seq`、`join_seq`、`latest_seq`、`unread_count`)。
1307
1310
 
1308
- 返回的每条群消息包含 `dispatch_mode`。Python / Go / TS / JS SDK 在解密后会保留顶层 `dispatch_mode`,并把同一值注入到 `payload.dispatch_mode`,方便应用层按 `"broadcast"` / `"mention"` UI 或通知策略。
1311
+ `group.pull` 是公开的 Forward Pull。实时 A/T/H 最新页同步由 SDK 内部自动完成,不提供需要应用传入的模式参数。普通 Forward 中,`retention_floor_message_seq` 只表示已提交物理 GC;`earliest_available_message_seq-1` 表示服务端综合 retention、入群点和 epoch 后的当前成员可见性排他下界。SDK 以 `max(retention_floor_message_seq, cursor.join_seq, earliest_available_message_seq-1)` 推进 A;History 不修改 A/T/H。
1312
+
1313
+ Forward 原始页校验通过后按页内最大 seq 推进 A,单条解密失败通过 `group.message_undecryptable` 报告而不阻塞水位。Piggy ACK 保留:有待提交 ACK 时,非满页会继续拉一页并携带 ACK,空页后停止。
1314
+
1315
+ `group.pull` 与 `group.history` 进入当前 `AUNClient` 的客户端级 Pull Gate。该 Gate 与 P2P Message、Group Event Pull 共享,始终 single-inflight;相同请求 key 折叠并共享结果,不同 key 按前台 FIFO(Tail/History)优先于后台 FIFO(Forward/Gap Fill/Group Event)排队。不同 `AUNClient` 实例之间不共享 Gate,应用层无需自行实现并发控制。
1316
+
1317
+ 解密当前群消息时若缺少 sender IK,SDK 先执行同发送端 single-flight 的有界同步 bootstrap,最多等待 3 秒;P2P bootstrap 未命中时可继续读取 Group bootstrap。成功后立即重试当前消息,失败或超时才 pending,且不阻塞实时扫描水位。
1318
+
1319
+ SDK 只保证单个实时拉取响应页内按 seq 升序、同 seq 最多发布一次。A/T/H 是扫描水位,不记录应用是否已经收到回调;跨 Push、SDK 自动最新页同步和 Forward 页允许重复和乱序。全局去重与排序由应用业务仓库负责,不是 SDK 交付契约;应用必须在群 namespace 内按 `message_id` 幂等并按 `seq` 排序。SDK 进程内折叠仅作 best-effort 优化。History 只返回结果,不参与实时发布。
1320
+
1321
+ 返回的每条群消息包含 `mention_mode`。Python / Go / TS / JS SDK 在解密后会保留顶层 `mention_mode`,并把同一值注入到对象 `payload.mention_mode`,方便应用层按 `"disabled"` / `"mention-only"` 做 UI 或通知策略。
1322
+
1323
+ ### group.history
1324
+
1325
+ 只读向前翻页群消息。Group Event 不进入此接口,也不受消息 A/T/H 影响。
1326
+
1327
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
1328
+ |------|------|------|--------|------|
1329
+ | `group_id` | string | 是 | — | 群组标识 |
1330
+ | `before_seq` | integer | 是 | — | 排他上界,只返回 `seq < before_seq` 的消息 |
1331
+ | `limit` | integer | 否 | 50 | 单页上限,最大 50 |
1332
+
1333
+ 响应包含 `messages`、`window_start_seq`、`next_before_seq`、`has_older`、`retention_floor_seq` 和 `earliest_available_seq`。页内按 seq 升序;解密失败项以结构化错误返回。下一页必须直接复用 `next_before_seq`,不得根据首条消息自行加减。History 不推进消息/事件 ACK,不修改实时 A/T/H,也不触发 `group.message_created`。
1309
1334
 
1310
1335
  ### group.ack
1311
1336
 
@@ -1315,7 +1340,7 @@ result = await client.call("group.thought.get", {
1315
1340
 
1316
1341
  | 参数 | 类型 | 必填 | 说明 |
1317
1342
  |------|------|------|------|
1318
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1343
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1319
1344
  | `device_id` | string | 是 | 设备 ID |
1320
1345
  | `msg_seq` | integer | 是 | 确认到的消息序号 |
1321
1346
 
@@ -1340,7 +1365,7 @@ result = await client.call("group.thought.get", {
1340
1365
 
1341
1366
  | 参数 | 类型 | 必填 | 说明 |
1342
1367
  |------|------|------|------|
1343
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1368
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1344
1369
  | `message_ids` | string[] | 是 | 待撤回消息 ID 列表,最多 100 个(`recall_max_batch`)|
1345
1370
  | `reason` | string | 否 | 可选撤回理由,建议短文本(最长 255 字符)|
1346
1371
 
@@ -1395,9 +1420,9 @@ result = await client.call("group.thought.get", {
1395
1420
 
1396
1421
  权限与签名约束:
1397
1422
 
1398
- - 群自有区是除 `memberdata` 等系统保留路径外的整个 `group_aid` namespace。`group_aid` 当前证书签名可写;成员角色中 `owner/admin` 默认可写,`member` 默认不可写。`group_aid:/.group/` 是系统控制目录,用于群公告、群规则、入群要求附件,默认允许 `owner/admin` 写入。
1399
- - 老群如果缺少 `.group/` 默认 ACL,group 服务会在该群首次被 RPC 访问时 best-effort 触发 namespace/ACL lazy repair;只有本次 baseline ACL 全部同步成功才记录本进程已检查,失败会在后续访问继续重试。
1400
- - `group.fs.set_acl` / `group.fs.remove_acl` / `group.fs.get_acl` / `group.fs.list_acl` 只能由当前 group `owner/admin` 调用。当前支持 `grantee_aid="role:admin"` 与 `grantee_aid="role:member"`;`role:member` 只能授予具体业务目录的 `rw` 权限,不能授予根目录或 `.group/`,也不能获得删除、移动、重命名权限。成员升降级、退群、踢出不会联动授权或撤销目录 ACL。
1423
+ - 群自有区是除 `memberdata` 等系统保留路径外的整个 `group_aid` namespace。`group_aid` 当前证书签名可写;成员角色中 `owner/admin` 默认可写,`member` 默认不可写。`group_aid:/.group/` 是系统控制目录,用于群公告、群规则、入群要求附件,默认允许 `owner/admin` 写入。
1424
+ - 老群如果缺少 `.group/` 默认 ACL,group 服务会在该群首次被 RPC 访问时 best-effort 触发 namespace/ACL lazy repair;只有本次 baseline ACL 全部同步成功才记录本进程已检查,失败会在后续访问继续重试。
1425
+ - `group.fs.set_acl` / `group.fs.remove_acl` / `group.fs.get_acl` / `group.fs.list_acl` 只能由当前 group `owner/admin` 调用。当前支持 `grantee_aid="role:admin"` 与 `grantee_aid="role:member"`;`role:member` 只能授予具体业务目录的 `rw` 权限,不能授予根目录或 `.group/`,也不能获得删除、移动、重命名权限。成员升降级、退群、踢出不会联动授权或撤销目录 ACL。
1401
1426
  - `memberdata/{member_ref}` 写入默认只允许该成员本人;SDK 只传 group path,不拼接真实 storage 路径。
1402
1427
  - 上传控制面会透传 `parents` 到 storage:默认 `parents=true` 时可递归创建父目录,显式 `parents=false` 时父目录必须已存在。
1403
1428
  - JavaScript 浏览器版 `cp(string, group)` 默认把 string 当文本内容上传;Node 本地路径需显式传 `sourceType: "path"`、`localPath: true` 或使用 `local:` 前缀。Python、TypeScript 和 Go 默认把 string 当本地路径。
@@ -1422,27 +1447,29 @@ result = await client.call("group.thought.get", {
1422
1447
 
1423
1448
  查看群文件系统用量。参数可传 `path` 或 `group_id`。
1424
1449
 
1425
- ### group.fs.create_download_ticket
1426
-
1427
- 创建下载票据。参数:`path` 必填。响应包含 `download_url`、可选 `sha256`、`content_type`、`file_name`。SDK 下载数据面使用该票据执行 HTTP GET 并校验 sha256。
1450
+ ### group.fs.create_download_ticket
1451
+
1452
+ 创建下载票据。参数:`path` 必填。响应包含 `url` / `download_url`、`expire_at`,以及可选的 `token`、`sha256`、`content_type`、`file_name`。私有文件和跨 issuer 文件由资源所在域签发短 TTL `?t=` 能力凭据;Group 只返回票据,不代理文件字节。
1453
+
1454
+ SDK Group FS 门面使用票据执行 HTTP GET 并校验 sha256。应用自行下载时遵守与 `storage.create_download_ticket` 相同的数据面规则:完整保留 URL 中的 `?t=`;只有端点明确要求 AID Bearer 时,才在每次请求前调用 Python `get_access_token()`、TypeScript / JavaScript `getAccessToken()` 或 Go `GetAccessToken()`;不得长期复用 `authenticate()` 首次返回的 token,也不得把当前域的 AID JWT 发送给另一 issuer 的 storage。401/403 仅在重新读取到不同 token 时重试一次;票据过期应重新申请。完整流程见 [Storage RPC 手册](09-storage-rpc-manual.md#数据面-http-下载流程)。
1428
1455
 
1429
1456
  ### group.fs.set_acl
1430
1457
 
1431
- 授予群自有区角色 ACL。需要当前 group `owner/admin` 身份调用;底层由 group 服务以内部门面写入 `storage.set_acl`。
1432
-
1433
- 参数:`path` 必填,指向群自有区路径;`grantee_aid` 可为 `role:admin` 或 `role:member`。`role:admin` 默认 `rwx`;`role:member` 只能为 `rw`,且只能授到具体业务目录,不能授到根目录或 `.group/`。`path` 可传 `group_aid:/archive` 等 group path。服务端写入 storage 内部权限位时会把 POSIX 删除位 `x` 映射为内部 `d`,对外响应仍显示 `rwx`;不授删除、移动、重命名权限时使用 `rw`。
1458
+ 授予群自有区角色 ACL。需要当前 group `owner/admin` 身份调用;底层由 group 服务以内部门面写入 `storage.set_acl`。
1459
+
1460
+ 参数:`path` 必填,指向群自有区路径;`grantee_aid` 可为 `role:admin` 或 `role:member`。`role:admin` 默认 `rwx`;`role:member` 只能为 `rw`,且只能授到具体业务目录,不能授到根目录或 `.group/`。`path` 可传 `group_aid:/archive` 等 group path。服务端写入 storage 内部权限位时会把 POSIX 删除位 `x` 映射为内部 `d`,对外响应仍显示 `rwx`;不授删除、移动、重命名权限时使用 `rw`。
1434
1461
 
1435
1462
  ### group.fs.remove_acl
1436
1463
 
1437
- 撤销群自有区角色 ACL。需要当前 group `owner/admin` 身份调用;底层由 group 服务以内部门面写入 `storage.remove_acl`。
1438
-
1439
- 参数:`path` 必填,指向群自有区路径;`grantee_aid` 可为 `role:admin` 或 `role:member`。撤销 `role:member` 后,member 不再因该目录 ACL 获得创建/写入权限。
1464
+ 撤销群自有区角色 ACL。需要当前 group `owner/admin` 身份调用;底层由 group 服务以内部门面写入 `storage.remove_acl`。
1465
+
1466
+ 参数:`path` 必填,指向群自有区路径;`grantee_aid` 可为 `role:admin` 或 `role:member`。撤销 `role:member` 后,member 不再因该目录 ACL 获得创建/写入权限。
1440
1467
 
1441
1468
  ### group.fs.get_acl
1442
1469
 
1443
- 查询群自有区角色 ACL。需要当前 group `owner/admin` 身份调用;普通 member 不能查询。参数:`path` 必填,指向群自有区路径;可传裸路径 + `group_id`,也可传完整 `group_aid:/...`。
1444
-
1445
- 响应包含 `group_id`、`group_aid`、`path`、`area`、`storage` 和 `acls`。`acls[].perms` 使用 POSIX 视图,删除权限显示为 `x`,因此授权 `role:admin:rwx` 后查询也返回 `rwx`;`role:member` 只应返回 `rw`。
1470
+ 查询群自有区角色 ACL。需要当前 group `owner/admin` 身份调用;普通 member 不能查询。参数:`path` 必填,指向群自有区路径;可传裸路径 + `group_id`,也可传完整 `group_aid:/...`。
1471
+
1472
+ 响应包含 `group_id`、`group_aid`、`path`、`area`、`storage` 和 `acls`。`acls[].perms` 使用 POSIX 视图,删除权限显示为 `x`,因此授权 `role:admin:rwx` 后查询也返回 `rwx`;`role:member` 只应返回 `rw`。
1446
1473
 
1447
1474
  ### group.fs.list_acl
1448
1475
 
@@ -1490,7 +1517,7 @@ result = await client.call("group.thought.get", {
1490
1517
 
1491
1518
  获取当前在线成员列表。
1492
1519
 
1493
- **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
1520
+ **参数**:`group_id`(string,必填;兼容字段,值使用目标态 `group_aid`)
1494
1521
 
1495
1522
  **响应**:
1496
1523
 
@@ -1505,10 +1532,10 @@ result = await client.call("group.thought.get", {
1505
1532
  {
1506
1533
  "aid": "alice.agentid.pub",
1507
1534
  "role": "owner",
1508
- "joined_at": 1234567890000,
1535
+ "joined_at": 1234567890000,
1509
1536
  "online": true,
1510
1537
  "session_id": "sess_123",
1511
- "last_active_at": 1234567890000,
1538
+ "last_active_at": 1234567890000,
1512
1539
  "expire_at": 1234571490
1513
1540
  }
1514
1541
  ]
@@ -1523,18 +1550,18 @@ result = await client.call("group.thought.get", {
1523
1550
 
1524
1551
  ### group.pull_events
1525
1552
 
1526
- 增量拉取群事件,支持多设备独立游标。
1553
+ 增量拉取群事件,支持多设备独立游标。SDK 将其作为后台 Pull 放入当前 `AUNClient` 的客户端级 Pull Gate;该 Gate 与 P2P Message、Group Message Pull 共享,始终 single-inflight,相同请求 key 折叠并共享结果,不同 key 按后台 FIFO 排队。Group Event 使用独立的 Forward Cursor,不修改消息 A/T/H;不同 `AUNClient` 实例之间不共享 Gate。应用层无需自行实现并发控制。
1527
1554
 
1528
1555
  **参数**:
1529
1556
 
1530
1557
  | 参数 | 类型 | 必填 | 默认值 | 说明 |
1531
1558
  |------|------|------|--------|------|
1532
- | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1559
+ | `group_id` | string | 是 | — | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1533
1560
  | `device_id` | string | 否 | — | 设备 ID,多设备模式必填 |
1534
1561
  | `device_name` | string | 否 | — | 设备名称(首次注册时使用) |
1535
1562
  | `device_type` | string | 否 | — | 设备类型 |
1536
1563
  | `after_event_seq` | integer | 否 | 游标位置 | 从该事件 seq 之后拉取;多设备模式下默认使用设备游标 |
1537
- | `limit` | integer | 否 | 50 | 最大条数(最大 50;`pull_max_limit` 配置只能进一步收紧) |
1564
+ | `limit` | integer | 否 | 50 | 最大条数(最大 50;`pull_max_limit` 配置只能进一步收紧) |
1538
1565
 
1539
1566
  **响应**:
1540
1567
 
@@ -1544,17 +1571,20 @@ result = await client.call("group.thought.get", {
1544
1571
  "events": [ ... ],
1545
1572
  "latest_event_seq": 100,
1546
1573
  "has_more": false,
1547
- "limit": 50,
1574
+ "limit": 50,
1575
+ "retention_floor_event_seq": 20,
1576
+ "earliest_available_event_seq": 31,
1548
1577
  "cursor": {
1549
- "current_seq": 50,
1550
- "join_seq": 0,
1578
+ "current_seq": 25,
1579
+ "join_seq": 30,
1551
1580
  "latest_seq": 100,
1552
- "unread_count": 50
1581
+ "retention_floor_seq": 20,
1582
+ "unread_count": 70
1553
1583
  }
1554
1584
  }
1555
1585
  ```
1556
1586
 
1557
- > `cursor` 仅多设备模式(提供 `device_id`)时返回。响应大小受 `pull_max_response_bytes` 配置限制。包含 E2EE epoch 范围检查,不返回成员加入前的加密事件。
1587
+ > `retention_floor_event_seq` 只表示已提交物理 GC;`earliest_available_event_seq-1` 是综合 retention、入群点和 epoch 后的当前成员可见性排他下界。SDK 以 `max(retention_floor_event_seq, cursor.current_seq, cursor.join_seq, earliest_available_event_seq-1)` 恢复或推进 Group Event A,ACK 仍只能提交已持久化 A。`cursor` 仅多设备模式(提供 `device_id`)时返回。响应大小受 `pull_max_response_bytes` 配置限制。
1558
1588
 
1559
1589
  ### group.ack_messages
1560
1590
 
@@ -1564,7 +1594,7 @@ result = await client.call("group.thought.get", {
1564
1594
 
1565
1595
  | 参数 | 类型 | 必填 | 说明 |
1566
1596
  |------|------|------|------|
1567
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1597
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1568
1598
  | `device_id` | string | 是 | 设备 ID |
1569
1599
  | `msg_seq` | integer | 是 | 确认到的消息序号 |
1570
1600
 
@@ -1580,7 +1610,7 @@ result = await client.call("group.thought.get", {
1580
1610
 
1581
1611
  | 参数 | 类型 | 必填 | 说明 |
1582
1612
  |------|------|------|------|
1583
- | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1613
+ | `group_id` | string | 是 | 群组标识;兼容字段,值语义为目标态 `group_aid` |
1584
1614
  | `device_id` | string | 是 | 设备 ID |
1585
1615
  | `event_seq` | integer | 是 | 确认到的事件序号 |
1586
1616
 
@@ -1590,7 +1620,7 @@ result = await client.call("group.thought.get", {
1590
1620
 
1591
1621
  列出当前用户在指定群组的所有设备及游标状态。
1592
1622
 
1593
- **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1623
+ **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1594
1624
 
1595
1625
  **响应**:
1596
1626
 
@@ -1613,7 +1643,7 @@ result = await client.call("group.thought.get", {
1613
1643
 
1614
1644
  注销设备游标(清理不再使用的设备记录)。
1615
1645
 
1616
- **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`),`device_id` (必填)
1646
+ **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`),`device_id` (必填)
1617
1647
 
1618
1648
  **响应**:`{ "success": true }`
1619
1649
 
@@ -1625,7 +1655,7 @@ result = await client.call("group.thought.get", {
1625
1655
 
1626
1656
  获取管理员列表(owner + admin 角色)。
1627
1657
 
1628
- **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1658
+ **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1629
1659
 
1630
1660
  **响应**:
1631
1661
 
@@ -1636,7 +1666,7 @@ result = await client.call("group.thought.get", {
1636
1666
  "aid": "alice.agentid.pub",
1637
1667
  "role": "owner",
1638
1668
  "member_type": "human",
1639
- "joined_at": 1234567890000
1669
+ "joined_at": 1234567890000
1640
1670
  }
1641
1671
  ]
1642
1672
  }
@@ -1646,7 +1676,7 @@ result = await client.call("group.thought.get", {
1646
1676
 
1647
1677
  获取群主 AID。
1648
1678
 
1649
- **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1679
+ **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1650
1680
 
1651
1681
  **响应**:`{ "group_id": "g-abc123.agentid.pub", "owner_aid": "alice.agentid.pub" }`
1652
1682
 
@@ -1654,7 +1684,7 @@ result = await client.call("group.thought.get", {
1654
1684
 
1655
1685
  获取群组综合统计摘要。
1656
1686
 
1657
- **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1687
+ **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1658
1688
 
1659
1689
  **响应**:
1660
1690
 
@@ -1673,8 +1703,8 @@ result = await client.call("group.thought.get", {
1673
1703
  "message_seq": 1000,
1674
1704
  "event_seq": 2000,
1675
1705
  "e2ee_epoch": 3,
1676
- "created_at": 1234567890000,
1677
- "updated_at": 1234567890000
1706
+ "created_at": 1234567890000,
1707
+ "updated_at": 1234567890000
1678
1708
  }
1679
1709
  ```
1680
1710
 
@@ -1683,7 +1713,7 @@ result = await client.call("group.thought.get", {
1683
1713
 
1684
1714
  刷新成员类型分类统计。
1685
1715
 
1686
- **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1716
+ **参数**:`group_id`(必填;兼容字段,值使用目标态 `group_aid`)
1687
1717
 
1688
1718
  **响应**:
1689
1719
 
@@ -1739,14 +1769,14 @@ result = await client.call("group.thought.get", {
1739
1769
  }
1740
1770
  ```
1741
1771
 
1742
- SDK 交付给应用层的群事件信封字段统一放在 `envelope`。0.5.x 当前仍保留顶层 `module_id` / `action` / `group_id` / `event_seq` 等兼容别名;新代码应优先通过 `ev["envelope"]["action"]` 等路径访问。
1772
+ SDK 交付给应用层的群事件信封字段统一放在 `envelope`。0.5.x 当前仍保留顶层 `module_id` / `action` / `group_id` / `event_seq` 等兼容别名;新代码应优先通过 `ev["envelope"]["action"]` 等路径访问。
1743
1773
 
1744
1774
  | 字段 | 类型 | 说明 |
1745
1775
  |------|------|------|
1746
1776
  | `envelope` | object | 群事件信封,包含 `module_id`、`action`、`group_id`、`event_seq`、`event_type`、`actor_aid`、`created_at`、`device_id`、`slot_id` 等存在的字段 |
1747
1777
  | `module_id` | string | 固定 `"group"` |
1748
1778
  | `action` | string | 变更类型(见下表) |
1749
- | `group_id` | string | 兼容字段,值语义为目标态 `group_aid` |
1779
+ | `group_id` | string | 兼容字段,值语义为目标态 `group_aid` |
1750
1780
  | `event_seq` | integer | 可选,服务端分配的单调递增序号,用于 SDK 内部保序去重 |
1751
1781
  | `path` | string | 可选,Group FS 相关 action 的节点路径 |
1752
1782
 
@@ -1784,9 +1814,9 @@ SDK 交付给应用层的群事件信封字段统一放在 `envelope`。0.5.x
1784
1814
  | `invite_code_revoked` | 邀请码撤销 |
1785
1815
  | `member_banned` | 成员封禁 |
1786
1816
  | `member_unbanned` | 成员解封 |
1787
- | `suspended` | 群组暂停 |
1788
- | `resumed` | 群组恢复 |
1789
- | `dissolved` | 群组解散 |
1817
+ | `suspended` | 群组暂停 |
1818
+ | `resumed` | 群组恢复 |
1819
+ | `dissolved` | 群组解散 |
1790
1820
 
1791
1821
  **订阅**:
1792
1822
 
@@ -1796,9 +1826,13 @@ client.on("group.changed", lambda ev: print(ev["action"]))
1796
1826
 
1797
1827
  ### event/group.message_created
1798
1828
 
1799
- 群消息创建时推送给所有在线成员。支持两种模式:
1829
+ 群消息创建时推送给所有在线成员。
1830
+
1831
+ **实时推送优化**(0.5.6+):当客户端在 `auth.connect` 时声明 `inline_realtime_payload_v1: true` 能力后,Gateway 会优先推送带完整 `payload` 的消息模式。SDK 自动声明此能力,应用层无需关注。
1832
+
1833
+ 支持两种模式:
1800
1834
 
1801
- **消息推送模式**(带 `payload`):
1835
+ **模式 1:消息推送模式**(带 `payload`):
1802
1836
 
1803
1837
  ```json
1804
1838
  {
@@ -1808,27 +1842,27 @@ client.on("group.changed", lambda ev: print(ev["action"]))
1808
1842
  "message_id": "uuid",
1809
1843
  "sender_aid": "alice.agentid.pub",
1810
1844
  "type": "e2ee.group_encrypted",
1811
- "dispatch_mode": "broadcast",
1845
+ "mention_mode": "disabled",
1812
1846
  "payload": { "type": "e2ee.group_encrypted", "..." : "..." },
1813
- "dispatch": {"mode": "broadcast", "reason": "duty_disabled"},
1814
- "kind": "group.broadcast",
1815
- "member_aids": ["bob.agentid.pub"],
1816
- "proximity": {
1817
- "same_device": false,
1818
- "same_egress_ip": true,
1819
- "same_network": true,
1820
- "basis": "egress_ip",
1821
- "asserted_by": "gateway"
1822
- },
1823
- "same_device": false,
1824
- "same_egress_ip": true,
1825
- "same_network": true
1826
- }
1827
- ```
1847
+ "dispatch": {"mode": "broadcast", "reason": "duty_disabled"},
1848
+ "kind": "group.broadcast",
1849
+ "member_aids": ["bob.agentid.pub"],
1850
+ "proximity": {
1851
+ "same_device": false,
1852
+ "same_egress_ip": true,
1853
+ "same_network": true,
1854
+ "basis": "egress_ip",
1855
+ "asserted_by": "gateway"
1856
+ },
1857
+ "same_device": false,
1858
+ "same_egress_ip": true,
1859
+ "same_network": true
1860
+ }
1861
+ ```
1828
1862
 
1829
1863
  SDK 收到后自动解密 `payload`,解密后的明文消息直接交付用户回调。
1830
1864
 
1831
- **通知模式**(不带 `payload`):
1865
+ **模式 2:通知模式**(不带 `payload`,回退场景):
1832
1866
 
1833
1867
  ```json
1834
1868
  {
@@ -1838,12 +1872,12 @@ SDK 收到后自动解密 `payload`,解密后的明文消息直接交付用户
1838
1872
  "message_id": "uuid",
1839
1873
  "sender_aid": "alice.agentid.pub",
1840
1874
  "type": "e2ee.group_encrypted",
1841
- "dispatch_mode": "broadcast",
1875
+ "mention_mode": "disabled",
1842
1876
  "dispatch": {"mode": "broadcast", "reason": "duty_disabled"}
1843
1877
  }
1844
1878
  ```
1845
1879
 
1846
- SDK 收到后自动调用 `group.pull` 拉取最新消息并逐条解密后交付用户回调。
1880
+ SDK 收到新 Head 后自动同步最新消息页并逐条解密;若 A 与 T 之间仍有未扫描区间,再执行一页后台 Forward。应用无需为此调用 `group.pull`。
1847
1881
 
1848
1882
  **SDK 应用层回调形态**:
1849
1883
 
@@ -1860,12 +1894,12 @@ SDK 收到后自动调用 `group.pull` 拉取最新消息并逐条解密后交
1860
1894
  "message_id": "uuid",
1861
1895
  "sender_aid": "alice.agentid.pub",
1862
1896
  "message_type": "group.message",
1863
- "dispatch_mode": "broadcast",
1897
+ "mention_mode": "disabled",
1864
1898
  "payload": {"type": "text", "text": "Hello"}
1865
1899
  }
1866
1900
  ```
1867
1901
 
1868
- SDK 交付给应用层的 `payload` 是明文业务 JSON 对象;群消息信封字段统一放在 `envelope`。`envelope` 只保留可转发的归一化元数据,`from` 由 `sender_aid` 归一化而来,`timestamp` 由 `created_at` / `t_server` 归一化而来。0.5.x 当前仍保留顶层 `group_id` / `seq` / `message_id` / `sender_aid` / `dispatch_mode` 等兼容别名;新代码应优先通过 `msg["envelope"]["from"]`、`msg["envelope"]["timestamp"]` 等路径访问。Gateway 可能附加 `proximity` 及 `same_device` / `same_egress_ip` / `same_network`,表示由 Gateway 基于连接上下文判断的近端关系提示,不参与 E2EE AAD 或业务鉴权。
1902
+ SDK 交付给应用层的 `payload` 是明文业务 JSON 对象;群消息信封字段统一放在 `envelope`。`envelope` 只保留可转发的归一化元数据,`from` 由 `sender_aid` 归一化而来,`timestamp` 由 `created_at` / `t_server` 归一化而来。当前仍保留顶层 `group_id` / `seq` / `message_id` / `sender_aid` / `mention_mode` 等字段;新代码应优先通过 `msg["envelope"]["from"]`、`msg["envelope"]["timestamp"]` 等路径访问。Gateway 可能附加 `proximity` 及 `same_device` / `same_egress_ip` / `same_network`,表示由 Gateway 基于连接上下文判断的近端关系提示,不参与 E2EE AAD 或业务鉴权。
1869
1903
 
1870
1904
  ### event/group.message_recalled
1871
1905
 
@@ -1897,13 +1931,13 @@ SDK 交付给应用层的 `payload` 是明文业务 JSON 对象;群消息信
1897
1931
  }
1898
1932
  ```
1899
1933
 
1900
- SDK 交付给应用层的撤回事件同样带 `envelope`。`envelope` 表示当前交付的撤回 tombstone / 通知自身信封,不是被撤回原消息的信封;业务侧被撤回的原消息列表继续使用 `message_ids` / `target_message_seqs`。`message_id` / `seq` 继续只保留在顶层兼容字段中,不进入 `envelope`。0.5.x 当前仍保留顶层 `group_id` / `seq` / `message_id` / `sender_aid` 等兼容别名;新代码应优先读取 `envelope`、`message_ids` 和 `target_message_seqs`。
1934
+ SDK 交付给应用层的撤回事件同样带 `envelope`。`envelope` 表示当前交付的撤回 tombstone / 通知自身信封,不是被撤回原消息的信封;业务侧被撤回的原消息列表继续使用 `message_ids` / `target_message_seqs`。`message_id` / `seq` 继续只保留在顶层兼容字段中,不进入 `envelope`。0.5.x 当前仍保留顶层 `group_id` / `seq` / `message_id` / `sender_aid` 等兼容别名;新代码应优先读取 `envelope`、`message_ids` 和 `target_message_seqs`。
1901
1935
 
1902
1936
  | 字段 | 类型 | 说明 |
1903
1937
  |------|------|------|
1904
1938
  | `envelope` | object | 撤回 tombstone / 通知自身信封,包含 `group_id`、`from`、`type`、`kind`、`timestamp`、`encrypted`、`context`、`protected_headers` 等存在的字段 |
1905
1939
  | `module_id` | string | 固定 `"group"` |
1906
- | `group_id` | string | 兼容字段,值语义为目标态 `group_aid` |
1940
+ | `group_id` | string | 兼容字段,值语义为目标态 `group_aid` |
1907
1941
  | `seq` | integer | 当前交付的撤回 tombstone / 通知 seq;在线 push 为 notice_seq,原 seq 占位 tombstone 为原消息 seq |
1908
1942
  | `message_id` | string | 当前交付的撤回 tombstone / 通知自己的 message_id |
1909
1943
  | `tombstone_message_id` | string | 兼容别名,等同于撤回 tombstone / 通知自身的 `message_id` |