前言¶
在 DeepSeek Harness(DSH)裏走 OpenCode / OpenCode Go 路由時,網關要求每個推理請求攜帶 x-opencode-session 頭;缺省會直接返回 400 MissingSessionID。主對話、子代理等請求通常帶有 sessionId,dsh-llm-pi-ai 會據此讓 pi-ai 補上該頭。但啓用 auto 權限預設時,工具調用會先經過 @deepseek-ai/dsh-experimental-auto-review 的 reviewer;這條 reviewer 請求是手工組裝的,沒有 sessionId,於是 reviewer 在 OpenCode 側 400,審查失敗,DSH 按 fail-closed 策略不會執行工具體。下面介紹社區插件 dsh-opencode-session-fallback(維護者 zlxlsy666,分類:工作流),它只在 LLM 流式調用層爲「缺 session 且命中 OpenCode 路由」的請求注入兜底 id,不碰全局 fetch、不改 provider 配置。
這是什麼¶
dsh-opencode-session-fallback 是一個體量很小的 DSH 插件(npm 包名同插件 id,當前版本 0.1.0,MIT 許可)。它在 DSH 啓動時對 ctx.llm.stream 做一次包裝:已有 sessionId 的請求、或非 OpenCode 系列 provider 的請求原樣透傳;只有 無 sessionId 且 provider 在配置列表內 的請求(實踐中主要是 auto-review 的 reviewer 調用)會帶上配置的 fallbackSessionId,再由 pi-ai 自動加上 x-opencode-session。
問題與修復思路¶
OpenCode / OpenCode Go 拒絕不帶 x-opencode-session 的推理請求,典型錯誤體如下:
400 {"type":"error","error":{"type":"MissingSessionID","message":"Request is missing x-opencode-session ..."}}
在 opencode-go 路由 + auto 預設下,鏈路是:
- 每次工具調用先發給 reviewer 模型;
- reviewer 請求無 session 頭 → 網關 400;
- 審查失敗 → 工具體不執行,日誌中可見類似
Auto review of tool "pwsh" failed; its body was not executed與INVALID_REQUEST: 400: {"type":"MissingSessionID", ...}。
插件的決策邏輯可以概括爲:
ctx.llm.stream(options)
├─ options.sessionId 已存在 .......... 透傳(主對話、子代理、壓縮、標題等)
├─ provider 不在 opencode/opencode-go .. 透傳(官方 deepseek 等不受影響)
└─ 無 sessionId + OpenCode 路由 ...... 合併 fallback sessionId 後再走 pi-ai
README 明確說明:不採用替換 globalThis.fetch 的做法,以免包住宿主應用自身的出網調用並引發 UI 連接錯誤;本插件只改 LLM 服務上的 stream 方法。
行爲保證¶
資料中列出的保證包括:
- 已有
sessionId不會被替換,會話級路由與 prompt-cache 親和性保持不變。 - 其他 provider 不受影響。
- 傳入的 options 不會被原地修改(使用拷貝,凍結對象也可)。
- 卸載後 自動恢復 原始
ctx.llm.stream。 - 若未來 DSH 中服務形態變化、無法注入,插件 打 warning 並保持空操作,避免拖垮啓動。
安裝與啓用¶
插件在 DSH 啓動時裝配,安裝或卸載後都需要 重啓 DSH。
從 npm 安裝(web profile):
dsh plugin --profile web add dsh-opencode-session-fallback
也可在 GUI:Settings → Plugins → install,包名填 dsh-opencode-session-fallback。
從 Git 倉庫安裝:
dsh plugin --profile web add git+https://github.com/zlxlsy666/dsh-opencode-session-fallback.git
本地目錄(示例路徑來自 README,請按本機路徑替換):
dsh plugin --profile web add "file:C:\path\to\dsh-opencode-session-fallback"
桌面應用使用 desktop profile,應由應用內 Plugin Manager 管理,而不是上述 CLI 的 --profile web。
啓動成功後,日誌中應出現類似一行:
[opencode-session-fallback] active for providers [opencode, opencode-go], fallback session id "dsh-opencode-session-fallback"
可選配置¶
在對應 profile 的 cordis.patch.yml 中,用插件條目 id opencode-session-fallback 覆蓋默認值:
- id: opencode-session-fallback
name: dsh-opencode-session-fallback
config:
providers: [opencode, opencode-go] # 需要 session id 的路由
fallbackSessionId: my-stable-id # 請求無 session 時使用的值
debug: false # 爲 true 時記錄每次注入
卸載¶
dsh plugin --profile web remove dsh-opencode-session-fallback
卸載後同樣需重啓 DSH;ctx.llm.stream 會恢復爲安裝前行爲。
兼容性與驗證環境¶
- 插件依賴 DSH 中存在
ctx.llm.stream(inject: ['llm']);否則只打 warning、不生效。 - README 記載在 DSH
0.2.1-rc.2(desktop)上,配合opencode-go與deepseek-v4.1-flash端到端驗證:auto 預設下工具可執行,reviewer 正常返回 allow/deny。 - 與自帶 pi-ai OpenCode providers 的 DSH 版本搭配使用即可。
- 運行環境要求 Node
>=20(見 package.jsonengines)。
適用場景與注意¶
適合誰: 在 DSH 中使用 OpenCode / OpenCode Go 路由,並啓用 auto 權限預設(或任何會觸發無 sessionId 的 LLM 請求且走 OpenCode 網關的場景),且遇到 MissingSessionID 導致 auto-review 或同類調用失敗時。
注意: DSH 社區插件目錄(如 SkillHub 上的條目)爲獨立生態站點,與 DeepSeek / 幻方無官方從屬關係;插件以當前 DSH 進程權限運行,安裝前請自行查看 GitHub 源碼 與 MIT 許可證。兜底 sessionId 僅用於滿足網關頭要求,不應替代你爲主對話刻意配置的 per-conversation session 策略——插件設計上不會覆蓋已有 sessionId。
結尾¶
dsh-opencode-session-fallback 用最小侵入的方式解開 OpenCode 路由上 auto-review reviewer 因缺 x-opencode-session 而全線 400 的卡點,讓 auto 預設下的工具審查鏈路能繼續工作。目錄頁:https://www.skillhub.cn/plugins/zlxlsy666/dsh-opencode-session-fallback;源碼與完整說明:https://github.com/zlxlsy666/dsh-opencode-session-fallback。