@agentunion/fastaun-browser 0.5.18 → 0.5.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +172 -79
  2. package/_packed_docs/CHANGELOG.md +172 -79
  3. package/_packed_docs/INDEX.md +244 -116
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +98 -69
  5. package/_packed_docs/agent.md/SCHEMA.md +245 -205
  6. package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +11 -11
  7. 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 +42 -15
  8. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +4 -4
  9. package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +45 -134
  10. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1072 -1072
  11. package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +5 -20
  12. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +687 -668
  13. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +19 -28
  14. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/211.md +443 -0
  15. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.0.md +161 -0
  16. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +658 -0
  17. package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2113.0.md +233 -0
  18. package/_packed_docs/protocol/agent.md/SCHEMA.md +4 -0
  19. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +1 -1
  20. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +68 -61
  21. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +1 -1
  22. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +279 -285
  23. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +3 -3
  24. package/_packed_docs/sdk/09-group-rpc-manual.md +271 -235
  25. package/_packed_docs/sdk/09-message-rpc-manual.md +47 -6
  26. package/_packed_docs/sdk/09-storage-rpc-manual.md +70 -68
  27. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +63 -34
  28. package/_packed_docs/sdk/INDEX.md +105 -34
  29. package/_packed_docs/sdk/Ownership-SDK/345/256/236/347/216/260/346/214/207/345/215/227.md +169 -0
  30. package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/227.md +349 -0
  31. package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +922 -0
  32. package/_packed_docs/sdk/Ownership-SDK/351/233/206/346/210/220/346/214/207/345/215/227.md +270 -0
  33. package/_packed_docs/sdk/Ownership2.1-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +300 -0
  34. package/_packed_docs/sdk/Ownership2.1-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +382 -0
  35. package/_packed_docs/sdk/Ownership2.1-TDD/345/210/206/351/230/266/346/256/265/345/256/236/346/226/275/350/256/241/345/210/222.md +708 -0
  36. package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +476 -0
  37. package/_packed_docs/sdk/Ownership/347/256/241/347/220/206/344/270/223/351/242/230.md +559 -0
  38. package/_packed_docs/sdk/ProtectedHeaders/347/224/250/346/263/225/344/270/223/351/242/230.md +299 -0
  39. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +173 -0
  40. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +211 -0
  41. package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273SDK/345/256/236/347/216/260/347/247/273/346/244/215/346/214/207/345/215/227.md +331 -0
  42. package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273SDK/351/233/206/346/210/220/346/214/207/345/215/227.md +207 -0
  43. package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/344/273/243/347/240/201/345/256/241/346/237/245/346/212/245/345/221/212.md +252 -0
  44. package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/345/256/236/346/226/275/350/256/241/345/210/222.md +156 -0
  45. package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/346/226/271/346/241/210.md +273 -0
  46. package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/350/257/246/347/273/206/350/256/276/350/256/241.md +211 -0
  47. package/dist/agent-md-schema.d.ts +17 -3
  48. package/dist/agent-md-schema.d.ts.map +1 -1
  49. package/dist/agent-md-schema.js +94 -26
  50. package/dist/agent-md-schema.js.map +1 -1
  51. package/dist/agent-md.d.ts +54 -3
  52. package/dist/agent-md.d.ts.map +1 -1
  53. package/dist/agent-md.js +711 -65
  54. package/dist/agent-md.js.map +1 -1
  55. package/dist/aid-store.d.ts +58 -46
  56. package/dist/aid-store.d.ts.map +1 -1
  57. package/dist/aid-store.js +254 -248
  58. package/dist/aid-store.js.map +1 -1
  59. package/dist/aid.d.ts +4 -1
  60. package/dist/aid.d.ts.map +1 -1
  61. package/dist/aid.js +27 -33
  62. package/dist/aid.js.map +1 -1
  63. package/dist/auth.d.ts +4 -1
  64. package/dist/auth.d.ts.map +1 -1
  65. package/dist/auth.js +426 -39
  66. package/dist/auth.js.map +1 -1
  67. package/dist/bundle.js +38179 -32054
  68. package/dist/cert-utils.d.ts +50 -2
  69. package/dist/cert-utils.d.ts.map +1 -1
  70. package/dist/cert-utils.js +105 -47
  71. package/dist/cert-utils.js.map +1 -1
  72. package/dist/client/delivery.d.ts +22 -1
  73. package/dist/client/delivery.d.ts.map +1 -1
  74. package/dist/client/delivery.js +389 -78
  75. package/dist/client/delivery.js.map +1 -1
  76. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  77. package/dist/client/rpc-pipeline.js +103 -77
  78. package/dist/client/rpc-pipeline.js.map +1 -1
  79. package/dist/client/v2-e2ee.d.ts +1 -0
  80. package/dist/client/v2-e2ee.d.ts.map +1 -1
  81. package/dist/client/v2-e2ee.js +182 -89
  82. package/dist/client/v2-e2ee.js.map +1 -1
  83. package/dist/client.d.ts +100 -1
  84. package/dist/client.d.ts.map +1 -1
  85. package/dist/client.js +1220 -25
  86. package/dist/client.js.map +1 -1
  87. package/dist/crypto.d.ts.map +1 -1
  88. package/dist/crypto.js +8 -6
  89. package/dist/crypto.js.map +1 -1
  90. package/dist/errors.d.ts.map +1 -1
  91. package/dist/errors.js +3 -2
  92. package/dist/errors.js.map +1 -1
  93. package/dist/events.d.ts +9 -2
  94. package/dist/events.d.ts.map +1 -1
  95. package/dist/events.js +72 -13
  96. package/dist/events.js.map +1 -1
  97. package/dist/facades.d.ts +82 -2
  98. package/dist/facades.d.ts.map +1 -1
  99. package/dist/facades.js +100 -6
  100. package/dist/facades.js.map +1 -1
  101. package/dist/index.d.ts +7 -3
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +3 -2
  104. package/dist/index.js.map +1 -1
  105. package/dist/keystore/index.d.ts +17 -0
  106. package/dist/keystore/index.d.ts.map +1 -1
  107. package/dist/keystore/indexeddb-shared.d.ts +10 -1
  108. package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
  109. package/dist/keystore/indexeddb-shared.js +111 -0
  110. package/dist/keystore/indexeddb-shared.js.map +1 -1
  111. package/dist/keystore/indexeddb-token-store.d.ts +7 -1
  112. package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
  113. package/dist/keystore/indexeddb-token-store.js +30 -1
  114. package/dist/keystore/indexeddb-token-store.js.map +1 -1
  115. package/dist/org-protocol.d.ts +98 -0
  116. package/dist/org-protocol.d.ts.map +1 -0
  117. package/dist/org-protocol.js +1802 -0
  118. package/dist/org-protocol.js.map +1 -0
  119. package/dist/ownership-proof.d.ts +93 -5
  120. package/dist/ownership-proof.d.ts.map +1 -1
  121. package/dist/ownership-proof.js +239 -53
  122. package/dist/ownership-proof.js.map +1 -1
  123. package/dist/ownership-v21.d.ts +194 -0
  124. package/dist/ownership-v21.d.ts.map +1 -0
  125. package/dist/ownership-v21.js +678 -0
  126. package/dist/ownership-v21.js.map +1 -0
  127. package/dist/ownership-workflow.d.ts +151 -0
  128. package/dist/ownership-workflow.d.ts.map +1 -0
  129. package/dist/ownership-workflow.js +1229 -0
  130. package/dist/ownership-workflow.js.map +1 -0
  131. package/dist/seq-tracker.d.ts +1 -0
  132. package/dist/seq-tracker.d.ts.map +1 -1
  133. package/dist/seq-tracker.js +10 -2
  134. package/dist/seq-tracker.js.map +1 -1
  135. package/dist/tools/cross-sdk-agent.d.ts +83 -0
  136. package/dist/tools/cross-sdk-agent.d.ts.map +1 -1
  137. package/dist/tools/cross-sdk-agent.js +415 -7
  138. package/dist/tools/cross-sdk-agent.js.map +1 -1
  139. package/dist/transport.d.ts +7 -0
  140. package/dist/transport.d.ts.map +1 -1
  141. package/dist/transport.js +90 -2
  142. package/dist/transport.js.map +1 -1
  143. package/dist/v2/e2ee/decrypt.d.ts +1 -0
  144. package/dist/v2/e2ee/decrypt.d.ts.map +1 -1
  145. package/dist/v2/e2ee/decrypt.js +9 -1
  146. package/dist/v2/e2ee/decrypt.js.map +1 -1
  147. package/dist/version.d.ts +1 -1
  148. package/dist/version.js +1 -1
  149. package/package.json +1 -1
@@ -1,66 +1,66 @@
1
- # 10. Group 子协议
2
-
3
- > **适用版本**:AUN 1.0 | **状态**:Draft
4
-
5
- Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。Group 服务本身是一个 AID 持有者,客户端通过标准 `message.*` 协议与 Group 服务通信,Group 服务通过 JSON-RPC 2.0 暴露 `group.*` 命名空间方法。
6
-
7
- ---
8
-
9
- ## 10.1 架构与角色
10
-
11
- ```
12
- 客户端 A ──message.send──► Group Service (AID: group.service.aid)
13
- │
14
- ├── 存储群消息
15
- ├── 广播 event/group.message_created
16
- └── 推送 event/group.changed
17
- ```
18
-
19
- - **Group Service**:持有独立 AID,作为 AUN 节点运行,暴露 `group.*` RPC 方法
1
+ # 10. Group 子协议
2
+
3
+ > **适用版本**:AUN 1.0 | **状态**:Draft
4
+
5
+ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。Group 服务本身是一个 AID 持有者,客户端通过标准 `message.*` 协议与 Group 服务通信,Group 服务通过 JSON-RPC 2.0 暴露 `group.*` 命名空间方法。服务 AID、群身份 `group_aid` 与群主 `owner_aid` 是三个不同角色。群主关系由 Group 生命周期管理,不走 Ownership 2.1 的双文件绑定、释放、转移、审批或 NS 关系账本。
6
+
7
+ ---
8
+
9
+ ## 10.1 架构与角色
10
+
11
+ ```
12
+ 客户端 A ──message.send──► Group Service (AID: group.service.aid)
13
+ │
14
+ ├── 存储群消息
15
+ ├── 广播 event/group.message_created
16
+ └── 推送 event/group.changed
17
+ ```
18
+
19
+ - **Group Service**:持有独立 AID,作为 AUN 节点运行,暴露 `group.*` RPC 方法
20
20
  - **成员**:通过 `group.request_join` / `group.add_member` / `group.invite_member` / `group.use_invite_code` 加入
21
- - **权限层级**:`owner` > `admin` > `member`(只读群另有 `observer` 角色)
22
-
23
- ---
24
-
25
- ## 10.2 数据模型
26
-
27
- ### Group 对象
28
-
29
- | 字段 | 类型 | 说明 |
30
- |------|------|------|
31
- | `group_id` | string | 群组唯一 ID(自动生成或自定义) |
32
- | `name` | string | 群组名称 |
33
- | `owner_aid` | string | 群主 AID |
34
- | `creator_aid` | string | 创建者 AID |
35
- | `visibility` | string | `"public"` / `"private"` |
36
- | `status` | string | `"active"` / `"suspended"` / `"closed"` |
21
+ - **权限层级**:`owner` > `admin` > `member`(只读群另有 `observer` 角色)
22
+
23
+ ---
24
+
25
+ ## 10.2 数据模型
26
+
27
+ ### Group 对象
28
+
29
+ | 字段 | 类型 | 说明 |
30
+ |------|------|------|
31
+ | `group_id` | string | 群组唯一 ID(自动生成或自定义) |
32
+ | `name` | string | 群组名称 |
33
+ | `owner_aid` | string | 群主 AID |
34
+ | `creator_aid` | string | 创建者 AID |
35
+ | `visibility` | string | `"public"` / `"private"` |
36
+ | `status` | string | `"active"` / `"suspended"` / `"dissolved"` |
37
37
  | `description` | string | 群组描述 |
38
38
  | `metadata` | object | 自定义元数据 |
39
39
  | `mention_mode` | string | 群提及过滤模式:`"disabled"`(默认)/ `"mention-only"`,详见 [10.2.3 群提及过滤模式](#1023-群提及过滤模式mention_mode) |
40
40
  | `member_count` | integer | 成员数量 |
41
- | `message_seq` | integer | 最新消息序号 |
42
- | `event_seq` | integer | 最新事件序号 |
43
- | `created_at` | integer | 创建时间(Unix 秒) |
44
-
45
- ### Group ID 格式与规范化
46
-
47
- `group_id` 是群组的全网唯一标识,前缀 `g-` 为 Group 保留前缀。普通 AID 的本地名称不得以 `g-` 开头,避免与群 ID 混淆。短形式必须以 `g-` 开头,总长度 6 到 16 字符;`g-` 后面的 slug 为 4 到 14 位,只能使用小写字母和数字。
48
-
49
- 服务端必须接受以下三种输入形式,并在内部统一为 canonical group_id:
50
-
51
- | 输入形式 | 用途 | canonical 结果 |
52
- |----------|------|----------------|
53
- | `g-{slug}` | 本地域内简写别名 | 若本域 issuer 为 `issuer-domain`,规范化为 `g-{slug}.issuer-domain` |
54
- | `g-{slug}@issuer-domain` | 跨域传播兼容形式 | 规范化为 `g-{slug}.issuer-domain` |
55
- | `g-{slug}.issuer-domain` | canonical 形式 | 保持为 `g-{slug}.issuer-domain` |
56
-
57
- 规范化规则:
58
-
59
- - `group_id` 比较、数据库存储、成员归属、权限校验、E2EE AAD / 签名输入均必须使用 canonical group_id。
60
- - 输入必须先 trim 并转换为小写;`@issuer-domain` 形式仅作为兼容输入,进入内部前必须转换为 `.issuer-domain`。
61
- - 本域内客户端可以提交 `g-{slug}` 简写;服务端按本域 `AUN_ISSUER_DOMAIN` 解析为 canonical group_id。没有本域 issuer 配置时,简写保持为 `g-{slug}`。
62
- - 跨域消息、邀请传播、日志和协议响应应使用 canonical group_id,避免远端误把短 ID 当成本域群。
63
- - `group.create` 可以指定 `group_id`;指定时必须满足上述格式且未被占用,被占用时返回错误。未指定时由服务端自动分配。
41
+ | `message_seq` | integer | 最新消息序号 |
42
+ | `event_seq` | integer | 最新事件序号 |
43
+ | `created_at` | integer | 创建时间(Unix 秒) |
44
+
45
+ ### Group ID 格式与规范化
46
+
47
+ `group_id` 是群组的全网唯一标识,前缀 `g-` 为 Group 保留前缀。普通 AID 的本地名称不得以 `g-` 开头,避免与群 ID 混淆。短形式必须以 `g-` 开头,总长度 6 到 16 字符;`g-` 后面的 slug 为 4 到 14 位,只能使用小写字母和数字。
48
+
49
+ 服务端必须接受以下三种输入形式,并在内部统一为 canonical group_id:
50
+
51
+ | 输入形式 | 用途 | canonical 结果 |
52
+ |----------|------|----------------|
53
+ | `g-{slug}` | 本地域内简写别名 | 若本域 issuer 为 `issuer-domain`,规范化为 `g-{slug}.issuer-domain` |
54
+ | `g-{slug}@issuer-domain` | 跨域传播兼容形式 | 规范化为 `g-{slug}.issuer-domain` |
55
+ | `g-{slug}.issuer-domain` | canonical 形式 | 保持为 `g-{slug}.issuer-domain` |
56
+
57
+ 规范化规则:
58
+
59
+ - `group_id` 比较、数据库存储、成员归属、权限校验、E2EE AAD / 签名输入均必须使用 canonical group_id。
60
+ - 输入必须先 trim 并转换为小写;`@issuer-domain` 形式仅作为兼容输入,进入内部前必须转换为 `.issuer-domain`。
61
+ - 本域内客户端可以提交 `g-{slug}` 简写;服务端按本域 `AUN_ISSUER_DOMAIN` 解析为 canonical group_id。没有本域 issuer 配置时,简写保持为 `g-{slug}`。
62
+ - 跨域消息、邀请传播、日志和协议响应应使用 canonical group_id,避免远端误把短 ID 当成本域群。
63
+ - `group.create` 可以指定 `group_id`;指定时必须满足上述格式且未被占用,被占用时返回错误。未指定时由服务端自动分配。
64
64
  - 自动生成的群 ID 使用 `g-` 加随机小写十六进制短 slug,服务端必须通过唯一约束或等效机制保证 canonical group_id 唯一;发现碰撞时重新生成。
65
65
  - 在 `group.{issuer-domain}` 这类已携带 issuer 的公开 HTTP 主机下,生成的群链接 path 应使用本域简写,例如 `https://group.issuer-domain/g-abc123` 或 `https://group.issuer-domain/g-abc123/invite/ic-xxx`。
66
66
 
@@ -82,16 +82,16 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
82
82
  5. **变更不追溯**:群管理员变更 `mention_mode` 后仅对之后的新消息生效;服务端随消息保存发送时的模式快照
83
83
 
84
84
  `mention-only` 必须基于结构化的 `payload.mentions` 判断,不得仅扫描文本中的 `@xxx`;`{ "scope": "all" }` 视为命中所有成员。该设置仅适用于群组,群 owner/admin 可写,普通成员只读。
85
-
85
+
86
86
  ### Member 对象
87
-
88
- | 字段 | 类型 | 说明 |
89
- |------|------|------|
90
- | `aid` | string | 成员 AID |
91
- | `group_id` | string | 群组 ID |
92
- | `role` | string | `"owner"` / `"admin"` / `"member"` |
93
- | `joined_at` | integer | 加入时间(Unix 秒) |
94
- | `last_ack_seq` | integer | 最后已读消息序号 |
87
+
88
+ | 字段 | 类型 | 说明 |
89
+ |------|------|------|
90
+ | `aid` | string | 成员 AID |
91
+ | `group_id` | string | 群组 ID |
92
+ | `role` | string | `"owner"` / `"admin"` / `"member"` |
93
+ | `joined_at` | integer | 加入时间(Unix 秒) |
94
+ | `last_ack_seq` | integer | 投递消费确认位置,与业务已读位置独立 |
95
95
 
96
96
  ### Member Status 对象
97
97
 
@@ -104,169 +104,171 @@ Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。
104
104
  | `updated_at` | integer | 最近一次状态上报时间(Unix 毫秒) |
105
105
  | `last_message_at` | integer | 该成员在此群最后一条成功发送消息的时间(Unix 毫秒) |
106
106
  | `last_payload_type` | string | 最后一条成功发送消息的 `payload.type` |
107
-
108
- ### Message 对象
109
-
110
- | 字段 | 类型 | 说明 |
111
- |------|------|------|
112
- | `group_id` | string | 群组 ID |
113
- | `seq` | integer | 消息序号(群内单调递增) |
114
- | `message_id` | string | 消息 UUID |
115
- | `sender_aid` | string | 发送者 AID |
116
- | `message_type` | string | 信封/封装类型,如 `e2ee.group_encrypted`;业务负载类型在 `payload.type` 中 |
117
- | `payload` | object | 消息内容 |
118
- | `attachments` | array | 附件存储引用列表 |
119
- | `created_at` | integer | 创建时间(Unix 毫秒) |
120
-
121
- ---
122
-
123
- ## 10.3 权限模型
124
-
125
- | 操作 | owner | admin | member |
126
- |------|:-----:|:-----:|:------:|
127
- | 发送消息 | ✅ | ✅ | ✅ |
128
- | 查看成员 | ✅ | ✅ | ✅ |
129
- | 邀请成员 | ✅ | ✅ | 规则决定 |
130
- | 踢出成员 | ✅ | ✅(非 owner)| ❌ |
131
- | 设置角色 | ✅ | ❌ | ❌ |
132
- | 更新群信息 | ✅ | ✅ | ❌ |
133
- | 更新公告 | ✅ | ✅ | ❌ |
107
+
108
+ ### Message 对象
109
+
110
+ | 字段 | 类型 | 说明 |
111
+ |------|------|------|
112
+ | `group_id` | string | 群组 ID |
113
+ | `seq` | integer | 消息序号(群内单调递增) |
114
+ | `message_id` | string | 消息 UUID |
115
+ | `sender_aid` | string | 发送者 AID |
116
+ | `message_type` | string | 信封/封装类型,如 `e2ee.group_encrypted`;业务负载类型在 `payload.type` 中 |
117
+ | `payload` | object | 消息内容 |
118
+ | `attachments` | array | 附件存储引用列表 |
119
+ | `created_at` | integer | 创建时间(Unix 毫秒) |
120
+
121
+ ---
122
+
123
+ ## 10.3 权限模型
124
+
125
+ | 操作 | owner | admin | member |
126
+ |------|:-----:|:-----:|:------:|
127
+ | 发送消息 | ✅ | ✅ | ✅ |
128
+ | 查看成员 | ✅ | ✅ | ✅ |
129
+ | 邀请成员 | ✅ | ✅ | 规则决定 |
130
+ | 踢出成员 | ✅ | ✅(非 owner)| ❌ |
131
+ | 设置角色 | ✅ | ❌ | ❌ |
132
+ | 更新群信息 | ✅ | ✅ | ❌ |
133
+ | 更新公告 | ✅ | ✅ | ❌ |
134
134
  | 审批申请 | ✅ | ✅ | ❌ |
135
135
  | 禁言/取消禁言 | ✅ | ✅(受角色层级限制) | ❌ |
136
136
  | 屏蔽/取消屏蔽其他成员 | ✅ | ✅(受角色层级限制) | ❌ |
137
137
  | 屏蔽/取消屏蔽自己 | ✅ | ✅ | ✅ |
138
138
  | 上报自己状态/查询成员状态 | ✅ | ✅ | ✅ |
139
139
  | 暂停/关闭群 | ✅ | ✅ | ❌ |
140
- | 转让群主 | ✅ | ❌ | ❌ |
141
- | Group FS 写入 | ✅ | 配置决定 | ❌ |
142
-
143
- ---
144
-
145
- ## 10.4 群组生命周期方法
146
-
147
- ### `group.create`
148
-
140
+ | 转让群主 | ✅ | ❌ | ❌ |
141
+ | Group FS 写入 | ✅ | 配置决定 | ❌ |
142
+
143
+ ---
144
+
145
+ ## 10.4 群组生命周期方法
146
+
147
+ ### `group.create`
148
+
149
+ 创建自动建立调用者与群的 owner 关系;群身份公私钥及证书由该 owner 持有,Group 服务不接收或保存群私钥。群名片须含当前 `owner`,不含通用 `ownership` 声明;由当前 owner 使用本人证书和私钥代签、代上传,文件 `aid` 仍是 `group_aid`。签名块 `signer_aid`、V2 上传授权、实体证书代际和条件恢复见 [Ownership 协议定义 2.1 §2.5](Ownership协议定义2.1.md#25-grouporg-名片的-owner-代签与上传)。创建、群证书绑定和名片发布的参数/响应以 [Group RPC Manual](../sdk/09-group-rpc-manual.md#groupcreate) 为准。
150
+
149
151
  创建群组。
150
152
 
151
153
  SDK 高层建群流程必须支持崩溃恢复:命名群复用已持久化密钥并重放相同 `group_name + public_key` 的已提交结果;匿名群复用已持久化的创建上下文,使响应丢失后的重试返回同一数字群,再继续群身份绑定和 `agent.md` 上传。服务端必须原子提交群记录、群主成员、成员索引、入群设置、首个 `group.changed` 事件及匿名创建映射。直接调用 RPC 且没有 SDK 恢复上下文时,每次调用仍表示一次新的自动群创建。
152
-
153
- **参数**:
154
-
155
- | 参数 | 类型 | 必填 | 说明 |
156
- |------|------|:----:|------|
157
- | `name` | string | ✅ | 群组名称 |
158
- | `group_id` | string | ❌ | 自定义群 ID,短形式必须以 `g-` 开头且总长度 6 到 16 字符;不提供则服务端自动生成;已被占用时返回错误 |
159
- | `visibility` | string | ❌ | `"public"` / `"private"`,默认由服务配置决定 |
160
- | `description` | string | ❌ | 群组描述 |
161
- | `metadata` | object | ❌ | 自定义元数据 |
162
- | `avatar_ref` | string | ❌ | 头像存储引用 |
163
- | `join_mode` | string | ❌ | `"open"` / `"approval"` / `"invite_only"` / `"closed"` |
164
- | `join_question` | string | ❌ | 入群问题 |
165
- | `max_pending` | integer | ❌ | 最大待审批数,默认 100 |
166
-
167
- **响应**:
168
-
169
- ```json
170
- {
171
- "group": {
172
- "group_id": "g-abc123.agentid.pub",
173
- "name": "测试群",
174
- "owner_aid": "alice.agentid.pub",
175
- "creator_aid": "alice.agentid.pub",
176
- "visibility": "private",
177
- "status": "active",
178
- "member_count": 1,
179
- "message_seq": 0,
180
- "event_seq": 0,
181
- "created_at": 1234567890
182
- },
183
- "aid": "alice.agentid.pub"
184
- }
185
- ```
186
-
187
- ### `group.get_info`
188
-
189
- 查询群组信息,返回平铺格式。默认返回公开字段;需要成员权限的字段必须通过 `required` 显式声明。
190
-
191
- **参数**:
192
-
193
- - `group_id` (string, 必填)
194
- - `required` (string[], 可选):受限字段声明,可取 `member`、`state`、`e2ee`、`avatar`
195
-
196
- **默认响应**:
197
-
198
- `{ "found": true, "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "name": "项目讨论", "visibility": "public", "status": "active", "description": "", "member_count": 3, "created_at": 1234567890 }`
199
-
200
- `required=["member"]` 会额外返回 `owner_aid`、`creator_aid`、`message_seq`、`event_seq`、`e2ee_epoch`、`updated_at`、`my_role` 等成员可见字段。
201
-
202
- > `group.get` 和 `group.info` 已合并到 `group.get_info`;`group.get_info` 默认行为等价于原公开信息查询。
203
-
204
- ### `group.update`
205
-
206
- 更新群组资料。需要 admin 及以上权限。
207
-
208
- **参数**:`group_id` (必填) + 可选字段:`name` / `description` / `metadata` / `avatar_ref`
209
-
210
- **响应**:`{ "group": { ... } }`
211
-
212
- ### `group.list` / `group.list_my`
213
-
214
- 列出当前 AID 加入的所有群组。
215
-
216
- **参数**:`size` (integer, 可选,默认 50)
217
-
218
- **响应**:`{ "items": [ ... ], "total": 3, "page": 1, "size": 50, "aid": "alice.agentid.pub" }`
219
-
220
- ### `group.search`
221
-
222
- 搜索公开群组(`visibility=public`)。
223
-
224
- **参数**:`query` (string, 可选), `size` (integer, 可选)
225
-
226
- **响应**:`{ "query": "...", "items": [ ... ], "total": 3 }`
227
-
228
-
229
- ### `group.suspend`
230
-
154
+
155
+ **参数**:
156
+
157
+ | 参数 | 类型 | 必填 | 说明 |
158
+ |------|------|:----:|------|
159
+ | `name` | string | ✅ | 群组名称 |
160
+ | `group_id` | string | ❌ | 自定义群 ID,短形式必须以 `g-` 开头且总长度 6 到 16 字符;不提供则服务端自动生成;已被占用时返回错误 |
161
+ | `visibility` | string | ❌ | `"public"` / `"private"`,默认由服务配置决定 |
162
+ | `description` | string | ❌ | 群组描述 |
163
+ | `metadata` | object | ❌ | 自定义元数据 |
164
+ | `avatar_ref` | string | ❌ | 头像存储引用 |
165
+ | `join_mode` | string | ❌ | `"open"` / `"approval"` / `"invite_only"` / `"closed"` |
166
+ | `join_question` | string | ❌ | 入群问题 |
167
+ | `max_pending` | integer | ❌ | 最大待审批数,默认 100 |
168
+
169
+ **响应**:
170
+
171
+ ```json
172
+ {
173
+ "group": {
174
+ "group_id": "g-abc123.agentid.pub",
175
+ "name": "测试群",
176
+ "owner_aid": "alice.agentid.pub",
177
+ "creator_aid": "alice.agentid.pub",
178
+ "visibility": "private",
179
+ "status": "active",
180
+ "member_count": 1,
181
+ "message_seq": 0,
182
+ "event_seq": 0,
183
+ "created_at": 1234567890
184
+ },
185
+ "aid": "alice.agentid.pub"
186
+ }
187
+ ```
188
+
189
+ ### `group.get_info`
190
+
191
+ 查询群组信息,返回平铺格式。默认返回公开字段;需要成员权限的字段必须通过 `required` 显式声明。
192
+
193
+ **参数**:
194
+
195
+ - `group_id` (string, 必填)
196
+ - `required` (string[], 可选):受限字段声明,可取 `member`、`state`、`e2ee`、`avatar`
197
+
198
+ **默认响应**:
199
+
200
+ `{ "found": true, "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "name": "项目讨论", "visibility": "public", "status": "active", "description": "", "member_count": 3, "created_at": 1234567890 }`
201
+
202
+ `required=["member"]` 会额外返回 `owner_aid`、`creator_aid`、`message_seq`、`event_seq`、`e2ee_epoch`、`updated_at`、`my_role` 等成员可见字段。
203
+
204
+ > `group.get` 和 `group.info` 已合并到 `group.get_info`;`group.get_info` 默认行为等价于原公开信息查询。
205
+
206
+ ### `group.update`
207
+
208
+ 更新群组资料。需要 admin 及以上权限。
209
+
210
+ **参数**:`group_id` (必填) + 可选字段:`name` / `description` / `metadata` / `avatar_ref`
211
+
212
+ **响应**:`{ "group": { ... } }`
213
+
214
+ ### `group.list` / `group.list_my`
215
+
216
+ 列出当前 AID 加入的所有群组。
217
+
218
+ **参数**:`size` (integer, 可选,默认 50)
219
+
220
+ **响应**:`{ "items": [ ... ], "total": 3, "page": 1, "size": 50, "aid": "alice.agentid.pub" }`
221
+
222
+ ### `group.search`
223
+
224
+ 搜索公开群组(`visibility=public`)。
225
+
226
+ **参数**:`query` (string, 可选), `size` (integer, 可选)
227
+
228
+ **响应**:`{ "query": "...", "items": [ ... ], "total": 3 }`
229
+
230
+
231
+ ### `group.suspend`
232
+
231
233
  暂停群组。暂停期间 owner/admin 可以继续通过 `group.send`、`group.v2.send` 和 `group.thought.put` 发言;member 禁止发言,入群、邀请、申请审批等准入操作继续拒绝。需要 admin 及以上权限。
232
-
233
- **参数**:`group_id` (string, 必填)
234
-
235
- **响应**:`{ "group": { ... }, "status": "suspended" }`
236
-
237
- ### `group.resume`
238
-
239
- 恢复已暂停的群组。需要 admin 及以上权限。
240
-
241
- **参数**:`group_id` (string, 必填)
242
-
243
- **响应**:`{ "group": { ... }, "status": "active" }`
244
-
245
- ### `group.dissolve`
246
-
247
- 永久解散群组。需要 **owner** 权限。解散后不可恢复。
248
-
249
- **参数**:`group_id` (string, 必填)
250
-
251
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "status": "dissolved" }`
252
-
253
- ---
254
-
255
- ## 10.5 成员管理方法
256
-
257
- ### `group.add_member`
258
-
234
+
235
+ **参数**:`group_id` (string, 必填)
236
+
237
+ **响应**:`{ "group": { ... }, "status": "suspended" }`
238
+
239
+ ### `group.resume`
240
+
241
+ 恢复已暂停的群组。需要 admin 及以上权限。
242
+
243
+ **参数**:`group_id` (string, 必填)
244
+
245
+ **响应**:`{ "group": { ... }, "status": "active" }`
246
+
247
+ ### `group.dissolve`
248
+
249
+ 永久解散群组。需要 **owner** 权限。解散后不可恢复,自动解除有效 owner 关系,终止待处理转移并撤销群证书及相关授权;旧 owner、旧证书、实体 token 和旧 pending 均不能继续上传群名片或代表群鉴权。历史 owner 和签名记录保留用于审计,不作为当前授权。解散墓碑及待转移清理先原子提交;事件发布、CA 撤销、Storage 权限失效与缓存清理通过持久 outbox 收尾,未全完成返回 -32002、status=unavailable/retryable=true/committed=true,重试续跑收尾,不能提前宣告成功。
250
+
251
+ **参数**:`group_id` (string, 必填)
252
+
253
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "status": "dissolved" }`
254
+
255
+ ---
256
+
257
+ ## 10.5 成员管理方法
258
+
259
+ ### `group.add_member`
260
+
259
261
  直接添加成员。需要 **owner** 权限;这是立即成为正式成员的显式例外。普通指定 AID 入群应使用 `group.invite_member`,由目标 AID 接受。
260
-
261
- **参数**:
262
-
263
- | 参数 | 类型 | 必填 | 说明 |
264
- |------|------|:----:|------|
265
- | `group_id` | string | ✅ | 群组 ID |
266
- | `aid` | string | ✅ | 要添加的 AID |
267
- | `role` | string | ❌ | `"member"` / `"admin"`,默认 `"member"` |
268
- | `member_type` | string | ❌ | `"human"` / `"ai"`,默认 `"human"` |
269
-
262
+
263
+ **参数**:
264
+
265
+ | 参数 | 类型 | 必填 | 说明 |
266
+ |------|------|:----:|------|
267
+ | `group_id` | string | ✅ | 群组 ID |
268
+ | `aid` | string | ✅ | 要添加的 AID |
269
+ | `role` | string | ❌ | `"member"` / `"admin"`,默认 `"member"` |
270
+ | `member_type` | string | ❌ | `"human"` / `"ai"`,默认 `"human"` |
271
+
270
272
  **响应**:`{ "group": { ... }, "member": { ... } }`
271
273
 
272
274
  ### `group.invite_member`
@@ -286,76 +288,84 @@ SDK 高层建群流程必须支持崩溃恢复:命名群复用已持久化密
286
288
  ### `group.revoke_invite`
287
289
 
288
290
  由原邀请发出者以 `invite_id` 撤回自己的待处理邀请。撤回、接受、拒绝和过期是互斥终态转换。
289
-
290
- ### `group.leave`
291
-
292
- 主动退出群组。owner 不可退出(须先转让)。
293
-
294
- **参数**:`group_id` (string, 必填)
295
-
296
- **响应**:`{ "group": { ... }, "left_aid": "alice.agentid.pub" }`
297
-
298
- ### `group.kick`
299
-
300
- 踢出成员。需要 admin 及以上权限,不能踢 owner。
301
-
302
- **参数**:`group_id` (必填), `aid` (必填)
303
-
304
- **响应**:`{ "group": { ... }, "removed_aid": "bob.agentid.pub" }`
305
-
306
- ### `group.set_role`
307
-
308
- 设置成员角色。需要 **owner** 权限。
309
-
310
- **参数**:`group_id` (必填), `aid` (必填), `role` (`"admin"` / `"member"`)
311
-
312
- **响应**:`{ "group": { ... }, "member": { ... } }`
313
-
291
+
292
+ ### `group.leave`
293
+
294
+ 主动退出群组。owner 不可退出(须先转让)。
295
+
296
+ **参数**:`group_id` (string, 必填)
297
+
298
+ **响应**:`{ "group": { ... }, "left_aid": "alice.agentid.pub" }`
299
+
300
+ ### `group.kick`
301
+
302
+ 踢出成员。需要 admin 及以上权限,不能踢 owner。
303
+
304
+ **参数**:`group_id` (必填), `aid` (必填)
305
+
306
+ **响应**:`{ "group": { ... }, "removed_aid": "bob.agentid.pub" }`
307
+
308
+ ### `group.set_role`
309
+
310
+ 设置成员角色。需要 **owner** 权限。
311
+
312
+ **参数**:`group_id` (必填), `aid` (必填), `role` (`"admin"` / `"member"`)
313
+
314
+ **响应**:`{ "group": { ... }, "member": { ... } }`
315
+
314
316
  ### `group.transfer_owner`
315
317
 
316
- 转让群主身份。需要 **owner** 权限。受让方无需手动确认,SDK 自动完成确认和转让收尾。
317
-
318
- **参数**:`group_id` (必填), `new_owner` (必填,新群主 AID;别名 `aid` 向后兼容)
319
-
320
- **响应**:`{ "group": { ... }, "new_owner_aid": "bob.agentid.pub" }`
321
-
322
- ### `group.get_members`
323
-
324
- 获取群成员列表。需要是群成员。
325
-
326
- **参数**:
327
-
328
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
329
- |------|------|:----:|--------|------|
330
- | `group_id` | string | ✅ | — | 群组 ID |
331
- | `page` | integer | ❌ | 1 | 页码 |
332
- | `size` | integer | ❌ | 50 | 每页条数 |
333
- | `role` | string | ❌ | — | 按角色过滤 |
334
-
335
- **响应**:`{ "members": [ ... ], "total": 10, "page": 1, "size": 50 }`
336
-
337
- ### `group.ban`
338
-
339
- 封禁成员(禁止发消息但保留群成员身份)。需要 admin 及以上权限。
340
-
341
- **参数**:`group_id` (必填), `aid` (必填), `duration_seconds` (integer, 可选,0 表示永久)
342
-
343
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "banned_aid": "bob.agentid.pub" }`
344
-
345
- ### `group.unban`
346
-
347
- 解除封禁。需要 admin 及以上权限。
348
-
349
- **参数**:`group_id` (必填), `aid` (必填)
350
-
351
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "unbanned_aid": "bob.agentid.pub" }`
352
-
318
+ 发起两阶段群主转让。需要 **owner** 权限,只建立 `pending_rekey`,暂不切换 owner;新 owner 通过 `group.complete_transfer` 提交本人接受证明和新群公钥,完成强制 rekey 后切换 owner,原 owner 降为 admin。旧群证书失效,新身份材料归新 owner;新 owner 按当前代际重新代签、代上传含新 `owner` 的群名片。
319
+
320
+ **参数**:`group_id` (必填), `new_owner` (必填,新群主 AID;别名 `aid` 向后兼容)
321
+
322
+ **响应**:`{ "status": "pending_rekey", "requires_ca_rekey": true, "complete_rpc": "group.complete_transfer", "group": { ... }, "new_owner": "bob.agentid.pub" }`。完整参数、旧群身份授权、新 owner 接受证明及幂等规则见 [Group RPC Manual](../sdk/09-group-rpc-manual.md#grouptransfer_owner)。
323
+
324
+ ### `group.complete_transfer`
325
+
326
+ 仅待转移的新 owner 可完成,必须生成新群密钥并提交 `transfer_accept`,禁止同密钥续证代替 rekey。成功状态为 `transferred`;重复提交同一已完成转移可返回原结果。名片发布失败不反向撤销已提交的 owner 切换,SDK 保留新代际原字节和原 CAS 条件恢复上传。服务持久原已验证证书及 transfer nonce/旧 serial CAS,已提交 CA 的可恢复待办超 TTL 仍收敛,未提交 CA 的过期待办拒绝,旧请求不得提交新的转移。
327
+
328
+ ### `group.bind_group_aid` / `group.renew_group_aid`
329
+
330
+ `bind_group_aid` 为匿名群补齐专属群身份,不是 Ownership 绑定;仅当前 owner 可操作,匹配公钥可幂等重放,不同公钥拒绝。`renew_group_aid` 是当前 owner 主动换钥,必须持有旧群私钥并提交换钥证明;它不替代两阶段 owner 转移。成功后 owner 持有新材料,并用本人身份重新代签、代上传群名片。
331
+
332
+ ### `group.get_members`
333
+
334
+ 获取群成员列表。需要是群成员。
335
+
336
+ **参数**:
337
+
338
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
339
+ |------|------|:----:|--------|------|
340
+ | `group_id` | string | ✅ | — | 群组 ID |
341
+ | `page` | integer | ❌ | 1 | 页码 |
342
+ | `size` | integer | ❌ | 50 | 每页条数 |
343
+ | `role` | string | ❌ | — | 按角色过滤 |
344
+
345
+ **响应**:`{ "members": [ ... ], "total": 10, "page": 1, "size": 50 }`
346
+
347
+ ### `group.ban`
348
+
349
+ 封禁成员(禁止发消息但保留群成员身份)。需要 admin 及以上权限。
350
+
351
+ **参数**:`group_id` (必填), `aid` (必填), `duration_seconds` (integer, 可选,0 表示永久)
352
+
353
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "banned_aid": "bob.agentid.pub" }`
354
+
355
+ ### `group.unban`
356
+
357
+ 解除封禁。需要 admin 及以上权限。
358
+
359
+ **参数**:`group_id` (必填), `aid` (必填)
360
+
361
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "unbanned_aid": "bob.agentid.pub" }`
362
+
353
363
  ### `group.get_banlist`
354
-
355
- 获取封禁列表。需要 admin 及以上权限。
356
-
357
- **参数**:`group_id` (必填)
358
-
364
+
365
+ 获取封禁列表。需要 admin 及以上权限。
366
+
367
+ **参数**:`group_id` (必填)
368
+
359
369
  **响应**:`{ "group_id": "g-abc123.agentid.pub", "items": [ ... ] }`
360
370
 
361
371
  禁言和屏蔽是独立状态,可以同时设置。禁言禁止发送但不影响接收;屏蔽停止接收但不影响发送。
@@ -399,78 +409,78 @@ SDK 高层建群流程必须支持崩溃恢复:命名群复用已持久化密
399
409
  **参数**:`group_id`(必填)
400
410
 
401
411
  **响应**:`{ "group_id": "g-abc123.agentid.pub", "group_aid": "g-abc123.agentid.pub", "items": [ { "group_id": "g-abc123.agentid.pub", "aid": "alice.agentid.pub", "online_status": "online", "work_status": "busy", "updated_at": 1234567890000, "last_message_at": 1234567890123, "last_payload_type": "text" } ] }`
402
-
403
- ---
404
-
405
- ## 10.6 消息方法
406
-
407
- ### `group.send`
408
-
409
- 发送群消息。
410
-
411
- **参数**:
412
-
413
- | 参数 | 类型 | 必填 | 说明 |
414
- |------|------|:----:|------|
415
- | `group_id` | string | ✅ | 群组 ID |
416
- | `type` | string | ❌ | 信封/封装类型,普通业务消息无需填写;SDK 加密群消息时自动使用 `e2ee.group_encrypted` |
417
- | `payload` | object | ✅ | 消息内容 |
418
- | `attachments` | array | ❌ | 存储引用列表 |
419
-
420
- ##### Payload 参考约定
421
-
422
- `group.send.params.payload` 的统一业务负载格式见 [消息Payload参考约定](../sdk/消息Payload参考约定.md)。完整群消息请求仍在 `payload` 同级传入 `group_id`;业务类型放在 `payload.type`,不要与 `group.send.params.type` 信封/封装类型混用。
423
-
424
- 协议层只要求 `payload` 是 JSON 对象,并按服务端配置做大小、信封/封装类型和 E2EE epoch 相关检查;字段语义由应用层约定,接收端应对未知 `payload.type`、未知 `kind` 和缺失展示字段做降级处理。
425
-
426
- **响应**:
427
-
428
- ```json
429
- {
430
- "group_id": "g-abc123.agentid.pub",
431
- "message": {
432
- "seq": 42,
433
- "message_id": "gm-...",
434
- "sender_aid": "alice.agentid.pub",
435
- "message_type": "text",
436
- "payload": { ... },
437
- "attachments": [],
438
- "created_at": 1234567890123
439
- },
440
- "event": {
441
- "seq": 10,
442
- "event_type": "message_created",
443
- "actor_aid": "alice.agentid.pub",
444
- "data": { "dispatch": { ... } },
445
- "created_at": 1234567890123
446
- },
447
- "dispatch": { ... }
448
- }
449
- ```
450
-
451
- **设计约束**:
412
+
413
+ ---
414
+
415
+ ## 10.6 消息方法
416
+
417
+ ### `group.send`
418
+
419
+ 发送群消息。
420
+
421
+ **参数**:
422
+
423
+ | 参数 | 类型 | 必填 | 说明 |
424
+ |------|------|:----:|------|
425
+ | `group_id` | string | ✅ | 群组 ID |
426
+ | `type` | string | ❌ | 信封/封装类型,普通业务消息无需填写;SDK 加密群消息时自动使用 `e2ee.group_encrypted` |
427
+ | `payload` | object | ✅ | 消息内容 |
428
+ | `attachments` | array | ❌ | 存储引用列表 |
429
+
430
+ ##### Payload 参考约定
431
+
432
+ `group.send.params.payload` 的统一业务负载格式见 [消息Payload参考约定](../sdk/消息Payload参考约定.md)。完整群消息请求仍在 `payload` 同级传入 `group_id`;业务类型放在 `payload.type`,不要与 `group.send.params.type` 信封/封装类型混用。
433
+
434
+ 协议层只要求 `payload` 是 JSON 对象,并按服务端配置做大小、信封/封装类型和 E2EE epoch 相关检查;字段语义由应用层约定,接收端应对未知 `payload.type`、未知 `kind` 和缺失展示字段做降级处理。
435
+
436
+ **响应**:
437
+
438
+ ```json
439
+ {
440
+ "group_id": "g-abc123.agentid.pub",
441
+ "message": {
442
+ "seq": 42,
443
+ "message_id": "gm-...",
444
+ "sender_aid": "alice.agentid.pub",
445
+ "message_type": "text",
446
+ "payload": { ... },
447
+ "attachments": [],
448
+ "created_at": 1234567890123
449
+ },
450
+ "event": {
451
+ "seq": 10,
452
+ "event_type": "message_created",
453
+ "actor_aid": "alice.agentid.pub",
454
+ "data": { "dispatch": { ... } },
455
+ "created_at": 1234567890123
456
+ },
457
+ "dispatch": { ... }
458
+ }
459
+ ```
460
+
461
+ **设计约束**:
452
462
  - 群 `status=suspended` 时仅 owner/admin 可以发送,member 发送会被拒绝
453
- - 消息 ID 自动生成(格式:`gm-{uuid}`),客户端无需提供
454
-
455
- ### `group.pull`
456
-
457
- 增量拉取群消息。事件请用 `group.pull_events` 单独拉取。
458
-
459
- **参数**:
460
-
461
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
462
- |------|------|:----:|--------|------|
463
+ - 消息 ID 自动生成(格式:`gm-{uuid}`),客户端无需提供
464
+
465
+ ### `group.pull`
466
+
467
+ 增量拉取群消息。事件请用 `group.pull_events` 单独拉取。
468
+
469
+ **参数**:
470
+
471
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
472
+ |------|------|:----:|--------|------|
463
473
  | `group_id` | string | ✅ | — | 群组 ID |
464
474
  | `after_message_seq` | integer | ❌ | 0 | 拉取该 seq 之后的消息 |
465
475
  | `limit` | integer | ❌ | 50 | 最大条数(最大 50) |
466
476
  | `device_id` | string | ❌ | — | 设备 ID(多设备模式) |
467
477
  | `window_mode` | string | ❌ | — | 可选 Pull 模式;`tail` 表示读取以安全 Head 结尾的最新一页 |
468
-
469
- **响应**:
470
-
471
- ```json
472
- {
473
- "group_id": "g-abc123.agentid.pub",
478
+
479
+ **响应**:
480
+
481
+ ```json
482
+ {
483
+ "group_id": "g-abc123.agentid.pub",
474
484
  "messages": [ ... ],
475
485
  "latest_message_seq": 42,
476
486
  "has_more": false,
@@ -503,212 +513,220 @@ History 不推进消息或事件 ACK,不修改 cursor/floor/Pull activity,
503
513
  **客户端发布语义**:单个通过校验的 Tail/Forward 响应页内必须按 seq 升序处理,并折叠页内重复 seq。A/T/H 只描述扫描进度,不是应用发布账本;跨 Push/Tail/Forward 页不承诺唯一或有序。全局去重与排序属于应用层业务仓库职责,不是 SDK 交付契约;应用层必须在群 namespace 内按 `message_id` 幂等,并按 `seq` 排序。SDK 进程内折叠只能作为 best-effort 优化。History 不进入实时发布流。
504
514
 
505
515
  ### `group.ack`
506
-
507
- 提交已读游标(per-AID,非 per-device)。
508
-
509
- **参数**:`group_id` (必填), `seq` (integer, 必填)
510
-
511
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "aid": "alice.agentid.pub", "ack_seq": 42, "latest_message_seq": 100 }`
512
-
513
- ---
514
-
515
- ## 10.7 入群方式
516
-
517
- ### `group.request_join`
518
-
519
- 申请加入群组(适用于 `join_mode=approval` 的群)。
520
-
521
- **参数**:`group_id` (必填), `message` (string, 可选,申请消息), `answer` (string, 可选,回答入群问题)
522
-
523
- **响应**:`{ "status": "pending", "request": { ... } }`
524
-
525
- ### `group.list_join_requests`
526
-
527
- 列出入群申请。需要 admin 及以上权限。
528
-
529
- **参数**:
530
-
531
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
532
- |------|------|:----:|--------|------|
533
- | `group_id` | string | ✅ | — | 群组 ID |
534
- | `status` | string | ❌ | `"pending"` | `"pending"` / `"approved"` / `"rejected"` |
535
- | `page` | integer | ❌ | 1 | 页码 |
536
- | `size` | integer | ❌ | 50 | 每页条数 |
537
-
538
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "items": [ ... ], "total": 1 }`
539
-
540
- ### `group.review_join_request`
541
-
542
- 审批单个入群申请。需要 admin 及以上权限。**以 `aid` 定位申请**(非 request_id)。
543
-
544
- **参数**:
545
-
546
- | 参数 | 类型 | 必填 | 说明 |
547
- |------|------|:----:|------|
548
- | `group_id` | string | ✅ | 群组 ID |
549
- | `aid` | string | ✅ | 申请人 AID |
550
- | `approve` | boolean | ❌ | 批准(true)或拒绝(false),默认 true |
551
- | `reason` | string | ❌ | 拒绝原因 |
552
-
553
- **响应**:`{ "request": { ... }, "group": { ... } }`
554
-
555
- ### `group.batch_review_join_request`
556
-
557
- 批量审批入群申请。需要 admin 及以上权限。
558
-
559
- **参数**:`group_id` (必填), `aids` (array, 必填), `approve` (boolean, 必填)
560
-
561
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "results": [ ... ] }`
562
-
563
- ### `group.get_join_requirements`
564
-
565
- 获取入群要求配置。
566
-
567
- **参数**:`group_id` (string, 必填)
568
-
569
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "requirements": { "mode": "approval", "question": "...", ... } }`
570
-
571
- ### `group.update_join_requirements`
572
-
573
- 更新入群要求配置。需要 admin 及以上权限。
574
-
575
- **参数**:`group_id` (必填), `mode` / `question` / `auto_approve_patterns` / `max_pending` (可选)
576
-
577
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "requirements": { ... } }`
578
-
579
- ### `group.create_invite_code`
580
-
581
- 创建邀请码。需要 owner/admin 权限,或群规则允许成员邀请。
582
-
583
- **参数**:
584
-
585
- | 参数 | 类型 | 必填 | 说明 |
586
- |------|------|:----:|------|
587
- | `group_id` | string | ✅ | 群组 ID |
588
- | `code` | string | ❌ | 自定义邀请码,不提供则自动生成 |
589
- | `max_uses` | integer | ❌ | 最大使用次数,默认 1,必须 > 0 |
590
- | `expires_in_seconds` | integer | ❌ | 有效期(秒),默认由配置决定(7 天) |
591
-
592
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "invite_code": { ... } }`
593
-
594
- ### `group.list_invite_codes`
595
-
596
- 列出群组的邀请码。需要 admin 及以上权限。
597
-
598
- **参数**:`group_id` (必填), `status` (可选,`"active"` / `"expired"` / `"revoked"`)
599
-
600
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "items": [ ... ] }`
601
-
602
- ### `group.use_invite_code`
603
-
604
- 使用邀请码加入群组。邀请码自动转为小写匹配。
605
-
606
- **参数**:`code` (string, 必填)
607
-
608
- **响应**:`{ "status": "joined", "group": { ... }, "invite_code": { ... } }`
609
-
610
- ### `group.revoke_invite_code`
611
-
612
- 撤销邀请码。需要 admin 及以上权限。
613
-
614
- **参数**:`group_id` (必填), `code` (必填)
615
-
616
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "code": "abc123", "status": "revoked" }`
617
-
618
- ---
619
-
620
- ## 10.8 公告与规则
621
-
622
- ### `group.get_announcement`
623
-
624
- 获取群公告。需要是群成员。
625
-
626
- **参数**:`group_id` (string, 必填)
627
-
628
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "announcement": { ... } }`
629
-
630
- ### `group.update_announcement`
631
-
632
- 更新群公告。需要 admin 及以上权限。
633
-
634
- **参数**:`group_id` (必填), `content` (string, 必填,上限默认 4000 字符), `attachments` (array, 可选)
635
-
636
- ### `group.get_rules`
637
-
638
- 获取群规则(可见性设置、加入模式等)。
639
-
640
- **参数**:`group_id` (string, 必填)
641
-
642
- ### `group.update_rules`
643
-
644
- 更新入群要求。需要 admin 及以上权限。
645
-
646
- **参数**:
647
-
648
- | 参数 | 类型 | 必填 | 说明 |
649
- |------|------|:----:|------|
650
- | `group_id` | string | ✅ | 群组 ID |
651
- | `mode` | string | ❌ | `"open"` / `"approval"` / `"invite_only"` / `"closed"` |
652
- | `question` | string | ❌ | 入群问题 |
653
- | `auto_approve_patterns` | array | ❌ | 自动批准正则列表 |
654
- | `max_pending` | integer | ❌ | 最大待审批数 |
655
-
656
- ---
657
-
658
- ## 10.9 Group FS
659
-
660
- Group FS 是群文件系统的唯一对外模型,所有群文件浏览、创建目录、移动、删除、上传、下载和成员数据挂载都通过 `group.fs.*` 完成;不再提供独立的旧资源引用接口。
661
-
662
- ### 路径语义
663
-
664
- - `group_aid:/memberdata`:系统保留虚拟目录。
665
- - `group_aid:/memberdata/{member_aid}`:成员挂载槽位,只能通过 `group.fs.mount` / `group.fs.umount` 等受控流程管理。
666
- - 除 `memberdata` 和其它系统保留路径外,整个群根命名空间都属于群自有区。
667
-
668
- ### 常用 RPC
669
-
670
- | 方法 | 说明 |
671
- |------|------|
672
- | `group.fs.ls` / `group.fs.find` | 列目录、查找节点 |
673
- | `group.fs.stat` / `group.fs.lstat` | 查看节点状态 |
674
- | `group.fs.mkdir` / `group.fs.rm` | 创建目录、删除节点 |
675
- | `group.fs.cp` / `group.fs.mv` | 复制、移动或改名 |
676
- | `group.fs.check_upload` / `group.fs.create_upload_session` / `group.fs.complete_upload` | 上传流程控制面 |
677
- | `group.fs.create_download_ticket` | 创建下载票据 |
678
- | `group.fs.mount` / `group.fs.umount` | 管理成员数据挂载 |
679
- | `group.fs.set_visibility` | 设置群自有区节点可见性 |
680
- | `group.fs.set_acl` | owner 授予群自有区 `role:admin` 写 ACL |
681
- | `group.fs.remove_acl` | owner 撤销群自有区 `role:admin` 写 ACL |
682
-
683
- ### 权限规则
684
-
685
- - 群自有区默认 `public` 表示群内公开,当前群成员可读。
686
- - `private` 节点不再自动授予所有成员读权限,需要显式读授权或下载票据。
687
- - 群自有区写权限默认授予当前 `group_aid` 证书签名和 `role:owner`;`role:admin` 只有在 group owner 通过 `group.fs.set_acl` 显式授权后才可写。
688
- - `group.fs.set_acl/remove_acl` 只允许当前 group owner 调用,当前只允许管理 `grantee_aid="role:admin"`;授权和撤销的是角色策略,不与某个 admin 成员绑定,成员升降级、退群、踢出不会联动 ACL。
689
- - `memberdata` 不受普通群自有区规则覆盖;群主、管理员和 `group_aid` 都不能用普通文件操作删除或改名成员槽位根。
690
- - 成员写自己的挂载区,本质上写入成员个人 Storage 的群专属目录,由 `group.fs` 映射到 `/memberdata/{member_aid}`。
691
-
692
- ---
693
-
516
+
517
+ 提交投递消费游标。SDK 的多设备/slot 游标按当前实例隔离;业务已读独立使用 `group.read/read_state`,不能以 ACK 表示用户已经阅读话题。
518
+
519
+ **参数**:`group_id` (必填), `seq` (integer, 必填)
520
+
521
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "aid": "alice.agentid.pub", "ack_seq": 42, "latest_message_seq": 100 }`
522
+
523
+ ---
524
+
525
+ ### `group.read` / `group.read_state`
526
+
527
+ `group.read` 以 `states` 上报当前认证 AID/device 的群话题最后已读消息,每项包含 `group_id`、原样保存的 `topic_key`、`last_read_message_id`;缺省 scope 为 `group`。只有省略 `states` 时兼容顶层单条,显式空数组/null 拒绝;四个已读门面保留显式空值供服务端校验。历史 Group ID 别名解析为 canonical ID,新写状态键、响应和事件使用 canonical ID,历史别名参与事实/公共位置/设备映射的事务查询,权限复用既有版本同步。回执是设备写入结果,不是共享汇总。同域先校验全部项;混合域按所属域逐域校验和提交,任何域失败则 RPC 返回错误,已提交域不回滚,原样幂等重试可收敛。
528
+
529
+ `group.read_state` 按当前 AID 的 `group_id`、`topic_key` 可选条件查询共享汇总;未指定群时发现本域及远域有权限的成员群。响应 `states` 包含公共 `last_read_order`、当前设备 `current_device_seq` 和 `mapping_status`(resolved/not_received/unresolved);无映射 seq 为 null。晚到公共位置对仍匹配该消息且 order=0 的事实条件持久回填,不能只更新缓存或覆盖并发前进的事实。网络整数保持 int64 语义,Gateway 本域服务及 federation 回程不得经浮点中转,TS/JS API 超安全整数使用精确十进制字符串。
530
+
531
+ 共享位置已提交并前进后发布 `event/group.read_changed`,SDK 订阅名为 `group.read_changed`,owner 必须非空且为当前身份,scope 必须匹配原事件;Gateway 校验 Kernel 转发的可信 Group 来源,即使显式 route 也只向该 owner AID 分发,支持所属域向该外域成员 AID 转发,不能广播给其他成员。事件 ID 对身份、话题及公共位置组成的 JSON 元组取 SHA-256,失败日志不泄露 topic。事件包含 owner AID、scope、group、topic、消息 ID、公共顺序和更新时间,不进入 Pull 队列。SDK 重连保留原查询过滤范围,通过仅本地发布的 `read_state_sync` 交付本轮状态及逐项错误;身份切换按代际隔离旧缓存及补偿完成事件,A→B→A 也不能接收旧代际结果;原在途 RPC 仍可返回。完整契约见 `aun-sdk-core/docs/跨设备已读未读详细设计.md`。
532
+
533
+ ## 10.7 入群方式
534
+
535
+ ### `group.request_join`
536
+
537
+ 申请加入群组(适用于 `join_mode=approval` 的群)。
538
+
539
+ **参数**:`group_id` (必填), `message` (string, 可选,申请消息), `answer` (string, 可选,回答入群问题)
540
+
541
+ **响应**:`{ "status": "pending", "request": { ... } }`
542
+
543
+ ### `group.list_join_requests`
544
+
545
+ 列出入群申请。需要 admin 及以上权限。
546
+
547
+ **参数**:
548
+
549
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
550
+ |------|------|:----:|--------|------|
551
+ | `group_id` | string | ✅ | — | 群组 ID |
552
+ | `status` | string | ❌ | `"pending"` | `"pending"` / `"approved"` / `"rejected"` |
553
+ | `page` | integer | ❌ | 1 | 页码 |
554
+ | `size` | integer | ❌ | 50 | 每页条数 |
555
+
556
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "items": [ ... ], "total": 1 }`
557
+
558
+ ### `group.review_join_request`
559
+
560
+ 审批单个入群申请。需要 admin 及以上权限。**以 `aid` 定位申请**(非 request_id)。
561
+
562
+ **参数**:
563
+
564
+ | 参数 | 类型 | 必填 | 说明 |
565
+ |------|------|:----:|------|
566
+ | `group_id` | string | ✅ | 群组 ID |
567
+ | `aid` | string | ✅ | 申请人 AID |
568
+ | `approve` | boolean | ❌ | 批准(true)或拒绝(false),默认 true |
569
+ | `reason` | string | ❌ | 拒绝原因 |
570
+
571
+ **响应**:`{ "request": { ... }, "group": { ... } }`
572
+
573
+ ### `group.batch_review_join_request`
574
+
575
+ 批量审批入群申请。需要 admin 及以上权限。
576
+
577
+ **参数**:`group_id` (必填), `aids` (array, 必填), `approve` (boolean, 必填)
578
+
579
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "results": [ ... ] }`
580
+
581
+ ### `group.get_join_requirements`
582
+
583
+ 获取入群要求配置。
584
+
585
+ **参数**:`group_id` (string, 必填)
586
+
587
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "requirements": { "mode": "approval", "question": "...", ... } }`
588
+
589
+ ### `group.update_join_requirements`
590
+
591
+ 更新入群要求配置。需要 admin 及以上权限。
592
+
593
+ **参数**:`group_id` (必填), `mode` / `question` / `auto_approve_patterns` / `max_pending` (可选)
594
+
595
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "requirements": { ... } }`
596
+
597
+ ### `group.create_invite_code`
598
+
599
+ 创建邀请码。需要 owner/admin 权限,或群规则允许成员邀请。
600
+
601
+ **参数**:
602
+
603
+ | 参数 | 类型 | 必填 | 说明 |
604
+ |------|------|:----:|------|
605
+ | `group_id` | string | ✅ | 群组 ID |
606
+ | `code` | string | ❌ | 自定义邀请码,不提供则自动生成 |
607
+ | `max_uses` | integer | ❌ | 最大使用次数,默认 1,必须 > 0 |
608
+ | `expires_in_seconds` | integer | ❌ | 有效期(秒),默认由配置决定(7 天) |
609
+
610
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "invite_code": { ... } }`
611
+
612
+ ### `group.list_invite_codes`
613
+
614
+ 列出群组的邀请码。需要 admin 及以上权限。
615
+
616
+ **参数**:`group_id` (必填), `status` (可选,`"active"` / `"expired"` / `"revoked"`)
617
+
618
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "items": [ ... ] }`
619
+
620
+ ### `group.use_invite_code`
621
+
622
+ 使用邀请码加入群组。邀请码自动转为小写匹配。
623
+
624
+ **参数**:`code` (string, 必填)
625
+
626
+ **响应**:`{ "status": "joined", "group": { ... }, "invite_code": { ... } }`
627
+
628
+ ### `group.revoke_invite_code`
629
+
630
+ 撤销邀请码。需要 admin 及以上权限。
631
+
632
+ **参数**:`group_id` (必填), `code` (必填)
633
+
634
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "code": "abc123", "status": "revoked" }`
635
+
636
+ ---
637
+
638
+ ## 10.8 公告与规则
639
+
640
+ ### `group.get_announcement`
641
+
642
+ 获取群公告。需要是群成员。
643
+
644
+ **参数**:`group_id` (string, 必填)
645
+
646
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "announcement": { ... } }`
647
+
648
+ ### `group.update_announcement`
649
+
650
+ 更新群公告。需要 admin 及以上权限。
651
+
652
+ **参数**:`group_id` (必填), `content` (string, 必填,上限默认 4000 字符), `attachments` (array, 可选)
653
+
654
+ ### `group.get_rules`
655
+
656
+ 获取群规则(可见性设置、加入模式等)。
657
+
658
+ **参数**:`group_id` (string, 必填)
659
+
660
+ ### `group.update_rules`
661
+
662
+ 更新入群要求。需要 admin 及以上权限。
663
+
664
+ **参数**:
665
+
666
+ | 参数 | 类型 | 必填 | 说明 |
667
+ |------|------|:----:|------|
668
+ | `group_id` | string | ✅ | 群组 ID |
669
+ | `mode` | string | ❌ | `"open"` / `"approval"` / `"invite_only"` / `"closed"` |
670
+ | `question` | string | ❌ | 入群问题 |
671
+ | `auto_approve_patterns` | array | ❌ | 自动批准正则列表 |
672
+ | `max_pending` | integer | ❌ | 最大待审批数 |
673
+
674
+ ---
675
+
676
+ ## 10.9 Group FS
677
+
678
+ Group FS 是群文件系统的唯一对外模型,所有群文件浏览、创建目录、移动、删除、上传、下载和成员数据挂载都通过 `group.fs.*` 完成;不再提供独立的旧资源引用接口。
679
+
680
+ ### 路径语义
681
+
682
+ - `group_aid:/memberdata`:系统保留虚拟目录。
683
+ - `group_aid:/memberdata/{member_aid}`:成员挂载槽位,只能通过 `group.fs.mount` / `group.fs.umount` 等受控流程管理。
684
+ - 除 `memberdata` 和其它系统保留路径外,整个群根命名空间都属于群自有区。
685
+
686
+ ### 常用 RPC
687
+
688
+ | 方法 | 说明 |
689
+ |------|------|
690
+ | `group.fs.ls` / `group.fs.find` | 列目录、查找节点 |
691
+ | `group.fs.stat` / `group.fs.lstat` | 查看节点状态 |
692
+ | `group.fs.mkdir` / `group.fs.rm` | 创建目录、删除节点 |
693
+ | `group.fs.cp` / `group.fs.mv` | 复制、移动或改名 |
694
+ | `group.fs.check_upload` / `group.fs.create_upload_session` / `group.fs.complete_upload` | 上传流程控制面 |
695
+ | `group.fs.create_download_ticket` | 创建下载票据 |
696
+ | `group.fs.mount` / `group.fs.umount` | 管理成员数据挂载 |
697
+ | `group.fs.set_visibility` | 设置群自有区节点可见性 |
698
+ | `group.fs.set_acl` | owner 授予群自有区 `role:admin` 写 ACL |
699
+ | `group.fs.remove_acl` | owner 撤销群自有区 `role:admin` 写 ACL |
700
+
701
+ ### 权限规则
702
+
703
+ - 群自有区默认 `public` 表示群内公开,当前群成员可读。
704
+ - `private` 节点不再自动授予所有成员读权限,需要显式读授权或下载票据。
705
+ - 群自有区写权限默认授予当前 `group_aid` 证书签名和 `role:owner`;`role:admin` 只有在 group owner 通过 `group.fs.set_acl` 显式授权后才可写。
706
+ - `group.fs.set_acl/remove_acl` 只允许当前 group owner 调用,当前只允许管理 `grantee_aid="role:admin"`;授权和撤销的是角色策略,不与某个 admin 成员绑定,成员升降级、退群、踢出不会联动 ACL。
707
+ - `memberdata` 不受普通群自有区规则覆盖;群主、管理员和 `group_aid` 都不能用普通文件操作删除或改名成员槽位根。
708
+ - 成员写自己的挂载区,本质上写入成员个人 Storage 的群专属目录,由 `group.fs` 映射到 `/memberdata/{member_aid}`。
709
+
710
+ ---
711
+
694
712
  ## 10.12 在线状态与群内成员状态
695
-
696
- 群组在线状态是 per-AID 的全局状态(非 per-group)。在线索引由 Gateway 的 `client.online` / `client.offline` 事件驱动,Group 服务消费这些事件维护在线状态;客户端不需要也不能调用单独的上线、下线或心跳 RPC。
697
-
698
- ### `group.get_online_members`
699
-
700
- 查询群内在线成员列表。
701
-
702
- **参数**:`group_id` (string, 必填)
703
-
704
- **响应**:`{ "group_id": "g-abc123.agentid.pub", "members": [ ... ], "items": [ ... ], "online_members": [ ... ], "online_count": 2, "total": 10, "page": 1, "size": 10 }`
705
-
713
+
714
+ 群组在线状态是 per-AID 的全局状态(非 per-group)。在线索引由 Gateway 的 `client.online` / `client.offline` 事件驱动,Group 服务消费这些事件维护在线状态;客户端不需要也不能调用单独的上线、下线或心跳 RPC。
715
+
716
+ ### `group.get_online_members`
717
+
718
+ 查询群内在线成员列表。
719
+
720
+ **参数**:`group_id` (string, 必填)
721
+
722
+ **响应**:`{ "group_id": "g-abc123.agentid.pub", "members": [ ... ], "items": [ ... ], "online_members": [ ... ], "online_count": 2, "total": 10, "page": 1, "size": 10 }`
723
+
706
724
  字段约定:`members` 是主字段;`items` 和 `online_members` 是兼容别名,内容与 `members` 完全相同。
707
725
 
708
726
  `group.get_online_members` 返回 Gateway 在线索引中的全局连接状态。`group.report_status` / `group.get_member_statuses` 管理成员在单个群内主动上报的在线/工作状态及最后发言摘要,两套状态来源相互独立。
709
-
710
- ---
711
-
727
+
728
+ ---
729
+
712
730
  ## 10.13 群设置与 `group.index`
713
731
 
714
732
  `group.set_settings` / `group.get_settings` 是群公告、群规则、入群要求、提及过滤模式等群级设置的统一 RPC。`group.index` 是保留设置 key,用于保存 owner/admin SDK 生成并签名的群索引 JSONL。
@@ -740,120 +758,121 @@ Group FS 是群文件系统的唯一对外模型,所有群文件浏览、创
740
758
  ---
741
759
 
742
760
  ## 10.14 事件
743
-
744
- Group 服务通过 `event/group.*` 事件推送变更通知给相关 AID。
745
-
746
- ### `event/group.created`
747
-
748
- 群组创建时推送给群主。
749
-
750
- ```json
751
- {
752
- "module_id": "group",
753
- "group_id": "g-abc123.agentid.pub",
754
- "owner_aid": "alice.agentid.pub",
755
- "visibility": "private"
756
- }
757
- ```
758
-
759
- ### `event/group.changed`
760
-
761
- 群组状态变化时推送给所有成员。
762
-
763
- ```json
764
- {
765
- "module_id": "group",
766
- "action": "member_added",
767
- "group_id": "g-abc123.agentid.pub"
768
- }
769
- ```
770
-
771
- | `action` 值 | 说明 |
772
- |-------------|------|
773
- | `upsert` | 群组创建/更新 |
774
- | `update` | 群组信息更新 |
775
- | `member_added` | 成员加入 |
776
- | `member_left` | 成员退出 |
777
- | `member_removed` | 成员被踢出 |
778
- | `role_changed` | 角色变更 |
779
- | `owner_transferred` | 群主转让 |
780
- | `rules_updated` | 规则更新 |
781
- | `announcement_updated` | 公告更新 |
782
- | `join_requested` | 收到入群申请 |
783
- | `joined` | 成员加入(通过邀请码等) |
784
- | `join_approved` | 入群申请批准 |
785
- | `join_rejected` | 入群申请拒绝 |
786
- | `join_requirements_updated` | 入群要求配置更新 |
787
- | `invite_code_created` | 邀请码创建 |
788
- | `invite_code_used` | 邀请码使用 |
789
- | `invite_code_revoked` | 邀请码撤销 |
761
+
762
+ Group 服务通过 `event/group.*` 事件推送变更通知给相关 AID。
763
+
764
+ ### `event/group.created`
765
+
766
+ 群组创建时推送给群主。
767
+
768
+ ```json
769
+ {
770
+ "module_id": "group",
771
+ "group_id": "g-abc123.agentid.pub",
772
+ "owner_aid": "alice.agentid.pub",
773
+ "visibility": "private"
774
+ }
775
+ ```
776
+
777
+ ### `event/group.changed`
778
+
779
+ 群组状态变化时推送给所有成员。
780
+
781
+ ```json
782
+ {
783
+ "module_id": "group",
784
+ "action": "member_added",
785
+ "group_id": "g-abc123.agentid.pub"
786
+ }
787
+ ```
788
+
789
+ | `action` 值 | 说明 |
790
+ |-------------|------|
791
+ | `upsert` | 群组创建/更新 |
792
+ | `update` | 群组信息更新 |
793
+ | `member_added` | 成员加入 |
794
+ | `member_left` | 成员退出 |
795
+ | `member_removed` | 成员被踢出 |
796
+ | `role_changed` | 角色变更 |
797
+ | `owner_transfer_rekey_pending` | 群主转让已发起,等待新 owner 完成强制换钥与确认 |
798
+ | `owner_transferred` | 强制 rekey 后群主转让完成 |
799
+ | `rules_updated` | 规则更新 |
800
+ | `announcement_updated` | 公告更新 |
801
+ | `join_requested` | 收到入群申请 |
802
+ | `joined` | 成员加入(通过邀请码等) |
803
+ | `join_approved` | 入群申请批准 |
804
+ | `join_rejected` | 入群申请拒绝 |
805
+ | `join_requirements_updated` | 入群要求配置更新 |
806
+ | `invite_code_created` | 邀请码创建 |
807
+ | `invite_code_used` | 邀请码使用 |
808
+ | `invite_code_revoked` | 邀请码撤销 |
790
809
  | `member_banned` | 成员被封禁 |
791
810
  | `member_unbanned` | 成员解除封禁 |
792
811
  | `member_blocked` | 成员被屏蔽 |
793
812
  | `member_unblocked` | 成员取消屏蔽 |
794
- | `suspended` | 群组暂停 |
795
- | `resumed` | 群组恢复 |
796
- | `dissolved` | 群组解散 |
797
- | `fs_updated` | Group FS 节点更新 |
798
- | `fs_visibility_updated` | Group FS 可见性更新 |
799
- | `fs_deleted` | Group FS 节点删除 |
800
-
801
- ### `event/group.message_created`
802
-
803
- 群内新消息时推送给所有在线成员。支持两种模式:
804
-
805
- **消息推送模式**(带 `payload`):事件包含完整消息体,SDK 自动解密后直接交付用户。
806
-
807
- ```json
808
- {
809
- "module_id": "group",
810
- "group_id": "g-abc123.agentid.pub",
811
- "seq": 42,
812
- "message_id": "550e8400-...",
813
- "sender_aid": "alice.agentid.pub",
814
- "type": "e2ee.group_encrypted",
815
- "payload": { "type": "e2ee.group_encrypted", "..." : "..." },
816
- "dispatch": { "mode": "broadcast", "reason": "duty_disabled" },
817
- "kind": "group.broadcast",
818
- "member_aids": ["bob.agentid.pub", "carol.agentid.pub"]
819
- }
820
- ```
821
-
822
- **通知模式**(不带 `payload`):仅包含元数据,SDK 收到后自动调用 `group.pull` 拉取最新消息。
823
-
824
- ```json
825
- {
826
- "module_id": "group",
827
- "group_id": "g-abc123.agentid.pub",
828
- "seq": 42,
829
- "message_id": "550e8400-...",
830
- "sender_aid": "alice.agentid.pub",
831
- "type": "e2ee.group_encrypted",
832
- "dispatch": { "mode": "broadcast", "reason": "duty_disabled" },
833
- "member_aids": ["bob.agentid.pub", "carol.agentid.pub"]
834
- }
835
- ```
836
-
837
- > **SDK 行为**:`payload.type == "e2ee.group_encrypted"` 时自动 E2EE 解密;`payload` 缺失时自动 pull;其他情况原样透传。
838
-
839
- ---
840
-
813
+ | `suspended` | 群组暂停 |
814
+ | `resumed` | 群组恢复 |
815
+ | `dissolved` | 群组解散 |
816
+ | `fs_updated` | Group FS 节点更新 |
817
+ | `fs_visibility_updated` | Group FS 可见性更新 |
818
+ | `fs_deleted` | Group FS 节点删除 |
819
+
820
+ ### `event/group.message_created`
821
+
822
+ 群内新消息时推送给所有在线成员。支持两种模式:
823
+
824
+ **消息推送模式**(带 `payload`):事件包含完整消息体,SDK 自动解密后直接交付用户。
825
+
826
+ ```json
827
+ {
828
+ "module_id": "group",
829
+ "group_id": "g-abc123.agentid.pub",
830
+ "seq": 42,
831
+ "message_id": "550e8400-...",
832
+ "sender_aid": "alice.agentid.pub",
833
+ "type": "e2ee.group_encrypted",
834
+ "payload": { "type": "e2ee.group_encrypted", "..." : "..." },
835
+ "dispatch": { "mode": "broadcast", "reason": "duty_disabled" },
836
+ "kind": "group.broadcast",
837
+ "member_aids": ["bob.agentid.pub", "carol.agentid.pub"]
838
+ }
839
+ ```
840
+
841
+ **通知模式**(不带 `payload`):仅包含元数据,SDK 收到后自动调用 `group.pull` 拉取最新消息。
842
+
843
+ ```json
844
+ {
845
+ "module_id": "group",
846
+ "group_id": "g-abc123.agentid.pub",
847
+ "seq": 42,
848
+ "message_id": "550e8400-...",
849
+ "sender_aid": "alice.agentid.pub",
850
+ "type": "e2ee.group_encrypted",
851
+ "dispatch": { "mode": "broadcast", "reason": "duty_disabled" },
852
+ "member_aids": ["bob.agentid.pub", "carol.agentid.pub"]
853
+ }
854
+ ```
855
+
856
+ > **SDK 行为**:`payload.type == "e2ee.group_encrypted"` 时自动 E2EE 解密;`payload` 缺失时自动 pull;其他情况原样透传。
857
+
858
+ ---
859
+
841
860
  ## 10.15 错误码
842
-
843
- | 错误码 | 说明 | 客户端处理 |
844
- |--------|------|-----------|
845
- | -32601 | Method not found | 检查方法名 |
846
- | -32602 | Invalid params(如缺少 group_id) | 检查参数 |
847
- | -32004 | Permission denied(权限不足) | 提示用户,不重试 |
848
- | -32001 | Authentication failed | 重新认证 |
849
- | -33001 | Group not found | 检查 group_id |
850
- | -33002 | Group state invalid(群状态不允许该操作) | 检查群状态 |
851
- | -33003 | Group suspended | 等待恢复或联系管理员 |
852
- | -33004 | Group member limit reached | 不重试 |
853
- | -33005 | Already a member | 无需处理 |
854
- | -33006 | Not a member | 先加入群组 |
855
- | -33007 | Role insufficient(权限不足) | 检查角色 |
856
- | -33008 | Invite code invalid or expired | 获取新邀请码 |
861
+
862
+ | 错误码 | 说明 | 客户端处理 |
863
+ |--------|------|-----------|
864
+ | -32601 | Method not found | 检查方法名 |
865
+ | -32602 | Invalid params(如缺少 group_id) | 检查参数 |
866
+ | -32004 | Permission denied(权限不足) | 提示用户,不重试 |
867
+ | -32001 | Authentication failed | 重新认证 |
868
+ | -33001 | Group not found | 检查 group_id |
869
+ | -33002 | Group state invalid(群状态不允许该操作) | 检查群状态 |
870
+ | -33003 | Group suspended | 等待恢复或联系管理员 |
871
+ | -33004 | Group member limit reached | 不重试 |
872
+ | -33005 | Already a member | 无需处理 |
873
+ | -33006 | Not a member | 先加入群组 |
874
+ | -33007 | Role insufficient(权限不足) | 检查角色 |
875
+ | -33008 | Invite code invalid or expired | 获取新邀请码 |
857
876
  | -33009 | Join rejected | 不重试 |
858
877
 
859
878
  `group.index etag conflict` 表示 `expected_index_etag` 与服务端当前 `group.index` etag 不一致。客户端应重新读取 `group.index`,在最新 index 上合并本地修改并重新签名后再提交。
@@ -866,8 +885,8 @@ Group 服务通过 `event/group.*` 事件推送变更通知给相关 AID。
866
885
  - **group.index 由 SDK 生成**:Group 服务只校验、CAS 保存和注入 meta,不根据 DB 状态拼装 `group.index`。
867
886
  - **Gateway/Message 不承载 group.index 业务语义**:只能转发或合并 `_meta`,不能生成或改写 `_meta.group_indexes`。
868
887
  - **消息 seq 单调递增**:per-group 粒度,确保顺序一致性,`ack_seq` 仅增不减。
869
- - **事件 seq 独立计数**:`event_seq` 与 `message_seq` 独立;消息增量拉取使用 `group.pull`,事件增量拉取使用 `group.pull_events`。
870
- - **duty 模式**:`duty_mode` 非 `"none"` 且 `duty_human_message_policy = "dispatch"` 时,消息先推送给当班成员处理,回复后再广播;`group.pull` 始终可拉取全量消息。
871
- - **Group FS**:群文件能力统一由 `group.fs.*` 提供;不再提供独立资源审批 RPC。
872
- - **在线状态**:通过 `group.get_online_members` 查询当前在线成员列表。
873
- - **Group FS 系统目录保护**:`memberdata` 是 Group FS 视图层的虚拟系统目录;根节点和成员槽位根不得被普通文件操作删除、覆盖或重命名。成员槽位子路径映射到成员个人 Storage 的 `group_data/{group_aid}`,只能通过 `group.fs.*` 间接访问。完整保护规则见 [16-系统目录保护方案.md](16-系统目录保护方案.md)。
888
+ - **事件 seq 独立计数**:`event_seq` 与 `message_seq` 独立;消息增量拉取使用 `group.pull`,事件增量拉取使用 `group.pull_events`。
889
+ - **duty 模式**:`duty_mode` 非 `"none"` 且 `duty_human_message_policy = "dispatch"` 时,消息先推送给当班成员处理,回复后再广播;`group.pull` 始终可拉取全量消息。
890
+ - **Group FS**:群文件能力统一由 `group.fs.*` 提供;不再提供独立资源审批 RPC。
891
+ - **在线状态**:通过 `group.get_online_members` 查询当前在线成员列表。
892
+ - **Group FS 系统目录保护**:`memberdata` 是 Group FS 视图层的虚拟系统目录;根节点和成员槽位根不得被普通文件操作删除、覆盖或重命名。成员槽位子路径映射到成员个人 Storage 的 `group_data/{group_aid}`,只能通过 `group.fs.*` 间接访问。完整保护规则见 [16-系统目录保护方案.md](16-系统目录保护方案.md)。