What problem does this solve?
这里有两个相邻但不同的 routing 语义,需要拆开:
- 已有 thread / 已有对话历史时,无
@mention
- 当前期望:默认继续找最近一个可用的猫
- 这条行为已经存在,应该保持不变
- 新开一个会话 / 新 thread / 没有历史、没有 participants、没有
@mention
- 当前行为:默认落到
opus
- 我们现在想改的是这一条全局默认,让它变成一个运行时可配置项
也就是说,这个需求不是改 last replier 规则,也不是改 thread 的 preferredCats,而是把“无历史时谁来接第一棒”的全局默认回复猫做成可配置。
当前代码边界:
packages/api/src/domains/cats/services/agents/routing/AgentRouter.ts
- 现有链路:
mentions -> last-replier (scoped to preferredCats) -> first preferred -> default cat
packages/api/src/config/cat-config-loader.ts
getDefaultCatId() 当前通过 breeds[0].defaultVariantId 推导默认猫
docs/features/F078-smart-routing-group-mentions.md
- 明确写了
No participants and no preferredCats -> default to opus
问题在于:
- 这个“新会话全局默认”现在被耦合在 breed 默认 variant 上
- 配置位置不对,不能在运行时通过成员管理调整
- 多 family / 多分身并存时,真正想表达的是“当前默认由哪个成员接无历史第一条消息”,而不是“哪个 breed 的默认 variant 排在最前面”
Proposed solution
- 在成员总览/成员列表里支持设置“全局默认回复猫(仅用于新会话无历史时)”
- 这个状态挂在成员级事实源上,而不是
breeds[0].defaultVariantId 上
- UI 交互是单选唯一:
- 任一时刻有且只有一个成员是默认
- 如果 A 当前是默认,再把 B 设为默认时,A 会自动取消
AgentRouter 的最终 fallback 改为读取这个成员级全局默认,而不是直接走 breed-based getDefaultCatId()
- 已有 thread 无
@ 时继续走最近一个可用猫,这条规则不改
preferredCats 语义保持不变:它仍然是 thread 级候选范围,不承担“新会话全局默认”的职责
Acceptance criteria
- 已有 thread / 有历史时,无
@mention 仍然路由到最近一个可用的猫,行为不回退
- 新 thread / 新会话在无
@mention、无 participants、无 preferredCats 时,路由到成员总览里配置的全局默认成员,而不是固定 opus
- 成员总览里该配置是单选唯一:设置 B 为默认时,A 的默认状态会自动清除
- 修改该配置后生效,不需要改代码或依赖 breed 顺序
- 默认成员不可用时,fallback 行为明确且有测试覆盖
AgentRouter、config loader、connector/callback 等读取默认猫的路径共用同一套解析逻辑
- 前端有保存/刷新回显测试,后端有唯一性/兜底测试
Alternatives considered
- 继续复用
breeds[0].defaultVariantId
- 不合适:它表达的是 breed 默认 variant,不是“新会话无历史时的全局默认回复猫”
- 复用
preferredCats
- 修改“已有 thread 无
@ -> 最近一个可用猫”的规则
- 不合适:这不是本需求,本需求只改“新会话无历史”的 fallback
Additional context
相关文件/文档:
packages/api/src/domains/cats/services/agents/routing/AgentRouter.ts
packages/api/src/config/cat-config-loader.ts
packages/web/src/stores/chat-types.ts (preferredCats)
docs/features/F078-smart-routing-group-mentions.md
docs/features/F032-agent-plugin-architecture.md
docs/features/F128-cat-create-thread.md
What problem does this solve?
这里有两个相邻但不同的 routing 语义,需要拆开:
@mention@mentionopus也就是说,这个需求不是改
last replier规则,也不是改 thread 的preferredCats,而是把“无历史时谁来接第一棒”的全局默认回复猫做成可配置。当前代码边界:
packages/api/src/domains/cats/services/agents/routing/AgentRouter.tsmentions -> last-replier (scoped to preferredCats) -> first preferred -> default catpackages/api/src/config/cat-config-loader.tsgetDefaultCatId()当前通过breeds[0].defaultVariantId推导默认猫docs/features/F078-smart-routing-group-mentions.mdNo participants and no preferredCats -> default to opus问题在于:
Proposed solution
breeds[0].defaultVariantId上AgentRouter的最终 fallback 改为读取这个成员级全局默认,而不是直接走 breed-basedgetDefaultCatId()@时继续走最近一个可用猫,这条规则不改preferredCats语义保持不变:它仍然是 thread 级候选范围,不承担“新会话全局默认”的职责Acceptance criteria
@mention仍然路由到最近一个可用的猫,行为不回退@mention、无 participants、无preferredCats时,路由到成员总览里配置的全局默认成员,而不是固定opusAgentRouter、config loader、connector/callback 等读取默认猫的路径共用同一套解析逻辑Alternatives considered
breeds[0].defaultVariantIdpreferredCats@-> 最近一个可用猫”的规则Additional context
相关文件/文档:
packages/api/src/domains/cats/services/agents/routing/AgentRouter.tspackages/api/src/config/cat-config-loader.tspackages/web/src/stores/chat-types.ts(preferredCats)docs/features/F078-smart-routing-group-mentions.mddocs/features/F032-agent-plugin-architecture.mddocs/features/F128-cat-create-thread.md