DSH Hub

beihzb/dsh-opencode-session-header

dsh-opencode-session-header

BundleWorkflow14 GitHub stars· updated 2026-09-07

Per-conversation x-opencode-session injection for OpenCode Go in DeepSeek Harness - fixes 400 MissingSessionID without breaking other providers

Install

npx @deepseek-ai/dsh plugin --profile web add dsh-opencode-session-header

Restart `dsh web` after install. Bundle APIs can change during the developer preview.

README badge

dsh-opencode-session-header DSH Hub badge
[![DSH Hub](https://dshhub.dev/badge/dsh-opencode-session-header.svg)](https://dshhub.dev/plugins/dsh-opencode-session-header)

Paste this into your README. The star count updates with every catalog sync.

From the README

Excerpt from beihzb/dsh-opencode-session-header, cleaned of badges and images.

dsh-opencode-session-header

Per-conversation x-opencode-session header injection for DeepSeek Harness (DSH) → OpenCode Go.

It fixes the 400 MissingSessionID rejection and keeps OpenCode's per-conversation routing / prompt-cache optimization working — scoped strictly to opencode.ai, runtime-switchable without restart, zero dependencies.

中文文档

The problem

Since 2026-09-05, OpenCode Go requires a stable x-opencode-session header on every inference request (used for routing and prompt caching). DeepSeek Harness ≤ 0.1.2-rc.1 sends no such header on any adapter path, so every opencode-go model call fails:

400: {"type":"MissingSessionID","message":"Error from provider (Console Go): Request is missing x-opencode-session ..."}

Upstream fix is tracked in deepseek-harness discussion #5495 but has not shipped yet. This plugin fills the gap locally.

Why not the common workarounds?

Static headers in settings.yamlGlobal opencode_zen profile (dsh-custom-header)This plugin
Fixes the 400✅✅✅
Per-conversation id (cache / routing optimal)❌ one shared id → cache misses, slower & pricier✅✅ real DSH session id
Other providers untouched✅❌ rewrites UA + x-opencode-* on every host✅ opencode.ai only
Toggle without restart——✅ JSON file flip
Extra dependencies—third-party plugin, client bundlenone

Install

dsh plugin --profile web add dsh-opencode-session-header

or from a local clone / checkout:

dsh plugin --profile web add "file:C:\path\to\dsh-opencode-session-header"

Then restart dsh web once — plugins load at boot. The startup log should show:

[dsh-opencode-session-header] loaded: header=x-opencode-session hosts=opencode.ai fallback=dsh-default
[dsh-opencode-session-header] runtime switch: <DSH_HOME>\plugins\dsh-opencode-session-header.json ({"enabled":false} disables; missing file = enabled)

Runtime switch (no restart needed)

State file: <DSH_HOME>/plugins/dsh-opencode-session-header.json (defaults to ~/.dsh):

{ "enabled": false }
  • false → injection off (all requests pass through untouched);
  • true or file missing → injection on;
  • the file is re-read on every LLM request, so toggling takes effect immediately.

How it works

Two seams, both proven inside DSH 0.1.2-rc.1:

  1. llm/stream waterfall observer — wraps every adapter stream iteration in an AsyncLocalStorage carrying GenerateOptions.sessionId (stable per DSH conversation across turns, compaction and retries; fresh per conversation / fork / subagent).
  2. Fetch transport middleware — stamps x-opencode-session only when the request host matches the allowlist (default: opencode.ai + subdomains). Value = the current session id, or the fallback id (dsh-default) outside any LLM context (e.g. model discovery). Every other host passes through byte-for-byte untouched.

…

Related plugins