Repository navigation
【Bug】--patch 被用户设置层静默覆盖(silently overridden by user settings layer),--dump-config 报告失真 #6912
Replies: 3 comments
|
感谢反馈,这是一个配置作用域隔离的问题。~/.dsh/settings.yaml 最初是为 Web 端的用户设置引入的,后来 Settings 被挂载到了共享 base,使 headless 也读取了这份设置,并在 profile 配置合成之后再次覆盖模型选择,导致 --patch 和 --dump-config 的结果与实际运行不一致。我们计划将 Settings 的默认挂载限定在 Web,headless 使用合成后的 profile 配置及命令行覆盖,不再受 Web 设置影响。 |
|
补一个同类案例,说明这不止影响 另一个受害 section:
|
|
我们在无人值守(headless/自动化)面反复踩到同一机制,补三个实证+一个诉求,供本讨论参考。 实证 1:与本报告同构的 headless 静默降级。 用户层存在 实证 2:委派/subagent 面的同族缺口(shipped 源码)。 实证 3:交互面已有 fail-closed,自动化面没有。 providers 文档对「已保存默认指向已删除 provider」有显式阻断(composer 显示 Select model 并阻止输入);而无人值守面省略模型时静默回落交互默认。同一语义、两面不一致。 外部同族实案(佐证非孤例): OpenHands/software-agent-sdk#4494——自动化任务 诉求(按优先级):
另:看到维护者 2026-09-19 的计划(Settings 默认挂载限定 Web、headless 用合成 profile+命令行覆盖)——方向完全同意;补充请求是让该隔离覆盖委派/subagent 组装层,并把 effective 路由纳入报告,无人值守面即可闭环。 关于写入完整性(用户设置写盘裁掉无关 namespace):我们只在机制层确证(整体替换语义),尚未坐实触发条件,不敢妄下断言;若可分单跟踪,愿意补最小复现。 以上结论来自本机两周实测(交互默认 14 天内被重写 9 次、3 次成灾:无人值守任务秒败/漂移/批量投递失败)。需要最小复现细节可以继续补。 |
Uh oh!
There was an error while loading. Please reload this page.
中文
环境
0.1.6-alpha.1(npm i -g @deepseek-ai/dsh安装)期望与实际行为
--help把--patch描述为 "extra patch-list overlay applied after the profile layer",字面理解应当"覆盖 profile 层"。我期望--patch里对agent-default-model的覆盖能决定 headless 运行实际使用的模型。实际发生的是:一旦用户层(
~/.dsh/settings.yaml,由 UI 里选择默认模型 /saveSelection写入)存在agent-default-model段,用户层会在运行时静默胜出,--patch的值被降级为兜底默认值。全程没有任何警告,--json事件流里也没有任何字段能暴露实际生效的模型。最小复现
同样的 CLI 调用,仅仅因为看不见的 global 状态(
~/.dsh/settings.yaml)就服务了不同的模型。根因(来自打包后的插件源码)
@deepseek-ai/dsh-agent-default-model/lib/index.js把组合树里的配置项作为兜底默认值安装,然后让 settings provider 的用户层在运行时实时替换它:所以优先级是刻意设计的:用户层 >
--patch> profile bundles。我理解"用户显式选择优先"对交互式使用是合理的 UX——问题在于对 headless / 自动化场景,这一切都是静默且不可检测的。为什么这是问题(两个具体缺陷)
--dump-config报告了一个不会运行的配置。--help说--dump-config打印 "the composed profile tree",并把它和--dump-default-config("without its user layer or --patch overlays")对比——强烈暗示--dump-config包含用户层。实际并不包含:上面第 3 步打印deepseek-official/deepseek-flash,第 4 步却实际运行kimi-coding/k3-256k。官方提供的"看生效配置"工具给出了错误答案,排查这种问题非常痛苦。自动化无法信任自己的注入。 我们用 headless 模式(
--profile headless --json)驱动无人值守的修复流水线,并通过--patch钉死模型。某天有人在 dsh UI 里设置了默认模型后,我们所有的运行都悄悄迁移到了另一个 provider/model 上。直到预期 provider 的用量面板一片空白才发现。对一个明显面向自动化的 headless/JSON 模式来说,"服务的模型 ≠ 请求的模型、且无任何信号"是最糟糕的失败形态。建议
--json事件流里输出实际生效的 provider/model(比如放在session事件里),让调用方可以核对;--patch的某项被用户层覆盖时,在 stderr 打警告;--dump-config反映用户层的效果,或新增--dump-effective-config;--patch> profile bundles > 内置默认值。可提供更多日志或协助测试修复。感谢 dsh 团队的工作!
English
Environment
0.1.6-alpha.1(installed vianpm i -g @deepseek-ai/dsh)Expected vs. actual
--helpdescribes--patchas "extra patch-list overlay applied after the profile layer", which reads as "wins over the profile". I expected a--patchentry foragent-default-modelto determine the model a headless run actually uses.What actually happens: once the user layer (
~/.dsh/settings.yaml, written via model selection in the UI /saveSelection) contains anagent-default-modelsection, the user layer silently wins at runtime and the--patchvalue is demoted to a fallback default. There is no warning, and the effective model is not exposed anywhere in the--jsonevent stream.Minimal repro
Same CLI invocation serves a different model depending on invisible global state (
~/.dsh/settings.yaml).Root cause (from the bundled plugin source)
@deepseek-ai/dsh-agent-default-model/lib/index.jsinstalls the composed config entry as a fallback default and then lets the settings provider's user layer replace it live:So the precedence is by design: user layer >
--patch> profile bundles. I understand "user's explicit choice wins" is reasonable UX for interactive use — the problem is the silent and undetectable part for headless/automation use.Why this hurts (two concrete defects)
--dump-configreports a config that will not run.--helpsays it prints "the composed profile tree" and contrasts with--dump-default-config("without its user layer or --patch overlays") — strongly implying--dump-configincludes the user layer. It does not: step 3 above printsdeepseek-official/deepseek-flashwhile step 4 actually runskimi-coding/k3-256k. The one tool meant for "what will my config be" gives the wrong answer, which makes debugging this a real pain.Automation cannot trust its own injection. We drive dsh headless (
--profile headless --json) from an unattended bug-fixing pipeline and pin the model via--patch. After someone set a default model in the dsh UI, all our runs silently moved to a different provider/model. We only noticed because the expected provider's usage dashboard showed nothing. For a headless/JSON mode that is clearly aimed at automation, "served model ≠ requested model, with no signal" is the worst kind of failure mode.Suggestions
--jsonstream (e.g. in thesessionevent), so callers can verify what actually served.--patchentry is shadowed by the user layer.--dump-configreflect the user layer's effect, or add a--dump-effective-configthat does.--patch> profile bundles > built-in defaults.Happy to provide more logs or test a fix. Thanks for the great work on dsh!
All reactions