dsh-pet-sayaka:把 DSH 会话状态变成表情和配音的桌宠插件

前言

在 DSH Web 界面里跑长任务时,界面是沉默的:你不知道现在模型在思考、命令在执行,还是已经出错了,只能盯着日志反复确认。dsh-pet-sayaka 这个插件做的事很直接——它监听 DSH 会话的状态,在界面右下角用一个桌宠(美树沙耶香)把状态翻译成表情、短台词和配音,跑代码拔刀、报错伤心、成功高兴,让执行情况一眼可见。

它由 KOGGUA-EDIT 维护,开源、MIT 协议。下面按「这是什么—状态怎么映射—配音怎么触发—怎么装—怎么用」的顺序介绍。

这是什么

一句话定位:给 DeepSeek Harness Web UI 加一个桌面宠物,把会话运行状态映射到十二张立绘,并配上台词气泡与录音。维护者是 KOGGUA-EDIT,源码在 GitHub 的 dsh-pet-sayaka 仓库,标注的分类是「趣味换装」。

它解决的不是功能问题,是反馈问题。命令执行要多久、这一轮到底成功没有、现在是不是卡住了,不需要读日志就能看出来。

该插件面向 Web 端,通过 DSH 插件系统的 bundle 机制注入前端资源,不走函数调用那一套。

状态映射

插件把 DSH 的会话状态映射到十二张立绘(assets/pet/<state>.png,784×720 透明底),切换是直接替换、没有淡入淡出。README 给出的对照如下:

会话状态 对应表情 立绘名
没事 睡觉 sayaka-睡觉(常驻,闲着会时不时擦剑)
模型思考中 思考 sayaka-思考
跑代码(bash / pwsh 等命令类工具) 拔刀 sayaka-拔刀
跑失败(非零退出、isError、超时、被杀、整轮报错) 伤心 5 秒 sayaka-伤心
跑成功 高兴 5 秒 sayaka-高兴
一轮对话跑完,且没有别的会话还在跑 累倒 5 秒 sayaka-累倒
第一次跑完之后的一分钟 平常心 → 一分钟到 → 睡觉 sayaka-平常心
睡觉 / 平常心 / 思考时,每 14~30 秒 擦剑 3.5 秒 sayaka-擦剑
被点前两下 不理 —
十秒点三下 害羞 1 秒 sayaka-害羞
十秒点五下 生气 3 秒 sayaka-生气
十秒点十下 气炸了 6 秒 sayaka-生气2(优先级最高)
按住拖动 被拖走 sayaka-拖拽

实现上,立绘缓存在运行时直接换图。前八张是从原始大图切好、去底、压过的版本(一张 75~95 KB);后四张是后来补的,量化到 255 色后一张 64~79 KB。仓库里没放 1 MB 级原图。

台词气泡与配音

每个状态刚切换时会冒一个独白气泡,一块白底、深灰描边、圆角 20px 的大圆角长方形,只显示 1 秒。睡觉、平常心这类长状态不会一直挂字,只在切换那一秒出现。气泡宽度跟着字数走(最宽到桌宠宽的 1.7 倍),字号随桌宠大小缩放。

例如思考显示 emmmmm,拔刀显示 武装保卫见泷原!,高兴显示 耶✌️,气炸了显示 你再戳一下试试!。完整台词表见 README。

台词不只是状态切换时的固定句,还会按累计次数换回应。同一个状态累计碰到第几次,会换一句更像在回应的台词,必要时连表情和录音一起换。规则写在 lib/client.js 的 QUIPS 表里,加一条就是加一行,at 字段表示这个状态本轮累计到第几次:

状态 第几次 台词 录音 顺带
伤心 2 又出问题了 quip-sad-2.wav —
伤心 5 气死我了!!! angry.wav 表情切生气 3 秒
伤心 9 这点小事才不会让我认输! quip-sad-9.wav 然后清零重新数
高兴 2 嘿嘿,成了 quip-happy-2.wav —
高兴 5 今天日子真不错 quip-happy-5.wav 然后清零重新数
拔刀 5 我可不是跑腿的! quip-sword-5.wav 然后清零重新数
思考 3 想不出来… quip-thinking-3.wav 然后清零重新数
被连点十秒 5 下 — 别戳了!!! quip-poke.wav 生气 3 秒
被连点十秒 10 下 — 你再戳一下试试,我绝对不放过你! quip-poke2.wav 气炸了 6 秒

走到最后一档会清零,所以是「每错五次气一次」,下一个五次还会再气,而不是只气开头那一回。

配音方面,每个状态都有一段录音(assets/pet/<state>.wav),跟着状态播放;情境台词另有专属录音(assets/pet/quip-*.wav)。状态录音不是每次都放,而是每个状态各记一份计数:每进入该状态 +1,攒够 5~8 次才播一次、清零,然后重新掷一个 5~8 的随机间隔。轻松的 morning.wav 每次启动后说第一句,页面刷新不重播;浏览器拦住自动播放时,会在第一次点/按键时补上。害羞每次被点都出声,不攒次数;被拖动和连点则有各自的专属录音。同一时间只放一段,播下一段前上一段没放完会被直接截断,不会出现两句话叠在一起。

不想要这个间隔的话,设置页「sayaka」分区里有「每次变换都出声」开关:打开后不再计数,拔刀 / 高兴 / 伤心 / 思考 / 睡觉 / 平常心每次变化都直接播一段(害羞、生气、被拖走本来就有专属那句,不会重复叠)。同一分区里的「配音」开关能一键关掉所有声音,表情照常动。

安装与启用

从 npm 安装(推荐):

dsh plugin --profile web add dsh-pet-sayaka

或者直接从 GitHub 装:

dsh plugin --profile web add github:KOGGUA-EDIT/dsh-pet-sayaka

装完需要重启一次 Web 服务才能生效:DSH 标题栏「⋯」→「重启 Web 服务」,然后刷新页面,右下角就能看到桌宠。原因是浏览器插件的清单(哪些插件有前端 bundle)是 Web 服务启动时扫出来的,页面加载时从服务端拿这份清单。

本机开发时,README 还介绍了一种不打包的接线方式:源码放在固定目录,用一个 tools/install.mjs 脚本把插件写进 profile 的 dependencies、加入 dsh.profile.bundles、并在 node_modules 里建一个指向源码目录的链接(link: / junction)。脚本带 --status / --uninstall 参数,幂等,重复跑没事。改用源码开发时,改完或改了偏好都要重启 Web 服务才生效,安装、卸载同理。

卸载走 CLI:

NODE="$LOCALAPPDATA/Deepseek Harness EAC/dsh-desktop/vendor/node/node.exe"
BIN="$LOCALAPPDATA/Deepseek Harness EAC/dsh-desktop/node_modules/@deepseek-ai/dsh/lib/bin.js"
"$NODE" --use-system-ca "$BIN" plugin --profile web-desktop remove dsh-pet-sayaka

需要说明的是,这份卸载命令抄自 README 里作者 Windows 本机的路径,换机器时要按自己的 DSH_HOME 和 profile 名调整。每个版本都打了 tag 并附打包好的 tgz,在 Releases 页面。

适用场景与注意

适合需要长时间盯长任务、注重运行时反馈的 DSH Web 用户,尤其是单人开发、不想让日志占满视线的场景。它只读会话状态做视觉映射,不改命令执行逻辑,也不影响插件本身的正常调用。

几点需要注意:

  1. 它被插件系统加载后,以当前 dsh Web 进程的权限运行,能访问该 profile 加载的会话与工具事件。安装前应打开源码核对,确认没有夹带额外请求或本地数据外发行为。
  2. 许可证是 MIT,作者署名 KOGGUA-EDIT;想复刻立绘和录音需要自己确认素材版权,仓库里只放了压缩后的图片和 wav。
  3. 它面向 Web 界面,通过 frontend bundle 注入,所以在没有 Web 服务的 profile 上装了也看不到东西。
  4. 气泡和配音都会打断注意力,对需要安静环境的人,装完建议先在设置页关掉「配音」,或只保留状态换脸。

结尾

dsh-pet-sayaka 的价值不在于多一个功能,而是给沉默的会话加上一个可感知的可视化层:命令跑起来就拔刀、结束就累倒、出错就切换到伤心,反复出错还会换台词。对盯着 Web UI 跑任务的人来说,它比反复看日志省事。目录页在 https://www.skillhub.cn/plugins/KOGGUA-EDIT/dsh-pet-sayaka ,源码在 https://github.com/KOGGUA-EDIT/dsh-pet-sayaka 。

羽毛球分组比赛记分
小程序二维码

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

小夜