🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

请求头注入 chenyifawan-cell/dsh-litellm-extra-headers

DeepSeek Harness
chenyifawan-cell17 天前有提交已提供中文文档扫描:含敏感能力

给指定上游的请求体注入自定义头部字段

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/15 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add chenyifawan-cell/dsh-litellm-extra-headers
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · model
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 17 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 1 处,展示前 1 条)
  • 写入本地文件
    index.js:265
    appendFile(file, `${JSON.stringify(entry)}\n`, 'utf8').catch((error) => {
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 插件:给指定服务商和上游主机的 OpenAI 兼容 chat/completions 请求注入 body 级 extra_headers 字段(唯一能穿过 LiteLLM 中转的注入点)。

README

由 DeepSeek 最新模型翻译生成
dsh-litellm-extra-headers 给 DeepSeek Harness 用的宿主插件:把 extra_headers: { "": "<value>" } 塞进 OpenAI 兼容请求的 body,只对「配置里列出的 provider 路由」+「配置里列出的上游 host」生效。 用途:绕过 LiteLLM 之类的反向代理丢弃客户端 HTTP 头的问题——某些上游(例如 OpenCode / 网关自建的会话亲和)要求每个请求带 x-opencode-session,而代理只在 body.extra_headers 里认这个字段。 为什么只能这么做(已核实,改动前先读) 1. 客户端 HTTP 头在 LiteLLM 这一跳被丢弃。 实测把 x-opencode-session 加在请求头上,上游仍然 500;改放 body.extra_headers 后 200。 2. DSH 的 llm-pi-ai 适配器只白名单转发 temperature / maxTokens / sessionId / signal / headers / … 这些字段(见其 profileOptions()),pi-ai 唯一能塞任意 body 字段的入口 options.samplingParams 在 DSH 里没有暴露,所以纯配置解决不了。
展开完整文档(README 剩余 1 节)
dsh-litellm-extra-headers

给 DeepSeek Harness 用的宿主插件:把 extra_headers: { "": "<value>" } 塞进 OpenAI 兼容请求的 body,只对「配置里列出的 provider 路由」+「配置里列出的上游 host」生效。

用途:绕过 LiteLLM 之类的反向代理丢弃客户端 HTTP 头的问题——某些上游(例如 OpenCode / 网关自建的会话亲和)要求每个请求带 x-opencode-session,而代理只在 body.extra_headers 里认这个字段。

为什么只能这么做(已核实,改动前先读)

1. 客户端 HTTP 头在 LiteLLM 这一跳被丢弃。 实测把 x-opencode-session 加在请求头上,上游仍然 500;改放 body.extra_headers 后 200。
2. DSH 的 llm-pi-ai 适配器只白名单转发 temperature / maxTokens / sessionId / signal / headers / … 这些字段(见其 profileOptions()),pi-ai 唯一能塞任意 body 字段的入口 options.samplingParams 在 DSH 里没有暴露,所以纯配置解决不了。
3. 现成的 dsh-opencode-session 插件是「加 HTTP 头」的,在这条链路上注定无效;而且它的默认 providers 是 pi-ai 目录里的 ['opencode', 'opencode-go'],不含自定义路由键(如 gwds、go)。
4. pi-ai 的 openai-completions 走官方 openai SDK(v6.40.0),SDK 通过 this.fetch = options.fetch ?? globalThis.fetch 调用 globalThis.fetch。因此运行时替换 globalThis.fetch 是当前唯一可用的宿主侧注入点。

结论:不要在别处再加 header,那条路已经验证过是死的;要新字段就往 body 里合。

安装

已发布在 npm:dsh-litellm-extra-headers@0.1.0

npm(推荐)
dsh plugin --profile web add dsh-litellm-extra-headers

从本地目录(开发时推荐,link 安装,改动即时生效)
dsh plugin --profile web add ./dsh-litellm-extra-headers
从打包产物
dsh plugin --profile web add ./dsh-litellm-extra-headers-0.1.0.tgz
从 git 主机(本包是纯 JS,无需 pnpm 放行构建脚本)
dsh plugin --profile web add github:chenyifawan-cell/dsh-litellm-extra-headers

包内 cordis.patch.yml 会插入一行插件;dsh plugin add 识别到 dsh.bundle 后自动把本包加进该 profile 的 bundles 列表。装完确认一层存在:

dsh --profile web --dump-config | Select-String litellm-extra-headers

不想装包也可以手工把这一行写进 profile 的 cordis.patch.yml(行指向本包名或 index.js 路径)。包内自带的这一行 providers / hosts 默认留空(空列表 = 插件保持惰性),把你的路由键和上游地址填进去才生效:

- insert:
- id: litellm-extra-headers
name: dsh-litellm-extra-headers
config:
providers: [gwds, go] # 你的路由键
hosts: ["litellm.internal:4000"] # 只有这些上游才注入
header: x-opencode-session
mode: session-id
value: null
debug: false
debugFile: null

配置字段

| 字段 | 类型 | 默认 | 说明 |
| providers | string[] | [] | llm/stream 的 options.provider 路由键白名单。必须显式列出,匹配大小写不敏感。 |
| hosts | string[] | [] | 允许注入的上游 host[:port] 白名单;带 scheme / path 的写法会被归一化(http://litellm.internal:4000/v1 → litellm.internal:4000)。必须显式列出。 |
| header | string | x-opencode-session | 放进 extra_headers 的字段名。 |
| mode | session-id \| uuid \| fixed | session-id | 取值来源:DSH 会话 id(跨轮次、跨重启稳定)/每会话一个进程内随机 uuid/配置里的字面量。 |
| value | string | — | mode: fixed 时的字面量;fixed 却没给值会在加载时报错。 |
| debug | boolean | false | 每次注入决策打一条 ctx.logger.info。 |
| debugFile | string | — | 每次注入决策追加一行 JSON(含 provider / model / session / host / path / event / reason),进程控制台看不到时用它排错。 |

providers 或 hosts 为空时插件保持惰性并打一条 warning:一个可以共享出去的包,不应该对别人没被告知过的网关偷偷加字段。

设计要点

1. 双层匹配,缺一不可。
- llm/stream waterfall 里判断 options.provider ∈ providers 且存在 options.sessionId,才把 { value, provider, model, session } 放进 AsyncLocalStorage(这一步才有路由键)。
- fetch patch 里再判断目标 URL 的 host ∈ hosts 才改 body。
- 于是别人路由键跟你不同时,只会改白名单里的网关,不会给别人的网关塞未知字段。
2. 只改 /chat/completions 的 JSON body。 条件是 method === 'POST' + content-type 含 application/json + typeof init.body === 'string' + pathname 以 /chat/completions 结尾。解析失败一律原样放行;extra_headers 已存在时合并而不覆盖,已有同名字段时尊重调用方、不覆盖。
3. 零依赖 + 可还原。 只用 node:async_hooks / node:crypto / node:fs/promises;安装与卸载都是 ctx.effect(),dispose 时 globalThis.fetch 按引用还原(被别人又包了一层也不会误还原)。

验证

npm test # node --test:条目命中 / 非命中 / 已存在不覆盖 / 非 JSON 原样 / dispose 还原(19 项)
npm run test:e2e # 真机链路:本地 mock 上游 + 真实 dsh headless 跑一轮,对照组不带插件

按顺序,前一步不过不进下一步:

1. npm test 全绿。
2. npm run test:e2e:起一个会记录请求体的本地 OpenAI 兼容上游,用 dsh --profile headless --patch 把 provider 指向它并挂上本插件,跑一轮真实会话。断言:命中的请求 body 里多出 extra_headers、值在整轮里稳定(同一个会话 id)、对照组(去掉插件行)没有这个字段,并且 debugFile 有 event: "inject" 记录。
3. 换到能连到 LiteLLM 的那台机器上(第 2 步用的是本地 mock 上游,不需要网络)再跑一轮,用 debugFile 确认日志里出现注入记录,且上游不再报缺少会话头。这一步验证的是 LiteLLM 自己的「body.extra_headers → 上游请求头」合并行为,只有真实网关能证明。
对照实验:手动 curl 只带 HTTP 头、不带 extra_headers → 上游报错;body 里带 extra_headers → 通过。

发布备忘(首次发布踩过的坑)

1. 2FA 必须开:npm 只支持安全密钥(Windows Hello 指纹/PIN 或 YubiKey),没有 Google Authenticator 那种 TOTP。
2. npm publish 要在真终端里跑:npm 只在 stdin/stdout 都是 TTY 时才走「自动开浏览器 → 轮询授权 → 自动重试上传」那条路(lib/utils/auth.js 的 otplease);管道化的非交互进程会直接抛 EOTP,而错误文本里的授权 URL 被 @npmcli/redact 打码,等于拿不到链接。
3. 新包名会先进审核:首次发布会先在 registry 上生成一个 0.0.0-stage 占位版本("Temporary package placeholder for staged publishing"),真正的版本进入审核,CLI 只提示 Your package is being processed。几分钟后正式版本自动上线,latest 指向它,占位版留在历史里。期间 npm stage list 可能为空,不用慌。
4. 发布前记得 --registry=https://registry.npmjs.org:本机若把 registry 指向 npmmirror 这类只读镜像,默认 npm publish 会打错源。

已知边界

- input 是 Request 对象时(body 在 Request 里,同步读不出来)不改,原样放行;当前 pi-ai + openai SDK 走的是「URL 字符串 + init.body 字符串」,不触发这条。
- extra_headers 存在但不是普通对象(数组 / 字符串等)时原样放行,避免把别人的 body 改坏。
- 只注入,不做重试、不改 header、不改其它 body 字段。

English summary

Host plugin for DeepSeek Harness: while a model call routed to a configured provider streams, globalThis.fetch merges extra_headers[] = <value> into the JSON body of POST .../chat/completions requests sent to a configured upstream host. It exists because a LiteLLM relay drops client HTTP headers (verified: header-only 500, body extra_headers 200), DSH's pi-ai adapter whitelists request fields, and the existing dsh-opencode-session plugin only sets a header. Both providers and hosts must be listed explicitly, or the plugin stays inert. MIT.

License

MIT
预览分享卡片长什么样 ↓chenyifawan-cell/dsh-litellm-extra-headers
分享 · DeepSeek Harness Hub
chenyifawan-cell/dsh-litellm-extra-headers

给指定上游的请求体注入自定义头部字段

回到顶部