前言¶
在 DeepSeek Harness(DSH)裏給 OpenCode 走自定義 Go 推理路由時,模型目錄、路由級配置和 pi-ai 的內置包裝疊在一起,會缺一段:自建路由能打到 opencode.ai/inference/go,卻沒有像內置 opencode-go / opencode 那樣自動帶上按會話區分的 x-opencode-session。靜態寫死一個頭能讓請求通過,但所有 DSH 會話共用一個 ID,OpenCode 側的路由與 prompt cache 就無法按會話隔離。下面介紹社區插件 dsh-opencode-session(維護者 FFFengMJL,分類爲模型推理),它通過 DSH 的 llm-pi-ai/request-headers 瀑布流,只對配置中的自定義路由補上每會話穩定的會話頭。
這是什麼¶
dsh-opencode-session 是給自定義 OpenCode Go 路由(默認示例路由名爲 opencode-go-extra)注入 x-opencode-session 的 DSH 插件。當前公開版本爲 0.2.2,通過 GitHub Release 分發,不發佈到 npm。要求 DSH ≥ 0.2.2-rc.1(從該版起提供 llm-pi-ai/request-headers waterfall),以及 Node.js ≥ 24.9.0(DSH 0.2.2-rc.1 自身的要求)。許可證爲 MIT。
插件目錄頁:skillhub.cn/plugins/FFFengMJL/dsh-opencode-session。社區目錄爲獨立站點,與 DeepSeek / 幻方無官方從屬關係。
爲什麼需要它¶
三層設計各有一套合理約束,疊在一起會在「自定義 OpenCode Go 路由」上留下缺口:
- pi-ai 的模型目錄是靜態打包的。
opencode-go的模型表來自@earendil-works/pi-ai的data/opencode-go.json,新模型不會自動出現在這條內置路由上。 - DSH 的協議和端點只能寫在路由級。模型條目沒有
api/baseURL字段;opencode-go又是多協議目錄,給整條路由寫死一個api會覆蓋全部模型,因此常見做法是自建一條api: openai-completions且baseURL指向 OpenCode Go 的路由。 - OpenCode 按會話路由,而 pi-ai 僅在內置的
opencode/opencode-goprovider 上通過withOpenCodeSessionHeader包裝請求頭。
自建路由沒有這層包裝。本插件補的是:在匹配 host 與路徑前綴的前提下,爲每次推理請求寫入與 DSH 會話綁定的 x-opencode-session,且不改寫 globalThis.fetch。
核心功能¶
監聽與注入¶
- 監聽
llm-pi-ai/request-headerswaterfall。每次推理請求都會攜帶{ provider, model, sessionId, purpose, baseURL }。 - 僅對
providers配置裏列出的路由,且baseURL的 hostname 與pathPrefix均命中規則的請求,補上x-opencode-session。 - 若請求已存在同名頭(大小寫不敏感),插件保持原值並跳過,便於從靜態頭遷移或回退。
- 卸載時只移除自己的監聽器,不使用
AsyncLocalStorage。
會話 ID 取值規則¶
- 匹配
[A-Za-z0-9._:-]且長度不超過 128:prefix + sessionId,默認即dsh-<sessionId>。 - 其他非空值:
prefix + "h-" + SHA-256(sessionId)(完整 64 位小寫十六進制,不截斷)。 - 空、
null或缺失:實例級aux-<uuid>回退,同一插件實例內穩定。
配置項¶
在 profile 的插件塊中配置(加載時校驗,非法值會拋出指明字段的 TypeError):
- id: opencode-session
name: dsh-opencode-session
config:
providers:
- opencode-go-extra
# host: opencode.ai
# pathPrefix: /inference/go/
# headerName: x-opencode-session
# prefix: dsh-
# debugLog: /tmp/opencode-session.log
providers:路由名列表,字符串數組;省略或空數組時默認opencode-go-extra。host:裸主機名、host:port或 HTTP(S) URL;只取 hostname 參與匹配,協議和端口不參與。pathPrefix:與url.pathname做字面startsWith;限定路徑段時建議帶尾斜槓。headerName:合法 HTTP token(RFC 9110)。prefix:最多 64 個可打印 ASCII,不能以空白開頭或結尾。debugLog:每注入一次追加一行日誌,含會話標識;生產環境不要開啓。
若機器上目標路由名不是 opencode-go-extra,在 profile 的 cordis.patch.yml 裏覆蓋插件行的 providers 即可,不要改插件包內默認值。
安裝與啓用¶
插件以當前 DSH 進程權限運行,安裝前應自行查看 GitHub 倉庫 源碼與 LICENSE。
從 GitHub Release 下載並校驗(推薦):
curl -fLO https://github.com/FFFengMJL/dsh-opencode-session/releases/download/v0.2.2/dsh-opencode-session-0.2.2.tgz
curl -fLO https://github.com/FFFengMJL/dsh-opencode-session/releases/download/v0.2.2/SHA256SUMS
sha256sum -c SHA256SUMS
dsh plugin --profile web add ./dsh-opencode-session-0.2.2.tgz
Windows PowerShell 將最後一行換成本地 tgz 路徑即可。從本機源碼目錄安裝(開發時):
dsh plugin --profile web add /path/to/dsh-opencode-session
安裝後應刪除目標路由上靜態配置的 headers.x-opencode-session,由插件接管。安裝與更新請使用 dsh plugin 命令,不要手改 profile 依賴清單或 node_modules。
適用場景與注意¶
| 場景 | 是否需要本插件 | 說明 |
|---|---|---|
內置 opencode-go / opencode 路由 |
否 | pi-ai catalog provider 自帶該頭 |
| 自定義路由指向 OpenCode Go 推理端點 | 是 | DSH 拼裝 provider 時沒有原生包裝 |
自定義路由 + 靜態 x-opencode-session |
可不裝 | 插件見已有頭會跳過;全會話共用一個 ID |
| 非 OpenCode 配置的 host / 路徑 | 否 | 只匹配配置的 host 與路徑前綴 |
DSH 0.2.1-rc.1 至 0.2.1-rc.5 |
不支持 | 無 llm-pi-ai/request-headers 事件 |
已知邊界:換域名或換協議路徑需同步改 host / pathPrefix;同一 hostname 不同端口會命中同一條規則;插件保證發出的 ID 每會話穩定且不同,不承諾與 OpenCode 內部緩存行爲的絕對一致。缺少該頭時服務端是否拒收取決於 OpenCode;pi-ai 側將其視爲 OpenCode 路由必需頭。
結尾¶
在 DSH 尚未支持按模型聲明 api / baseURL、pi-ai 也未對任意自定義 provider 按 baseURL 補會話頭之前,dsh-opencode-session 是「自定義 OpenCode Go 路由 + 按會話隔離」組合的實用補丁。