opencode-go 无法发送逐对话会话头(x-opencode-session):compat 门控 withhold 导致配置层无解,缓存命中率受损 #6173
aobakaolengmian
started this conversation in
General
Replies: 1 comment
|
补充:pi-ai 侧的对应 issue 已提交(含 另附本机上已验证可行的临时方案:把 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
English TL;DR — OpenCode Go requires a per-conversation session ID header (
x-opencode-session; the gateway also acceptsx-session-id/session_id). dsh already forwards the conversation id (session.id) down to pi-ai, but pi-ai maps session affinity only to OpenRouter/OpenAI header names, and dsh'sCOMPLETIONS_COMPAT_GATEmarkssendSessionAffinityHeaders/sessionAffinityFormatas"withhold"(also absent from thecompatProfileschema) — so it cannot be enabled by configuration. Users are forced to hard-code a staticx-opencode-sessioninheaders, which defeats the intended per-conversation routing / prompt-cache affinity. A local patch flipping those two gate entries to"offer"pluscompat: { sendSessionAffinityHeaders: true, sessionAffinityFormat: openrouter }was verified to emit a distinctx-session-idper conversation (all requests 200, ~50% cache hit on turn 2). Suggested fix: offer those compat fields, or declare affinity in the opencode-go catalog, or add an"opencode"affinity format emittingx-opencode-session.现象
使用 OpenCode Go(
https://opencode.ai/zen/go)作为供应商时,任何请求都返回:OpenCode Go 官方文档明确要求(原文):
即该头是逐对话的稳定标识,用于路由亲和与提示词缓存优化。
环境
0.1.5-rc.1(npm 全局安装),macOS 26.6 arm64@earendil-works/pi-ai0.85.1~/.dsh/settings.yaml):根因分析
会话 ID 的管道其实是通的,断在最后一层映射 + 配置门控:
dsh-agent-loopsessionId: this.session.id(dsh-agent-loop/lib/index.js:1215)dsh-llm-pi-ai...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) }(lib/index.js:1871)pi-aisessionAffinityFormat: "openrouter"→x-session-idsessionAffinityFormat: "openai"→session_id+x-client-request-id+x-session-affinity没有映射到
x-opencode-sessiondsh-llm-pi-ai配置层COMPLETIONS_COMPAT_GATE把sendSessionAffinityHeaders/sessionAffinityFormat标记为"withhold"(lib/index.js:403,405),且compatProfileschema 中不含这两个字段 → 用户无法通过配置启用,字段即便写入也会被 schema 剥离结果:用户只能退化为「全局静态头」workaround(配置文件
headers只能写死字符串),所有对话共用同一个路由/缓存桶,恰好与官方"逐对话"的意图相反,缓存命中率受损。实测:网关接受的头名(用真实 key 逐个验证)
x-opencode-sessionx-session-idsession_idx-session-affinityx-client-request-id即 pi-ai 现有的
openrouter格式(x-session-id)就能被 OpenCode Go 接受——只差把门控放开、让配置能声明它。已验证的本地补丁方案(供参考)
改动
@deepseek-ai/dsh-llm-pi-ai/lib/index.js两处:compatProfile增加两个字段:COMPLETIONS_COMPAT_GATE:sendSessionAffinityHeaders与sessionAffinityFormat由"withhold"改为"offer"随后在供应商配置中声明:
抓包验证结果:每个对话携带各自不同的动态会话 ID(对话请求与标题生成请求均带上),所有请求 200,第二轮缓存命中约 50%:
建议的修复方向(任一即可)
sendSessionAffinityHeaders/sessionAffinityFormat从withhold改为offer,并加入compatProfileschema,让用户可为 OpenCode 类路由启用会话亲和。"sendSessionAffinityHeaders": true, "sessionAffinityFormat": "openrouter",开箱即可获得逐对话会话头(openai-responses 类是否适用需单独确认)。
sessionAffinityFormat: "opencode"→ 发送x-opencode-session,并在 opencode-go 目录中启用。注意事项
anthropic-messages协议路径发送的是x-session-affinity(见pi-ai/dist/api/anthropic-messages.js),该头被 OpenCode Go 拒绝。因此若采用路由级 compat,需确认 OpenCode 路由下 anthropic 类模型会被正确跳过(route 级字段对不支持该字段的协议应 skip),否则会引入 400。earendil-works/pi(见下)。All reactions