[dsh-llm-pi-ai] opencode Go 需要 x-opencode-session,但 pi-ai SDK 从不生成 #6417
Replies: 3 comments 2 replies
|
Thanks for the detailed report — the root cause is confirmed, and your three observations each hold up against the sources. A few precision points that change which fix is worth taking, from checking 1. The gap is sharper than "no opencode branch": affinity is a switch plus a formatIn if (sessionId && compat.sendSessionAffinityHeaders) { // switch, default false
if (compat.sessionAffinityFormat === "openrouter") headers["x-session-id"] = sessionId;
else {
if (compat.sessionAffinityFormat === "openai") headers.session_id = sessionId;
headers["x-client-request-id"] = sessionId; // always, in the else branch
headers["x-session-affinity"] = sessionId;
}
}and the vocabulary is fixed:
One more consequence: 2. Most of the affinity machinery is already inherited; it is inherited dead
3. On your three suggestionsSuggestion 1 (
Suggestion 2 is right that pi-ai owns the proper fix, but it needs two changes, not one: a new vocabulary member and flipping the switch on the opencode catalogs — plus adding those models' format entries. Landing only the format (as Suggestion 3 checks out, and your instinct to call it out was right. 4. Why this cannot be a plugin today (the part that decides where the fix lands)I checked for a mountable seam and there is none, for four independent reasons:
So 5. For whoever implements itThe observable is best pinned in two places: a unit test on the adapter's request construction (assert the header is present on an opencode-go route and absent on others), and a pi-ai-side test asserting the full emitted set — I'd be glad to ship a small plugin if a request-header field ever lands on |
|
别蒸了兄弟,这个问题早好多天之前就已经有个120+⬆的讨论 #5495 了,tianyicui都参与了,可以去看看那一条,讨论里有个dsh-opencode-session插件可以暂时缓解(亲测有效),用静态头也不是不行,就是不知道缓存命中会不会受到影响 |
|
核实结论:报告机制属实,修复归属可以确认 —— 责任在 pi-ai 侧,dsh 侧只有静态头 workaround。
两点细节修正:opencode-go catalog 只有 openai-responses 条目带 openai-nosession 格式(openai-completions 条目没有);剥离大小写冲突 attribution 头的函数是 requestHeaders() 而不是 assertValidHeaders(后者只做合法性校验)。修复需改代码:dsh-llm-pi-ai 在 adapter 层按 model.provider === 'opencode-go' 注入,或上游 pi-ai 为 opencode 系补分支。 |
Uh oh!
There was an error while loading. Please reload this page.
dsh-llm-pi-ai:opencode Go provider 需要
x-opencode-session,但 pi-ai SDK 从不生成该头English:
dsh-llm-pi-aipassesoptions.sessionIdinto@earendil-works/pi-ai, but the SDK only mapssessionIdto provider-specific headers for Anthropic/Mistral/Azure. Foropencode/opencode-gonothing setsx-opencode-session, so every request to opencode Go is rejected with400 {"type":"MissingSessionID"}.环境
@deepseek-ai/dsh0.1.5-rc.2,profileweb,provider 配置在~/.dsh/settings.yaml的llm-pi-ai.providers.opencode-go@earendil-works/pi-ai0.85.1(随 dsh 一起安装于~/.dsh/profiles/node_modules/)https://opencode.ai/zen/go/v1/*,模型deepseek-v4-flash现象
dsh 侧表现为每一轮运行都失败:
本轮运行失败+INVALID_REQUEST(该错误码映射见dsh-client-connection/dsh-llm-pi-ai/dsh-llm-deepseek)。分析
dsh-llm-pi-ai/lib/index.js:1873附近已经把 sessionId 传给 SDK:但
@earendil-works/pi-ai@0.85.1只在下列分支使用sessionId:anthropic-messages(x-session-affinity,见sendSessionAffinityHeaders)、mistral-conversations(x-affinity)、azure/codex(prompt_cache_key)。没有 opencode/opencode-go 分支,因此该头永远不会生成。pi 本体是在应用层补的(二进制内可见
return { "x-opencode-session": sessionId, "x-opencode-client": "pi" },仅当 provider 为opencode/opencode-go或 baseUrl 命中 OPENCODE_HOST),SDK 消费者无法自动获得。实测对照(同一 key、同一模型)
x-opencode-sessionMissingSessionIDx-opencode-session: <uuid>+x-opencode-client: dsh建议
dsh-llm-pi-ai在requestHeaders()里为 opencode-go 合并x-opencode-session(用会话级 id 更佳;目前sessionId已传入,只是没被用上);@earendil-works/pi-ai对 opencode 系 provider 支持sessionId → x-opencode-session;assertValidHeaders会剥离大小写冲突的 attribution 头,合并时注意别把该头剥掉。临时规避
在 provider 配置里写静态头(
headers: { x-opencode-session: <uuid>, x-opencode-client: dsh })即可恢复;代价是全进程共用同一路由 id,若遇到会话级限流需要轮换。All reactions