前言¶
在 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 用戶,尤其是單人開發、不想讓日誌佔滿視線的場景。它只讀會話狀態做視覺映射,不改命令執行邏輯,也不影響插件本身的正常調用。
幾點需要注意:
- 它被插件系統加載後,以當前 dsh Web 進程的權限運行,能訪問該 profile 加載的會話與工具事件。安裝前應打開源碼覈對,確認沒有夾帶額外請求或本地數據外發行爲。
- 許可證是 MIT,作者署名 KOGGUA-EDIT;想復刻立繪和錄音需要自己確認素材版權,倉庫裏只放了壓縮後的圖片和 wav。
- 它面向 Web 界面,通過 frontend bundle 注入,所以在沒有 Web 服務的 profile 上裝了也看不到東西。
- 氣泡和配音都會打斷注意力,對需要安靜環境的人,裝完建議先在設置頁關掉「配音」,或只保留狀態換臉。
結尾¶
dsh-pet-sayaka 的價值不在於多一個功能,而是給沉默的會話加上一個可感知的可視化層:命令跑起來就拔刀、結束就累倒、出錯就切換到傷心,反覆出錯還會換臺詞。對盯着 Web UI 跑任務的人來說,它比反覆看日誌省事。目錄頁在 https://www.skillhub.cn/plugins/KOGGUA-EDIT/dsh-pet-sayaka ,源碼在 https://github.com/KOGGUA-EDIT/dsh-pet-sayaka 。