homily707/dsh-session-header
项目介绍Project Overview
dsh-session-header 是 DeepSeek Harness 插件,通过拦截 llm/stream 并补丁 globalThis.fetch,为每次 LLM 请求注入携带当前会话 ID 的 x-session-id 头(可用 AsyncLocalStorage 隔离并发,不覆盖已有头)。适用于网关按会话做路由、缓存或审计的场景;仅覆盖基于 fetch 的适配器,卸载后恢复原 fetch。
dsh-session-header is a DeepSeek Harness plugin that injects an x-session-id HTTP header on every LLM provider request, carrying that call's harness session id. It combines the llm/stream waterfall with a globalThis.fetch patch, using AsyncLocalStorage so only in-call fetches are touched and existing headers are never overwritten. Use it when a gateway or proxy keys routing, caching, or auditing on a session header. Caveat: only fetch-based adapters are covered; unloading restores the original fetch.
请帮我了解并安装插件:【dsh-session-header】【https://github.com/homily707/dsh-session-header】
把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.
或使用命令行安装(适合开发者)Or use CLI install (for developers)
命令行安装CLI Install
dsh plugin --profile web add github:homily707/dsh-session-header
把 homily707/dsh-session-header 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
dsh-session-header
English | 中文
A DeepSeek Harness plugin that injects an x-session-id HTTP header onto every LLM provider request the harness sends, carrying the harness session id of that exact call.
Why
The harness has no per-request header seam — GenerateOptions has no headers field and every adapter builds its own wire headers internally. If your model gateway (or an intermediary proxy) keys routing, caching, or auditing on a session header, the harness cannot send one by itself.
This plugin closes that gap with the two official interception points composed together:
- the
llm/streamwaterfall names the calls that are LLM calls and carriesoptions.sessionId; - a
globalThis.fetchpatch adds the header, so every fetch-based adapter (llm-deepseek,llm-pi-ai, and any SDK whose transport bottoms out in global fetch) is covered without touching adapter code.
Context propagation uses AsyncLocalStorage: only fetches that happen inside an LLM call's stream are touched; unrelated fetches (web RPC, telemetry, tool traffic) pass through untouched. A header anyone else already set is never overwritten (case-insensitive, per HTTP semantics). Unloading the plugin restores the original fetch.
Semantics of the value:
- default:
GenerateOptions.sessionIdof the call in flight, with the harness'ssession-branding prefix stripped (a plain UUID is sent) — main-session turns, compaction/title helper calls, and in-process subagent children each report their own session id (subagents get their own child session ids); valueconfig: a fixed value for every call instead (sent verbatim, no prefix stripping);- calls with neither get no header.
Install
Requires the dsh CLI and Node ≥ 22.
As a bundle (recommended)
dsh plugin --profile <name> add github:homily707/dsh-session-header
This package is plain JavaScript with no build scripts, so the pnpm ≥ 10 build allowance is not needed. Verify the layer and boot:
dsh --profile <name> --dump-config # look for the "# == dsh-session-header" layer
dsh --profile <name>
As a --patch overlay from a local checkout
# my-overlay.yml — plugin rows need an absolute module path here
- insert:
- id: session-header
name: /absolute/path/to/dsh-session-header/index.js
config:
header: x-session-id
# value: my-fixed-session-id
dsh --patch ./my-overlay.yml
Configuration
| field | type | default | meaning |
|---|---|---|---|
header |
string | x-session-id |
header name to inject; case-insensitive on the wire |
value |
string | — | fixed value; unset = the harness session id of the call in flight |
Verify it
Point a provider's baseURL at a logging gateway (or any endpoint that echoes request headers) and start a session:
x-session-id: ba104306-a748-4052-a6e3-ab60be2e4c1f
Every request of the same conversation carries the same id; a spawned subagent's requests carry the child session id.
Notes
- The
llm-deepseekadapter already sends its ownx-deepseek-harness-session-idon every request; this plugin is provider-neutral and intentional about not overwriting existing headers. attributionHeaders()(the harness User-Agent attribution contract) is never touched.- Concurrent sessions are handled correctly: the header value is resolved per call through AsyncLocalStorage, not through shared mutable state.
nexu-io/open-design
freestylefly/awesome-gpt-image-2
anywhere-labs/dsh-desktop
walkinglabs/learn-harness-engineering
awesome-dsh-plugin/awesome-dsh-plugin
MemTensor/MemOS