dsh-default-reasoning-efforts
Manifest validAdd the three-tier `high` / `xhigh` / `max` `reasoningEfforts` to every model in DeepSeek Harness that doesn't declare `reasoningEfforts`, as a Host plugin: zero runtime dependencies, no build steps, idempotent, writes go through the normal `configEditor` path and are deliberately kept outside the HMR transaction.
dsh-default-reasoning-efforts
给 DeepSeek Harness(DSH)用的 Host 插件:
所有没有声明推理等级的模型,自动获得 high / xhigh / max 三档。
配套 dsh-codex-effort-slider 用: 滑条能不能滑到某档,取决于模型有没有那一档;本插件负责把缺的档位补上。
为什么必须改配置(而不是在界面上"造"三档)
档位不是 UI 变出来的,是 Host 侧 LLM 适配器报出来的模型能力:
profile 配置 reasoningEfforts
→ dsh-llm-pi-ai: resolveModelReasoning() → pi-ai thinkingLevelMap
→ getSupportedThinkingLevels() → reasoningInfo() → ctx.llm.resolveModelInfo()
→ 模型目录(浏览器)→ 官方菜单「推理等级」那一行 / 滑条刻度
配置里没写 reasoningEfforts 的模型,解析结果是 reasoning: false
(手写声明的模型不在 pi-ai 内置目录里,没有可继承的能力)。后果是双重的:
- 模型目录里没有档位 → 官方菜单连「推理等级」那一行都不渲染 → 滑条无处可挂;
- 就算客户端硬塞一个档位,
dsh-llm在resolveCallWithInfo()里也会以UNSUPPORTED_REASONING_EFFORT直接拒掉这次请求。
所以唯一端到端成立的做法是把档位写进 provider 配置,让适配器自己认。
它做什么
apply() 里做一次幂等、可重入的配置补齐:
- 等目标 entry(默认
@deepseek-ai/dsh-llm-pi-ai)出现在configEditor里(退避重试约 30 秒); - 读它的有效配置,找出
providers.<route>.models[]里所有reasoningEfforts未声明的模型; - 用官方
ctx.configEditor.edit()写回 profile patch (走 Loader 正常路径:校验 → 原子写 → 失败回滚;YAML 注释保留); ctx.emit('llm/adapters-updated')—— 已连接的浏览器会立刻重拉模型目录,不用刷新页面。
幂等:没有任何要补的模型时,一个字节都不写,也不会触发重载循环 (档位已经等于目标档位的模型会被跳过,所以第二次运行是彻底的 no-op)。
热装即可生效(不用等重启):写配置这一步被刻意放在 HMR 事务之外执行。
原因是实测踩到的坑 —— configEditor.edit() 内部是 hmr.runExclusive(),而
runExclusive 一旦发现自己已经处在一次 HMR 事务里就直接拒绝
(HMR transactions cannot be nested);插件热装/热启用时 apply() 恰好跑在
这样一次事务里,而且 hmr 用的是 AsyncLocalStorage,上下文会顺着 setTimeout
一路传下去 —— 所以"晚一点再写"根本逃不出去(第一版插件就是这么静默失败的)。
现在照官方 hmr.watchConfig 的做法用 AsyncLocalStorage.exit() 把写入放到事务外,
拿不到就退回普通调用;写入被拒时还会退避重试(约 37 秒),绝不静默吞掉。
默认规则
| 模型状态 | 默认行为 |
|---|---|
没写 reasoningEfforts | 补上 {high: high, xhigh: xhigh, max: max} |
写了 reasoningEfforts: false | 不动(显式声明"这个模型没有推理",视为用户的明确选择) |
| 写了别的档位表 | 不动 |
| 写了但恰好就是这三档 | 不动(保证幂等) |
可选配置
$DSH_HOME/dsh-default-reasoning-efforts/config.json(不存在就用内置默认值,改完下次检查即生效):
{
"enabled": true,
"levels": { "high": "high", "xhigh": "xhigh", "max": "max" },
"targets": ["@deepseek-ai/dsh-llm-pi-ai"],
"providers": [],
"includeDeclared": false,
"dryRun": false
}
| 键 | 含义 |
|---|---|
enabled | false = 完全不动手(插件照常加载,只跳过补齐) |
levels | 要补的档位表:键只能是 pi-ai 的七档名 off/minimal/low/medium/high/xhigh/max,值是线上拼写(off 允许 null = 不发送该参数) |
targets | 要管的 entry 包名(默认只动 pi-ai 适配器;别的适配器 schema 不同,别乱加) |
providers | provider route 白名单([] = 全部) |
includeDeclared | true = 连已声明(含 false)的模型也覆盖成 levels |
dryRun | true = 只在日志里说会改什么,不写文件 |
pollSeconds | 兜底自检间隔(秒,默认 30,0 = 关掉)。见下 |
新加的模型什么时候会被补上
| 时机 | 会不会补 |
|---|---|
| 每次 DSH 启动 | 一定。启动那次检查会扫全部模型,缺档位的一个不落 |
| 运行中在设置页新增模型 | 会,最多 pollSeconds(默认 30 秒)内 |
运行中手改 cordis.patch.yml 文件 | 要等下次启动(实测:这个环境里 HMR 的配置监视没把文件改动送进运行中的 Loader;反正下次启动会补) |
插件被禁用(enabled: false) | 不补 |
为什么要有 pollSeconds 这个自检:宿主确实会发 llm/adapters-updated /
settings/document-updated / hmr/reload 这几个事件(插件都订阅了),
但"事件有没有送达"不在本插件的控制范围内 —— 与其把正确性押在上面,
不如按固定间隔自己看一眼:有活就干,没活就是一次纯读的 no-op。
30 秒一次的读取成本可以忽略,换来的是"新加的模型一定会被补上"这个确定性。
配置非法时会退回内置默认值并在日志里说明原因(不静默)。
回执:它到底做了什么
每次检查的结论会写到 $DSH_HOME/dsh-default-reasoning-efforts/status.json
(只在结果变化时写,不是每次事件都动磁盘):
{
"at": "2026-10-14T01:41:46.342Z",
"pid": 23388,
"enabled": true,
"targets": ["@deepseek-ai/dsh-llm-pi-ai"],
"levels": { "high": "high", "xhigh": "xhigh", "max": "max" },
"status": "patched",
"matchedEntries": ["llm-pi-ai"],
"changedModels": [{ "provider": "local", "model": "step-5-preview", "levels": { "high": "high", "xhigh": "xhigh", "max": "max" } }],
"wrote": true,
"error": null
}
status 取值:patched(补了)/ no-change(没活可干)/ dry-run / waiting-entry
(目标 entry 还没出现)/ read-failed / write-failed / crashed / disabled。
排障第一步就是看这个文件 —— 它比宿主日志好找,也比"猜插件跑没跑"可靠。
安装
# 面板:设置 → 插件 → 添加插件 → 填仓库地址或本目录绝对路径
# 或命令行(非 desktop profile):
dsh plugin --profile web add github:junjundesk/dsh-default-reasoning-efforts
# 本地开发时直接链本目录:
dsh plugin --profile web add link:"<本目录的绝对路径>"
零运行时依赖、无构建步骤(只用 node 内置模块),解开就能装。
测试
node test/plan.test.mjs # 43 项断言:档位规范化 / 配置规范化 / 补齐规划 / HMR 事务逃逸 / 端到端接线
测试里有一份假 configEditor:edit() 会把新配置落到 entry 上,所以"第二次运行必须
一个字节都不写"这件事是被真断言守着的,而不是靠肉眼。其中一项是回归测试:用真的
AsyncLocalStorage 模拟 hmr 的事务上下文,并让 edit() 在事务内直接抛
HMR transactions cannot be nested —— 它复现了第一版插件的真实故障,也守着修复不被改回去。
已知边界
- 只改
providers.*.models[].reasoningEfforts这一个字段,其它字段原样保留。 - 补的是声明,不是"让模型真的会思考":端点是否接受
xhigh/max由上游决定, 与你在同一个 provider 里给别的模型写的那套拼写保持一致。 targets默认只含 pi-ai 适配器。别的适配器(如官方 DeepSeek)有自己的固定档位表, 强行补档位可能让请求被上游拒掉。- 卸载/关掉后,已经写进 profile patch 的
reasoningEfforts不会自动删掉 (那是你的配置,插件不替你回滚)——想恢复就把那几行删掉。
许可
MIT。
Comments
Loading…
Similar plugins
by HaoyueQin
Reasoning-effort editing for third-party models in DeepSeek Harness: per-model thinking levels with a knowledge base + protocol inference, edited inside the official Models page card.
★ 56
↓ 995/wk
MIT
TypeScript
Oct 13, 2026
dsh plugin --profile web add dsh-better-reasoning-effortby AI-Galaxy-GPU
DeepSeek Harness 插件:在 Web GUI 中为会话选择模型的推理程度(reasoning effort),星光推理选择器一键切换 Off / 默认 / High / Max。
★ 0
JavaScript
Aug 15, 2026
dsh plugin --profile web add dsh-effortby chuling-lingling
给 DeepSeek Harness (dsh) 的第三方中转模型补上「推理等级」选择器 —— 和官方模型在聊天框里的体验完全一致。
★ 0
MIT
JavaScript
Sep 11, 2026
dsh plugin --profile web add dsh-plugin-reasoning-effortsby peterwangze
DSH (DeepSeek Harness) plugin: unified default reasoning level (thinking effort) for all models — per-model defaults with capability probing, live call statistics, one-command install via dsh plugin
★ 3
JavaScript
Sep 12, 2026
dsh plugin --profile web add dsh-reasoning-levelby Toukaiteio
A DeepSeek Harness plugin that allows you to change the reasoning effort of custom models in WebUI.
★ 4
MIT
TypeScript
Aug 13, 2026
dsh plugin --profile web add dsh-effort-tweakby icrefin
Per-model reasoning effort levels inside DeepSeek Harness Settings -> Models, written to that model's reasoningEfforts in cordis.patch.yml.
★ 0
MIT
TypeScript
Oct 11, 2026
dsh plugin --profile web add dsh-model-reasoning-levels