前言¶
在 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 路由 + 按会话隔离」组合的实用补丁。