前言¶
在 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 修复而非长期依赖本插件。