dsh 插件:进程内代理,注入官方 OpenCode Zen 客户端请求头,让 dsh 用上 Zen 免费模型,不再报 429 FreeUsageLimitError
37.8/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/10 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Yee-h/dsh-zen-proxy该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · model
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 26 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-zen-proxy(未发布到 npm,仅可源码安装)
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/31 07:31:45
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 4 处,展示前 4 条)
- 读取本地文件src/state.js:126
const text = readFileSync(filePath, 'utf8'); - 写入本地文件src/state.js:142
mkdirSync(dirname(filePath), { recursive: true }); - 写入本地文件src/state.js:143
writeFileSync(temporary, `${JSON.stringify(state)}\n`, 'utf8'); - 写入本地文件src/state.js:144
renameSync(temporary, filePath);
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-llm给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 进程内代理
- 注入官方请求头
- 使用Zen免费模型
README
由 DeepSeek 最新模型翻译生成dsh-zen-proxy
一个 DeepSeek Harness(dsh) 插件:把 OpenCode Zen 的免费模型车道接成 dsh 的原生 llm-provider。
装上即可在桌面端的模型选择器里直接使用 Zen 的免费模型,不需要监听端口、不需要写 settings.yaml、不需要 API Key。插件以官方 OpenCode 客户端的网络身份向上游发请求,每 10 分钟探测一次可用性,并且只把「判定为可用」的免费模型放进目录。
这次改造是破坏性变更。 旧版本是一个本地 HTTP 代理(监听 127.0.0.1:4097,要求用户把 provider 的 baseURL 指向它)。代理面、host/port/upstream/userAgent 等配置项已全部移除,也删掉了 index.js 里的 http/https 服务器代码。
这是什么
dsh 的模型选择器只从适配器的 listModels 取模型,而 listModels 与
normalizeModelInfo 都没有「不可用」字段(已核对宿主 @deepseek-ai/dsh-llm 的权威契约)。因此「哪些免费模型现在真的能用」这件事,只能由路由分组来表达。
展开完整文档(README 剩余 1 节)
dsh-zen-proxy
一个 DeepSeek Harness(dsh) 插件:把 OpenCode Zen 的免费模型车道接成 dsh 的原生 llm-provider。
装上即可在桌面端的模型选择器里直接使用 Zen 的免费模型,不需要监听端口、不需要写 settings.yaml、不需要 API Key。插件以官方 OpenCode 客户端的网络身份向上游发请求,每 10 分钟探测一次可用性,并且只把「判定为可用」的免费模型放进目录。
这次改造是破坏性变更。 旧版本是一个本地 HTTP 代理(监听 127.0.0.1:4097,要求用户把 provider 的 baseURL 指向它)。代理面、host/port/upstream/userAgent 等配置项已全部移除,也删掉了 index.js 里的 http/https 服务器代码。
这是什么
dsh 的模型选择器只从适配器的 listModels 取模型,而 listModels 与
normalizeModelInfo 都没有「不可用」字段(已核对宿主 @deepseek-ai/dsh-llm 的权威契约)。因此「哪些免费模型现在真的能用」这件事,只能由路由分组来表达。插件注册两条路由:
| 路由 id | 分组语义 | 目录内容 |
| opencode-free | 免费模型(主分组) | 最近一次探测判定为可用的免费模型 |
| opencode-free-region | 免费模型(地区受限) | 最近一次探测判定为地区受限的免费模型 |
两条路由的展示名分别是 OpenCode Zen 免费模型 与 OpenCode Zen 免费模型(地区受限)。
「免费」的判据是模型 id 以 -free 结尾(上游清单里没有表示免费的字段,实测清单每项只有 id / object / created / owned_by)。付费模型、判定不可用的模型、以及尚未判定完成的模型都不会出现在任何一条路由里。
安装
1. 用桌面端的插件管理器安装(推荐)
在桌面端「设置 → 插件」里安装 dsh-zen-proxy(本地 checkout 或 git 地址都可以)。插件管理器会调用该 profile 自己的包管理器完成安装,并把包名自动追加进 package.json 的 dsh.profile.bundles——这一步是必须的,否则包装上了但不会被当作 profile 层加载。
2. 命令行安装(等价做法)
dsh plugin --profile desktop add git+https://github.com/Yee-h/dsh-zen-proxy.git
或在本地 checkout 时:dsh plugin --profile desktop add file:C:/path/to/dsh-zen-proxy
dsh plugin 只把参数透传给 profile 的包管理器(本机为 pnpm),因此它不会替你写 dsh.profile.bundles(本机实测:手工移除该条目后重跑 dsh plugin add,条目未被加回)。
装完有两种方式补上它:
- 推荐:让运行中的宿主自己 reconcile——它检测到 dependencies 多了一个带 bundle patch 的包时,会把它追加进 dsh.profile.bundles(本机实测该行为确实发生)。装完重启宿主即可。
- 或手工在 $DSH_HOME/profiles/desktop/package.json 里补上:
{
"dsh": {
"profile": {
"bundles": [
// …已有的 bundle…
"dsh-zen-proxy"
]
}
}
}
profile 由 pnpm 管理(有 pnpm-lock.yaml、.modules.yaml),不是 npm 工程。
请用 dsh plugin 或 pnpm install;npm install 不会更新 pnpm-lock.yaml,会留下与 .modules.yaml 不一致的 node_modules。
@deepseek-ai/(cordis、dsh-llm、schemastery)由宿主在运行时注入,不会(也不应)出现在 profile 的 node_modules 里,因此它们只作为本包的 peerDependencies 声明。
3. 重启宿主
重启 dsh。本包通过自身的 dsh.bundle.patch(cordis.patch.yml)向 profile 注入 loader 条目:
- insert:
- id: zen-proxy
name: 'dsh-zen-proxy'
config: {}
本插件没有浏览器半身,因此 package.json 里刻意不声明 dsh.client。
4. 不需要任何其它配置
不再需要把某个 provider 的 baseURL 指向本地端口,也不再需要 settings.yaml。
凭据是池化的 Bearer public,无需用户密钥。
配置
插件有两个配置项(探测周期,以及受门槛约束的伪装版本号):
| 字段 | 默认值 | 说明 |
| probeIntervalMinutes | 10 | 探测周期(分钟)。运行中修改后,下一轮起生效,无需重启进程。 |
| opencodeVersion | 1.18.31 | 伪装用的 OpenCode 版本。低于闸门门槛 1.18.0 的值不会被使用,插件会记录一条诊断并回退到门槛值。 |
探测、宽限与退避语义
- 挂载后立即探测一轮,且不阻塞挂载(首轮异步发起,目录在首轮返回后填充)。
- 之后每 10 分钟(或配置的周期)重复一轮:先取上游清单 → 按 -free 过滤 → 逐个探测。
- 可用性判定必须解析数据帧:HTTP 200 不等于可用。实测网关会在 2xx 的流里塞进
错误对象(data: {"error":{"type":"server_error",…}}),只看状态码会把不可用的模型误判为可用。判定顺序是:非 2xx 按错误信封的 type 与状态码分类;2xx 则读数据帧,出现错误对象即判失败,出现正常增量才判可用。
- 瞬时故障宽限:限流、上游 5xx、网络失败属于瞬时故障。一个模型在连续 3 次以内的瞬时故障中保留此前的判定(因此一次抖动不会把它从目录里抹掉),第 3 次才转为不可用并移出目录。地区归属不会被一次 429 覆盖(地区受限的模型在限流那一轮仍留在地区分组)。
- 全轮限流退避:如果一整轮里所有模型都被判为限流,下一次探测的间隔按指数延长(退避间隔恒不小于配置周期),直到某一轮出现至少一个可用模型后回到配置周期。上限 1 小时。
- 身份/版本被拒是插件级失败:403 FreeTierError 或 426 UpgradeRequired 与具体模型无关,此时整条车道降级——所有模型转 unknown、两条路由都清空,并记录一条插件级诊断。其它情况下,清单拉取失败只会让本轮作废,既有目录保持不动。
- 结果持久化:最近一次判定写入宿主环境解析出的状态目录($DSH_HOME/zen-proxy/availability.json,未设置 DSH_HOME 时为宿主配置根下的同名路径),采用「先写临时文件再原子改名」。文件缺失或无法解析时按无历史处理,挂载不受影响。因此重启后目录在首轮探测完成前就反映上次已知状态。
- 探测流量与对话配额隔离:探测使用独立种子派生的 x-opencode-session,与任何用户对话的会话都不同;用户对话的会话按对话标识经 sha256 稳定派生,同一对话重启后仍是同一会话(免费配额按 session 计,逐请求新造会话会把配额打满)。
实测提醒:一轮探测会短时间内打出十来个请求,整条车道随后出现瞬时限流是正常的(实测遇到过:探测刚结束,紧接着的对话请求得到 429 RATE_LIMIT,等一分钟再试即恢复)。这正是上面「瞬时故障宽限」和「退避」存在的原因。
地区受限模型
muse-spark-1.2-contributor-free 与 muse-spark-1.3-contributor-free 在本机出口(实测国家 CN)恒为:
{"type":"error","error":{"type":"RegionError","message":"This model is not available in your country."}}
HTTP 状态码 403,无论走 /chat/completions 还是 /responses、无论是否携带工具都一样。它们只会出现在 opencode-free-region 分组里,opencode-free 里不会出现。
注意一个实测到的先后关系:当免费车道正处于限流状态时,这两个模型返回的是 429 FreeUsageLimitError 而不是 RegionError——限流发生在地区判定之前。因此「地区受限」只能在车道不处于限流时观察到;插件靠上面说的「瞬时故障宽限」保留此前的地区归属,不会被一次 429 抹掉。
思考强度
模型选择器里的「思考强度」下拉是插件提供的,上游没有这个概念。本车道的网关接受 reasoning_effort、thinking.budget_tokens、enable_thinking、thinking_budget 之后全部忽略(low 产生的思考 token 反而比 high 多,未知字段还会偶尔 503;四种拼写的对照取自参考实现的实测,本机复测的是 reasoning_effort,见 evidence.md (1)),唯一被执行的强度旋钮是输出预算上限。因此宿主需要的 reasoning.efforts 菜单由插件给出,每一档都折算成请求体的 max_tokens(chat 族)或 max_output_tokens(responses 族)。
| 档位 | 基准输出上限 | 实际发出 | 含义 |
| light · 精简 | 2048 | 2048 × 2 = 4096 | 最短思考,最快给出答案 |
| balanced · 均衡(默认) | 8192 | 8192 × 2 = 16384 | 思考与正文各占一半 |
| deep · 深度 | 模型容量 | 该模型的输出容量 | 尽量思考,正文可能先被截断 |
- 为什么乘 2:输出上限同时限制思考与正文,倍率 2 对应「思考占比不超过 50%」这一边界(正文 = 2 × 基准 × (1 − 占比),故占比 ≤ 50% 时档位名里的数字仍是正文的下界)。本机复核 mimo-v2.6-flash-free 的占比为 33%-43%(evidence.md (1)),落在边界内:light 档实测正文 3117 token(预算 4096、思考 979)。参考实现曾在同一模型上测得约 82%(92 次调用,见 evidence.md (2b)),该占比与 2 倍系数不相容,本机未复现,故未按它标定。
- 容量取自哪里:models.dev 的 limit.output,逐条溯源与取值日期写在 src/catalog.js 的 OUTPUT_LIMIT_SOURCE 注释里。没有溯源的模型(jev-1.13-free)回退到 32768。
- 档位名称里的数字是发出预算的千位表示:菜单上的 精简 · 4 K 与请求体里的 4096 由同一次折算得出,不存在两套算法(回归测试锁死这一点)。容量不是 1024 的整数倍时按四舍五入显示,例如 mimo-v2.6-flash-free 的容量 32000 显示为 深度 · 31 K。
- 调用方上限只收窄不抬高:宿主或调用方显式指定输出上限时,实际发出的是它与档位预算中的较小者——档位不会突破调用方上限,调用方上限也不会把档位抬高。预算恒为整数且不小于 512——非正数、NaN、Infinity 一律视为「没有该上限」,不会把回复压没。
上游协议
- 清单:GET https://opencode.ai/zen/v1/models(唯一允许写死的网络地址就是上游 base URL)。
- chat 协议族:POST https://opencode.ai/zen/v1/chat/completions。
- responses 协议族:POST https://opencode.ai/zen/v1/responses。
协议族按模型 id 判定:muse-spark 走 responses,其余走 chat。这个判据是间接的,且在本机无法证真:上游清单不披露协议族,而这两个 id 走哪条端点都返回 RegionError(地区闸门先于路由判定),因此真实链路无从区分;依据、反证与残留不确定性见 openspec/changes/archive/2026-10-07-add-opencode-free-provider/evidence.md 的「协议族的判据(间接;本机无法证真)」。
每个上游请求都带齐六个身份头。其中 user-agent(opencode/ 且不低于 1.18.0)与 x-opencode- 是实测的闸门必需项(去掉 user-agent 或去掉全部 x-opencode- → 403 FreeTierError);authorization: Bearer public 是该车道的池化免密凭据,插件始终携带,但实测单独去掉它仍返回 200(见 evidence (2) 的 F 行):
user-agent: opencode/<version> # version >= 1.18.0
authorization: Bearer public
x-opencode-client: desktop
x-opencode-project: global
x-opencode-session: ses_<12 hex><14 base62>
x-opencode-request: msg_<12 hex><14 base62>
请求体另外要满足两条闸门要求:流式(stream: true)与声明工具数组。工具数组里小写的 bash、glob、grep、read 四个名字必须齐备,缺失的槽位会优先把能真正代答的调用方工具改名填入(Windows 上宿主的 pwsh 填入 bash 槽),其余才补一个自禁用占位工具;响应侧再把被改写的工具名映射回调用方的原始拼写。
偏离 dsh attribution 契约的说明
宿主 @deepseek-ai/dsh-llm 要求每个 provider HTTP 请求携带 attributionHeaders(),其实测值为:
user-agent: deepseek-harness/<version> (+https://github.com/deepseek-ai/deepseek-harness)
而 Zen 免费车道的闸门只接受 user-agent: opencode/<version>(且版本不低于 1.18.0)。
两者互斥,实测对照(其余五个身份头齐备,同一份请求体):
| 发送的 user-agent | 结果 |
| opencode/1.18.31 | 200 ✅ |
| deepseek-harness/<version> (+…) | 403 FreeTierError:OpenCode's free tier can only be used from within OpenCode |
| opencode/1.17.0 / 更旧 | 426 UpgradeRequired:OpenCode 1.18.0 or newer is required to use the free tier |
本插件选择过闸,因此在这一处覆盖 attribution:user-agent 是官方客户端身份, 不携带任何用户数据,也不是遥测通道。该偏离在源码中对应位置有注释(src/identity.js 的模块头与 buildIdentityHeaders),此处是面向用户的同一说明。
已知限制
1. 地区受限模型无法在本机证真。muse-spark-1.2/1.3-contributor-free 在本机出口恒为 403 RegionError(车道处于限流时会先返回 429),因此只能验证「归类正确」,无法验证「在允许的地区可用」。
2. responses 协议族无法在本机走通真实链路。该族只有这两个 muse-spark 模型,全部被地区闸门挡住。它的请求编码与事件解析由注入式桩流覆盖(test/responses.test.js),真实连通性是未验证项。
3. 免费配额仍然存在。身份伪装只是让请求看起来来自官方客户端,不能创造配额;配额按会话池化,用满后会返回 429 FreeUsageLimitError(映射为 RATE_LIMIT),退避或等窗口恢复。
4. 首版不支持图片输入。目录里每个模型都声明 inputModalities: ['text'],宿主会把图片投影成文本占位符,适配器永远不需要处理图片块。
5. 能力元数据只有上下文窗口与输出上限,且只有部分模型有。上游清单不提供任何能力字段, contextWindow 与输出容量只在有可溯源来源时给出(来源与取值日期见 openspec/changes/archive/2026-10-07-add-opencode-free-provider/evidence.md),无来源的模型省略 context 但仍会出现在目录中;jev-1.13-free 既无窗口也无输出上限溯源,它的「深度」档因此回退到 32768。刻意不声明 defaultMaxTokens:它与档位无关,无法表达思考强度差异,请求体的输出预算改由档位折算给出(见「思考强度」)。
6. 档位 id 不跨 provider 通用,本车道不做别名。本车道的档位是 light / balanced / deep;若把别的 provider 的档位(例如 high、medium)带给本车道的模型,宿主会在调用适配器之前 抛 UNSUPPORTED_REASONING_EFFORT——这是宿主既定行为(不 clamp、不 alias),本插件也不做映射,因为档位语义在本车道是「输出预算」,与别的 provider 的强度档没有可溯源的换算关系。
实务影响:把 profile 的默认模型切到本车道时,若 agent-default-model 里还留着别的 provider 的 reasoningEffort,该轮请求会被拒;把该字段改成三个档位之一或删掉即可(删掉则用默认档 balanced)。
开发
npm install # 只装 devDependency:@deepseek-ai/schemastery
npm test # node:test,覆盖全部纯逻辑模块与适配器行为
scripts/ 保存开发期取证与验证脚本(不参与运行时,也不在 npm files 白名单里,因此不会随包发布)。它们被 openspec/ 的变更文档引用为「可复现命令」,因此随仓库一起版本化;每个脚本都用 import.meta.dirname 推导路径,在任意 checkout 位置都能直接运行:
node scripts/verify-sources.mjs # models.dev 实时值 / 常量表 / 文档表格 三方对照
node scripts/verify-evidence-matches-script.mjs # 文档粘贴块与脚本真实 stdout 逐行比对
node scripts/verify-all-models-ladder.mjs # 11 个模型逐档核对菜单名称与预算一致
node scripts/verify-catalog-resolve-consistency.mjs # 目录里每个 id 都能解析出合法档位菜单
node scripts/verify-foreign-effort.mjs # 跨 provider 档位 id 被宿主拒绝、未指定则落默认档
node scripts/e2e-tiers.mjs # 档位 → 宿主校验 → 请求体预算 端到端
node scripts/verify-import-regex.mjs # 依赖检查正则能抓到动态宿主 import
node scripts/count-imports.mjs # 说明符计数口径(旧单正则 40 / 新四正则去重 39)
node scripts/mutation-test-import-check.mjs # 变异测试:证明对抗用例真能抓住正则退化
node scripts/verify-archive-merge.mjs # 归档后 MODIFIED 头与主规格逐字匹配
node scripts/verify-version.mjs # package.json / lock 三处版本一致
scripts/effort.mjs、scripts/tiers.mjs、scripts/limits.mjs、scripts/final-consistency-scan.mjs 是直连上游/扫描仓库的实测脚本,其中前两个会真实调用 https://opencode.ai。
模块边界:
| 文件 | 职责 |
| index.js | 薄入口:name / inject / Config / apply |
| src/identity.js | 身份头与版本门槛、会话/请求 id 派生(含上面那处偏离的注释) |
| src/http.js | 上游请求封装、SSE 解码、错误分类接线 |
| src/catalog.js | 清单解析、免费过滤、协议族判定、可溯源能力元数据 |
| src/effort.js | 思考档位阶梯与「档位 → 输出预算」折算(宿主无关纯逻辑) |
| src/probe.js | 单模型探测与判定 |
| src/state.js | 判定状态机与持久化 |
| src/schedule.js | 周期调度与退避 |
| src/messages.js | harness 消息 → 两种 wire 请求体 |
| src/tools.js | 工具四连补齐与名称回写 |
| src/chunks.js | StreamChunk 构造、块索引追踪、用量换算 |
| src/chat.js | chat 族 SSE → StreamChunk |
| src/responses.js | responses 族 SSE → StreamChunk |
| src/failure.js | 失败分类与失败对象构造 |
| src/adapter.js | 适配器(六点:providerInfo/providerRetryPolicy/imageRequestPricing/listModels/resolveModel/prepareCall) |
| src/register.js | 宿主接线(唯一接触 @deepseek-ai/ 的地方) |
除 src/register.js 外没有任何模块 import 宿主包,因此全部纯逻辑都能在仓库内直接单测。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Yee-h/dsh-zen-proxy
dsh 插件:进程内代理,注入官方 OpenCode Zen 客户端请求头,让 dsh 用上 Zen 免费模型,不再报 429 FreeUsageLimitError
相关插件 · 模型接入
API 中继安全审计toby-bridges/api-relay-audit
面向 AI API 中转与 LLM 代理的本地安全审计。
★ 897已汉化DSH
69.4
免费搜索插件DDDMUC/dsh-free-search
DeepSeek Harness 免费搜索插件 —— 无需 API key,零成本,多引擎可切换。 一个插件,给…
★ 814已汉化DSH
68.8
免费联网搜索liustack/modsearch
在官方 App 里模型能联网,切到 API 就不能了。ModSearch 把联网补回来:网页搜索、X…
★ 863已汉化DSH
68.5
OpenCode 免费模型FishBottle7/opencode2dsh
在 DSHDeepSeek Harness里原生使用 OpenCode Zen 的免费匿名模型。
★ 385已汉化DSH
67.9
AI 模型网关tingly-dev/tingly-box
Tingly Box Web UI 演示
★ 373已汉化DSH
67.4
WorkBuddy 账号池XDTrees/dsh-xdpool
把你能白嫖的模型额度接进 DSH 同一个池:WorkBuddy 多账号自动容错、十三家扫码登录、76…
★ 359已汉化DSH
67.1
这是你的仓库?认领条目