前言¶
在 DeepSeek Harness(DSH)裏啓用 Auto review(實驗權限預設 EXP),並把當前模型切到 opencode 系列(例如 opencode-go)時,被審查的工具調用往往在真正執行前就失敗。日誌裏常見的是 reviewer 以 INVALID_REQUEST: 400 結束,響應體指向 MissingSessionID,說明請求缺少 x-opencode-session。主對話裏的 agent 會帶上 sessionId,而 Auto review 在 classifyRisk 路徑裏構造的 LLM 請求沒有這一字段,經 pi-ai 適配器轉發到 opencode 時就不會注入對應頭,網關直接拒收。這不是 provider 配錯,而是舊版 DSH 裏 reviewer 與主 agent 請求構造不一致。社區插件 dsh-opencode-session-fix(維護者 imx123,npm 包名同目錄)在 Host 側爲「沒有 sessionId 的 opencode 路由請求」補一個穩定 id,讓 Auto review 能走完審查流程。README 寫明:DSH 0.2.2 已在 upstream 修復;本插件僅針對 0.2.1-rc.5 及更早 版本,在 0.2.2+ 上相當於空操作,可卸載。
這是什麼¶
dsh-opencode-session-fix 是 Host-only 的 DSH 插件(分類:客戶端),通過 Cordis patch 在運行中的 Host 裏包裝 LLM 適配器的 prepareCall()(而非僅 stream()),在 sessionId 缺失或爲空時注入可配置的 session id,使 pi-ai 能爲 opencode 路由發出 x-opencode-session。已有 sessionId 的主對話請求原樣轉發,不受影響。插件不發起網絡請求、不寫盤、不碰憑證,卸載時恢復被包裝的方法。
問題從哪來(簡要)¶
| 環節 | 說明 |
|---|---|
| Auto review | dsh-experimental-auto-review 的 classifyRisk 調用 ctx.llm.stream(options),options 凍結且 無 sessionId |
| 主 agent | dsh-agent-loop 同路徑調用 帶 sessionId: this.session.id |
| pi-ai / opencode-headers | 無 sessionId 時不注入頭 → opencode 返回 400 |
插件選擇在 prepareCall() 返回的對象上打補丁,是因爲 0.2.1-rc.5 裏 reviewer 走 prepared call 的閉包 stream,只包實例 stream() 修不到該路徑。
核心行爲¶
- 默認作用於 provider 路由
opencode-go與opencode(可在配置裏收窄或擴展列表)。 sessionId缺失或空白 → 注入穩定 id(默認每次插件激活一個dsh-opencode-session-<uuid>,或用config.sessionId)。- 已有
sessionId→ 不改,主對話仍用真實 session,路由桶不與 reviewer 混用。 - 其他 provider、非目標路由 → 不改動。
- Auto review 深凍結的請求會被 複製 後再改,不原地 mutate。
llm/adapters-updated時補丁遷到新 adapter;卸載時恢復;若llm.adapters不是Map,僅 warn 一次,不阻斷 profile 激活。
安裝與啓用¶
CLI(將 web 換成你的 profile 名;desktop profile 由 Electron 佔用,CLI 不能寫,需走應用內安裝):
dsh plugin --profile web add dsh-opencode-session-fix
dsh --profile web --dump-config
dump-config 輸出中應出現 - id: opencode-session-fix。包已發佈 npm,也可在應用內插件中心用包名 dsh-opencode-session-fix 或倉庫 URL 安裝。源碼安裝(README 原文):
dsh plugin --profile web add github:imx123/dsh-opencode-session-fix
亦可用本地 checkout 路徑。測試環境 README 記錄爲 DSH Desktop 0.2.1-rc.5,profile bundle 含 @deepseek-ai/dsh-experimental-auto-review 與 @deepseek-ai/dsh-llm-pi-ai,provider 爲 opencode-go。
配置¶
在 profile 的 cordis.patch.yml 裏覆蓋對應插件行的 config(覆蓋會替換整個 config 塊):
- id: opencode-session-fix
name: dsh-opencode-session-fix
config:
providers: ['opencode-go'] # 默認 ['opencode-go', 'opencode']
sessionId: '' # 空 = 每次激活新 UUID
典型驗證方式¶
倉庫內自檢:
node --check lib/index.js
node test/wrapper.test.mjs
真機:開啓 Auto review(EXP),選 opencode-go 模型,觸發對 write 等工具的審查。會話日誌裏可見 permission/preset 爲 auto;審查應正常返回,而不再是 auto-review of tool "write" failed ... 400 MissingSessionID。迴歸時主對話的 x-opencode-session 仍應等於真實 session id(不是插件注入的 id);卸載插件後 400 應復現,說明補丁可逆。
適用場景與注意¶
適合誰: 仍在 DSH 0.2.1-rc.5 及更早 上使用 Auto review + opencode 系列 provider,且被 MissingSessionID 擋在審查門外的人。不必裝: 已升級到 DSH 0.2.2+(upstream commit 6fcb9b6c 爲 auto-review 傳入獨立 sessionId)的用戶,插件無維護承諾,可移除。
權限與信任: 插件以當前 DSH Host 進程權限運行,隻影響所配置 opencode 路由上的 x-opencode-session。安裝前建議閱讀 GitHub 源碼 與 MIT 許可證;README 聲明爲社區插件,與 DeepSeek 無隸屬或背書關係。
侷限(資料原文): ctx.llm.adapters 非文檔化擴展點,字段改名會降級爲警告;所有被修復的 reviewer 請求共用一個注入 id(路由/緩存粒度粗於真實 session,行爲仍正確);不修改 app.asar,不爲無關 provider 補 session,也不嘗試在 llm/stream 裏改寫 options。
結尾¶
dsh-opencode-session-fix 針對舊版 DSH 裏 Auto review 與 opencode 網關之間的 session 頭缺口,用 Host 側最小包裝補上 x-opencode-session,讓審查鏈路能跑通,同時不動主對話 session。新版本用戶應依賴 upstream 修復而非長期依賴本插件。