前言¶
在 DSH(DeepSeek Harness)裏做智能體開發時,經常要把文件交給模型:貼一張截圖、拖一份日誌、上傳一個數據集目錄。原生 Web GUI 對附件的處理比較剋制,瀏覽器側沒有可靠的文件路徑概念,文字模型也「看不懂」圖片;桌面上用戶拖進來的往往不只是小文件,還有目錄和幾個 GB 的日誌,直接上傳既不現實,落盤副本又會很快把工作區堆滿。
下面介紹的插件 xinstart-1/dsh-files-fallback 就是處理這一層的:它把「拖入 / 粘貼 / 上傳」統一成一條落盤管線,用 @絕對路徑 讓文本模型也能引用附件;在桌面殼裏能拿到真實操作系統路徑時,則直接 @原路徑 引用,零拷貝、無大小限制,只把「目錄、超大文件、上傳失敗」這類無法落盤的情況兜住。
這是什麼¶
- 維護者:xinstart-1
- 類型:標準 dsh 插件包,聲明瞭
dsh.bundle.patch(package.json中含dsh.bundlemanifest,patch+client) - 版本:0.9.12(來自
package.json) - 許可證:MIT
- 運行環境:Node.js >= 18
- 定位:DSH Web GUI 的文件引用與附件插件,宿主側(Host 半)落盤與 VLM 調用,客戶端側(Client 半)攔截拖入 / 粘貼 / 📎 按鈕並插入引用。
解決的問題分三塊:
- 瀏覽器裏沒有路徑概念,任何類型的文件都要先落成一份穩定副本,再讓模型能引用它;
- 桌面上能拿到真實路徑時,不該再複製一份,目錄和大文件更不該被上傳卡住;
- 文字模型不理解圖片,需要一個視覺模型把圖片轉成文字描述。
插件對這三塊分別給了落盤管線、@原路徑 兜底引用和 VLM 識別。
核心能力¶
三種入口,任意文件類型¶
拖入、Ctrl+V 粘貼、接管 dsh 原生 📎 附件按鈕(位置在加號右側、modes 左側,可多選),PC 與移動端瀏覽器均可。不再設擴展名白名單,任意文件都能進來,無需配置。
統一落盤管線¶
文件字節流由 Host 半經 node:fs/promises 直接寫盤,平鋪保存到:
<會話工作區>/.dsh-file-attachment/<文件名>
補充規則:
- 同名衝突在擴展名前追加
-N,絕不覆蓋; - 上傳前按「文件名 + 文件大小」查重,命中直接複用已有路徑、零字節上傳,索引文件是
.dsh-file-attachment/.index.json; - 單文件上限 50MB,空文件跳過;
- 會話工作區回退順序爲
session.header.cwd→sandboxPolicy.workspaceRoot→process.cwd(),每個項目維護自己的.dsh-file-attachment/。
桌面端零拷貝引用¶
在 DSH 桌面殼裏,插件通過 Electron webUtils 拿到拖入文件的真實操作系統路徑,然後一律直接插入 @原路徑 引用:不復制、不上傳、不落副本,沒有大小上限。文件被移動、改名或刪除後,引用它的消息在讀取時會明確報「文件不存在」,而不是展示一份過期副本。
純瀏覽器拿不到路徑時,才走上面的落盤管線,把 @絕對路徑 插入光標處。
輸入框 chip 與聊天區縮略圖¶
引用以草稿裏的原生 @路徑 chip 呈現(藍色),不額外渲染附件條,避免同一附件在附件條和草稿裏出現兩次。鼠標移到 chip 上,左側文件圖標變成 ×,點擊即刪除該引用,其他 chip 與文本不受影響。聊天區的圖片渲染爲可點擊放大的縮略圖(Lightbox),目錄以文件夾圖標 chip 呈現。
VLM 圖片識別¶
非多模態模型下,圖片自動調用視覺模型生成中文描述回填草稿,且只注入模型上下文。視覺模型從 harness 模型目錄下拉選取,默認走 harness 自帶模型;在設置裏填了 Base URL + API Key 則走自定義 OpenAI 兼容端點。agent 也可以主動調用 describe_image 工具。
設置頁路徑是「設置 → 文件附件」,包含思考模式開關(默認禁用)和超時時間(默認 60 秒)。未選模型時不啓用圖片識別。
安裝與啓用¶
安裝命令直接來自官方 README(在插件目錄下執行,參數會轉發給 profile 目錄的 pnpm):
dsh plugin --profile web add ./dsh-files-fallback
安裝後會自動進入 profile 的 dsh.profile.bundles,無需手改 profile 的 package.json。改完 lib/*.js 後重啓 web GUI 即生效。升級用:
dsh plugin --profile web update dsh-files-fallback
典型用法¶
以下行爲來自 README 的行爲一覽,可直接作爲驗收清單。
1、拖入單個文件。桌面端插入 @原路徑 引用;純瀏覽器落盤後在光標處插入 @絕對路徑,成功不提示,失敗給簡短 toast。
2、一次多個文件。批量處理並一次性插入全部引用;部分失敗只提示「N 個已跳過」。
3、拖入目錄。桌面端插入 @路徑/ 引用(文件夾圖標 chip);純瀏覽器 toast 提示「不支持拖入目錄」。
4、單文件超過 50MB 或空文件。桌面端仍按 @原路徑 引用(零拷貝、不受限制);純瀏覽器跳過並提示;單條目上傳失敗時,桌面端可取到真實路徑就自動轉爲 @路徑 引用,否則提示「文件處理失敗」。
5、當前模型不支持多模態。自動調 VLM 生成中文描述回填草稿;agent 可用 describe_image 工具。
6、粘貼純文本。不改寫,完全原生行爲。
7、移除引用。鼠標移到輸入框裏的 @路徑 chip 上點擊 ×,或把光標頂到 chip 後按退格。
存儲與清理¶
落盤文件默認永久保留在 .dsh-file-attachment/,不隨會話刪除而清理。如果同時裝了提供「刪除會話」能力的插件(README 以 dsh-session-delete 爲例),可以在「設置 → 文件附件 → 會話清理聯動」打開開關(默認關閉),實現刪除會話時連帶清理該會話上傳的落盤附件。
聯動機制要點:
- 監聽
api-session/removed總線事件觸發清理; - 按引用計數刪除,同名同大小被多個會話共享的條目,只有最後一個引用它的會話被刪除時才真正刪除;
- 啓用聯動之前上傳的舊文件沒有歸屬記錄,永遠不會被自動清理;
- 會話到文件的引用關係隨去重索引寫入
.index.json,重啓 GUI 不丟失; - 可通過
GET /dsh-file-attachment/cleanup-status?sessionId=<id>查詢該會話上傳的文件數與總字節,刪除前預覽將回收的空間。
適用場景與注意¶
適合下面這批人:
- 主要在 DSH Web GUI 裏工作,需要頻繁把本地文件交給模型;
- 同時使用桌面殼和瀏覽器,希望兩邊對同一批文件的處理方式一致;
- 模型是純文本模型,需要靠 VLM 把圖片內容轉成文字;
- 已經在用或準備用刪除會話類插件,希望附件一起清乾淨。
需要注意:
- 插件以當前 dsh 進程權限運行,配置落在
~/.dsh/file-attachment.json,附件落在會話工作區的.dsh-file-attachment/,安裝前先檢查源碼與許可證(MIT); - 桌面端的零拷貝引用依賴真實路徑始終有效,文件移走後引用會報「文件不存在」,這是設計行爲,不是 bug;
- 瀏覽器側 50MB 上限和目錄不支持是瀏覽器能力限制,桌面側沒有這類限制;
- 會話清理聯動默認關閉,需要配合刪除會話插件手動打開;
- 該插件目前星標數爲 0,屬於早期項目,功能描述以倉庫 README 爲準。
結尾¶
總結一下:dsh-files-fallback 把 DSH 裏散落的文件入口統一成一條管線——瀏覽器側落盤加 @絕對路徑 引用,桌面側零拷貝 @原路徑 兜底,再疊上 VLM 圖片識別和可選的會話清理聯動。它不改變 DSH 的模型能力,只是把「文件怎麼進上下文」這件事變得可預期、可復現。
目錄頁:https://www.skillhub.cn/plugins/xinstart-1/dsh-files-fallback
GitHub:https://github.com/xinstart-1/dsh-files-fallback