DeepSeek Harness 的模型菜单里有「推理等级」那一行,原本只能点开一个列表选档位。有个插件把它改成了一条可拖动的连续滑条:拖到哪一档,颜色、能量、星尘粒子就跟到哪。
好看是次要的。真正值得读的是它的另一面——这条滑条上所有「看起来是随机的」东西,都被压成了可以离线断言的常量。仓库里 272 项断言,其中一大半在守这些常量。
不新增入口,只改造已有那一行
插件没有往输入框工具行上加胶囊、加浮层,也没有自建面板。它做的事只有四步:给官方那一行写 4 个内联样式(height:auto、flex-wrap:wrap、padding-block:10px),再用 react-dom 的 portal 往行内 append 一个容器,滑条作为第二行铺满整行宽度。
官方的 label、value、chevron 一个没动,文字内容也一个字不碰。关菜单或插件卸载时,逐个还原。
这个选择的代价要写清楚:控制项活在官方菜单里,所以必须先点开模型菜单才能改档位,输入框工具行上没有常驻读数。收益是它不会和官方界面抢位置,也不会在官方改版时留下孤立的 UI。
语义锚点,不是哈希 class
前端插件最容易踩的坑是拿 class 做选择器。官方构建一换,class 前缀跟着变,插件当场失效,而作者往往几个月后才发现。
这个插件认的是四个语义属性:
| 锚点 | 官方产物里的形状 |
|---|---|
| 席 | button[aria-haspopup="menu"][aria-expanded="true"] |
| 菜单 | 席的 aria-controls → getElementById(…) |
| 目标行 | 菜单里 button[role="menuitem"] 的第 2 个(子面板用 menuitemradio,所以 menuitem 唯一标识根面板) |
| 归属 | 从自己的锚点向上找 [data-composer-card] |
第四项是最容易被忽略的一层:同一次会话里可能有好几个 composer,打开的那颗席必须在自己的 composer 里,否则滑条会插到别人的输入框上。
认不出任何一步就什么都不做——官方菜单保持原样,绝不会因为插件点不开。这种 fail-open 的写法在产品上是优点,在排障上是负担:官方改版后插件静默失效,不报错、不写日志,只能靠「菜单没变化」发现。
星空的第一版是错的
高档位会亮起紫色星云和 22 颗星尘粒子。第一版看起来没问题,直到有人把它连续看了一分钟:22 颗星排成了一条斜线。
原因不复杂。高度和相位取自同一个数——第 i 颗星的偏移都是 frac((i+1) × φ),黄金比 φ 让这个序列铺得很开,于是「越靠右的星越高」成立得非常彻底。作者量的相关系数是 0.999。
修法是把两件事拆开:相位继续用黄金比低差异序列(保证任意前缀都铺得开),高度改成一条确定性随机排列——哈希排序,不用 Math.random。为了让「会一直并排走」的两颗不至于凑成一坨,还自动挑一个盐值,保证相位相邻的两颗至少差 28% 轨道高度。
改完实测相关系数 −0.110,测试里加了断言守 |r| < 0.35,旧版会直接失败。
确定性这个词在这里是硬要求:Math.random 会让每次重渲染都跳一下,也没法离线断言。用哈希的话,同一个 index 永远得到同一个亮度系数,重渲染不跳变,测试里可以逐项校验。
聚集不是 bug,是数学
「有的星稍快、有的稍慢」听起来更好看。它的代价是:只要每颗星的时长不完全相同,相位就会缓慢互相错开,最终趋近随机分布——22 颗里总会有几对偶尔靠近。
作者没有把这件事藏着,而是量化了。轨道按 300×28px 模拟,两颗中心距小于 6px 记为「粘住」:
| 每颗星时长浮动 | t=0.5s | t=1s | t=2s | t=5s |
|---|---|---|---|---|
| ±8%(当前) | 1 | 7 | 9 | 17 |
| ±4% | 0 | 2 | 7 | 10 |
| ±2% | 0 | 0 | 2 | 11 |
| 0%(全同速) | 0 | 0 | 0 | 0 |
结论写进了 README:想彻底永不聚集,就把浮动设成 0,代价是所有星速度完全一致,少了层次。这个数字由常量 STARFIELD_DURATION_SPREAD 控制,随时可调。
这类「把审美问题翻译成参数问题」的写法,比任何形容词都有用——它让后来的人知道自己在调什么,也知道代价在哪。
对比度是算出来的
填充层是 linear-gradient(90deg, 蓝, 当前位置色):左端恒为蓝 #4d93f8,右端是当前位置的颜色,high 档 #9333ea、max 档深紫 #4c1d95。能量层(星云 + 扫光)的强度在第二档以前是 0,所以左半段是干净的蓝,往右才逐渐「通电」。
文字终点色 #8b5cf6 不是挑出来的,是试出来的:先用了更亮的 #c084fc,浅色主题下对比度只有 2.6:1,测试里的对比度断言直接拦下;换成 #8b5cf6 后白底 4.23:1、深底 #1b1c20 4.02:1,两种主题都读得清。
Off 档是个例外:两个界面里都保持官方灰。实现方式是 valueColorFor 返回空串——空串等于不写内联色,也就等于退回官方原本的颜色。档位是不是「关」按 id 和 name 都认(off / none / 关闭 / 无,大小写与空格不敏感)。
写入要节流,失败要回滚
拖动是一个高频事件。1 秒内 60 次 pointermove,如果每次都写回档位,等效于对宿主目录做 60 次写操作。
实现里叠了三层:同档位去重、在途合并、120ms 降频。结果是 1 秒 60 次拖动最多 3 次写回,落在当前档位时是 0 次;松手必定落地,不会因为节流丢掉最后一次。
写失败或超时(10s)就回滚到真实档位并显示原因——不谎报成功。这条在本类插件里不是可选项:档位是模型实际会用的东西,界面显示 Max 而实际还在 High,属于会误导判断的错误。
另外两个细节值得记:滑条吞掉自己的 pointer、click、方向键事件,不会误触官方那一行的 onClick(那会跳进等级列表);插件不注册任何宿主钩子、不注入消息,测试里有 ctx.on 的监视断言守着这一点。
坑一 · 1.1.2 的「简洁动画」在高刷屏上自激振荡
现象是旋钮持续抽搐。根因在参数:amax × 每帧时长(1200÷60=20)与 vmax(20)同量级,速度能在一帧内从 +vmax 翻到 −vmax,位置每帧摆 ±0.333,控制器退化成 bang-bang。issue #12 里的数据是 33.6% 帧间跳变、215 次折返、eff 恒为 0.5。
修法是对 60Hz 与 120Hz 分开重调「简洁」参数,1.1.3 起 60Hz 降到 5.6%、0 次折返、3 帧收敛。作者留了一句话很关键:高刷新率下会自行收敛,所以部分用户看不出来——这类 bug 的复现条件比它的表现更难描述。
坑二 · 主题令牌缺失时它会自己选色
轨道底色用的是 --dsw-alias-border-l1。宿主主题里没有这个令牌时(自建主题、旧版本),回退到中性灰加 #4d93f8——能用,但和周围不贴合。它不是错误,只是提醒你这套视觉效果依赖宿主的主题变量。
总结
这条滑条真正做的事情,是把「随机」「好看」「跟手」这些描述压成了常量、断言和一张可复现的数字表;同类插件的中文清单与安装形态,可以在 DeepSeek Harness Hub 插件清单 里对照着看。
适合与不适合
适合:想让推理档位切换更顺手的人;介意官方列表点击手感的人;愿意读参数表、会自己调 STARFIELD_DURATION_SPREAD 的人;需要把界面行为写成可回归断言的前端同学。
不适合:只用键盘、从不点模型菜单的人——控制项就在那个菜单里,不点开就没有;不打算重启 DSH Desktop 的人,客户端 bundle 在启动时注入,不重启等于没装;期待「输入框上方常驻读数」的人,这一版明确没做。
标签:dsh-codex-effort-slider、DeepSeek Harness、界面改造、可测试性、确定性随机
本文由 DeepSeek Harness Hub 自动整理,数据来源于插件详情页。