Repository navigation
Replies: 1 comment
|
补充一份基于本讨论的可核验操作指南(已发布 v0.5.278):\n\n- English: https://github.com/sandbaseai/deepseek-harness-handbook/blob/main/docs/en/agent-patterns/continuable-child-empty-tool-registry.md\n- 中文: https://github.com/sandbaseai/deepseek-harness-handbook/blob/main/docs/zh-CN/agent-patterns/continuable-child-empty-tool-registry.md\n- 在线站点: https://sandbaseai.github.io/deepseek-harness-handbook/\n\n指南把父/子工具视图、standing preset 组合顺序、toolFilter、cold resume 和安全绕行拆成独立证据边界,并附最小回归矩阵。手册是独立社区资料,不是官方插件或 API wrapper。 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
环境
DSH 版本:0.1.1-rc.2(撰写时 npm 上最新发布版)
操作系统:Windows 10/11 x64(Node 22)
安装方式:npm 全局安装;GUI 为 web profile;委派路径是通用的 dsh-subagent startContinuable,与具体 profile 无关
预设:一个自定义预设,其 standing scope 注册了全部模型向工具(agent.cordis.yml 中的 dsh-tool-fs / -fs-search / -pwsh / -bash / -web / -jobs / -goal / -todo / -ask-user / -skill 行);agent-presets.default 指向该预设
期望行为
通过 subagents.startContinuable({ ... }) 生成的 continuable 子代理(预设委派工具所用的路径),应当通过 applyChildComposition → agentPresets.composeFrom(childCtx, parent.ctx) 继承父会话 standing 预设中的工具,并按配置的 toolFilter(allow/deny)过滤。
实际行为
子代理的可调用目录里只有 report(由 dsh-tool-subagent-report 通过 registerContinuableSetup 无条件安装的那个工具)。调用 read 报错:
Error: unknown tool "read"
子代理看不到父会话 standing 作用域中的任何工具;挂在组合根层的 MCP 工具同样不可见。角色 persona 文本也没有被继承(子代理只收到通用的运行时上下文模板)。
复现步骤(最小化)
配置一个预设,在其 standing scope 挂载例如 dsh-tool-fs 与 dsh-tool-fs-search(使父会话拥有 read/write/edit/glob/grep)。
从绑定该预设的会话中,仿照 dsh-subagent/lib/types/continuation.js(约 723 行)/ index.js(约 1230 行)生成一个 continuable 子代理:startContinuable({ provider, label, request: { parent, agentOptions, persona, toolFilter } })。
在子代理中:枚举工具 → 只有 report;调用 read → Error: unknown tool "read"。
该现象在 5 个角色 × 多次生成中稳定复现;同时可复现"根层的 mcp__* 工具对子代理不可见,尽管父会话看得到"。
已检查的代码路径
dsh-subagent/lib/types/child-agent.js applyChildComposition(约 126–135 行): childCtx.get('agentPresets')?.composeFrom(childCtx, parent.ctx) —— 可选链使得解析失败成为静默空操作,子代理落入文档中描述的"未加入预设 → 空注册表"失败模式。
dsh-subagent/lib/types/continuation.js materializeTracked 的 setup(约 716–743 行):顺序为 appendDelegatedPolicyOverrides → applyChildComposition → setupRegistry.apply(continuable 注册项——含 report 与 scoped MCP——最后执行)。
dsh-agent-presets/lib/index.js:standing 挂载键为 { agentPreset: id }(约 1140 行);standingMountFor(parent.ctx);dsh-scope 的 bindScopeParent(已挂父级时会抛错)。
dsh-tools/lib/index.js view()(约 2843–2869 行):子代理视图 = 全局层 + 作用域链祖先层 + 自身层;自身层注册不受限制过滤器约束。
假设(未经证实——需要维护者协助确认)
可能是以下之一:
(a) 在标准 web-profile 部署中,materialize 时 childCtx.get('agentPresets') 为 undefined;
(b) standingMountFor(parent.ctx) 未命中 standing 挂载,bindScopeParent 从未被调用;
(c) 首轮工具快照在绑定落地之前被截取。
"空注册表"症状与"composeFrom 从未生效"完全吻合;在没有运行时插桩的情况下无法精确定位到具体失败行。
值得一提的反证:另一条生成路径(通过 subagent_role 的通用角色绑定子代理)确实继承了完整的父工具集(134 个工具,含全部 MCP)。这说明父工具位于可作用域化的层中;只有 continuable 组合路径绑定失败——问题更可能出在 continuable 路径本身,而非 standing 机制。
影响
所有基于委派的角色工具(oracle / designer / fixer / explorer / librarian)不可用:子代理只能 report,无法 read/grep/edit/write/执行命令。
幻觉风险:在完全没有 read 工具的情况下,某个子代理仍"成功读取了文件"——当工具只出现在提示词文字中时,模型会编造成功。工具过滤也无法缓解(因为根本没有可过滤的继承工具)。
期望修复 / 协助
让可选链失败变得显式(记录日志 + 抛出可感知的错误),或确保无论服务解析结果如何,continuable 子代理都能获得 composeFrom 绑定。
确认标准部署中 materialize 阶段 agentPresets 是否可从子 ctx 解析(以及什么会使其不可见)。
提供任何插桩线索(setup 上下文 / 作用域键)以便验证——或提供一个回归测试:生成 continuable 子代理并断言其工具注册表非空。
本地绕行方案(仅供参考)
预设插件现已通过 registerContinuableSetup 将工具插件直接挂载进子代理的自身作用域,并在 system-prompt/assemble 中注入 schema(与既有 installScopedMcp 同一模式),由各角色白名单驱动;只读沙箱通过在同一个 setup 中追加 sandbox/mode 事件实现。这绕开了 composeFrom 且可工作,但它只是绕行方案:过滤退化为插件粒度,继承工具的 restriction 语义丢失。如有需要可提供子代理会话日志(sandbox/mode、request/context、tool-call 事件)。
All reactions