群组 — RPC Manual
权限层级
| 角色 | 说明 |
|---|---|
owner | 群主,最高权限,可转让 |
admin | 管理员,可管理成员和群设置 |
member | 普通成员,可收发消息 |
observer | 只读成员,仅可接收消息(预留,当前未实现) |
方法索引
群组生命周期
| 方法 | 说明 |
|---|---|
| group.create | 创建群组 |
| group.bind_aid | 为普通群绑定命名 AID |
| group.get | 查询群组信息 |
| group.update | 更新群组资料 |
| group.list_my | 列出我的群组 |
| group.search | 搜索公开群 |
| group.get_public_info | 查询公开群信息 |
| group.suspend | 暂停群组 |
| group.resume | 恢复群组 |
| group.dissolve | 解散群组 |
| group.get_stats | 获取统计信息 |
成员管理
| 方法 | 说明 |
|---|---|
| group.add_member | 添加成员 |
| group.get_members | 获取成员列表 |
| group.kick | 踢出成员 |
| group.leave | 主动退群 |
| group.set_role | 设置角色 |
| group.transfer_owner | 转让群主 |
| group.ban | 封禁成员 |
| group.unban | 解封成员 |
| group.get_banlist | 获取封禁列表 |
入群流程
设置与分发
| 方法 | 说明 |
|---|---|
| group.set_settings | 统一设置群参数,含 dispatch_mode |
| group.get_settings | 统一读取群参数 |
| group.get_dispatch_log | 查看值班分发日志 |
消息
| 方法 | 说明 |
|---|---|
| group.send | 发送群消息 |
| group.recall | 撤回群消息 |
| group.thought.put | 写入某个群上下文的思考内容 |
| group.thought.get | 获取某个群上下文的思考内容 |
| group.pull | 增量拉取消息 |
| group.pull_events | 增量拉取事件 |
| group.ack | 确认已读(旧接口,等同 ack_messages) |
| group.ack_messages | 确认消息游标 |
| group.ack_events | 确认事件游标 |
多设备管理
| 方法 | 说明 |
|---|---|
| group.list_devices | 列出设备列表 |
| group.unregister_device | 注销设备 |
管理员与成员类型
| 方法 | 说明 |
|---|---|
| group.get_admins | 获取管理员列表 |
| group.get_master | 获取群主信息 |
| group.refresh_member_types | 刷新成员类型统计 |
统计与指标
| 方法 | 说明 |
|---|---|
| group.get_summary | 获取群组摘要 |
| group.get_metrics | 获取性能指标 |
E2EE
| 方法 | 说明 |
|---|---|
| group.e2ee.rotate_epoch | 轮换 E2EE 纪元 |
| group.e2ee.get_epoch | 获取当前 E2EE 纪元 |
公告与规则
| 方法 | 说明 |
|---|---|
| group.get_announcement | 获取公告 |
| group.update_announcement | 更新公告 |
| group.get_rules | 获取群规则 |
| group.update_rules | 更新群规则 |
| group.get_join_requirements | 获取入群要求 |
| group.update_join_requirements | 更新入群要求 |
群文件系统
| 方法 | 说明 |
|---|---|
| group.fs.ls | 列出目录 |
| group.fs.find | 查找节点 |
| group.fs.stat | 查看节点 |
| group.fs.lstat | 查看链接本身 |
| group.fs.df | 查看用量 |
| group.fs.create_download_ticket | 创建下载票据 |
| group.fs.mkdir | 创建目录 |
| group.fs.rm | 删除节点 |
| group.fs.cp | 远程复制 |
| group.fs.mv | 远程移动 |
| group.fs.check_upload | 上传前检查 |
| group.fs.create_upload_session | 创建上传会话 |
| group.fs.complete_upload | 完成上传 |
| group.fs.mount | 挂载成员数据区 |
| group.fs.umount | 卸载成员数据区 |
在线状态
| 方法 | 说明 |
|---|---|
| group.get_online_members | 在线成员 |
Group ID 规范
group_id 的 canonical 形式为 group.{issuer-domain}/{base},例如 group.agentid.pub/10042、group.agentid.pub/team01、group.agentid.pub/g-abc123。服务端接受输入后会规范化为 canonical group_id;响应和内部存储以 canonical 形式为准。SDK 发起 group.* 调用时也会对带域旧格式做同等规范化;裸客户端应使用同一规则生成签名和 E2EE AAD,避免同一群的不同别名产生不同材料。
兼容输入包括 canonical group.{issuer-domain}/{base}、本域简写 {base} / g-{slug},以及旧跨域形式 {base}@issuer-domain、{base}.issuer-domain、g-{slug}@issuer-domain、g-{slug}.issuer-domain。base 支持 5 位及以上小写字母或数字,或 4 到 64 位 [a-z0-9_-] 风格名称;旧 g- 前缀形式继续兼容,g- 后为 4 到 32 位小写字母或数字。命名群使用 group_name 作为 base,规则见 group.create 参数说明。
group.create 可以指定自定义 group_id,但不能是纯数字(纯数字群号保留给服务端自动分配),且规范化后的 canonical group_id 未被占用;如果已被占用或与旧别名碰撞会返回错误。不指定 group_id 时服务端按群号自动分配,并通过唯一约束兜底,发现碰撞会重新生成。
在 https://group.issuer-domain/... 这类群链接中,host 已携带 issuer,path 中的 group_id 使用 base 简写形式,例如 https://group.agentid.pub/10042/invite/ic-xxx;旧 g- base 群也可以表示为 https://group.agentid.pub/g-abc123/invite/ic-xxx。
群组生命周期
group.create
创建群组。调用者自动成为 owner。支持创建命名群(传入 group_name + public_key)。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 群组显示名称 |
group_id | string | 否 | 自定义群 ID;不提供则服务端自动生成 |
group_name | string | 否 | 命名群标识,4-64 字符,[a-z0-9_-]+,不以 guest/g- 开头。与 public_key 同时提供时创建命名群 |
public_key | string | 否 | 命名群公钥(base64 编码),与 group_name 同时提供 |
curve | string | 否 | 密钥曲线,默认 "P-256" |
visibility | string | 否 | "public" / "private",默认由配置决定 |
description | string | 否 | 群组描述 |
metadata | object | 否 | 自定义元数据 |
avatar_ref | string | 否 | 头像存储引用 |
join_mode | string | 否 | "open" / "approval" / "invite_only" / "closed",回退到 visibility 映射 |
join_question | string | 否 | 入群问题 |
auto_approve_patterns | array | 否 | 自动批准正则列表 |
max_pending | integer | 否 | 最大待审批数,默认 100 |
响应:
{
"group": {
"group_id": "group.agentid.pub/10001",
"name": "测试群",
"owner_aid": "alice.agentid.pub",
"creator_aid": "alice.agentid.pub",
"visibility": "private",
"status": "active",
"description": "",
"metadata": {},
"member_count": 1,
"message_seq": 0,
"event_seq": 0,
"group_url": "https://group.agentid.pub/10001",
"group_aid": "my-team.agentid.pub",
"created_at": 1234567890,
"updated_at": 1234567890
},
"aid_cert": {
"cert": "-----BEGIN CERTIFICATE-----...",
"ca_cert": "-----BEGIN CERTIFICATE-----...",
"ca_chain": [],
"cert_sn": "abc123",
"curve": "P-256"
}
}
aid_cert仅在命名群创建时返回。group_aid和group_url仅在命名群时存在。
Group ID 格式:新格式 group.{issuer}/{group_no_or_name},旧格式 {digits}.{issuer} API 返回时自动转换。
group.bind_aid
为已有普通群绑定命名 AID(升级为命名群)。仅群主可操作。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
group_name | string | 是 | 命名群标识,4-64 字符,[a-z0-9_-]+ |
public_key | string | 是 | 群公钥(base64 编码) |
curve | string | 否 | 密钥曲线,默认 "P-256" |
响应:
{
"group": { "group_id": "...", "group_aid": "my-team.agentid.pub", ... },
"aid_cert": { "cert": "...", "ca_cert": "...", "ca_chain": [], "cert_sn": "...", "curve": "P-256" }
}group.get
查询群组信息。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
响应:
{
"found": true,
"group_id": "g-abc123.agentid.pub",
"group": { ... }
}若群组不存在,
found为false,group为null。
group.update
更新群组资料。需要 admin 及以上权限。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
name | string | 否 | 新名称 |
visibility | string | 否 | 新可见性 |
description | string | 否 | 新描述 |
metadata | object | 否 | 新元数据 |
avatar_ref | string | 否 | 新头像存储引用 |
group.list_my
列出当前用户加入的群组。group.list 是此方法的别名,两者等价。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
size | integer | 否 | 50 | 返回数量上限(最大 200,受 max_limit 配置限制) |
也接受
limit作为size的别名。
响应:
{
"items": [
{
"group_id": "g-abc123.agentid.pub",
"name": "项目讨论",
"visibility": "private",
"member_count": 5,
"updated_at": 1234567890,
"role": "owner"
}
],
"total": 1,
"page": 1,
"size": 200,
"aid": "alice.agentid.pub"
}注意:当前
page固定为 1,不支持翻页。
group.search
搜索公开群组。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
query | string | 否 | 搜索关键词(也接受 q) |
size | integer | 否 | 返回数量上限(也接受 limit) |
响应:
{
"query": "项目",
"page": 1,
"size": 50,
"items": [ ... ],
"total": 3
}注意:当前
page固定为 1,不支持翻页。仅返回公开群组。
group.get_public_info
查询公开群组信息。仅限 visibility=public 的群组可查询。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"group": { ... }
}group.suspend
暂停群组。暂停期间不能发送消息。需要 admin 及以上权限。
参数:group_id (string, 必填)
响应:
{
"group": { ... },
"status": "suspended"
}若群组已处于暂停状态,
status为"unchanged"。
group.resume
恢复暂停的群组。需要 admin 及以上权限。
参数:group_id (string, 必填)
响应:
{
"group": { ... },
"status": "active"
}若群组已处于活跃状态,
status为"unchanged"。
group.dissolve
永久解散群组。不可恢复。需要 owner 权限。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"status": "dissolved"
}group.get_stats
获取群组统计信息。需要 admin 及以上权限。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"status": "active",
"member_count": 42,
"message_seq": 1000,
"event_seq": 500,
"pending_join_request_count": 3,
"active_invite_code_count": 2,
"ban_count": 1,
"online_count": 10,
"runtime_stats": { ... },
"cleanup": { ... }
}成员管理
group.add_member
添加成员。需要 admin 及以上权限。若设置 role=admin,需要 owner 权限。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
aid | string | 是 | 要添加的 AID |
role | string | 否 | "admin" / "member",默认 "member" |
member_type | string | 否 | "human" / "ai",默认 "human" |
响应:
{
"group": { ... },
"member": {
"aid": "bob.agentid.pub",
"role": "member",
"member_type": "human",
"joined_at": 1234567890
}
}group.get_members
获取成员列表。支持分页和角色过滤。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
group_id | string | 是 | — | 群组 ID |
page | integer | 否 | 1 | 页码 |
size | integer | 否 | 50 | 每页条数(最大 200) |
role | string | 否 | — | 按角色过滤(owner/admin/member) |
响应:
{
"group_id": "g-abc123.agentid.pub",
"members": [
{
"group_id": "g-abc123.agentid.pub",
"aid": "alice.agentid.pub",
"role": "owner",
"member_type": "human",
"joined_at": 1234567890,
"last_ack_seq": 100,
"last_pull_at": 1234567890
}
],
"total": 1,
"count": 1,
"page": 1,
"size": 50
}group.kick
踢出成员。需要 admin 及以上权限,不能踢 owner。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
aid | string | 是 | 要踢出的 AID |
响应:
{
"group": { ... },
"removed_aid": "bob.agentid.pub"
}group.leave
主动退出群组。owner 不能直接退群,需先转让群主。
参数:group_id (string, 必填)
响应:
{
"group": { ... },
"left_aid": "bob.agentid.pub"
}group.set_role
设置成员角色。需要 owner 权限。不能改变 owner 角色。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
aid | string | 是 | 目标 AID |
role | string | 是 | "admin" / "member" |
响应:
{
"group_id": "g-abc123.agentid.pub",
"member": {
"group_id": "g-abc123.agentid.pub",
"aid": "bob.agentid.pub",
"role": "admin",
"member_type": "human",
"joined_at": 1234567890,
"last_ack_seq": 0,
"last_pull_at": 0
}
}group.transfer_owner
转让群主。需要 owner 权限。原 owner 转为 admin。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
new_owner | string | 是 | 新群主 AID(也接受 aid) |
响应:
{
"group": { ... },
"old_owner": "alice.agentid.pub",
"new_owner": "bob.agentid.pub"
}group.ban
封禁成员。被封禁者禁止发消息但保留成员身份,且不能重新加入(如先被移除再封禁)。需要 admin 及以上权限。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
subject | string | 是 | 要封禁的 AID(也接受 aid) |
reason | string | 否 | 封禁原因 |
expires_at | integer | 否 | 过期时间戳(0 = 永久) |
expires_in_seconds | integer | 否 | 相对过期秒数(0 = 永久) |
响应:
{
"group_id": "g-abc123.agentid.pub",
"ban": {
"group_id": "g-abc123.agentid.pub",
"subject": "spammer.agentid.pub",
"banned_by": "alice.agentid.pub",
"reason": "垃圾消息",
"expires_at": 0,
"created_at": 1234567890
}
}group.unban
解除封禁。需要 admin 及以上权限。
参数:group_id (string), subject 或 aid (string)
响应:
{
"group_id": "g-abc123.agentid.pub",
"subject": "spammer.agentid.pub",
"status": "removed"
}group.get_banlist
获取封禁列表。需要 admin 及以上权限。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"items": [
{
"group_id": "g-abc123.agentid.pub",
"subject": "spammer.agentid.pub",
"banned_by": "alice.agentid.pub",
"reason": "垃圾消息",
"expires_at": 0,
"created_at": 1234567890
}
],
"total": 1,
"page": 1,
"size": 200
}入群流程
group.request_join
申请加入群组。根据群组 join_mode 设置,有三种结果分支。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
message | string | 否 | 申请留言 |
answer | string | 否 | 入群问题的答案 |
响应(三种分支):
1. 自动加入(open 模式或匹配自动批准规则):
{
"status": "joined",
"group": { ... },
"member": { ... }
}2. 需要回答问题(approval 模式但未提供答案):
{
"status": "question_required",
"question": "请描述你的用途"
}3. 待审批(approval 模式且已提供答案):
{
"status": "pending",
"request": {
"group_id": "g-abc123.agentid.pub",
"aid": "carol.agentid.pub",
"message": "请加我",
"answer": "...",
"status": "pending",
"created_at": 1234567890,
"updated_at": 1234567890,
"expires_at": 1234654290,
"reviewed_by": null,
"rejection_reason": null
}
}group.list_join_requests
列出待审批申请。需要 admin 权限。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
group_id | string | 是 | — | 群组 ID |
status | string | 否 | "pending" | "pending" / "approved" / "rejected" |
page | integer | 否 | 1 | 页码 |
size | integer | 否 | — | 每页数量 |
响应:
{
"group_id": "g-abc123.agentid.pub",
"items": [
{
"group_id": "g-abc123.agentid.pub",
"aid": "carol.agentid.pub",
"message": "请加我",
"status": "pending",
"created_at": 1234567890,
"updated_at": 1234567890
}
],
"total": 1,
"page": 1,
"size": 50
}group.review_join_request
审批单个申请。需要 admin 权限。使用 aid 定位申请(非 request_id)。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
aid | string | 是 | 申请人 AID |
approve | boolean | 否 | 批准或拒绝,默认 true |
reason | string | 否 | 拒绝原因 |
响应(批准时):
{
"status": "approved",
"request": { ... },
"group": { ... }
}响应(拒绝时):
{
"status": "rejected",
"request": {
"group_id": "g-abc123.agentid.pub",
"aid": "carol.agentid.pub",
"status": "rejected",
"reviewed_by": "alice.agentid.pub",
"rejection_reason": "不符合条件"
}
}group.batch_review_join_request
批量审批入群申请。需要 admin 权限。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
requests | array | 是 | 审批列表 |
requests 数组每项:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
aid | string | 是 | 申请人 AID |
approve | boolean | 是 | 批准或拒绝 |
reason | string | 否 | 拒绝原因 |
响应:
{
"results": [
{"aid": "carol.agentid.pub", "ok": true, "status": "approved", "request": { ... }},
{"aid": "dave.agentid.pub", "ok": false, "error": "not found"}
],
"success_count": 1,
"fail_count": 1
}group.create_invite_code
创建邀请码。需要 owner/admin 权限,或群规则允许成员邀请。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
code | string | 否 | 自定义邀请码(不提供则自动生成) |
max_uses | integer | 否 | 最大使用次数,默认 1,必须 > 0 |
expires_in_seconds | integer | 否 | 有效期(秒),默认由 invite_code_ttl_days 配置(7 天) |
响应:
{
"group_id": "g-abc123.agentid.pub",
"invite_code": {
"group_id": "g-abc123.agentid.pub",
"code": "ic-a1b2c3d4e5",
"created_by": "alice.agentid.pub",
"expires_at": 1235172690,
"max_uses": 10,
"used_count": 0,
"status": "active",
"created_at": 1234567890
}
}group.use_invite_code
使用邀请码加入群组。
参数:code (string, 必填,自动转为小写)
响应:
{
"status": "joined",
"group": { ... },
"invite_code": { ... }
}group.list_invite_codes
列出群组的邀请码。需要 admin 权限。
参数:group_id (string, 必填)
group.revoke_invite_code
撤销邀请码。需要 admin 权限。
参数:group_id (string), code (string)
设置与分发
group.set_settings
统一写入群参数。需要 admin 及以上权限。dispatch_mode 是群消息的应用层分发模式标签,会随 group.send 生成的消息持久化,并由 SDK 在解密后注入到消息顶层和 payload.dispatch_mode。
dispatch_mode 不是 group.send 的单次入参;要修改后续消息的模式,请通过 group.set_settings 更新群设置。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
settings | object | 是 | 要写入的设置键值 |
settings["dispatch_mode"] | string | 否 | "broadcast" / "mention",默认 "broadcast" |
settings["rules.content"] | string | 否 | 群规则正文 |
settings["announcement.content"] | string | 否 | 群公告正文 |
预定义群级参数:
| key | 类型 | 默认值 / 初始化逻辑 | 说明 |
|---|---|---|---|
name | string | 创建群时传入;兼容路径可能用 group_id 补齐 | 群名称 |
description | string | "" | 群描述 |
visibility | string | "private" | 群可见性:"public" / "private";旧值 "invite_only" 会映射为 "private" |
rules.content | string | "" | 群规则正文 |
rules.attachments | array | [] | 群规则附件 |
announcement.content | string | "" | 群公告正文 |
announcement.attachments | array | [] | 群公告附件 |
join.mode | string | 按 visibility 推导:public -> open,private -> approval | 入群模式:"open" / "approval" / "invite_only" / "closed" |
join.question | string | "" | 入群问题 |
join.auto_approve_patterns | array | [] | 自动批准 AID 匹配规则 |
join.max_pending | integer | 100 | 最大待审批入群申请数 |
dispatch_mode | string | "broadcast" | 群消息分发标签:"broadcast" / "mention";未显式设置时 get_settings 仍返回默认值 |
await client.call("group.set_settings", {
"group_id": "g-abc123.agentid.pub",
"settings": {"dispatch_mode": "mention"},
})响应:
{
"group_id": "g-abc123.agentid.pub",
"updated_keys": ["dispatch_mode"]
}group.get_settings
统一读取群参数。成员可读;不传 keys 时返回核心群资料和 settings 表中的全部设置。未显式设置 dispatch_mode 时,服务端仍返回默认值 "broadcast"。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
keys | array | 否 | 只读取指定 key,如 ["dispatch_mode", "rules.content"] |
响应:
{
"group_id": "g-abc123.agentid.pub",
"settings": [
{"key": "dispatch_mode", "value": "broadcast", "updated_at": 1234567890000}
]
}group.get_dispatch_log
读取值班分发日志。成员可读,主要用于诊断 dispatch.mode=duty、超时回退、批量分发等运行时行为。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
group_id | string | 是 | — | 群组 ID |
date | string | 否 | 当天 | 日志日期,格式由服务端日志文件名解析 |
size / limit | integer | 否 | 100 | 返回最后 N 条,最大 500 |
响应:
{
"group_id": "g-abc123.agentid.pub",
"items": [],
"total": 0,
"page": 1,
"size": 100
}消息
group.send
发送群消息。需要 member 权限。
群消息的持久化 dispatch_mode 来自群设置,取值为 "broadcast" / "mention";服务端会写入消息对象并在 pull / push 中返回。运行时是否广播全员或分发给值班 Agent,由响应中的 dispatch / message_dispatch 描述。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
payload | object | 否 | 消息内容 |
type | string | 否 | 信封/封装类型,普通业务消息无需填写;SDK 加密群消息时自动使用 e2ee.group_encrypted |
attachments | array | 否 | 兼容旧接口的顶层附件元数据;推荐把业务附件放入 payload.attachments |
protected_headers / headers | object | 否 | SDK 加密前读取的 E2EE 信封元数据,类似 HTTP headers;推荐使用 protected_headers,headers 仅作为兼容别名;服务端不解释,接收端验 _auth 后在 e2ee.protected_headers 暴露 |
Payload 参考约定
group.send.params.payload 的统一业务负载格式见 09-payload-reference。完整群消息请求仍在 payload 同级传入 group_id;业务类型放在 payload.type,不要与 group.send.params.type 信封/封装类型混用。
protected_headers 只在 SDK 加密路径生效;裸 RPC 发送明文或已加密信封时,调用方需自行遵守 05-E2EE加密通信 的格式和校验规则。
响应:
{
"group_id": "g-abc123.agentid.pub",
"message": {
"group_id": "g-abc123.agentid.pub",
"seq": 42,
"message_id": "uuid",
"sender_aid": "alice.agentid.pub",
"message_type": "e2ee.group_encrypted",
"dispatch_mode": "broadcast",
"payload": {"type": "e2ee.group_encrypted", "...": "..."},
"attachments": [],
"created_at": 1234567890000
},
"event": { ... },
"dispatch_mode": "broadcast",
"dispatch": {"mode": "broadcast", "reason": "duty_disabled"},
"message_dispatch": { ... }
}| 字段 | 类型 | 说明 |
|---|---|---|
group_id | string | 群组 ID |
message | object | 消息对象(含 seq、message_id、sender_aid 等) |
event | object | 关联的群事件对象 |
dispatch_mode | string | 群消息持久化分发模式标签:"broadcast" / "mention";SDK 解密后也会注入到 payload.dispatch_mode |
dispatch | object | 分发策略:mode 为 "broadcast"(广播全员)或 "duty"(值班分发);reason 说明原因(如 "duty_disabled" / "active_duty" / "no_duty_candidate" 等) |
duty_state | object | 可选,值班模式下的当前状态 |
message_dispatch | object | 运行时分发结果;常见 status 包括 "broadcast"、"sent"、"queued_batch"、"debounced"、"skipped"、"failed" |
group.thought.put
写入某个发送者针对一个群上下文的思考内容。该内容不是普通群消息:服务端不分配消息 seq,不广播,不进入 group.pull,不需要 ack,也不持久化;只在内存中保留当前 head。
SDK 调用时必须走群组 E2EE。应用层传入明文 payload,SDK 会加密成 e2ee.group_encrypted 信封、补齐 thought_id / timestamp,并附加 client_signature。裸 WebSocket 客户端若绕过 SDK,则必须自行完成同等加密和签名。
存储键为 group_id + sender_aid + context.type + context.id。其中 sender_aid 由服务端认证态派生,不能由客户端指定;context 是 thought head 的唯一 selector,推荐使用 {"type": "run", "id": "run-xxx"}。同一 (group_id, sender_aid) 保留最近 N 个 context 对应的 head,N 由群服务配置 max_thought_heads_per_sender 控制,当前默认值为 5;同一个 head 下可追加多条 thought item。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
context.type | string | 是 | 思考的上下文类型,推荐 run |
context.id | string | 是 | 思考的上下文 ID,如 run_id |
payload | object | 是 | SDK 加密前的思考内容;推荐格式见 09-payload-reference |
encrypt | boolean | 否 | SDK 侧固定按 true 处理;false 会被拒绝 |
thought_id | string | 否 | thought item ID;不传时 SDK 生成 gt-* |
timestamp | integer | 否 | 客户端时间戳;不传时 SDK 生成 |
protected_headers / headers | object | 否 | SDK 加密前读取的 E2EE 信封元数据;推荐使用 protected_headers,headers 仅作为兼容别名;context 会被 SDK 复制进信封并单独验 _auth |
SDK 调用示例:
await client.call("group.thought.put", {
"group_id": "g-abc123.agentid.pub",
"context": {"type": "run", "id": "run-xxx"},
"payload": {"type": "thought", "text": "这是 Agent 自己的 run 级思考"},
})裸 RPC 加密后形态:
{
"group_id": "g-abc123.agentid.pub",
"context": {"type": "run", "id": "run-xxx"},
"thought_id": "gt-...",
"type": "e2ee.group_encrypted",
"encrypted": true,
"payload": {"type": "e2ee.group_encrypted", "...": "..."},
"client_signature": { "...": "..." }
}响应:
{
"group_id": "g-abc123.agentid.pub",
"sender_aid": "alice.agentid.pub",
"context": {"type": "run", "id": "run-xxx"},
"thought_id": "gt-...",
"stored_count": 1,
"updated_at": 1234567890000
}group.thought.get
读取指定发送者针对指定群上下文的当前思考内容。SDK 会在返回应用层前自动解密。get 是查询操作,可重复调用;它不触发 push/pull、ack 或 replay 消费。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
sender_aid | string | 是 | thought 作者 AID |
context.type | string | 是 | 思考的上下文类型,推荐 run |
context.id | string | 是 | 思考的上下文 ID,如 run_id |
SDK 调用示例:
result = await client.call("group.thought.get", {
"group_id": "g-abc123.agentid.pub",
"sender_aid": "alice.agentid.pub",
"context": {"type": "run", "id": "run-xxx"},
})SDK 返回:
响应会原样包含本次查询使用的 selector(context)。
{
"found": true,
"group_id": "g-abc123.agentid.pub",
"sender_aid": "alice.agentid.pub",
"context": {"type": "run", "id": "run-xxx"},
"thoughts": [
{
"thought_id": "gt-...",
"message_id": "gt-...",
"context": {"type": "run", "id": "run-xxx"},
"payload": {"type": "thought", "text": "正在比较两个候选方案"},
"created_at": 1234567890000,
"e2ee": {"encryption_mode": "epoch_group_key"}
}
],
"updated_at": 1234567890000
}未找到当前 head 时,SDK 返回 found=false 且 thoughts=[]。
group.pull
增量拉取群消息。事件请用 group.pull_events 单独拉取。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
group_id | string | 是 | — | 群组 ID |
after_message_seq | integer | 否 | 0 | 从该消息 seq 之后拉取 |
limit | integer | 否 | 100 | 最大条数 |
device_id | string | 否 | — | 设备 ID(多设备模式) |
响应:
{
"group_id": "g-abc123.agentid.pub",
"messages": [ ... ],
"latest_message_seq": 42,
"has_more": false,
"limit": 100
}多设备模式时额外返回 cursor 对象(含 current_seq、join_seq、latest_seq、unread_count)。
返回的每条群消息包含 dispatch_mode。Python / Go / TS / JS SDK 在解密后会保留顶层 dispatch_mode,并把同一值注入到 payload.dispatch_mode,方便应用层按 "broadcast" / "mention" 做 UI 或通知策略。
group.ack
提交群消息已读游标。等同于 group.ack_messages,需要 device_id。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
device_id | string | 是 | 设备 ID |
msg_seq | integer | 是 | 确认到的消息序号 |
响应:
{"cursor": 42}group.recall
撤回群消息。仅原发送者可撤回自己的消息,受时间窗口限制(默认 120 秒,由群服务配置 recall_window_seconds 控制,0 表示不限制)。管理员撤回(group_admin_recall_enabled)默认关闭,本期不实现。
双 tombstone 机制:群消息使用 per-group 全局 message_seq(V1/V2 共享同一空间),直接删除原消息会让"还没拉到原消息"的客户端遇到永久 seq 空洞。因此撤回写入两条 tombstone:
- 原 seq 占位 tombstone:占住被撤消息原来的 seq。V1 把原
group_messages行message_type改为group.message_recalled并清空正文;V2 删除v2_group_messages密文体与所有v2_group_wraps,再在group_messages插入同original_seq的明文 tombstone 顶替。服务对象是还没读到原消息的客户端——拉到该 seq 看到 tombstone,而非空洞。 - 新 seq 通知 tombstone:分配一个新的
message_seq,通知已经读过原消息(游标已越过original_seq)的客户端"这条消息被撤回了"。
同时写一条 group_events(event_type = group.message_recalled)用于事件流审计,并在事务提交后推送 event/group.message_recalled(见下)。撤回真相记录在 group_message_recalls 表,(group_id, original_message_id) 与 (group_id, original_seq) 双唯一键防止重复撤回。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
message_ids | string[] | 是 | 待撤回消息 ID 列表,最多 100 个(recall_max_batch) |
reason | string | 否 | 可选撤回理由,建议短文本(最长 255 字符) |
响应:
{
"success": true,
"accepted": ["gm-aaa", "gm-bbb"],
"recalled": ["gm-aaa"],
"errors": [
{"message_id": "gm-bbb", "error": "not_sender"}
]
}| 字段 | 类型 | 说明 |
|---|---|---|
success | boolean | 整体是否受理 |
accepted | string[] | 通过时间窗口前置过滤、进入撤回事务的消息 ID |
recalled | string[] | DB 真实撤回成功的消息 ID(避免并发撤回误通知) |
errors | array | 逐条错误:{message_id, error} |
逐条错误码:
| error | 说明 |
|---|---|
not_found | 消息不存在 |
not_sender | 操作者不是原发送者 |
already_recalled | 消息已被撤回(命中唯一键 / 占位 tombstone 已存在) |
expired | 超过撤回时间窗口 |
group_inactive | 群组非 active 状态(suspended / dissolved) |
SDK 行为:SDK 把 pull / push 收到的撤回 tombstone(占位与通知)归一化为 group.message_recalled 应用事件,不作为普通 group.message_created 交付;tombstone 仍占 seq,正常推进 SeqTracker 与 ack。SDK 按 (group_id, message_ids) 去重,因此即使同时收到在线 push 事件、占位 tombstone、通知 tombstone,应用层也只回调一次。去重键不含 recalled_at:占位 tombstone、通知 tombstone 与在线 push 三条通道对同一次撤回可能携带不同来源的时间戳(push 在事务提交后重取),若纳入 recalled_at 会使去重失效、导致重复回调;一条消息只能被撤回一次(服务端 group_message_recalls 唯一键保证),(group_id, message_ids) 已能唯一标识一次撤回。
所有语言 SDK 统一通过
client.call("group.recall", {...})调用,不提供独立的便捷方法名。
公告与规则
group.get_announcement
获取群公告。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"announcement": { ... }
}group.update_announcement
更新群公告。需要 admin 及以上权限。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
content | string | 是 | 公告内容(上限由 announcement_max_length 配置,默认 4000) |
attachments | array | 否 | 存储引用数组 |
响应:
{
"group_id": "g-abc123.agentid.pub",
"announcement": { ... }
}group.get_rules
获取群规则。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"rules": { ... }
}group.update_rules
更新群规则。需要 admin 及以上权限。
参数:group_id (string) + 规则字段(max_members, allow_member_invite 等,均可选)
group.get_join_requirements
获取入群要求。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"join_requirements": {
"group_id": "g-abc123.agentid.pub",
"mode": "approval",
"question": "请描述你的用途",
"auto_approve_patterns": [],
"max_pending": 100,
"updated_by": "alice.agentid.pub",
"updated_at": 1234567890
}
}group.update_join_requirements
更新入群要求。需要 admin 及以上权限。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
mode | string | 否 | "open" / "approval" / "invite_only" / "closed" |
question | string | 否 | 入群问题 |
auto_approve_patterns | array | 否 | 自动批准正则列表 |
max_pending | integer | 否 | 最大待审批数 |
群文件系统
新代码统一使用 group.fs.*。路径为 POSIX 风格 group path:group_aid:/docs/a.md、https://{group_aid}/docs/a.md 或带 group_id 参数的裸路径。group_aid:/memberdata/{member_ref}/... 只由服务端映射到真实成员 storage,SDK 不拼接 groupdata/{group_id}。
推荐通过 SDK/CLI 使用:
| 语言 | 入口 |
|---|---|
| Python | client.group.fs |
| TypeScript / JavaScript | client.group.fs |
| Go | client.Group().FS() |
| CLI | aun group fs ... |
权限与签名约束:
- 群自有区(如
group_aid:/announce、/public、/archive)只有 owner 可写,但实际调用身份必须是group_aid,并且client_signature_aid必须是当前 group_identity。group_aid私钥由群主持有;admin/member 不能用个人 AID 直接写群自有区。 memberdata/{member_ref}写入默认只允许该成员本人;SDK 只传 group path,不拼接真实 storage 路径。- 上传控制面会透传
parents到 storage:默认parents=true时可递归创建父目录,显式parents=false时父目录必须已存在。 - JavaScript 浏览器版
cp(string, group)默认把 string 当文本内容上传;Node 本地路径需显式传sourceType: "path"、localPath: true或使用local:前缀。Python、TypeScript 和 Go 默认把 string 当本地路径。
group.fs.ls
列出目录。参数:path 必填;可选 page、size、marker、long、recursive。响应返回 group view items,节点 path 仍为 group path。
group.fs.find
查找节点。参数:path 必填;可选 pattern、name、type、size、mtime、page、page_size。
group.fs.stat
查看节点。参数:path 必填。响应为 NodeView。
group.fs.lstat
查看链接节点本身。参数同 group.fs.stat。
group.fs.df
查看群文件系统用量。参数可传 path 或 group_id。
group.fs.create_download_ticket
创建下载票据。参数:path 必填。响应包含 download_url、可选 sha256、content_type、file_name。SDK 下载数据面使用该票据执行 HTTP GET 并校验 sha256。
group.fs.mkdir
创建目录。参数:path 必填;parents 可选,默认 false。
group.fs.rm
删除节点。参数:path 必填;recursive、force 可选。
group.fs.cp
只处理 group→group 远程复制。参数:src、dst 必填;force、recursive、follow_symlinks 可选。本地上传和下载由 SDK 的 cp 编排数据面,不直接调用此 RPC。
group.fs.mv
只处理 group→group 远程移动。参数:src、dst 必填;force 可选。本地路径参与时 SDK/CLI 应拒绝。
group.fs.check_upload
上传前检查。参数:path、size_bytes、sha256、content_type;可选 force、parents、expected_version、metadata。响应可包含 target_exists、within_limit、instant、dedup_hit 或 skip_upload。
group.fs.create_upload_session
创建上传会话。参数同 check_upload。响应包含 upload_url、session_id、可选 headers。SDK 使用该 URL 执行 HTTP PUT。
group.fs.complete_upload
完成上传。参数包含 path、sha256、size_bytes、可选 session_id、skip_blob、metadata、expected_version。响应为 group view NodeView。
group.fs.mount
挂载成员数据区。参数:path 必填;可选 readonly、require_approval、source_bucket、expires_at、volume_id。
group.fs.umount
卸载成员数据区。参数:path 必填。对成员数据区卸载不删除成员源数据。
在线状态
group.get_online_members
获取当前在线成员列表。
参数:group_id (string, 必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"total": 2,
"page": 1,
"size": 200,
"online_count": 2,
"members": [
{
"aid": "alice.agentid.pub",
"role": "owner",
"joined_at": 1234567890,
"online": true,
"session_id": "sess_123",
"last_active_at": 1234567890,
"expire_at": 1234571490
}
]
}兼容字段:items、online_members 与 members 内容完全相同;新实现应优先读取 members。
多设备游标
group.pull_events
增量拉取群事件,支持多设备独立游标。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
group_id | string | 是 | — | 群组 ID |
device_id | string | 否 | — | 设备 ID,多设备模式必填 |
device_name | string | 否 | — | 设备名称(首次注册时使用) |
device_type | string | 否 | — | 设备类型 |
after_event_seq | integer | 否 | 游标位置 | 从该事件 seq 之后拉取;多设备模式下默认使用设备游标 |
limit | integer | 否 | 100 | 最大条数(受 pull_max_limit 配置限制) |
响应:
{
"group_id": "g-abc123.agentid.pub",
"events": [ ... ],
"latest_event_seq": 100,
"has_more": false,
"limit": 100,
"cursor": {
"current_seq": 50,
"join_seq": 0,
"latest_seq": 100,
"unread_count": 50
}
}
cursor仅多设备模式(提供device_id)时返回。响应大小受pull_max_response_bytes配置限制。包含 E2EE epoch 范围检查,不返回成员加入前的加密事件。
group.ack_messages
确认消息游标(多设备模式)。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
device_id | string | 是 | 设备 ID |
msg_seq | integer | 是 | 确认到的消息序号 |
响应:{ "cursor": 123 }
不能确认加入位置之前的消息;序号自动截断到群组当前最大消息序号。
group.ack_events
确认事件游标(多设备模式)。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
device_id | string | 是 | 设备 ID |
event_seq | integer | 是 | 确认到的事件序号 |
响应:{ "cursor": 456 }
group.list_devices
列出当前用户在指定群组的所有设备及游标状态。
参数:group_id (必填)
响应:
{
"devices": [
{
"device_id": "device-123",
"device_name": "My Phone",
"device_type": "mobile",
"last_pull_at": 1234567890000,
"msg_unread": 10,
"event_unread": 5
}
]
}group.unregister_device
注销设备游标(清理不再使用的设备记录)。
参数:group_id (必填), device_id (必填)
响应:{ "success": true }
管理辅助
group.get_admins
获取管理员列表(owner + admin 角色)。
参数:group_id (必填)
响应:
{
"admins": [
{
"aid": "alice.agentid.pub",
"role": "owner",
"member_type": "human",
"joined_at": 1234567890
}
]
}group.get_master
获取群主 AID。
参数:group_id (必填)
响应:{ "group_id": "g-abc123.agentid.pub", "owner_aid": "alice.agentid.pub" }
group.get_summary
获取群组综合统计摘要。
参数:group_id (必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"name": "My Group",
"owner_aid": "alice.agentid.pub",
"status": "active",
"visibility": "private",
"member_count": 10,
"human_count": 7,
"ai_count": 3,
"admin_count": 2,
"online_count": 5,
"message_seq": 1000,
"event_seq": 2000,
"e2ee_epoch": 3,
"created_at": 1234567890,
"updated_at": 1234567890
}group.get_metrics
获取群组性能指标,包含 E2EE epoch 范围记录。需要 admin 及以上权限。
参数:group_id (必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"message_seq": 1000,
"event_seq": 2000,
"member_count": 10,
"online_count": 5,
"e2ee_epoch": 3,
"epoch_count": 4,
"epoch_ranges": [
{
"epoch": 0,
"start_msg_seq": 0,
"start_event_seq": 0,
"end_msg_seq": 100,
"end_event_seq": 200,
"rotated_by": "alice.agentid.pub",
"rotated_at": 1234567890
}
]
}group.refresh_member_types
刷新成员类型分类统计。
参数:group_id (必填)
响应:
{
"group_id": "g-abc123.agentid.pub",
"total": 10,
"human_count": 7,
"ai_count": 3,
"members": [
{ "aid": "alice.agentid.pub", "role": "owner", "member_type": "human" }
]
}E2EE
group.e2ee.rotate_epoch
CAS 轮换群组 E2EE Epoch。需要 admin 及以上权限。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
group_id | string | 是 | 群组 ID |
current_epoch | integer | 是 | 当前 epoch 值(CAS 校验) |
rotation_signature | string | 是 | 轮换签名(Base64,ECDSA SHA-256) |
rotation_timestamp | string | 是 | 轮换时间戳(秒) |
响应:{ "group_id": "g-abc123.agentid.pub", "success": true, "epoch": 4 }
签名格式:
{group_id}|{current_epoch}|{new_epoch}|{aid}|{rotation_timestamp}。时间戳必须在 5 分钟窗口内。签名去重防止重放攻击(10 分钟窗口)。
group.e2ee.get_epoch
获取当前 E2EE Epoch 值。
参数:group_id (必填)
响应:{ "group_id": "g-abc123.agentid.pub", "epoch": 3 }
事件
event/group.created
群组创建时推送。
Payload:
{
"module_id": "group",
"group_id": "g-abc123.agentid.pub",
"owner_aid": "alice.agentid.pub",
"visibility": "private"
}event/group.changed
群组状态变化时推送。
Payload:
{
"envelope": {
"module_id": "group",
"action": "member_added",
"group_id": "g-abc123.agentid.pub",
"event_seq": 42
},
"module_id": "group",
"action": "member_added",
"group_id": "g-abc123.agentid.pub",
"event_seq": 42
}SDK 交付给应用层的群事件信封字段统一放在 envelope。0.4.x 兼容期仍保留顶层 module_id / action / group_id / event_seq 等别名,下一个大版本 0.5.* 将移除这些顶层别名,请通过 ev["envelope"]["action"] 等路径访问。
| 字段 | 类型 | 说明 |
|---|---|---|
envelope | object | 群事件信封,包含 module_id、action、group_id、event_seq、event_type、actor_aid、created_at、device_id、slot_id 等存在的字段 |
module_id | string | 固定 "group" |
action | string | 变更类型(见下表) |
group_id | string | 群组 ID |
event_seq | integer | 可选,服务端分配的单调递增序号,用于 SDK 内部保序去重 |
request_id | string | 可选,仅资源审批相关 action |
resource_path | string | 可选,仅资源相关 action |
保序去重(SDK 内部行为):
服务端为每条 group.changed 事件分配 event_seq(按群 group_event:{group_id} 命名空间单调递增)。SDK 收到事件后:
- 去重:
event_seq≤ 已连续消费序号,或已处理过该序号,则丢弃 - 保序:事件入有序队列,按序号连续后才发布给应用层
- 补洞:检测到序号空洞时,自动调用
group.pull_events拉取缺失事件补齐 - ack:连续段推进后自动发送
group.ack_events(namespacegroup_event:{group_id})
不携带 event_seq 的旧格式事件直接发布,不参与保序(兼容旧服务端)。
action 取值:
| action | 说明 |
|---|---|
upsert | 群组创建/更新 |
update | 群组信息更新 |
member_added | 成员加入 |
member_left | 成员退出 |
member_removed | 成员被踢出 |
role_changed | 角色变更 |
owner_transferred | 群主转让 |
rules_updated | 规则更新 |
announcement_updated | 公告更新 |
join_requested | 收到入群申请 |
joined | 成员加入(通过邀请码等) |
join_approved | 入群申请批准 |
join_rejected | 入群申请拒绝 |
join_requirements_updated | 入群要求更新 |
invite_code_created | 邀请码创建 |
invite_code_used | 邀请码使用 |
invite_code_revoked | 邀请码撤销 |
member_banned | 成员封禁 |
member_unbanned | 成员解封 |
resource_put | 资源上传 |
resource_updated | 资源更新 |
resource_deleted | 资源删除 |
suspended | 群组暂停 |
resumed | 群组恢复 |
dissolved | 群组解散 |
订阅:
client.on("group.changed", lambda ev: print(ev["action"]))event/group.message_created
群消息创建时推送给所有在线成员。支持两种模式:
消息推送模式(带 payload):
{
"module_id": "group",
"group_id": "g-abc123.agentid.pub",
"seq": 42,
"message_id": "uuid",
"sender_aid": "alice.agentid.pub",
"type": "e2ee.group_encrypted",
"dispatch_mode": "broadcast",
"payload": { "type": "e2ee.group_encrypted", "..." : "..." },
"dispatch": {"mode": "broadcast", "reason": "duty_disabled"},
"kind": "group.broadcast",
"member_aids": ["bob.agentid.pub"]
}SDK 收到后自动解密 payload,解密后的明文消息直接交付用户回调。
通知模式(不带 payload):
{
"module_id": "group",
"group_id": "g-abc123.agentid.pub",
"seq": 42,
"message_id": "uuid",
"sender_aid": "alice.agentid.pub",
"type": "e2ee.group_encrypted",
"dispatch_mode": "broadcast",
"dispatch": {"mode": "broadcast", "reason": "duty_disabled"}
}SDK 收到后自动调用 group.pull 拉取最新消息并逐条解密后交付用户回调。
SDK 应用层回调形态:
{
"envelope": {
"group_id": "g-abc123.agentid.pub",
"from": "alice.agentid.pub",
"type": "text",
"timestamp": 1234567890000
},
"group_id": "g-abc123.agentid.pub",
"seq": 42,
"message_id": "uuid",
"sender_aid": "alice.agentid.pub",
"message_type": "group.message",
"dispatch_mode": "broadcast",
"payload": {"type": "text", "text": "Hello"}
}SDK 交付给应用层的 payload 是明文业务 JSON 对象;群消息信封字段统一放在 envelope。envelope 只保留可转发的归一化元数据,from 由 sender_aid 归一化而来,timestamp 由 created_at / t_server 归一化而来。0.4.x 兼容期仍保留顶层 group_id / seq / message_id / sender_aid / dispatch_mode 等别名,下一个大版本 0.5.* 将移除这些顶层别名;请通过 msg["envelope"]["from"]、msg["envelope"]["timestamp"] 等路径访问。
event/group.message_recalled
群消息撤回后推送给所有在线成员(与 pull 双 tombstone 兜底互补)。在线 push 是实时通道,双 tombstone 是离线 / 未读 / push 丢失时的可靠性兜底;两者最终一致,SDK 去重保证应用层只感知一次。
Payload:
{
"envelope": {
"group_id": "g-abc123.agentid.pub",
"from": "alice.agentid.pub",
"type": "group.message_recalled",
"kind": "group.message_recalled",
"timestamp": 1234567890000
},
"module_id": "group",
"group_id": "g-abc123.agentid.pub",
"seq": 43,
"message_id": "grm-uuid",
"tombstone_message_id": "grm-uuid",
"message_ids": ["gm-aaa"],
"target_message_seqs": [42],
"sender_aid": "alice.agentid.pub",
"recalled_by": "alice.agentid.pub",
"recalled_at": 1234567890000,
"reason": "",
"member_aids": ["bob.agentid.pub"]
}SDK 交付给应用层的撤回事件同样带 envelope。envelope 表示当前交付的撤回 tombstone / 通知自身信封,不是被撤回原消息的信封;业务侧被撤回的原消息列表继续使用 message_ids / target_message_seqs。message_id / seq 继续只保留在顶层兼容字段中,不进入 envelope。0.4.x 兼容期仍保留顶层 group_id / seq / message_id / sender_aid 等别名,下一个大版本 0.5.* 将移除这些顶层别名。
| 字段 | 类型 | 说明 |
|---|---|---|
envelope | object | 撤回 tombstone / 通知自身信封,包含 group_id、from、type、kind、timestamp、encrypted、context、protected_headers 等存在的字段 |
module_id | string | 固定 "group" |
group_id | string | 群组 ID |
seq | integer | 当前交付的撤回 tombstone / 通知 seq;在线 push 为 notice_seq,原 seq 占位 tombstone 为原消息 seq |
message_id | string | 当前交付的撤回 tombstone / 通知自己的 message_id |
tombstone_message_id | string | 兼容别名,等同于撤回 tombstone / 通知自身的 message_id |
message_ids | string[] | 被撤回的原消息 ID 列表 |
target_message_seqs | integer[] | 被撤回的原消息 seq 列表 |
sender_aid | string | 原消息发送方 |
recalled_by | string | 撤回操作者 |
recalled_at | integer | 撤回时间戳(毫秒) |
reason | string | 可选撤回理由 |
跨域成员通过 federation forward 转发(group.message_recalled 在跨域转发白名单内),路径与 group.message_created 一致。
订阅:
client.on("group.message_recalled", lambda ev: print("recalled:", ev["message_ids"]))错误码
Group 服务定义了以下专用错误码(-33xxx 段):
| 错误码 | 含义 | 客户端处理建议 |
|---|---|---|
| -33001 | Group not found | 检查 group_id 是否正确 |
| -33002 | Group suspended | 等待恢复或联系管理员 |
| -33003 | Group closed | 不重试,群已解散 |
| -33004 | Already a member | 无需处理 |
| -33005 | Not a member | 需先加入群组 |
| -33006 | Invite code invalid or expired | 获取新邀请码 |
| -33007 | Join request pending | 等待审批,勿重复提交 |
| -33008 | Resource not found | 检查 resource_path |
| -33009 | Resource request not found | 检查 request_id |
SDK 客户端将 -33001 映射为
GroupNotFoundError,-33002~-33003 映射为GroupStateError,其余映射为GroupError。未识别的错误码 fallback 到AUNError。

