dsh-session-header:为 Harness 的 LLM 请求注入会话 Header

前言

DeepSeek Harness(DSH)在调用模型时,会把会话信息放在 GenerateOptions.sessionId 里,但 harness 本身没有统一的「请求级 header」扩展点:GenerateOptions 不含 headers 字段,各 adapter 各自构造线上 HTTP header。若你的模型网关、中间代理或审计层需要按 session header 做路由、缓存或关联日志,仅靠 harness 默认行为往往发不出这个头。

社区插件 dsh-session-header(维护者 EmotionTowel)通过 harness 官方拦截点,在每一次 LLM 相关 fetch 上注入可配置的 session header,并在需要时覆盖工具执行期内、指向指定网关前缀的请求。下面介绍它的定位、安装与典型配置。

这是什么

dsh-session-header 是 DSH 的 Cordis 插件(当前包版本 0.2.2,MIT 许可)。它在不改变 adapter 源码的前提下,给 harness 发出的 LLM 请求(以及按配置白名单匹配的工具期 fetch)加上 HTTP header,默认名为 x-session-id,值为该次调用对应的 harness session id。

与直连 DeepSeek 官方 API 不同:官方 llm-deepseek adapter 已自带 x-deepseek-harness-session-id;本插件面向 provider 中立场景,且默认不覆盖调用方已设置的同名 header。

为什么需要它

harness 缺少全局 header 缝,各传输层若最终走 globalThis.fetch,本插件用两处机制补齐:

  1. llm/stream waterfall:标记 LLM 调用,并携带 options.sessionId;
  2. globalThis.fetch 补丁:在 LLM 调用流内部的 fetch 上注入 header,覆盖 llm-deepseek、llm-pi-ai 等基于 fetch 的 adapter。

上下文通过 AsyncLocalStorage 传播:只有某次 LLM 调用流内部的 fetch 会被修改;web RPC、遥测、无关工具流量原样通过。别人已设置的 header 按 HTTP 语义(大小写不敏感)不会被覆盖;插件卸载时还原原始 fetch。

取值语义(资料原文):

  • 未配置 value:取当前调用的 GenerateOptions.sessionId,并去掉 harness 的 session- 品牌前缀,发送纯 UUID;主会话各轮、压缩/起标题辅助调用、in-process 子 agent 各自上报自己的 session id;
  • 配置了 value:所有匹配注入规则的调用使用固定字符串(原样发送,不剥前缀);
  • 两者皆无时,不发该 header。

核心功能

  • 可配置 header 名(默认 x-session-id)。
  • 可选固定 value,或动态使用当前 harness session id。
  • toolEndpoints:工具执行期(tools/execute 瀑布内)仅对 URL 前缀匹配的 fetch 注入 header;默认空数组时保持「仅 LLM 流内注入」行为。
  • overwriteHeaders:允许覆盖已有值的 header 名列表,用于替换某些 provider 硬编码的占位 session 头。
  • 不触碰 attributionHeaders();并发会话经 AsyncLocalStorage 解析,不依赖共享可变状态。

安装与启用

需要已安装 dsh CLI,且 Node ≥ 22。本包为纯 JavaScript,无构建脚本。

作为 bundle 安装(推荐)

在指定 profile 下执行:

dsh plugin --profile <name> add github:EmotionTowel/dsh-session-header

验证配置层并启动:

dsh --profile <name> --dump-config   # 应能看到 "# == dsh-session-header" 层
dsh --profile <name>

本地 checkout 用 overlay 加载

开发或本地路径时,可在 overlay 中用绝对路径引用 index.js(示例来自 README):

# my-overlay.yml —— 此处插件行需要绝对模块路径
- 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

配置项

字段 类型 默认 含义
header string x-session-id 注入的 header 名
value string — 固定值;不设则取当前调用的 harness session id
toolEndpoints string[] [] 工具执行期 URL 前缀白名单;非空时仅匹配前缀的 fetch 在工具期内注入
overwriteHeaders string[] [] 允许本插件覆盖已有值的 header 名列表

在 profile 的 cordis.patch.yml 中调整 session-header 插件的 config 即可。

典型用法:适配 OpenCode Go 网关

OpenCode Go 文档要求请求携带稳定的 session header(x-opencode-session),缺失时网关会返回 400(MissingSessionID)。README 给出三步配置,无需再查网关文档细节。

1. 会话请求(LLM)

# ~/.dsh/profiles/<name>/cordis.patch.yml
- id: session-header
  config:
    header: x-opencode-session
    toolEndpoints:
      - https://opencode.ai/zen/go/v1

2. web-search(工具执行期的网关 fetch)

Go 的 web-search 走 Anthropic Messages 端点,fetch 发生在工具执行期,需 toolEndpoints 纳入范围;必要时用 overwriteHeaders 替换硬编码占位值:

- id: session-header
  config:
    header: x-opencode-session
    toolEndpoints:
      - https://opencode.ai/zen/go/v1
    overwriteHeaders:
      - x-opencode-session

toolEndpoints 只匹配 URL 前缀,web_fetch 抓任意网页、GitHub、MCP 等第三方目标不受影响。

3. headless profile

每个 profile 的插件相互独立;使用 Go 网关跑 headless 时需单独安装并配置:

dsh plugin --profile headless add github:EmotionTowel/dsh-session-header
# ~/.dsh/profiles/headless/cordis.patch.yml
- id: session-header
  config:
    header: x-opencode-session
    toolEndpoints:
      - https://opencode.ai/zen/go/v1

验证示例(exit=0 且模型正常回答即为通过):

dsh --profile headless "运行 pwsh 命令 Get-Random -Maximum 1000000,只回复该数字"

验证注入是否生效

将某 provider 的 baseURL 指向会记录或回显请求 header 的端点,开启会话后应看到类似:

x-session-id: ba104306-a748-4052-a6e3-ab60be2e4c1f

同一会话内请求携带同一 id;spawn 出的子 agent 请求携带 child session id。

适用场景与注意

适合:自建或第三方模型网关按 session header 路由、缓存、审计;需要与 OpenCode Go 等强制 session 头的服务对齐;希望在不动 adapter 的前提下统一注入会话标识。

不需要本插件:直连 DeepSeek 官方 API(api.deepseek.com)时,llm-deepseek 已带 x-deepseek-harness-session-id,无需本节 OpenCode 类配置。

安全与权限:DSH 插件在当前 dsh 进程权限下运行,会 patch 全局 fetch 等行为。安装前应阅读 仓库源码 与 MIT 许可证,确认符合你的合规要求。社区目录 SkillHub 插件页 与 DeepSeek / 幻方无官方从属关系,属于 DSH「一切皆插件」生态中的第三方扩展。

结尾

dsh-session-header 用 llm/stream 与 fetch 补丁组合,补上 harness 缺少的请求级 session header 能力,并支持工具期白名单与有限覆盖,便于对接按 session 约束的网关。更多信息见 GitHub 仓库 与 SkillHub 目录页。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜