Repository navigation
Replies: 47 comments 19 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. |
|
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 |
|
There are still issues in the auto review mode. Even in this mode, the problem of the "x-opencode-go" header is still reported. |
OpenCode Go session routing: deterministic per-session
|
session_id in body |
result |
|---|---|
| absent | MissingSessionID |
"dsh-council-fixed0001" (non-UUID string) |
model_coming_soon |
550e8400-e29b-41d4-a716-446655440000 (RFC example UUID) |
success (later 6/6) |
fresh random UUID #1 (2222d277-…) |
model_coming_soon |
fresh random UUID #2 (428fa56e-…, ×6) |
model_coming_soon (0/6) |
The outcome is deterministic per session value (6/6 vs 0/6, no flapping within a 12-request window), same key / same model / same UA throughout. That pattern suggests session-based routing lands requests in backend buckets whose model catalogs currently differ — i.e. in this state model_coming_soon is a routing-fallback artifact rather than real availability (the model is on the Go list).
What we fixed on our side. Our bridge client used to send dsh-council-<12 hex chars> — a non-UUID string, regenerated per process — which violates the "stable session ID" requirement on both counts. It now persists an RFC 4122 UUID across processes. Heads-up for others with custom paths: the new persistent UUID still resolved to a model_coming_soon bucket as of a few minutes ago, so if you switch session formats, expect a transition window until the rollout converges.
UA is not the differentiator in our case: both the working agent path and the failing bridge path send the same DSH user agent; the only variables that changed outcomes were session-header presence and session value.
Happy to run more controlled probes if this data helps. — hbgangcn1
|
Adding a data point in support of shipping this, focused on one implementation detail that the static-header workaround does not cover. The static Why this matters for DSH users specifically:
Suggested shape (converging the existing proposals): add the opt-in Happy to test a build and report wire-level confirmation against Go/Zen if that helps. |
|
I'd like to support the proposal to add a configurable Our use case is DeepSeek Harness 0.2.0-rc.2 connected to a local OpenAI-compatible bridge, which delegates execution to OpenCode. The bridge already supports streaming and cancellation, but we need a stable, per-conversation DSH session identifier to safely reuse the corresponding OpenCode session across turns. We have confirmed that DSH passes A configurable It would also benefit other stateful gateways and agent bridges. Could you confirm whether this feature is planned for an upcoming release, or whether the proposed implementation is open for contribution? Thank you! |
|
Auto review still 400s on OpenCode Go ( Repro on 0.2.1-rc.2 with an Root cause: This is a second gap beyond the chat-call coverage discussed above: auxiliary/hand-built Minimal fix: const options: GenerateOptions = deepFreeze({
provider: snapshot.provider,
model: snapshot.model,
sessionId: agent.session.id, // ← add
...
})The review prompt never enters the Session log, so passing the identity only affects transport routing. Happy to send a PR with a test if that shape is acceptable. Deployed workaround in the meantime: a static per-route header opencode-go:
headers: { x-opencode-session: dsh-opencode-go }which trades per-conversation affinity for not breaking. |
|
新版本的dsh已经更新了pi-ai,所以现在会自己加x-opencode-session了,只不过自动审查没有 |
|
Confirming winliyou's note with a check on
Caveat that still holds from our earlier matrix: custom paths that hand-build |


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