tool-subagent 静默丢弃子代理路由覆盖(每调用 agentOptions)+ 两个面向仓库外(下游)插件的扩展点缺口 Subagent route override is silently dropped by tool-subagent (per-call agentOptions), plus two extension gaps for out-of-repo (downstream) plugins #1619
Replies: 3 comments
|
Verified all three against master (47f9438). The bug is exactly as diagnosed, the fix is correct — and two of the three points connect to threads that already have verified source work. Three additions: 1. Bug confirmed + fix is right; one merge-order nuance
2. Gap (out-of-repo session event types) = the #1538/#1584 family, already source-verifiedThis is the same write-side gap confirmed in #1538 (plugin 3. Gap (settings namespaces hard-coded) = the #1606 threadThe fixed On @yun520-1's "silent lossy transformation" framingAgreed, and the "actual route in the result" discriminant is the right addition — it also turns the fix into a self-verifying one: once the tool forwards per-call agentOptions AND the result echoes the effective route, a mismatch becomes a detectable signal instead of a silent divergence. |
|
第一项“每次调用指定 provider/model”现在有一条不改 DSH 源码、已经跑过真实 child request/header 的替代实现:Pi 的 dsh plugin --profile web add pi2dsh@0.11.0
dsh plugin --profile web add @tintinweb/pi-subagents它的 这正好避开本帖第 1 个 bug:参数不是塞给原生 项目与安装说明:https://github.com/weijiafu14/pi2dsh 本帖第 2/3 个缺口仍然是 DSH 下游插件的公共扩展面问题:持久事件至少要有逐事件 |
Uh oh!
There was an error while loading. Please reload this page.
中文: 在安装并实机验证一个第三方「子代理模型角色」插件(基于 settings 的每模型能力描述 + 每会话子代理模型固定,指引委派模型在每次 subagent 调用时携带 agentOptions: { provider, model })的过程中,遇到了三个 harness 侧问题,值得记录。第一个是 bug;另外两个是仓库外插件的扩展点缺口。 English: While installing and verifying a third-party "subagent model roles" plugin (settings-backed per-model capability descriptions + per-session subagent-model pinning that tells the delegating model to pass agentOptions: { provider, model } on each subagent call), I hit three harness-side issues worth recording. The first is a bug; the other two are extension-point gaps for out-of-repo (downstream) plugins.
症状 / Symptom 中文: 委派模型在 subagent 工具调用中传入了 agentOptions: { provider, model }(会话轨迹中可见),但每个子代理仍路由到父代理创建时的默认路由——本例中是一条无效路由,导致子代理报 subagent run failed(适配器返回 HTTP 401),list_agents 也没有持久化的子代理。 English: The delegating agent passes agentOptions: { provider, model } on the subagent tool call (visible in the session trace), but every spawned child still routed to the parent's creation-time default route — in our case an invalid route, so children failed with subagent run failed (HTTP 401 from the adapter) and list_agents showed no durable children.
根因 / Root cause 中文: packages/subagent/tool-subagent/src/index.ts 的 execute() 只读取 args.description 与 args.prompt。agentOptions 未在工具 schema 中声明,参数被「接受但忽略」;于是 request.agentOptions 只可能来自插件 config.agentOptions(固定默认值)。resolveChildAgentOptions(parent, request.agentOptions, depth) 本身已经能正确合并请求级覆盖——问题在于工具层从未把它转发出去。 English: packages/subagent/tool-subagent/src/index.ts's execute() only reads args.description and args.prompt. agentOptions was not declared in the tool schema and the argument was silently accepted-but-ignored, so request.agentOptions was only ever populated from the plugin's config.agentOptions (a fixed default). resolveChildAgentOptions(parent, request.agentOptions, depth) already merges a request override correctly — it is the tool that never forwards it.
修复(本地已实现 + 已测试)/ Fix (implemented + tested locally) 中文: 在工具 schema 中声明可选参数 agentOptions(provider / model / maxTokens),并在 execute() 中把每次调用的参数逐字段合并覆盖 config.agentOptions 后再构造 provider 请求;不传该参数时行为与之前完全一致。更新并新增了测试,packages/subagent/tool-subagent 套件 62/62 通过。参考提交:公共 fork qwased/deepseek-harness 的 fix/tool-subagent-agentoptions @ 57ea25e。 English: Declare an optional agentOptions parameter (provider / model / maxTokens) on the tool schema, and in execute() merge the per-call argument field-by-field over config.agentOptions before building the provider request. Omitting the argument preserves existing behavior exactly. Tests updated and added; the packages/subagent/tool-subagent suite passes 62/62. Reference commit: fix/tool-subagent-agentoptions @ 57ea25e on the public fork qwased/deepseek-harness.
症状 / Symptom 中文: 插件写入自己的会话事件(例如 model-roles/subagent-pin)后,重启恢复该会话会失败:SessionFormatUnsupportedError: session "…" contains event type "model-roles/subagent-pin" … unknown to this harness and not marked ignorable。 English: A plugin that logs its own session events (e.g. a model-roles/subagent-pin event) makes those sessions un-resumable after restart: SessionFormatUnsupportedError: session "…" contains event type "model-roles/subagent-pin" … unknown to this harness and not marked ignorable.
根因 / Root cause 中文: packages/core/session/src/known-event-types.ts 中的 KNOWN_SESSION_EVENT_TYPES 是由 scripts/gen-persistence-catalog.ts 生成的静态集合,只收录仓库内的 SessionEventMap 成员。生成文件自身的注释写明:仓库外插件的自定义事件「按构造不在列表内」,且「为它们提供的注册面推迟到出现这样的消费者」——本插件正是第一个这样的消费者。 English: KNOWN_SESSION_EVENT_TYPES in packages/core/session/src/known-event-types.ts is a generated static set of in-repo SessionEventMap members (via scripts/gen-persistence-catalog.ts). The generated file's own comment states that downstream (out-of-repo) plugin events are outside the list "by construction" and that "a registration surface for them is deferred until such a consumer exists" — this plugin is that first consumer.
建议 / Suggestion 中文: 为下游会话事件类型提供运行时注册面(例如 ctx.session.knownTypes.register(...)),或提供受支持的方式让插件把自己的事件标记为 ignorable,使包含插件事件的持久化日志无需重新生成目录即可被解释。 English: Add a runtime registration surface for downstream session-event types (e.g. ctx.session.knownTypes.register(...)), or a supported way for a plugin to mark its own events ignorable, so a persisted log containing plugin events stays interpretable without regenerating the catalog.
症状 / Symptom 中文: 从客户端保存插件的 settings 命名空间失败:settings namespace "model-roles" is not exposed to configuration clients。 English: Saving a plugin's settings namespace from the client fails with settings namespace "model-roles" is not exposed to configuration clients.
根因 / Root cause 中文: 宿主 api-proxy 的 PRODUCT_SETTINGS_NAMESPACES 是一个固定集合;下游插件无法在不改 harness 的前提下把自己的命名空间声明为客户端可写。 English: The host api-proxy's PRODUCT_SETTINGS_NAMESPACES is a fixed set; a downstream plugin cannot declare its own namespace as client-writable without patching the harness.
建议 / Suggestion 中文: 让「可暴露命名空间列表」可扩展(插件自行注册命名空间),使第三方设置页无需打 harness 补丁即可持久化。 English: Make the exposable-namespace list extensible (plugins register their namespace), so third-party settings pages can persist without a harness patch.
All reactions