前言¶
在 DSH 裏跑 Agent,多數時間你盯着的是 Web GUI:任務跑到哪一步、這一步調用了什麼工具、今天燒了多少 Token,都需要切回頁面看。網頁窗口也沒法做一個始終浮在桌面、點擊可交互的角色。dsh-desktop-pet-naiwa 是 Night-maze 維護的一個 Windows 客戶端插件,做的事是把這些信息投影到一個透明、無邊框、置頂的原生窗口裏,同時讓這個窗口可以單擊互動、長按拖拽、貼邊半隱藏,並支持把文件拖進去移動到回收站。
下面介紹這個插件:先講它爲什麼必須拆成兩層,再講功能、安裝命令和可用配置。
這是什麼東西¶
一句話定位:基於 DeepSeek Harness 插件機制的 Windows 桌面寵物(桌寵),維護者 Night-maze,分類爲客戶端,許可證 MIT,GitHub 倉庫創建於 2026-11-05,當前星標 0。npm 包名 dsh-desktop-pet-naiwa,版本 1.0.0。
它解決的問題:Agent 運行時狀態在原生桌面上缺席。現有的 DSH client plugin 只能渲染 Web GUI 內的 React 界面,不能創建任意 OS 窗口。
爲什麼要 Host 插件加 WPF 子進程¶
DSH 的 client plugin 跑在瀏覽器 sandbox 裏,沒有創建原生窗口的權限。要做出透明、無邊框、置頂、可拖拽的窗口,必須有一個獨立的原生進程。插件因此拆成兩層:
- Host 插件
lib/index.js(Cordis bundle),訂閱session/event,維護按天回填的 Token 賬本,讀取真實餘額,並負責拉起和守護子進程; - WPF 子進程
pet/DesktopPet.ps1+DesktopPet.cs,自己畫窗口、做手勢和動畫; - 兩者之間通過 127.0.0.1 loopback 上的 newline-delimited JSON 通信,並帶隨機 token 鑑權。
職責也有明確邊界:Host 不把 Token、餘額、進度寫死;WPF 子進程不訪問網絡、不讀 DSH 內部狀態,只消費宿主發來的 JSON。
核心功能¶
Agent 進度投影¶
按事件投影:turn/start 表示任務開始,step/start 和 tool/call 提供進度,assistant/message 與 assistant/attempt 提供 Token 用量,turn/end 給出完成、失敗或取消,agent/error 作爲失敗兜底。
默認顯示不確定進度條加「第 N 步 · 工具名」文本。插件明確不使用編造的 0–100% 數字,避免出現一個看着像進度、其實沒有依據的百分比。
Token 花費估算與真實餘額¶
「今日花費」是真實 Token 用量 × 公開列表單價,UI 裏用 ≈ 標註,這是估算值。利用率賬本按 sessionId:seq 去重;同一個 turn/step 的成功消息會替換失敗的 attempt;llm/retry-started 之後允許重試 attempt 再次計入。啓動時從 ctx.sessionPersistence 回填當天數據。
「餘額」來自 ctx.deepseekAccount.getBalance,是平臺錢包的真實值,不估算、不僞造。讀取失敗時保留上一次的值並標記爲 stale,刷新帶指數退避,絕不用 0 冒充。
價格默認內置 deepseek-flash、deepseek-v4-pro 的 CNY/USD 公開列表價,並區分峯時(北京時間工作日 9–12、14–18)與非峯時。沒有配單價的模型只顯示 Token,不計金額。
交互行爲¶
- 單擊:按權重隨機選一條
interactions配置,內置 6 種(blink、jump、shake、heart、random line、dance),可配權重、動畫、臺詞和對應精靈。 - 長按提起:按下後超過
longPressMs(默認 450ms)算提起,之後是鐘擺/彈簧拖拽,鬆手自然落回。 - 貼邊半隱藏:拖到屏幕邊緣釋放後,按當前顯示器
WorkingArea和edgeThreshold判斷方向,滑到只露edgeVisibleRatio;鼠標移入滑出,移出延遲滑回。 - 點擊穿透:
WM_NCHITTEST按當前精靈 alpha 判斷,透明像素返回HTTRANSPARENT,不擋住桌面其他操作。
拖拽文件到回收站¶
通過 IFileOperation 加 FOF_ALLOWUNDO | FOFX_RECYCLEONDELETE 實現,強制「回收或失敗」,沒有 File.Delete / Directory.Delete 回退。路徑受限:盤符根、系統目錄、符號鏈接/目錄聯接、無權限、文件被佔用、跨盤或網絡回收失敗,都會保留原文件並彈出明確錯誤。AppContainer 或低完整性進程會被拒絕執行。
客戶端側¶
client 側註冊側邊欄 🐾 桌寵 入口和設置頁,可調縮放、音量、統計顯示、長按/拖拽閾值,並支持刷新統計、重啓、顯示/隱藏。設置寫入數據目錄 ui-config.json,覆蓋 profile 同名字段;刪掉該文件並重啓插件可恢復 profile 配置。
安裝與啓用¶
前置:Windows 10/11,系統自帶 Windows PowerShell 5.1 和 .NET Framework 4.x(WPF 組件)。不需要額外 npm 依賴,Host 只用 Node 內置模塊。插件聲明基於 DSH 0.2.1-rc.5 的 Cordis 插件/服務 API。
推薦方式是用 bundle 安裝。先在 DSH Web GUI 打開 Plugins,執行:
dsh plugin --profile desktop add dsh-desktop-pet-naiwa
或者指向本地源碼目錄:
dsh plugin --profile desktop add link:F:\path\to\dsh-desktop-pet-naiwa
package.json 裏已經聲明瞭 bundle patch 和 client 注入:
"dsh": {
"bundle": { "patch": "./cordis.patch.yml" },
"client": { "platform": "web", "inject": ["..."] }
}
接下來的步驟:
- 在 Plugins 頁面把「桌寵-奶娃小時候」這個 bundle 打開,或把它加入 profile 的
dsh.profile.bundles。 - 移除任何指向絕對路徑的開發行,避免同一插件加載兩次。
- 刷新 DSH 頁面,側邊欄應出現 🐾 桌寵。若沒有,重啓 DSH 一次,讓 client graph 重新掃描
dsh.client。
另有一種開發行方式,只在 %USERPROFILE%\.dsh\profiles\<profile>\cordis.patch.yml 追加絕對路徑條目。它沒有 bundle 身份,Plugins 頁面沒有開關,也沒有 client 設置頁,只適合臨時調試,日常應刪掉。
配置¶
完整字段和註釋見倉庫的 config.example.yml。常用項:
| 字段 | 默認 | 說明 |
|---|---|---|
enabled |
true |
插件總開關 |
imagePath |
'' |
單張自定義形象;留空用內置 12 精靈 |
spriteDir / soundDir |
內置 assets | 相對插件目錄或絕對路徑 |
scale |
1.0 |
整體縮放 0.5–2,窗口、UI、形象一起縮放 |
volume |
0.7 |
音效音量 0–1 |
topmost |
true |
置頂 |
avoidFullscreen |
true |
全屏應用時隱藏 |
statsDisplay |
always |
always / hover / off |
longPressMs |
450 |
長按提起閾值 |
dragStartPx |
10 |
拖拽啓動閾值 |
edgeThreshold |
24 |
貼邊觸發距離(物理像素) |
edgeVisibleRatio |
0.38 |
半隱藏後可見比例 |
currency |
auto |
CNY / USD / auto(跟錢包) |
costPrecision |
4 |
花費小數位 |
balanceRefreshMs |
60000 |
餘額刷新,最小 30s,失敗指數退避到 5min |
statsRefreshMs |
30000 |
統計推送間隔 |
pricing |
公開價表 | 峯時、節假日、模型單價(每百萬 Token) |
interactions |
6 種 | 單擊隨機互動的權重/動畫/臺詞/精靈 |
protectPaths |
系統目錄 | 拒絕回收的路徑前綴 |
backfill |
開啓 | 啓動回填的數量/字節/超時上限 |
pricing.holidays 默認是空數組:中國法定節假日每年變化,插件不內置易過期日曆;需要精確峯谷賬單就手動填 YYYY-MM-DD。
配置裏的數組是整體替換,不是逐項合併。單擊是從 interactions 裏抽一條,再用該條的 sprite 指定顯示哪張圖(文件名去掉 .png)。想保留哪幾條就全部列出來,未列出的不會再出現。
數據與日誌¶
默認目錄 $DSH_HOME/storages/desktop-pet/:
| 文件 | 說明 |
|---|---|
pet-config.json |
Host 寫給 WPF 的合併配置 |
usage.json |
今日 + 最近 14 天 Token 賬本,含模型、時間、四個桶 |
host.log |
Host 插件診斷 |
pet.log |
WPF / 啓動器診斷 |
launcher.log |
啓動器編譯與啓動診斷 |
window.json |
上次窗口位置,用於多顯示器恢復 |
日誌可能輪轉爲 pet.log.old.<timestamp>,插件不會刪除用戶文件。
測試與驗證¶
node test/run-tests.mjs # host 單元測試
node test/mock-host.mjs # 真實 WPF + mock Cordis 集成
powershell -STA -File scripts/demo.ps1
回收站那條測試必須在普通用戶進程裏跑,不能在 DSH workspace sandbox 裏:
powershell -STA -File scripts/test-recycle.ps1
適用場景與注意¶
適合在 Windows 上跑 DSH Agent 的開發者:希望進度和成本留在桌面上可見,同時接受一個常駐子進程。全屏演示場景下 avoidFullscreen 會把它藏起來,不會打斷展示。
幾點需要留意:
- 插件以當前 dsh 進程權限運行。它確實會調用平臺餘額接口,並在收到文件拖入時操作回收站,所以安裝前應先審一遍源碼,確認
ctx.deepseekAccount.getBalance調用和IFileOperation調用符合你的預期。許可證是 MIT,來源是 npm 包和 GitHub 倉庫。 - 唯一會刪除文件的路徑是 Shell 回收 API。如果 Shell 無法回收,操作直接失敗,原文件保留,沒有永久刪除的回退。
- 「今日花費」只是估算,金額按公開列表價算,不等於已結算金額。
- 進度條刻意不顯示百分比,如果需要確切的數字,仍應回到 Web GUI 或日誌裏看。
結論¶
這個插件把 Agent 運行時狀態從 Web 頁面搬到了原生窗口,關鍵取捨是:用估算值標花費、用真實值標餘額、用不確定進度條代替僞造百分比。兩層結構(Host 插件 + WPF 子進程)是它繞開 client plugin sandbox 限制的方式,也是安裝和排障時需要看清的地方。
目錄頁:https://www.skillhub.cn/plugins/Night-maze/dsh-desktop-pet-naiwa
倉庫:https://github.com/Night-maze/dsh-desktop-pet-naiwa
npm:https://www.npmjs.com/package/dsh-desktop-pet-naiwa