dsh-liang-calibrator
滑动变祖器 31 档 —— 把 DeepSeek Harness 输入框里的「模型选择 + 推理等级」控件,换成一台物理课本里的滑动变阻器。
拖滑片 = 同时切换模型与思考强度;滑动时对应档位的形象图会铺在 DSH 背景上,停手 5 秒后自动淡出。
档位图可以逐档换成本机自定义图片,31 档的名字也都能改。
折叠态
界面
1. 折叠态:直接写清当前路由
输入框里只占一个小胶囊,显示 提供商 · 模型 · 思考强度(过长省略,悬停看完整内容)。
模型目录还没就绪、或会话被锁定时,旁边会直接说明原因并给出「重试」。
2. 点三角展开:滑动变阻器
铜线密绕瓷管 + 金属导轨 + 端板接线柱(C/D)+ 瓷管两端红色接线柱(A/B)+ 压板楔子滑片,
左侧到滑片的那段铜线微微发亮表示"接入电路"的长度。
展开面板
第一行是模型名(最大最亮),右侧是「梁名 + 带符号分值」,第二行是 提供商 · 思考强度。
点面板外、按 Esc、或点右上角 ✕ 都能收起。
3. 设置:四页 —— 路由 / 名字 / 背图
按状态设置
按档位设置
名字设置
背图设置
- 按状态 6:小难梁 / 牢梁 / 梁子 / 梁圣 / 梁神 / 梁祖,各一条路由,整段生效;
- 按档位 31:
-15 … 00 … +15 逐档一行,只覆盖你想改的那一档;
- 名字 31:给 31 档各起一个名字;相邻档位写成同一个名字就合并成一段(跨段同名不合并),
滑杆下方的站名行跟着变;留空用默认梁名;
- 背图 31:31 档各可指定一张自定义图片,滑动到该档时铺满窗口;留空用内置档位图,
同一张图给多个档位只存一份;
- 路由三列都能手填(provider / 模型 id / 思考强度),带自动补全但允许任意值 —— 接自己的 API 直接写进去即可;
- 灰色占位符显示自动分档会选什么,所以不改也能一眼看出每档接的是哪条路由;
- 优先级:逐档 > 按状态 > 自动;provider 不在当前目录时整行描琥珀色提示(仍会提交,由平台裁决);
- 右上角一键清空,按钮随页变:全部自动 / 全部默认 / 全部内置;设置只存在本机浏览器。
4. 滑动时的背景:不影响你原来的壁纸
背景效果
档位图只做临时叠加:
- 这一张图默认是内置档位图,也可以是你给这一档指定过的自定义图(见上节「背图 31」);
- 它挂在
body 的第一个子节点、z-index: -1,位置在你原来的壁纸之上、DSH 界面之下;
- 显示期间把控件到
body 之间的面板临时置为透明,配合图层自带的压暗层保证文字可读;
- 停手 5 秒后自动淡出(淡出 320ms),随后原样还原所有被改过的样式;
- 不修改、不替换你设置的壁纸,也不写入任何持久状态 —— 关掉插件后界面与原来完全一致。
5. 模型不可用的自救
会话当前选择的模型如果不在可用目录里,DSH 会在发送时拒绝:session/model-unavailable: Select an available model before sending a message.
这种状态不会自己恢复,所以插件做了四道防线(其中两条是 0.9.3 补的):
- 提交前校验可用性:手填的 provider / 模型必须当前真的在目录里。给某几档指定过
cmd,
之后那个 provider 因为改端点、丢密钥而公布不出模型时,插件不会再把它写进会话,而是就地提示
「cmd 当前不可用:no API key for provider route "cmd"」。手填自建 API 的场景(目录里暂时还没有
这个 provider)默认同样拦下,但给一个 「仍要使用」 显式放行。
- 提交前校验等级:目录里查得到该模型时,显式等级必须是它公布的之一。手填了不存在的等级
(例如目录只有
off/low/high/max、你写了 medium)不会写进会话,而是提示可选值。
- 自动档位默认优先
deepseek-account:同一个模型 id(如 deepseek-flash)往往同时被
deepseek-official(需要 API Key)与 deepseek-account(登录即用)公布,而"目录里有"≠"请求能成功"
—— 没配密钥的 api-key provider 照常公布模型,请求时才报
MISSING_CREDENTIAL: no API key for provider route "deepseek-official"。
客户端拿不到"某 provider 是否配了密钥"这个信号(宿主侧 hasProviderApiKey 没有 Remote 暴露),
所以插件跟 DSH 自己的规则对齐:没配 API Key 时用 deepseek-account
(对应宿主的 initializeDefaultModel)。设置里可关闭该开关,改为沿用你当前所在的 provider。
- 不可用提示 + 一键修回:宿主明确回报当前选择不可用时(目录里
routable === false),
输入框旁边出现红字 「当前模型不可用」(带上宿主给的失败原因)和 「修回可用档位」 按钮:
点一下会清掉挡在这条路由上的本机设置(逐档 + 该档所属状态),跳到最近一条确实可提交的档位并提交。
事故记录:本插件踩过两个连着的坑 —— ① 把某几档指到 cmd 后,那个 provider 一度公布不出模型,
插件照样写进会话,于是之后每次发送都被 session/model-unavailable 拒绝;② deepseek-flash
同时挂在 deepseek-official(没配密钥)与 deepseek-account 两组下,梯子取了排在前面的 official,
滑动时把本来能用的 account 路由悄悄换掉,下次发送就报 MISSING_CREDENTIAL。
上面四道防线(其中两条是 0.9.3 补的)就是照着这两个场景补的。
本机数据都存哪
- 路由设置:
localStorage 的 liang-calibrator:stages;
- 名字:
localStorage 的 liang-calibrator:names(31 项,读入时去首尾空格、截 24 字符);
- 背图:图片先压到长边 ≤ 1920 的 WebP,按内容哈希存进 IndexedDB(库
liang-calibrator / store images);
档位 → 图片 的映射在 localStorage 的 liang-calibrator:images;不再被任何档位引用的图片会自动回收;
- 排查现场:最近 8 条插件错误落在
localStorage 的 liang-calibrator:errors;
- 以上都只在本机浏览器里,不上传、不随插件分发。
档位语义
31 档由 buildLadder() 按当前模型目录动态生成:
- 模型分档:按
MODEL_TIERS 顺序(由弱到强)把六个状态带平均切给目录里实际存在的模型。
某个 provider 没配置或掉线时它的段会被跳过,帧区间自动重新平均给剩下的模型 —— 梯子只会变短,
滑杆不会失效。改顺序或增删模型只改 MODEL_TIERS 一个数组。
- 思考强度:每个模型覆盖的那段帧,按该模型在目录里公布的等级均分,从弱到强单调递增;
模型明确不提供等级时(例如
dsh-llm-pi-ai 对没声明 reasoningEfforts 的模型返回 reasoning: false),
这一段只提交模型本身,不带 reasoningEffort。
本机 DSH 0.2.0-rc.2、三个模型都在时(flash / pro 各有 off/low/high/max,cmd 不分等级):
| 帧 index | 分值 | 状态 | 模型 | 思考强度 |
|---|
| 0-4 | -15..-11 | 小难梁 | deepseek-flash | off |
| 5-8 | -10..-7 | 小难梁/牢梁 | deepseek-flash | low |
| 9-13 | -6..-2 | 牢梁/梁子 | deepseek-flash | high |
| 14-17 | -1..+2 | 梁子 | deepseek-flash | max |
| 18-23 | +3..+8 | 梁圣 | deepseek/deepseek-v4.1-flash(cmd) | 不设置 |
| 24-25 | +9..+10 | 梁神 | deepseek-v4-pro | off |
| 26-27 | +11..+12 | 梁神 | deepseek-v4-pro | low |
| 28-29 | +13..+14 | 梁神 | deepseek-v4-pro | high |
| 30 | +15 | 梁祖 | deepseek-v4-pro | max |
同一组合占据连续若干档:区间内拖动只换画面、不重复发请求;外部改变模型(/model 命令、设置页)时,
滑杆会回位到对应区间的代表档位。当前选择不在梯子上时,芯片回退显示真实路由,滑杆仍可跳到任意档位。
名字(31 档可改名、相邻同名合并成段)与背图(逐档自定义)都只是显示层,不改变上面这张映射表。
安装
# 从 Release 安装
dsh plugin --profile <profile> add https://github.com/TerryYu12/dsh-liang-calibrator/releases/latest/download/dsh-liang-calibrator-0.9.3.tgz
# 或本地 tarball
dsh plugin --profile <profile> add /path/to/dsh-liang-calibrator-0.9.3.tgz
<profile> 是你要装的 profile(通常是 desktop;用 dsh plugin --profile desktop add …)。
装好后 DSH 会把这个 bundle 追加进 profile 的 dsh.profile.bundles,客户端半部由 dsh-client-modules
作为 /plugins/dsh-liang-calibrator/client.js 提供。多数情况下无需重启即会热挂载;
若界面没变化,刷新页面或重启 Harness。
卸载:
dsh plugin --profile <profile> remove dsh-liang-calibrator
从源码构建 / 测试 / 截图
npm install
node scripts/fetch-frames.mjs # 可选:素材缺失时从上游补抓(仓库里已带)
npm run build # 生成 lib/index.js 与 lib/client.js(内嵌 31 帧,约 2 MB)
node verify-levels.mjs # 31 档 / 6 状态边界与梯子生成、名字分段与背图映射的纯逻辑
node render-test.mjs # jsdom + React 真渲染:21 个场景
node tools/screenshot.mjs # 重新生成 docs/ 里的 7 张界面截图(需要本机 Chrome/Edge)
npm pack
render-test.mjs 覆盖的 21 个场景包括:档位提交、段内不重复提交、目录未就绪与自愈重试、
锁定态、错误边界、背景图 5 秒淡出、注入面绝不抛错、折叠/展开/关闭、按状态与按档位两层设置、
逐档改名与同名合并、全梯同名、逐档自定义背图(含清除回退)、名字过多时站名行自动省略。
实现上有三条不能破坏的约束,改动前请先读 README 的对应注释:
① 客户端 inject 必须包含 remote / remote.session(Cordis 服务代理把 this.ctx 绑到调用方,
directoryFor() 内部会读它,漏了目录永远取不到);② 目录加载不能依赖注入函数的引用(否则渲染循环);
③ 插槽注入面绝不能抛异常(会被渲染器把整个入口退役,界面静默退回官方控件)。
素材与授权
本插件是对 Lichtspektrum/liang-intensity-calibrator
(滑动变祖器)的 DSH 化改造;控件结构参考了 HansLin911/dsh-liang-slider(MIT-0)。
assets/frame-00..30.webp 取自上游仓库的 public/frames/。依照上游仓库的处理方式,这些素材随仓库分发,
但——正如上游 README 所述——素材不随 MIT 协议共享:
media 与 public/frames 里的人像素材用于趣味演示,素材不随 MIT 协议共享。
复用或二次发布前,请确认你拥有相关肖像与素材的使用权。
本项目维护者不拥有这些图像中人物的肖像权,也不通过本项目授予任何与肖像、姓名、身份、公开权、隐私权、
商标、版权或其他第三方权利有关的许可。若需商业使用、再分发或制作衍生版本,请自行确认所在司法管辖区的
适用法律、素材来源及所需授权。如你是相关权利人并希望移除素材,请提 Issue 联系。
许可证
代码以 MIT-0 发布(不含 assets/ 中的第三方图像素材,见上节)。