dsh-theme-rheostat:随模型与推理等级换挡的 DSH「滑动变阻器」皮肤

前言

DSH 的理念是「一切皆插件」,外观自然也不例外。但如果你日常在 deepseek-v4-flash 和 deepseek-v4-pro 之间切换、也会调整推理等级,界面上并没有与挡位对应的视觉反馈,不同会话看起来是一样的。

nineandnine-9 写的 dsh-theme-rheostat 解决的就是这件事:把当前会话的模型 + 推理等级映射成四个挡位的外观,强调色、光晕、输入框上方的指示条都跟着挡位走。和常见的静态皮肤不同,它的外观不是写死的一套配色,而是由会话状态驱动;实现上它与 README 里对照的 maid-atelier 皮肤同构,不注册完整主题。下面按四挡外观、实现原理、安装与定制的顺序介绍。

这是什么

dsh-theme-rheostat 在社区目录里归类为「趣味换装」,一句话定位:根据当前会话的模型 + 推理等级,把界面切成四个挡位的外观,并在输入框上方显示挡位指示条。

隐喻是「滑动变阻器升温」:flush 走冷色系(蓝 → 靛),pro 走暖色系(琥珀 → 炽红),从「强」到「超强」在各自色系内升温并加宽光晕。

四挡外观

四个挡位的对应关系如下,每挡提供浅色 + 深色两套强调色:

挡位 模型 推理等级 强调色(浅色 / 深色) 光晕
flush-strong deepseek-v4-flash high(强) #2563EB / #60A5FA
flush-max deepseek-v4-flash max(超强) #4F46E5 / #818CF8
pro-strong deepseek-v4-pro high(强) #D97706 / #FBBF24
pro-max deepseek-v4-pro max(超强) #DC2626 / #F87171

当前只映射 high(强)与 max(超强)两挡推理等级;未知或缺失的 reasoningEffort 会回落到 high

实现原理

插件整体做三件事:注入一份 CSS、给输入框卡片加光晕、在官方插槽上挂挡位指示条。分别说明。

变色:覆盖语义 token

插件注入一份 CSS,用 body[data-dsh-rheostat][data-rheostat-level="…"] 选择器覆盖 --dsw-alias-brand-primary--dsw-alias-border-l2 等语义 token,深色模式用 [data-ds-dark-theme] 区分。它不注册完整主题,所以不会在外观设置的主题列表里多出一项。

光晕:输入框卡片

同一份 CSS 对 [data-composer-card](对话输入框卡片的稳定 DOM 钩子)按挡位写入 box-shadow 光环和外发光,四个挡位的光晕强度不同。

挡位指示条:官方插槽

指示条占用官方插槽 conversation.input.dock(输入框卡片正上方的整行)。组件用 React useSyncExternalStore 订阅当前会话的 ctx.modelDirectories.directoryFor(sessionId).store,读取 { model, reasoningEffort },解析成挡位后把 data-rheostat-* 属性写到 <body>——上面的 CSS 选择器正是靠这些属性生效。

鲸鱼滑片

挡位条上方有一条四段色块分区的连续滑轨,滑块是一只卡通鲸鱼,支持拖动、点击、方向键切换模型与推理等级。四张挡位 PNG 以 base64 内嵌进 src/client/assets.generated.ts,由 scripts/embed-assets.mjs 生成。

安装与启用

README 给出的安装方式是本地 link + profile bundles 手动配置,没有 registry 安装命令,所以要先在本地构建产物:

cd dsh-theme-rheostat
pnpm install      # 只需 tsdown
pnpm run assets   # assets/ 里 PNG 改动后重新生成 base64 资产
pnpm build        # 产出 lib/index.js + lib/client.js

构建产出 host 半的 lib/index.js 和 client 半的 lib/client.js。然后把包挂进你的 web profile:

1、在 profile 的 package.json(如 C:\Users\rzh15\.dsh\profiles\web\package.json)的 dependencies 里加一行,link 路径按你本地仓库的实际位置改:

"@dsh-external/dsh-theme-rheostat": "link:E:/dsh-workplace2/dsh-theme-rheostat"

2、在同一个文件的 dsh.profile.bundles 数组里追加:

"@dsh-external/dsh-theme-rheostat"

3、安装并重启 web:

dsh plugin --profile web install
dsh web

dsh plugin --profile web install 等价于把参数转发给 profile 目录下的 pnpm。也可以一条命令加包(再手动补 bundles 行):

dsh plugin --profile web add "link:E:/dsh-workplace2/dsh-theme-rheostat"

定制挡位

经过上面的步骤,插件就挂进 profile 了。想调整行为,主要动三个文件:

  • 配色和光晕:编辑 src/client/levels.tsLEVELS,每挡有 accent / ring / glow / spread 四组参数。
  • 模型匹配:modelMatch 是对 ModelSelection.model 做大小写不敏感的子串匹配,当前是 v4-flush / v4-pro;如果你 catalog 里的模型 id 不同,改这里即可。
  • 文案:指示条上的文字在 src/client/index.tszh / en 字典里。

改完源码或 PNG 后,重新跑一遍 pnpm run assetspnpm build,再重启 web 生效。

适用场景与注意

适合的人群:在 flash / pro 与强 / 超强之间切换、希望挡位一眼可见的人,或者单纯想给界面换装的用户。除鲸鱼滑片可以切换模型与推理等级外,插件的其余改动都在外观层。

使用前有几点需要知道:

  • 体积:四张挡位图是 1024×1024 原图,base64 内嵌后 lib/client.js 约 6.3MB,一次性加载。在意体积的话,先把 PNG 压到 ~128px,再跑 pnpm run assets
  • 皮肤共存:插件只覆盖少量语义 token 和输入框光晕,作为「强调层」叠加在现有皮肤上。如果与覆盖同一批 token 的皮肤同时启用,由 CSS 选择器特异性决定谁生效——本插件的 body[data-dsh-rheostat][data-rheostat-level] 特异性更高。
  • 等级映射:只映射 high(强)与 max(超强),未知 / 缺失的 reasoningEffort 回落到 high
  • 平台与依赖:package.json 声明 client platform 为 web,注入 @deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-ui-conversation@deepseek-ai/dsh-client-ui-model-selection 四个依赖。
  • 权限与许可证:插件以当前 dsh 进程的权限运行,安装前建议先读一遍源码。package.json 标记 private: true 且未声明 license 字段,README 也没有给出许可证信息,是否能在你的场景里使用需自行确认。

结尾

dsh-theme-rheostat 的价值在于把「当前会话跑在哪个模型、哪一挡推理」变成可见的界面状态:四个挡位、两套色系、一条输入框上方的指示条,外加一只可以拖动的鲸鱼。想试的话,从下面的入口进入:

  • 社区目录页:https://www.skillhub.cn/plugins/nineandnine-9/dsh-theme-rheostat
  • GitHub 仓库:https://github.com/nineandnine-9/dsh-theme-rheostat
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜