Repository navigation
Replies: 40 comments 17 replies
|
we started looking for the deepseek header that has this info so it should be ok |
|
Update from our telemetry: we can now see the session header when it arrives, and the picture is model-specific. muse-spark-* requests arrive with session context 74-90% of the time, but deepseek-v4-flash is at ~2.5% and mimo-v2.5 / glm-5.3-flash / everything else are near 0%. Flash is your highest-volume model through us, so that is where most of the breakage will land on 09/06. So the ask narrows: whatever attaches the session header on the Spark-serving path needs to run on all provider adapters, not just that one. Happy to re-measure the moment a build ships it. |
Proposed Fix:
|
|
How interesting, would it solve opencode's own problem of reducing intelligence? Why should we have to adapt to it for this |
|
I am trying to use my opencode go sub with deepseek harness and I get this error: Is that related? @thdxr. By the way, the sub works perfectly in claude code |
|
Following this thread's requirement (in effect from 09/05): I implemented The header is injected at the chat call site from the per-conversation session id, gated like the official client ( Two scope notes: (1) this currently covers all |
|
Hi @thdxr thanks for the report. Does it make more sense for the pi-ai package to include this header when it's configured to use the OpenCode Go provider? It is supposed to be that package that handles and normalizes all the providers particular needs. |
|
A config-driven implementation: Following tianyicui's point that the pi-ai package should normalize provider particulars, we implemented this as an explicit, opt-in profile field rather than a route-name gate, converging with RaulLazaro's proposal: providers:
opencode-go:
sessionHeader: x-opencode-sessionHow it works: the adapter already threads Why not pi-ai's Context: we run DeepSeek Harness daily on Windows against the OpenCode Go/Zen gateways (28 Go models, 7 free, plus dedicated Branch: Separately: we also have a proposed write-validation rule for agent edits to |
|
åĻsettings.yamläļæ·ŧå headersïžåģåŊč§ĢåģïžåĻdeekseek harnessäļéčŊŊäļéĒæđįĻdeekseek v4 flashæĻĄåč§Ģåģïž |
|
Fix verified â proposed patch for Root cause confirmed locally: DSH's request path ( We patched { "n-session": sessionId, "n-client": "deepseek-harness", "x-opencode-session": sessionId }Both header sets are sent for belt-and-suspenders coverage of native-header recognition and the public contract. Verified end-to-end: reproducible Suggested upstream fix (â10 LOC): port pi's |
|
Just to unlock temporarily the situation And asked it to crawl this issue page and find a fix But the dsh team should come with a clean solution |
|
Status report: A brief update from our side, now that the deadline has passed and the thread has heated up: 1. In production since Sep 5, no errors and no cost anomaly. Our deployment has been running the 2. On the cost reports after the static header (downnititiffany-spec and z3347212573-cloud): your diagnosis is correct, and this is exactly what a per-conversation id avoids. A fixed value collapses every conversation into one affinity bucket: switching sessions in DSH still points at the same replica with different prefixes, so cache locality degrades as you observed. The 3. Data for the clean fix (lws2004, good find). We verified by direct probe, before the deadline, that the gateway accepts Branch: |
|
Independent confirmation on Route: Local change in { "x-opencode-session": sessionId, "n-session": sessionId, "n-client": "deepseek-harness" }After restart, the same sessions proceeded (tool calls / completed turns). Remaining Happy to treat |
|
We hit this too and have a working local implementation you may want to adopt or adapt (external PRs are currently not accepted per CONTRIBUTING.md, so sharing the details here). Root cause: pi-ai does not send any What we did (all inside the
Validation: llm-pi-ai unit suite 291/291 green; full repository Reference branch (two commits):
Happy to reshape this however the team prefers â e.g. as an |
|
Hi, Iâm using DeepSeekâHarness to call your API, and as youâve noted, it currently doesnât include the xâopencodeâsession header. But DeepSeekâHarness is still under active development. Setting a hard deadline with such short notice is unreasonable â it breaks my integration, which is why Iâm here commenting. It would be much more sensible to wait until the harness officially adds support for that header before enforcing the change, rather than forcing users to patch or adapt the tool themselves. |
|
pi aiéĢčūđå äļäščŋäļŠåč―ïžåŠčĶįpiäļäļæŽĄåįåščŊĨå°ąčĄ |
|
a workaround by monkey patch for global fetch, see: https://github.com/haoliangwu/dsh-me/blob/main/src/plugins/x-opencode-session-shim/index.ts.
it is dirty, but it works. |
|
Measured on a shipped install ( Direct probes against
So Go accepts Why it cannot be fixed from configuration today. Both affinity switches are withheld: Workaround that works today (verified live â a real turn completes after the change): the session id is already plumbed into the request, it is just not used for headers ( llm-pi-ai:
providers:
opencode-go:
headers:
x-opencode-session: "<one stable uuid per install>"That is exactly what @RaulLazaro's |
|
Adding evidence from a library-level consumer of The gap is adapter-specific, and the missing half is the pi-ai adapter.
That is why a DeepSeek route pointed at
Upstream Wire evidence (Go key,
So the endpoint accepts DSH's native header â the id just never reaches the wire on this path. The fix looks small. Happy to test a patch if that is useful. |
|
Correction / narrower scope. I checked pi's
So everything above holds for the released 0.85.1, but this is a release lag, not an open DSH implementation task: The one piece a bump does not cover: a hand-declared or protocol-overridden route. Retracting the "happy to test a patch" for the catalog case: the thing to track is the release, not a DSH change. |
|
I resolved the issue using this method, and I can now use the opencode go ds4.1 model normally. |
Status check on the current shipped desktop build, plus measured cost of the static headerTwo things that may help converge this: what the released build actually ships today, and numbers on what the static-header workaround costs in practice. 1. Still not covered in the shipped build (DSH Desktop 2.0.13, Windows, 2026-09-21) So on this build the only config-level option remains a static 2. The predicted cache degradation, measured Session records from this install (8,150 assistant turns; per-step Median per-step latency moved with it: 8.0s (09-16) â 13.8s (09-20) â 13.5s (09-21). On Go pricing ($0.30/M input vs $0.006/M cached read), 09-20 billed â$5.99 against â$1.68 if the prefix had stayed warm â roughly $4.3 of waste in a single day against a $60 monthly limit. The prompt prefix itself is stable; what is lost is a warm server-side prefix: 3. A gap a pi-ai pin bump would not close on this install This route is hand-declared in llm-pi-ai:
providers:
opencode-go:
api: openai-completions
baseURL: https://opencode.ai/zen/go/v1
headers: { x-opencode-session: ses_<one-fixed-id> } # shared by every conversation
models: [ { id: deepseek-v4.1-flash, ... } ]Hand-declared routes are how users add models the catalog has not shipped (that is how this one was added), so it would be worth confirming whether the intended fix covers that path or only catalog routes. 4. It is not purely client-side Independently of any header question, byte-identical requests to the Go endpoint flap between full hit and full miss â 8/18 cold in one run, 1/12 in another, with Ask: which path do the maintainers intend â land |
|
Status: the fix is released â what remains is the dependency range, not the code. While this thread was converging on a
Verifiable without installing: npm view @earendil-works/pi-ai version # 0.87.0
curl -s https://unpkg.com/@earendil-works/pi-ai@0.87.0/dist/providers/data/opencode-go.json \
| grep -o 'deepseek-v4[^"]*'
curl -s https://unpkg.com/@earendil-works/pi-ai@0.87.0/dist/providers/opencode-headers.js \
| grep -c x-opencode-sessionWhat still blocks it on shipped builds is the range: On the question above about which path is intended, as far as this thread can tell it splits in two:
One data point for the interim: the DeepSeek adapter route ( |
|
Adding the plugin-side data point, since this thread keeps splitting on "catalog route vs. a route that sets 1. Independent confirmation of the release/range state, on a shipped stack On
So no published consumer resolves the fix yet â that matches the comment above. 2. What a pin bump will not cover, from a plugin that is exactly that case I maintain Because of (a), that route is a "route that sets Our header half is protocol-agnostic and version-independent: a 3. One nuance about the catalog addition
Nothing needed from anyone here â recording it so the plugin-side consequences of the two paths are on the record. |
|
Thanks for opening this éĨ?I hit the same 400 and traced it to a root cause with Root causeOpenCode Go requires every request to carry a stable per-conversation The value exists the whole time:
But pi-ai only turns a session id into its own affinity headers FixOne seam, all three protocols. function opencodeSessionHeaders(baseUrl: string | undefined, sessionId: unknown): Record<string, string> {
if (sessionId === undefined || baseUrl === undefined) return {}
let host: string
try {
host = new URL(baseUrl).hostname
} catch {
return {}
}
if (host !== 'opencode.ai' && !host.endsWith('.opencode.ai')) return {}
return { 'x-opencode-session': String(sessionId) }
}headers: {
...requestHeaders(profile.headers),
...opencodeSessionHeaders(model.baseUrl, options.sessionId),
},The full change is also pushed as a cherry-pickable branch (commit Why this seam: VerificationA harness drives the real adapter against the real bundled pi-ai
6/6 pass on the patched build; the same harness on the pre-patch build fails Happy to adjust placement if maintainers prefer the helper inside Branch for maintainers: https://github.com/Jay0130-a/deepseek-harness/tree/fix/opencode-session-header ( |
|
Reconciling the three proposed paths: they do not have the same coverage, and one of them closes both 400s at once. The thread now carries three candidate fixes â @Jay0130-a's in-tree adapter patch, @itchenshi's out-of-tree plugin, and widening the dependency range. They get discussed as interchangeable, but they differ in which of the two 400s they close, and that decides whether the model is actually usable afterwards. I pulled the published artifacts and checked. 1. The second 400 does not exist on the catalog path@itchenshi is right that a catalog-unknown That is a real consequence of hand-declaring the model. It is not a property of the model. "deepseek-v4.1-flash": {
"api": "openai-completions",
"baseUrl": "https://opencode.ai/zen/go/v1",
"reasoning": true,
"compat": {
"supportsStore": false,
"supportsDeveloperRole": false,
"supportsStrictMode": true,
"maxTokensField": "max_tokens",
"requiresReasoningContentOnAssistantMessages": true,
"thinkingFormat": "deepseek"
},
"contextWindow": 1000000,
"maxTokens": 384000
}The two keys itchenshi identified as missing are present and identical to 2. Coverage by path
The practical reading: itchenshi's point 3 is a correct objection to the adapter patch, not to the bump. If the goal is "make 3. The two review points also apply upstreamWorth settling before maintainers pick a direction, because it affects the bump too. function withSessionHeader(options) {
if (!options?.sessionId || hasHeader(options.headers, OPENCODE_SESSION_HEADER))
return options;
return {
...options,
headers: { ...options.headers, [OPENCODE_SESSION_HEADER]: options.sessionId },
};
}So (1) the value sent to OpenCode is the raw session id â the privacy concern is not specific to the patch; and (2) there is no character validation, so the CRLF-to- It does respect a pre-existing header ( 4. Where the bump actually standsChecked against published artifacts:
Under 0.x semver |
|
I hit the same It adds The repository's pre-commit checks and full pre-push typecheck passed. I also applied the equivalent runtime change to my local DSH installations; an already-running DSH process still needs a restart to load it. As discussed above, this fixes the session-header 400. A catalog-unknown model can have separate protocol or |
|
Hello, the dsh 0.1.7-rc.2 version published yesterday still ships with earendil-works/pi 0.85.1 while the fix is in 0.86.0 and later versions (current latest is 0.87.1). Is there any way for dsh maintainers to upgrade the version? It would simplify a lot. |
|
Workaround while dsh still pins The official fix landed upstream in pi-ai 0.86.0 (#9326) â I couldn't just bump the dependency: What I did (local, surgical): transplanted the upstream fix into the installed package â added Wire-verified with a captured (non-delivered) request: Ask: could dsh bump |



Uh oh!
There was an error while loading. Please reload this page.
Hi - we operate the OpenCode Go managed-inference API, and about 25k of your users orgs call it through deepseek-harness. Starting 09/05, requests without an x-opencode-session header will error on our side (we need a stable per-conversation ID for routing and optimization). We measured all recent harness versions at near-zero header presence, so harness users on Go will break. Ask: include x-opencode-session set to a stable UUID per conversation on all outbound inference HTTP requests. Happy to confirm from our telemetry once a build ships it. Thanks!
All reactions