dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH 推理等级补齐:为 API 地址非官方的自定义提供方实测出与官方同形的推理等级,每一档都在上游真实生效
为 API 地址非官方的自定义提供方,补齐与官方提供方同形的推理等级菜单, 并且保证每一档在上游真实生效——经实测探测,不可区分的档位不会出现在菜单里。
一句话:官方提供方的 Off / Low / High / Max 是适配器写死的;自定义提供方没有这份表, 所以菜单是空的。本插件把这份表实测出来再写回去。
项目地址:https://github.com/polan-prologue/dsh-reasoning-plus · 许可证:MIT
# 从 GitHub 安装(推荐:锁定 tag,升级由你决定)
dsh plugin --profile desktop add github:polan-prologue/dsh-reasoning-plus#v0.2.0
# 从本地目录安装(二次开发时用这个)
dsh plugin --profile desktop add <插件目录>
装完重启 DSH(新增插件行必须重启才生效),然后到「设置 → 模型」的插件区找「推理等级++」卡片。
DSH 里官方 DeepSeek 提供方(@deepseek-ai/dsh-llm-deepseek)把 Off / Low / High / Max
写死在适配器里,所以模型选择器里永远有推理等级菜单。
自定义提供方走的是 @deepseek-ai/dsh-llm-pi-ai。它的 reasoningInfo(model, defaultLevel)
在 !model.reasoning 时返回 {}——手工声明的模型拿不到任何档位信息,于是:
根因是「等级表来自 profile 的 reasoningEfforts 声明」。所以真正的修复就是写配置——
这一处写入同时喂给两条路径:菜单渲染(resolveModelInfo)与出网派发(wire dispatch)。
只做 UI 是假的,因为没有任何东西会真的改变请求。
off 在 OpenCode Zen 上必然 400,而在本地 wb 网关上是唯一可行的关闭方式。插件通过 profile 的 bundle patch 接入。安装后需要重启 DSH 才生效 (新增插件行必须重启;改已有插件的客户端 bundle 才支持热重载)。
重启后在「设置 → 模型」的插件区会出现「推理等级++」卡片。
实测通过 / 实测进行中 / 提供方配置已变更… / 尚未实测),
不需要点任何按钮就能看到结果。autoApply 时自动接管;否则点「接管」把这些档位写进 profile。unset 移除,不会写回一个假的默认值)。判据是配置指纹(内容),不是"什么时候测的"、更不是提供方的 ID / 显示名:
baseURL、api、apiKeyEnv、models[].id(按序)、compat(不含本插件自己
写进去的键)、probeMaxTokens、recommendWhenInconclusive 算出;<DSH_HOME>/storages/reasoning-plus/probe-memo.json);probeReuseMs 设成正数即可(0 = 不设期限,默认)。实测踩过的坑,直接决定了探测器的设计:
MIN_RATIO_DELTA = 0.25)才算「可区分」。max_tokens=8192 时,
baseline 与所有档位全部落在 8191/8192——测量无效,不是档位无用。
探测器会先标定 baseline,撞顶(baselineMedian ≥ 0.9 × maxTokens)时
沿提示词阶梯换更轻的提示词重试至多 3 次;仍撞顶则如实返回
ok:false, ceilingBound:true,不产出任何档位。界面会显式标示撞顶状态并禁止接管——因为此时的结论不可信。
| 字段 | 含义 |
|---|---|
enabled | 总开关 |
autoApply | 是否在插件加载时自动完成一轮接管(默认 false,生效时机见下) |
officialHosts | 视为官方的域名(不接管这些) |
only / skip | 白名单 / 黑名单路由 |
defaultEffort | 菜单的默认档位 |
manageDeclared | 已显式声明 reasoningEfforts 的模型是否也接管(交还时还原原值) |
recommendWhenInconclusive | 测不出可区分档位时,是否仍按官方同形给出完整阶梯 |
probeEnabled | 是否允许发起真实探测请求 |
probeTimeoutMs | 单次探测超时(默认 90000:实测单次 6–48 秒) |
probeMaxTokens | 探测请求的 max_tokens(撞顶判定基于它,默认 8192) |
probeDeadlineMs | 整轮探测的总预算(默认 300000):超预算即停止发请求、用已有数据出结论 |
probeConcurrency | 并发度(默认 4):轮次各臂与关闭档候选共用这一个上限 |
probeReuseMs | 结论的复用期限。0(默认)= 只要配置指纹一致就一直复用 |
probeCacheMs已被probeReuseMs取代(旧字段不再生效,配置里留着它会得到一条告警)。 改名的理由:旧字段的0是"每次都重测",新语义的0是"不设期限"——同一个名字下把0反过来解释,会让老配置静默变成相反的行为。
autoApply 的生效时机autoApply 的语义是在插件加载时自动完成一轮接管,而不是常驻监听配置变化:
autoApply 并重启 DSH 后,插件在加载时会自动筛出可接管的路由、按需实测、并把实测得出的档位写入 profile;之所以不做成常驻监听:监听 volatile 配置变化需要额外的订阅与去重,还要处理"自动接管与手动接管互相打架"的情形,会引入新的失败面。当前实现让契约里"宿主逻辑在没有 webServer 时同样能自动接管"这一条真正成立(已在无 webServer 的组合下实测通过)。
注意:开启后每次 DSH 启动都会检查一遍,但只有"没有有效结论 / 配置改过"时才真的发探测请求
(结论持久化在备忘文件里)。不想产生任何探测流量可关闭 probeEnabled。
管理路由前缀 /api/dsh-reasoning-plus(仅本机来源可访问):
| 方法 | 路径 | 作用 |
|---|---|---|
GET | / | 快照:路由列表、判定、已有探测结论、正在进行的实测、配置、警告 |
POST | /probe | 对某条路由发起真实探测(force: true 表示不管指纹、强制重测) |
POST | /ensure | 确保该测的测了:立即返回 { started, skipped },实测在后台跑 |
POST | /takeover | 写入实测得出的档位声明 |
POST | /revert | 移除本插件写入的声明 |
PUT | /settings | 更新插件配置 |
完整字段契约见 docs/接口契约.md(§13 是本节这批改动的契约)。
probeEnabled。reasoning_effort: none
与 thinking:{type:"disabled"} 都返回 400,因此该路由不会提供 off 档。
这是如实反映上游能力,不是缺陷。cordis.patch.yml 可能被设置的恢复机制重写。 若接管结果被清掉,
重新进插件页点「接管」即可重建。probeReuseMs 设成正数定期失效。compat:优先用进程内的"用户原值记录";记录不在时(插件重载 /
进程重启)改用持久备忘里记下的"我们写过哪些键、写的是什么值"——当前值与之逐键一致才
移除。两者都没有时才退回实测结论的指纹比对(那条路径的边界见下)。告警会列出被删的键与
值,可手工恢复。compat 恰好与指纹完全相等),跨重启交还
会把它一并移除。取舍理由:反向选择(留下残留)会让插件写下的派发形态长期改变你后续自写
档位的线缆,危害更大。skipped(不改动任何配置)。
这种情况下告警文案里的「本插件未写入过这条路由」在少数情形下可能不准确(已记为低优先
文案问题)。# 全部测试
node --test "tests/*.test.mjs"
# 回溯注入:把"修复前的行为"逐条注入副本,确认新关卡真会红
node tests/falsify-injections.mjs
注意:本仓库的测试不能用 node --test <目录> 形式运行(该形式会把目录当模块路径而失败),
必须用上面的 glob 形式或显式文件列表。
开发环境相关的坑与实测数据见:
docs/实测记录.md —— 原始实测数据docs/修复报告-13.md —— 配置指纹 / 持久备忘 / 主动实测 / 提速的
根因、真机 A/B/C 数据与回溯注入结论docs/开发踩坑记录.md —— 环境陷阱与事故复盘docs/接口契约.md —— 冻结的接口契约(§13 是"配置指纹 / 持久备忘 /
主动实测 / 提速"这一批改动的契约)