feat: add X-Session-Id header for proxy cache routing affinity#31511
Merged
Conversation
35e9346 to
9b67f1c
Compare
Providers like LLM++ (TimiAI) use X-Session-Id to route requests from the same session to the same upstream account, maximizing KV-Cache hit rate. Without this header, multi-turn conversations get scattered across different upstream accounts, causing frequent cache misses. The header is sent alongside the existing x-session-affinity header for all non-opencode providers.
9b67f1c to
e1e97f4
Compare
Collaborator
|
which providers are requiring this one? |
shoootyou
added a commit
to shoootyou/opencode
that referenced
this pull request
Jun 10, 2026
* test(core): cover skill directory output (anomalyco#31263) * fix(opencode): avoid duplicate skill catalog (anomalyco#31269) * chore(opencode): update MCP SDK to 1.29.0 (anomalyco#31268) * chore: generate * chore: update nix node_modules hashes * run: make minimal mode more minimal (anomalyco#31227) * chore: generate * chore: update web and desktop code owners (anomalyco#31289) * fix(desktop): few WSL bugs (anomalyco#31095) * chore: generate * fix(opencode): respect MCP server capabilities (anomalyco#31271) * console: update email * zen: fix * fix(opencode): include acp pending tool input (anomalyco#31321) * fix(lsp): resolve JDTLS root to topmost pom.xml in Java Maven multi-module projects (anomalyco#28761) Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com> * chore: generate * fix(session): merge per-call tool rules into session permission (anomalyco#30529) Co-authored-by: Simon Klee <hello@simonklee.dk> * docs(go): update MiniMax M3 pricing (anomalyco#31350) * fix: speed up fff file search (anomalyco#31366) * chore: generate * fix(stats): show new for leaderboard deltas * fix: stabilize fff file results (anomalyco#31369) * chore: generate * fix(core): restore npm proxy agent patch (anomalyco#31373) * chore: update nix node_modules hashes * chore: upgrade OpenTUI to v0.3.4 (anomalyco#31326) * chore: update nix node_modules hashes * fix(core): disable fff trace logs (anomalyco#31380) * fix(session): avoid sticky prompt tool overrides (anomalyco#31394) * fix(opencode): await run event loop (anomalyco#31389) * refactor(core): replace legacy logger with Effect logging (anomalyco#31310) * chore: generate * fix(tui): trim select footer action highlight (anomalyco#31411) * fix(opencode): support MiniMax M3 thinking toggle (anomalyco#31426) * fix: adjust item id stripping to happen prior to request signing (anomalyco#31429) * fix(opencode): generate reasoning variants for all OpenRouter models. (anomalyco#30332) Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Co-authored-by: Aiden Cline <aidenpcline@gmail.com> * feat(app): add draft tab support to tabs store (anomalyco#31343) * chore: generate * fix(opencode): paginate MCP catalogs (anomalyco#31442) * fix(opencode): pass abort signal to MCP tool calls (anomalyco#31455) * feat(app): draft prompt state (anomalyco#31452) * chore: generate * feat(app): tabs help button (anomalyco#31454) * feat: add "reasoning" as interleaved field option for vLLM providers (anomalyco#30477) Co-authored-by: Ben Sandbrook <1126483+delta9000@users.noreply.github.com> Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> * fix(app): clip rounded session panels (anomalyco#31462) * core: fix idle CPU use in file logger (anomalyco#31478) * docs: add uninstall troubleshooting steps (anomalyco#31424) Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> * leave a breadcrumb comment about batchWindow zero (anomalyco#31508) * chore: stats -> data * test(core): avoid Windows worker close race (anomalyco#31532) * refactor(tui): centralize application exit (anomalyco#31524) * chore: generate * feat(opencode): configure Cohere North model (anomalyco#31536) * refactor(core): consolidate references (anomalyco#31539) * feat(tui): show project copy in session list (anomalyco#31421) * chore: generate * fix(stats): use data branding assets * drop citation_options from cohere (anomalyco#31543) * zen: add north mini code model * fix(data): timestamp formatting * fix(opencode): support Claude Fable reasoning (anomalyco#31546) * fix(mcp): log actionable connection statuses (anomalyco#31544) * refactor(core): simplify location filesystem (anomalyco#31545) * chore: generate * chore: update nix node_modules hashes * fix(opencode): restore effect error logging (anomalyco#31551) * chore: generate * feat(opencode): add typed application layer graph (anomalyco#31531) * zen: add claude fable 5 * chore: generate * refactor(mcp): simplify service helpers (anomalyco#31549) * feat: add X-Session-Id header for proxy cache routing affinity (anomalyco#31511) * zen: update email * fix(desktop): update Electron stack and panel layout (anomalyco#31571) * chore: generate * chore: update nix node_modules hashes --------- Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Simon Klee <hello@simonklee.dk> Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com> Co-authored-by: Filip <34747899+neriousy@users.noreply.github.com> Co-authored-by: Frank <frank@anoma.ly> Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com> Co-authored-by: huangli <areyouok@gmail.com> Co-authored-by: Tommy D. Rossi <beats.by.morse@gmail.com> Co-authored-by: Jack <jack@anoma.ly> Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com> Co-authored-by: Dax <mail@thdxr.com> Co-authored-by: James Long <longster@gmail.com> Co-authored-by: Anthony Lau <anthony.lau2000@live.com> Co-authored-by: Aiden Cline <aidenpcline@gmail.com> Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com> Co-authored-by: Ben Sandbrook <sandbrookvt@gmail.com> Co-authored-by: Ben Sandbrook <1126483+delta9000@users.noreply.github.com> Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Sebastian <hasta84@gmail.com> Co-authored-by: Songchao Wang <songchaow@outlook.com> Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
Contributor
Author
Seems to be zenlayer. |
|
does this also maximize KV-Cache hit rate for deepseek-v4 models? |
BYK
added a commit
to BYK/loreai
that referenced
this pull request
Jun 11, 2026
…#687) ## Summary Adds first-class support for OpenCode v1.17+'s new `X-Session-Id` header for deterministic Tier-1 session identification, and simplifies the vestigial client-type detection code. ## Context OpenCode v1.17.0 ([#31511](anomalyco/opencode#31511)) added an `X-Session-Id` header alongside the existing `x-session-affinity` header for proxy setups that need sticky routing. Both carry the same stable session ID value. The gateway already recognized `x-session-affinity`, so this was functionally handled — but only through the legacy name. Adding explicit `x-session-id` recognition future-proofs against OpenCode dropping the legacy header and supports any other client adopting the standard name. ## Changes - **Add `x-session-id` to `KNOWN_SESSION_HEADERS`** (`session.ts`): ranked above `x-session-affinity` so the standard name wins when both are present. Intentionally **not** added to `GATEWAY_MANAGED_HEADERS` — the header is forwarded upstream as designed for sticky cache routing. - **Fix stale `x-session-affinity` comment**: was described as "nanoid, volatile — regenerated on restart" which is no longer accurate (current OpenCode sets it to the stable DB session ID). - **Replace `detectClientType()` with `isClaudeCodeClient()`**: the tri-state `ClientType` (`claude-code` / `opencode` / `generic`) was vestigial — nothing branched on `=== "opencode"`. The only behavioral question is "is this Claude Code?" (for `max_tokens` sizing), which is now a simple boolean. Removes the `ClientType` type export entirely. - **Update tests**: replaced `detectClientType` tests with `isClaudeCodeClient` tests, including coverage for the new `x-session-id` header returning false (session identity ≠ client identity).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes N/A (improvement — no existing issue)
Type of change
What does this PR do?
Adds an
X-Session-Idheader (set to the session ID) alongside the existingx-session-affinityheader for all non-opencode providers.Why: Anthropic API proxies (e.g. enterprise gateways that front multiple upstream Anthropic accounts) use
X-Session-Idto implement routing affinity — pinning all requests from the same session to the same upstream account. This maximizes KV-Cache hit rate on the upstream side because the cached prompt prefix lives on that specific account.Without this header, multi-turn conversations get scattered across different upstream accounts by the load balancer, causing frequent prompt cache misses and significantly higher latency + cost.
The header name
X-Session-Idis the convention used by Anthropic-compatible proxy providers (documented in their API specs). It is sent unconditionally for non-opencode providers — providers that do not recognize it will simply ignore an unknown header, so there is no behavioral change for direct Anthropic API usage or other providers.The change is a single line addition in
packages/opencode/src/session/llm/request.ts.How did you verify your code works?
bun run build --skip-embed-web-ui --singleX-Session-Idis present in all outgoing requestscache_creation_input_tokens: 1538on request 1, thencache_read_input_tokens: 1538on request 2 — confirming the routing affinity enables cache hitsScreenshots / recordings
N/A — backend-only change, no UI impact.
Checklist