Repository navigation
Replies: 1 comment
|
Thanks for the report — I re-verified the whole chain against A plugin cannot reach the preset plane either, so I took the one seam that can act on this at runtime —
- insert:
- id: team-delegation-guard
name: '@argszero/cordis-plugin-team-delegation-guard'What it doesFor every agent whose scope carries the Team tool set, it withdraws the legacy delegation names that agent can still see: agent.ctx.tools.restrict({ deny: ['subagent', 'subagent_fork', /* … */] })Three properties of the seam are what make that precise instead of approximate, and they are why the plugin is shaped this way:
The discriminator is a marker tool, not a flag and not the Team service. It also goes inert by itself once fix A lands: What it deliberately does not do
Verification
On the core-side fixA is right, and the per-row form matters for exactly the reason you give — the Worth including in the same change: the bundle README contradicts itself today. On CI: the blind spots you name — a recorded Team snapshot that runs headless, and a Web overlay test whose scaffold does not enable The plugin is a runtime-plane enforcement of the bundle's own declared intent, offered as an immediate stop-gap; fix A remains the fix. |
Uh oh!
There was an error while loading. Please reload this page.
中文摘要:在 Web/Desktop(preset 平面)上开启 Agent Teams bundle 后,
subagent/subagent_fork并没有被禁用(bundle 的disabledpatch 只落在 host 平面),而 Team 的send_message/list_agents/interrupt_agent又以同名工具遮蔽了 preset 的 continuable-child 控件。结果:模型用subagent派出的子代理既不在 Team roster 里,也没有任何工具能按agent_id联系它们 —— 也就是"我明明派了人,却找不到也联系不上"。English summary: With the Agent Teams bundle enabled on Web/Desktop, the bundle's
disabledpatches only hit host-plane rows, so the preset plane still exposessubagent/subagent_fork. The Team tools shadow the preset's same-named child controls, so children spawned throughsubagentare not Team members:list_agentsnever shows them andsend_messagereportsactive teammate "…" not found.环境
0.1.7-rc.1(源码 checkout,HEAD46a7f68b09),Web GUIweb,dsh.profile.bundles = ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@deepseek-ai/dsh-experimental-agent-team-profile"](在 Plugins 页开启 Agent Teams)现象
开启 bundle 后,Lead 会话的工具表同时包含两套语义冲突的委派工具:
spawn_teammate、send_message、list_agents、interrupt_agent、wait_agent、team_task_*subagent、subagent_fork其中
send_message/list_agents/interrupt_agent的描述是 Team 版(target为 teammate 名、role: lead/teammate),不是agent_id/scope版;即 bundle 想要禁用的旧控件只是被同名遮蔽,而subagent/subagent_fork原样可用。实测(同一会话)
subagent派一个后台子代理,子代理正常返回。list_agents()→[{"target":"lead","role":"lead","status":"running","diagnostics":[]}],只有 lead。send_message({target:"<子代理 id 或 label>"})→Error: active teammate "190afdd6-…" not found。也就是说:模型按
subagent正常委派之后,既无法列出、也无法联系它自己创建的子代理。错误信息只说明"找不到这个 teammate",不提示任何可行的替代路径。最小复现
web(或 Desktop)profile 启用@deepseek-ai/dsh-experimental-agent-team-profile。subagent委派一个后台子任务。list_agents→ 只有lead。send_message({ target: "<子代理 id/label>" })→active teammate "…" not found。根因
bundle 的禁用意图是 host 平面的 id patch
agent-team-profile/cordis.patch.yml禁用tool-subagent-control/tool-subagent-list-agents/tool-subagent/tool-subagent-fork;README 也承诺 "Ordinary subagent delegation … disabled"(README L12、L49)。Web profile 里这些 id 属于 host 平面,且早已被 web-app 禁用
web-app/cordis.patch.ymlL497-L514。bundle 的 patch 命中了正确的 id,但那一行本来就是关的 —— 静默无效。真正给模型的 delegation 工具由 agent preset 声明
presets/standard.patch.ymlL80-L118 的delegation组(tool-subagent-control、tool-subagent-list-agents、tool-subagent、tool-subagent-fork);ptc、cordis两个 preset 同样声明(minimal没有)。GUI 每个 agent 都会挂默认 preset:api/session-controller/src/agent.tsL381-L397。顶层 patch 跨不进 preset 内部,且这是被强制的两平面架构
applyEntryPatches只索引顶层条目与同层group行(vendor/include/src/index.tsL65-L74),未命中的 id 只 warn 并跳过(L109-L113);同时scripts/verify-cordis-config.tsL139-L166 要求"一行只属于一个平面"。因此 preset 行无法被任何其他 bundle 的 patch 层禁用。Team 工具靠"同名遮蔽"替换旧控件,但只遮蔽了三个
preset scope 通过
bindScopeParent成为 agent scope 的父层(agent-preset-registryL248-L257、core/scopeL72);Team 工具注册进 agent 自身的层(tool-agent-teamL164-L175),工具解析里 own 层最后写入并遮蔽 inherited(core/toolsL1177-L1208)。于是send_message/list_agents/interrupt_agent被替换,subagent/subagent_fork存活。普通子代理不是 Team 成员,因此不可见也不可达
tryMembership对带 subagent descriptor 的子代理返回undefined(roster.tsL92-L122),list只返回 Lead + roster(L129-L160),send_message按 member 名解析并抛TEAM_MEMBER_NOT_FOUND(L43-L55)。这不是"模型乱用 Agent Teams 语义"
模型的路径其实被工具文档教成这样,且完全不需要用户提及 Agent Teams:
tool:policy只约束"创建 teammate"(create teammates only when the user explicitly asks…),不约束是否委派,也不禁止subagent;九件套对 Lead 是无条件安装的(tool-agent-teamL402-L421)。subagent的系统提示段写着 "Use subagent in the background by default…"(tool-subagentL599-L605),工具描述本身也写着 "send_messagesteers the child's nearest step…"(L387)。send_message是 Team 版:传agent_id→invalid arguments: missing required property "target";传子代理名字/id →active teammate "…" not found。policy 中没有任何一句说明"本会话的send_message/list_agents只认 Team 成员"。因此在开启 bundle 的 Web/Desktop 上,每一次普通委派都会踩到这条死路;用户不提 teams 时反而更容易踩,因为此时没有 teammate,而可用的控制工具全是 Team 语义。
为什么 CI 没有发现
subagent(snapshots/session/team-targets/tool-schemas.expected.json)—— 测试钉住的是正确组合,与 Web/Desktop 无关。agent-team-panel.e2e.tsL36-L54 只断言 overlay == bundle patch + 面板 UI,其 scaffold 没有开启agentPresets(scaffold.tsL665-L667),因此看不到该泄漏。影响面
standard/ptc/cordis三个 shipped preset 都声明这些行。建议修复
A(推荐,符合两平面架构的最小改动):让 preset 平面对 Team 服务感知 —— 在
presets/standard|ptc|cordis.patch.yml的这 4 个 legacy child-control 行上各加disabled: !!js "ctx.get('agentTeams') !== undefined"(同文件已有!!js先例,host 平面也有!ctx.get('profileContext')先例)。注意必须逐行加、不能禁用整个delegation组,否则workflow也会一起消失(headless Team 快照中workflow是保留的)。配套:增加一条"Web preset × Team bundle"组合下断言模型可见工具表的产品级测试,并同步 README。B:由 Team bundle 自带一个 Team preset 并 patch 顶层
agent-preset-registry的 default。不动 web-app,但要复制整份 preset 声明,与 preset 编辑器/用户自定义 preset 冲突,实验包还需承担 release preset 的维护成本 —— 不推荐。C:让
tool-subagent检测到agentTeams就不注册。隐式耦合,且会让 host 平面行也静默消失 —— 不建议。D(止血,不足以修复):在 Team policy/工具错误信息中说明"本会话仍可能出现
subagent,其子代理不属于 Team,send_message/list_agents无法到达它们",并修正 README 的矛盾表述。备注
以上结论均在开启 bundle 的真实 Web 会话中实测(工具表比对 +
list_agents/send_message的实际返回),代码位置对应 HEAD46a7f68b09。All reactions