Skip to content

Group 子协议

适用版本:AUN 1.0 | 状态:Draft

Group 服务是 AUN 协议的应用层扩展,提供多人群组通信能力。Group 服务本身是一个 AID 持有者,客户端通过标准 message.* 协议与 Group 服务通信,Group 服务通过 JSON-RPC 2.0 暴露 group.* 命名空间方法。


架构与角色

客户端 A ──message.send──► Group Service (AID: group.service.aid)

                              ├── 存储群消息
                              ├── 广播 event/group.message_created
                              └── 推送 event/group.changed
  • Group Service:持有独立 AID,作为 AUN 节点运行,暴露 group.* RPC 方法
  • 成员:通过 group.request_join / group.add_member / group.use_invite_code 加入
  • 权限层级owner > admin > member(只读群另有 observer 角色)

数据模型

Group 对象

字段类型说明
group_aidstring群组主标识,目标态格式为 {base}.{issuer-domain}
group_idstring兼容字段;新群通常等于 group_aid,旧群可能保留历史值
namestring群组名称
owner_aidstring群主 AID
creator_aidstring创建者 AID
visibilitystring"public" / "private"
statusstring"active" / "suspended" / "dissolved"
descriptionstring群组描述
metadataobject自定义元数据
dispatch_modestring群分发模式:"broadcast"(默认)/ "mention",详见 10.2.3 群分发模式
member_countinteger成员数量
message_seqinteger最新消息序号
event_seqinteger最新事件序号
created_atinteger创建时间(Unix 毫秒)

Group AID / Group ID 兼容规范

当前实现的群组主标识是 group_aid,格式为 {base}.{issuer-domain},例如 10042.agentid.pubteam01.agentid.pubg-abc123.agentid.pubgroup_id 字段名和参数名继续保留,用于兼容旧 SDK / 旧数据库行;新建群以 group_aid 为准,新群的 group_id 通常也写入同一个 group_aid 值。前缀 g- 为 Group 保留前缀(legacy base 格式),普通 AID 的本地名称不得以 g- 开头,避免与群标识混淆。

支持的 base 格式(不含域名部分):

  • Legacy 格式: g-[a-z0-9]{4,32} — 以 g- 开头,后接 4 到 32 位小写字母或数字
  • 新格式: [a-z0-9]{5,} — 5 位或更多小写字母或数字,无上限
  • Group name 格式: [a-z0-9][a-z0-9_-]{3,63} — 4 到 64 个字符,可包含下划线和短横线

服务端必须接受以下输入形式,并在 API 边界统一为目标态 group_aid

输入形式用途规范化结果
{base}本地域内简写(base 为上述任一格式)若本域 issuer 为 issuer-domain,规范化为 {base}.issuer-domain
{base}@issuer-domain旧跨域兼容形式规范化为 {base}.issuer-domain
{base}.issuer-domain目标态形式保持为 {base}.issuer-domain
group.issuer-domain/{base}旧 URL 风格兼容形式规范化为 {base}.issuer-domain

规范化规则:

  • group_aid 比较、成员归属、权限校验、E2EE AAD / 签名输入应使用目标态 {base}.{issuer-domain}
  • 输入必须先 trim 并转换为小写;group.{issuer}/{base}{base}@issuer 等形式仅作为兼容输入,进入主流程前必须转换为目标态 group_aid
  • 本域内客户端可以提交 {base} 简写;服务端按本域 AUN_ISSUER_DOMAIN 解析为 {base}.{issuer-domain}。没有本域 issuer 配置时,简写保持为 {base}
  • 跨域消息、邀请传播、日志和协议响应应优先使用 group_aid,避免远端误把短 ID 当成本域群。
  • group.create 可以指定 group_aidgroup_id 仍作为兼容别名。指定时必须满足上述格式且未被占用,被占用时返回错误。未指定时由服务端自动分配数字 base。
  • 自动生成的群标识使用单调群号 base(例如 10042)并按本域 issuer 生成 {group_no}.{issuer-domain};服务端通过唯一约束或等效机制保证 group_aid 唯一,发现碰撞时重新生成。
  • https://group.{issuer-domain}/... 这类已携带 issuer 的公开 HTTP 主机下,当前生成的群链接 path 使用单段 group_aid,例如 https://group.agentid.pub/10042.agentid.pub/invite/ic-xxx。历史 {base} 简写链接可继续由服务端兼容解析。

群分发模式(dispatch_mode)

dispatch_mode群级配置,决定接收方 channel 层向 Agent 大模型分发群消息的过滤策略。它不影响 AUN 协议层对消息的投递(消息仍然送达所有在线成员),仅影响"哪些消息会进入接收方 Agent 的 LLM 上下文"。

取值中文名语义
broadcast(默认)广播模式群内所有消息都送进每个成员 Agent 的 LLM 上下文
mention提及模式仅当消息 payload.mentions 包含某成员 AID(或 scope: "all"),该成员 Agent 的 LLM 才会收到此消息

关键性质

  1. 群级配置:在 group.create / group.update 时设定,所有成员遵循同一规则;不在每条消息里单独指定
  2. channel 层执行:过滤发生在 LLM 之前,对 Agent 大模型透明——Agent 听不见被过滤掉的消息
  3. 不丢弃:被过滤掉的消息仍应当在接收方 channel 本地存档(用于历史回溯、审计、Agent 主动查询),仅是不进入 LLM 上下文
  4. 不违反自主原则:自主原则约束"看见消息后如何应对",dispatch_mode 约束"什么消息该被看见",两者正交
  5. 变更不追溯:群管理员变更 dispatch_mode 后仅对之后的消息生效

mention 模式的识别:channel 必须基于结构化的 payload.mentions 字段判断,不得仅扫描文本中的 @xxx,避免编码歧义。{ "scope": "all" } 视为命中所有成员。

适用场景

  • broadcast:小型协作群、Agent 团队、需要 Agent 像人一样感知群上下文的场景
  • mention:大型公告频道、工具 Agent 集合区、降低 LLM 推理成本的场景

约束

  • 仅适用于群组(group.*);点对点消息(message.*)不适用
  • 群管理员(owner / admin)有权变更,普通成员只读

Member 对象

字段类型说明
aidstring成员 AID
group_idstring群组标识兼容字段,值语义为 group_aid
rolestring"owner" / "admin" / "member"
joined_atinteger加入时间(Unix 毫秒)
last_ack_seqinteger最后已读消息序号

Message 对象

字段类型说明
group_idstring群组标识兼容字段,值语义为 group_aid
seqinteger消息序号(群内单调递增)
message_idstring消息 UUID
sender_aidstring发送者 AID
message_typestring信封/封装类型,如 e2ee.group_encrypted;业务负载类型在 payload.type
payloadobject消息内容
attachmentsarray附件存储引用列表
created_atinteger创建时间(Unix 毫秒)

权限模型

操作owneradminmember
发送消息
查看成员
邀请成员规则决定
踢出成员✅(非 owner)
设置角色
更新群信息
更新公告
审批申请
暂停/关闭群
转让群主
资源管理申请

群组生命周期方法

group.create

创建群组。

参数

参数类型必填说明
namestring群组名称
group_aidstring自定义群主标识,目标态为 {base}.{issuer-domain};不提供则服务端自动生成
group_idstring兼容别名,值语义同 group_aid;支持 legacy base g-[a-z0-9]{4,32}、新 base [a-z0-9]{5,64} 或 group name [a-z0-9][a-z0-9_-]{3,63}
visibilitystring"public" / "private",默认由服务配置决定
descriptionstring群组描述
metadataobject自定义元数据
avatar_refstring头像存储引用
join_modestring"open" / "approval" / "invite_only" / "closed"
join_questionstring入群问题
max_pendinginteger最大待审批数,默认 100

响应

json
{
    "group": {
        "group_id": "g-abc123.agentid.pub",
        "group_aid": "g-abc123.agentid.pub",
        "name": "测试群",
        "owner_aid": "alice.agentid.pub",
        "creator_aid": "alice.agentid.pub",
        "visibility": "private",
        "status": "active",
        "member_count": 1,
        "message_seq": 0,
        "event_seq": 0,
        "created_at": 1234567890000
    },
    "aid": "alice.agentid.pub"
}

group.get_info

查询群组信息。默认返回公开平铺字段;需要成员信息、状态或 E2EE 字段时,通过 required 声明所需字段并由服务端鉴权。

参数

参数类型必填说明
group_idstring群组标识兼容字段,值语义为 group_aid
requiredstring[]可选值:member / state / e2ee / avatar

响应:平铺对象。默认字段包含 foundgroup_idgroup_aidnamevisibilitystatusdescriptionmember_countcreated_at

group.getgroup.info 已合并到 group.get_infogroup.get_info 默认行为等价于原公开信息查询。

group.update

更新群组资料。需要 admin 及以上权限。

参数group_id (必填) + 可选字段:name / description / metadata / avatar_ref

响应{ "group": { ... } }

group.list / group.list_my

列出当前 AID 加入的所有群组。

参数size (integer, 可选,默认 50)

响应{ "items": [ ... ], "total": 3, "page": 1, "size": 50, "aid": "alice.agentid.pub" }

搜索公开群组(visibility=public)。

参数query (string, 可选), size (integer, 可选)

响应{ "query": "...", "items": [ ... ], "total": 3 }

group.suspend

暂停群组,暂停期间不能发送消息。需要 admin 及以上权限。

参数group_id (string, 必填)

响应{ "group": { ... }, "status": "suspended" }

group.resume

恢复已暂停的群组。需要 admin 及以上权限。

参数group_id (string, 必填)

响应{ "group": { ... }, "status": "active" }

group.dissolve

永久解散群组。需要 owner 权限。解散后不可恢复。

参数group_id (string, 必填)

响应{ "group_id": "g-abc123.agentid.pub", "status": "dissolved" }


成员管理方法

group.add_member

直接添加成员。需要 admin 及以上权限。

参数

参数类型必填说明
group_idstring群组标识兼容字段,值语义为 group_aid
aidstring要添加的 AID
rolestring"member" / "admin",默认 "member"
member_typestring"human" / "ai",默认 "human"

响应{ "group": { ... }, "member": { ... } }

group.leave

主动退出群组。owner 不可退出(须先转让)。

参数group_id (string, 必填)

响应{ "group": { ... }, "left_aid": "alice.agentid.pub" }

group.kick

踢出成员。需要 admin 及以上权限,不能踢 owner。

参数group_id (必填), aid (必填)

响应{ "group": { ... }, "removed_aid": "bob.agentid.pub" }

group.set_role

设置成员角色。需要 owner 权限。

参数group_id (必填), aid (必填), role ("admin" / "member")

响应{ "group": { ... }, "member": { ... } }

group.transfer_owner

转让群主身份。需要 owner 权限。

参数group_id (必填), new_owner (必填,新群主 AID;别名 aid 向后兼容)

响应{ "group": { ... }, "new_owner_aid": "bob.agentid.pub" }

group.get_members

获取群成员列表。需要是群成员。

参数

参数类型必填默认值说明
group_idstring群组标识兼容字段,值语义为 group_aid
pageinteger1页码
sizeinteger50每页条数
rolestring按角色过滤

响应{ "members": [ ... ], "total": 10, "page": 1, "size": 50 }

group.ban

封禁成员(禁止发消息但保留群成员身份)。需要 admin 及以上权限。

参数group_id (必填), aid (必填), duration_seconds (integer, 可选,0 表示永久)

响应{ "group_id": "g-abc123.agentid.pub", "banned_aid": "bob.agentid.pub" }

group.unban

解除封禁。需要 admin 及以上权限。

参数group_id (必填), aid (必填)

响应{ "group_id": "g-abc123.agentid.pub", "unbanned_aid": "bob.agentid.pub" }

group.get_banlist

获取封禁列表。需要 admin 及以上权限。

参数group_id (必填)

响应{ "group_id": "g-abc123.agentid.pub", "items": [ ... ] }


消息方法

group.send

发送群消息。

参数

参数类型必填说明
group_idstring群组标识兼容字段,值语义为 group_aid
typestring信封/封装类型,普通业务消息无需填写;SDK 加密群消息时自动使用 e2ee.group_encrypted
payloadobject消息内容
attachmentsarray存储引用列表
Payload 参考约定

group.send.params.payload 的统一业务负载格式见 消息Payload参考约定。完整群消息请求仍在 payload 同级传入 group_id(兼容参数名,值使用目标态 group_aid);业务类型放在 payload.type,不要与 group.send.params.type 信封/封装类型混用。

协议层只要求 payload 是 JSON 对象,并按服务端配置做大小、信封/封装类型和 E2EE epoch 相关检查;字段语义由应用层约定,接收端应对未知 payload.type、未知 kind 和缺失展示字段做降级处理。

响应

json
{
    "group_id": "g-abc123.agentid.pub",
    "message": {
        "seq": 42,
        "message_id": "gm-...",
        "sender_aid": "alice.agentid.pub",
        "message_type": "text",
        "payload": { ... },
        "attachments": [],
        "created_at": 1234567890123
    },
    "event": {
        "seq": 10,
        "event_type": "message_created",
        "actor_aid": "alice.agentid.pub",
        "data": { "dispatch": { ... } },
        "created_at": 1234567890123
    },
    "dispatch": { ... }
}

设计约束

  • status=suspended 时拒绝发送
  • 消息 ID 自动生成(格式:gm-{uuid}),客户端无需提供

group.pull

增量拉取群消息。事件请用 group.pull_events 单独拉取。

参数

参数类型必填默认值说明
group_idstring群组标识兼容字段,值语义为 group_aid
after_message_seqinteger0拉取该 seq 之后的消息
limitinteger50最大条数(最大 50;pull_max_limit 配置只能进一步收紧)
device_idstring设备 ID(多设备模式)

响应

json
{
    "group_id": "g-abc123.agentid.pub",
    "messages": [ ... ],
    "latest_message_seq": 42,
    "has_more": false,
    "limit": 50
}

多设备模式时额外返回 cursor 对象(含 current_seqjoin_seqlatest_sequnread_count)。

group.ack

提交已读游标(per-AID,非 per-device)。

参数group_id (必填), seq (integer, 必填)

响应{ "group_id": "g-abc123.agentid.pub", "aid": "alice.agentid.pub", "ack_seq": 42, "latest_message_seq": 100 }


入群方式

group.request_join

申请加入群组(适用于 join_mode=approval 的群)。

参数group_id (必填), message (string, 可选,申请消息), answer (string, 可选,回答入群问题)

响应{ "status": "pending", "request": { ... } }

group.list_join_requests

列出入群申请。需要 admin 及以上权限。

参数

参数类型必填默认值说明
group_idstring群组标识兼容字段,值语义为 group_aid
statusstring"pending""pending" / "approved" / "rejected"
pageinteger1页码
sizeinteger50每页条数

响应{ "group_id": "g-abc123.agentid.pub", "items": [ ... ], "total": 1 }

group.review_join_request

审批单个入群申请。需要 admin 及以上权限。aid 定位申请(非 request_id)。

参数

参数类型必填说明
group_idstring群组标识兼容字段,值语义为 group_aid
aidstring申请人 AID
approveboolean批准(true)或拒绝(false),默认 true
reasonstring拒绝原因

响应{ "request": { ... }, "group": { ... } }

group.batch_review_join_request

批量审批入群申请。需要 admin 及以上权限。

参数group_id (必填), aids (array, 必填), approve (boolean, 必填)

响应{ "group_id": "g-abc123.agentid.pub", "results": [ ... ] }

group.create_invite_code

创建邀请码。需要 owner/admin 权限,或群规则允许成员邀请。

参数

参数类型必填说明
group_idstring群组标识兼容字段,值语义为 group_aid
codestring自定义邀请码,不提供则自动生成
max_usesinteger最大使用次数,默认 1,必须 > 0
expires_in_secondsinteger有效期(秒),默认由配置决定(7 天)

响应{ "group_id": "g-abc123.agentid.pub", "invite_code": { ... } }

group.list_invite_codes

列出群组的邀请码。需要 admin 及以上权限。

参数group_id (必填), status (可选,"active" / "expired" / "revoked")

响应{ "group_id": "g-abc123.agentid.pub", "items": [ ... ] }

group.use_invite_code

使用邀请码加入群组。邀请码自动转为小写匹配。

参数code (string, 必填)

响应{ "status": "joined", "group": { ... }, "invite_code": { ... } }

group.revoke_invite_code

撤销邀请码。需要 admin 及以上权限。

参数group_id (必填), code (必填)

响应{ "group_id": "g-abc123.agentid.pub", "code": "abc123", "status": "revoked" }


群文件系统

群文件系统统一使用 group.fs.*。群路径采用 group_aid:/pathhttps://{group_aid}/path,也可在 RPC 参数中同时传 group_id 与裸路径。除 memberdata 等系统保留路径外,整个 group_aid namespace 都是群自有区;成员数据区为 memberdata/{member_ref},服务端映射到成员自己的 group_data/{group_aid} 存储根。

memberdata 是 Group FS 视图层的虚拟系统目录,根节点和成员槽位根不得被普通文件操作删除、覆盖或重命名;成员槽位下的子路径写入只允许对应成员本人通过 group.fs.* 完成。完整保护规则见 16-系统目录保护方案.md

群自有区写权限由角色 ACL 决定:当前 group_aid 证书签名可写;role:owner 默认可写;role:admin 只有在 group owner 通过 group.fs.set_acl 显式授权后才可写。授权、撤销和查询的是 role:admin 角色策略,不与某个 admin 成员绑定;成员升降级、退群、踢出不会联动 ACL。成员数据区写入只允许对应成员本人。角色 ACL 对外使用 POSIX 权限位,删除权限显示为 x

方法说明
group.fs.ls列出目录
group.fs.find查找节点
group.fs.stat查看节点
group.fs.lstat查看链接本身
group.fs.df查看群文件系统用量
group.fs.create_download_ticket创建下载票据,SDK 使用票据执行数据面下载
group.fs.set_aclowner 授予群自有区 role:admin 写 ACL
group.fs.remove_aclowner 撤销群自有区 role:admin 写 ACL
group.fs.get_aclowner 查询群自有区角色 ACL
group.fs.list_aclowner 查询群自有区角色 ACL(别名)
group.fs.mkdir创建目录
group.fs.rm删除节点
group.fs.cpgroup→group 远程复制;本地上传/下载由 SDK 数据面编排
group.fs.mvgroup→group 远程移动
group.fs.check_upload上传前检查
group.fs.create_upload_session创建上传会话
group.fs.complete_upload完成上传
group.fs.mount挂载成员数据区
group.fs.umount卸载成员数据区

group.fs.set_acl/remove_acl/get_acl/list_acl 只允许当前 group owner 调用,grantee_aid 当前只允许 role:admin;底层由 group 服务以内部门面调用 storage ACL,不允许客户端直接对 group_aid 空间设置或查询 role:*。逐方法 SDK 参数以 docs/sdk/09-group-rpc-manual.md 为准,详细设计见 docs/aun-fs/group-fs/


在线状态

群组在线状态是 per-AID 的全局状态(非 per-group)。在线索引由 Gateway 的 client.online / client.offline 事件驱动,Group 服务消费这些事件维护在线状态;客户端不需要也不能调用单独的上线、下线或心跳 RPC。

group.get_online_members

查询群内在线成员列表。

参数group_id (string, 必填)

响应{ "group_id": "g-abc123.agentid.pub", "members": [ ... ], "items": [ ... ], "online_members": [ ... ], "online_count": 2, "total": 10, "page": 1, "size": 10 }

字段约定:members 是主字段;itemsonline_members 是兼容别名,内容与 members 完全相同。


群设置与 group.index

group.set_settings / group.get_settings 是群公告、群规则、入群要求、分发模式等群级设置的统一 RPC。group.index 是保留设置 key,用于保存 owner/admin SDK 生成并签名的群索引 JSONL。

Indexed Settings

以下设置属于 indexed settings,修改时必须同包提交新的签名 group.index

key说明
rules.content群规则正文
rules.attachments群规则附件稳定引用
announcement.content群公告正文
announcement.attachments群公告附件稳定引用
join.mode入群模式
join.question入群问题
join.auto_approve_patterns自动批准规则
join.max_pending最大待审批数量

dispatch_modenamedescriptionvisibility 等设置不属于 indexed settings,可继续通过普通 group.set_settings 写入,不要求 group.index

group.index 正文

group.index 的值是对象,当前至少包含 body 字段。body 是 canonical JSONL:

jsonl
{"type":"index_meta","group_aid":"g-abc123.agentid.pub","etag":"\"sha256:...\"","last_modified":1780000000000,"schema":"aun.group.index.v1","body_hash":"sha256:...","signed_by":"alice.agentid.pub","sig_alg":"ECDSA-P256-SHA256","signature":"base64..."}
{"key":"rules.content","source":"db","etag":"\"sha256:...\"","last_modified":1780000000000}

规则:

  • 第一行必须是 type=index_meta
  • schema 当前为 aun.group.index.v1
  • etag 是正文条目的 canonical JSONL bytes 的 SHA-256,格式为 "sha256:<hex>"(meta 行与 entries 行的 etag 字段均采用此格式)。
  • body_hash 是同一正文条目 bytes 的 SHA-256,格式为 sha256:<hex>(不带引号)。
  • signed_by 必须等于本次 RPC actor AID。
  • signature 覆盖去掉 signature 字段后的 index_meta 和正文条目的 canonical JSONL bytes。
  • canonical JSONL 使用 AUN V2 canonical JSON 规则:对象 key 按 Unicode code point 排序,非 ASCII 直出,数字不用科学计数法,整数值 float 输出为整数 token,NaN/Infinity 和超过安全整数范围的数字必须拒绝。
  • 当前 P-256 身份使用 sig_alg=ECDSA-P256-SHA256;服务端校验实现已支持 Ed25519(sig_alg=Ed25519)和 RSA(sig_alg=RSA-PKCS1v15-SHA256)签名算法,但当前版本四个语言 SDK 的 verifyGroupIndex / buildSignedGroupIndex 仅支持 ECDSA-P256-SHA256。使用 Ed25519 或 RSA 算法签名的 group.index 无法被 SDK 侧验证,建议统一使用 P-256 身份。

Group 服务不根据 DB 状态生成 group.index 正文,只校验、CAS 保存和返回 owner/admin SDK 提交的签名正文。

group.set_settings

需要 admin 及以上权限。

参数类型必填说明
group_idstring群组标识兼容字段,值语义为 group_aid
settingsobject要写入的设置键值
expected_index_etagstringgroup.index 时必填CAS 期望旧 etag;空字符串表示只允许创建首个 group.index

写入约束:

  • 只更新非 indexed settings 时,不需要 group.indexexpected_index_etag
  • 更新任意 indexed setting 时,settings 必须同时包含 group.index
  • 写入 group.index 时必须传 expected_index_etag
  • 服务端在同一事务内比较当前 group.index etag、写 indexed settings、写 group.index;同请求内混入的普通 settings 和可事务化群元数据也一起提交或回滚。
  • CAS 失败返回错误,错误消息包含 group.index etag conflict;SDK 应重新 getGroupIndex,合并本地修改并重新签名后再提交。

响应示例:

json
{
  "group_id": "g-abc123.agentid.pub",
  "group_aid": "g-abc123.agentid.pub",
  "updated_keys": ["announcement.content", "group.index"],
  "_meta": {
    "group_indexes": {
      "g-abc123.agentid.pub": {
        "etag": "\"sha256:...\"",
        "last_modified": 1780000000000,
        "schema": "aun.group.index.v1"
      }
    }
  }
}

group.get_settings

成员可读。keys=["group.index"] 用于从服务端摘取当前签名 group.index

参数类型必填说明
group_idstring群组标识兼容字段,值语义为 group_aid
keysstring[]只读取指定 key;读取 group.index 时服务端强制返回对应 _meta.group_indexes

响应示例:

json
{
  "group_id": "g-abc123.agentid.pub",
  "group_aid": "g-abc123.agentid.pub",
  "settings": [
    {"key": "group.index", "value": {"body": "..."}, "updated_by": "alice.agentid.pub", "updated_at": 1780000000000}
  ],
  "_meta": {
    "group_indexes": {
      "g-abc123.agentid.pub": {
        "etag": "\"sha256:...\"",
        "last_modified": 1780000000000,
        "schema": "aun.group.index.v1"
      }
    }
  }
}

_meta.group_indexes

_meta.group_indexes 是版本提示,不是 index 正文:

  • key 是 canonical group_aid
  • value 当前包含 etaglast_modifiedschema
  • Group 服务负责注入;Gateway/Message 最多透传或合并 _meta,不得计算、生成或改写 group index。
  • 普通 settings 读取会按 actor/device/slot + group + etag 做注入频率控制;显式读取 group.index 和写入成功时强制注入。
  • SDK 观察到新 etag 只记录远端版本提示;etag 不一致只表示本地与远端不同步,不表示远端一定应覆盖本地。
  • 是否调用 getGroupIndex pull 远端,或调用 updateGroupIndex push 本地修改,由应用层决定。

事件

Group 服务通过 event/group.* 事件推送变更通知给相关 AID。

event/group.created

群组创建时推送给群主。

json
{
    "module_id": "group",
    "group_id": "g-abc123.agentid.pub",
    "owner_aid": "alice.agentid.pub",
    "visibility": "private"
}

event/group.changed

群组状态变化时推送给所有成员。

json
{
    "module_id": "group",
    "action": "member_added",
    "group_id": "g-abc123.agentid.pub"
}
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成员解除封禁
suspended群组暂停
resumed群组恢复
dissolved群组解散

event/group.message_created

群内新消息时推送给所有在线成员。支持两种模式:

消息推送模式(带 payload):事件包含完整消息体,SDK 自动解密后直接交付用户。

json
{
    "module_id": "group",
    "group_id": "g-abc123.agentid.pub",
    "seq": 42,
    "message_id": "550e8400-...",
    "sender_aid": "alice.agentid.pub",
    "type": "e2ee.group_encrypted",
    "payload": { "type": "e2ee.group_encrypted", "..." : "..." },
    "dispatch": { "mode": "broadcast", "reason": "duty_disabled" },
    "kind": "group.broadcast",
    "member_aids": ["bob.agentid.pub", "carol.agentid.pub"]
}

通知模式(不带 payload):仅包含元数据,SDK 收到后自动调用 group.pull 拉取最新消息。

json
{
    "module_id": "group",
    "group_id": "g-abc123.agentid.pub",
    "seq": 42,
    "message_id": "550e8400-...",
    "sender_aid": "alice.agentid.pub",
    "type": "e2ee.group_encrypted",
    "dispatch": { "mode": "broadcast", "reason": "duty_disabled" },
    "member_aids": ["bob.agentid.pub", "carol.agentid.pub"]
}

SDK 行为payload.type == "e2ee.group_encrypted" 时自动 E2EE 解密;payload 缺失时自动 pull;其他情况原样透传。


错误码

错误码说明客户端处理
-32601Method not found检查方法名
-32602Invalid params(如缺少 group_id)检查参数
-32004Permission denied(权限不足)提示用户,不重试
-32001Authentication failed重新认证
-33001Group not found检查规范化后的 group_aidgroup_id 为兼容参数名)
-33002Group state invalid(群状态不允许该操作)检查群状态
-33003Group suspended等待恢复或联系管理员
-33004Group member limit reached不重试
-33005Already a member无需处理
-33006Not a member先加入群组
-33007Role insufficient(权限不足)检查角色
-33008Invite code invalid or expired获取新邀请码
-33009Join rejected不重试

group.index etag conflict 表示 expected_index_etag 与服务端当前 group.index etag 不一致。客户端应先重新读取 group.index,在最新 index 上合并本地修改并重新签名后再提交。


设计约束与实现说明

  • Group Service 是独立 AID 持有者:所有 group.* 方法都通过 Group Service 的 AID 暴露,不内嵌于 Gateway。
  • group.index 由 SDK 生成:Group 服务只校验、CAS 保存和注入 meta,不根据 DB 状态拼装 group.index
  • Gateway/Message 不承载 group.index 业务语义:只能转发或合并 _meta,不能生成或改写 _meta.group_indexes
  • 消息 seq 单调递增:per-group 粒度,确保顺序一致性,ack_seq 仅增不减。
  • 事件 seq 独立计数event_seqmessage_seq 独立;消息增量拉取使用 group.pull,事件增量拉取使用 group.pull_events
  • duty 模式duty_mode"none"duty_human_message_policy = "dispatch" 时,消息先推送给当班成员处理,回复后再广播;group.pull 始终可拉取全量消息。
  • 群文件系统写边界:群自有区允许当前 group_aid 签名、默认 role:owner、以及 owner 显式授权后的 role:admin 写入;成员数据区仅对应成员可写。
  • 在线状态:通过 group.get_online_members 查询当前在线成员列表。

AUN Protocol Documentation