前言¶
在 DeepSeek Harness(DSH)里走 cline-pass 模型时,请求会经 api.cline.bot 这类多上游网关转发。对同一快照模型,网关可能在 deepseek、pareto、fireworks 等渠道之间切换,稳定别名还可能落到匿名回退网。若你关心「实际是谁在推理」或需要和观测插件对齐,仅靠 profile 里的官方路由配置,在 Desktop 版上往往走不通。下面介绍社区插件 dsh-clinepass-pin(维护者 liujuntao123),它在发往网关的聊天请求体里写入 providerOptions.gateway.only,把路由硬钉到单一上游(默认第一方 deepseek)。
这是什么¶
dsh-clinepass-pin 是 DSH 的模型推理类插件,版本 0.1.0,许可证 MIT。它不改流式缓冲、不重试、不碰 headers,只在匹配的 POST .../api/v1/chat/completions 的 JSON body 上追加:
"providerOptions": { "gateway": { "only": ["deepseek"] } }
README 写明:配套 dsh-clinepass 使用时,后者只观察网关真实用了谁,本插件负责让请求一直走 DeepSeek(或你在配置里写的 only 列表)。
它解决什么问题¶
api.cline.bot 对日期快照 cline-pass/deepseek-v4.1-flash-1017 默认会在十余个渠道里挑选;同一进程内几分钟内就可能从 pareto 漂到 deepseek。官方做法是在 profile 里配置 compat.vercelGatewayRouting.only,并把 pi-ai 的 COMPLETIONS_COMPAT_GATE.vercelGatewayRouting 从 "withhold" 改为 "offer"。在 DSH Desktop 上这条路不可用:门禁代码在带完整性校验的 app.asar 里,就地改字节过不了校验,且更新会被覆盖;随包脚本依赖的 profiles/<profile>/node_modules 路径在 Desktop 安装里也不对应运行中加载的那份。
本插件改在更底层的 globalThis.fetch 上注入字段,与 dsh-clinepass 观察用的钩子同一层。资料中的实测(2026-10-19,同一把 key)表明:对 1017 快照,only: ["deepseek"] 时 fallbacksAvailable 为 0;负控制 only: ["__no_such_upstream__"] 会返回 500 且提示 No available providers match the 'only' filter,说明网关确实执行了 only。稳定别名则可能无视 only,因此 models 里应写快照 id,不要写别名。
核心功能与行为边界¶
- 钉选上游:默认
only: ['deepseek'],必须非空(空列表会导致网关 500)。 - 按模型过滤:默认只对
cline-pass/deepseek-v4.1-flash-1017改写;其它 model 与原请求透传。 - 保守改写:只添加
providerOptions.gateway.only;若 body 里已有非空only则不动(让 profile 侧 compat 优先);已有的gateway.order会保留。 - 失败回落:解析或形状异常时退回原请求,不应单独导致对话失败(
counters.errors可查看)。 - 状态文件:默认写入
$DSH_HOME/dsh-clinepass-pin-status.json,可关;log默认开启。
代价是硬钉:当 deepseek 不可用时请求会直接失败(500),不会自动落到 pareto / fireworks 等。若要「优先 deepseek、挂了再回落」,需网关的 gateway.order(本插件未暴露配置;资料称对 1017 实测有效的是 only 这一形状)。
安装与启用¶
环境要求:dsh ≥ 0.2.0-rc.2、node ≥ 20。安装后需重启 dsh。
从 GitHub 安装(推荐)¶
dsh plugin --profile desktop add github:liujuntao123/dsh-clinepass-pin
插件声明了 dsh.bundle.patch,进入 profile 的 dsh.profile.bundles 后,cordis.patch.yml 随包生效,无需手写 bundle 配置。
若同时使用 dsh-clinepass,请把 dsh-clinepass-pin 排在 dsh-clinepass 之前。顺序决定谁在最外层:dsh-clinepass 后装才能继续 owns() globalThis.fetch,其状态文件里 hook 才会是 installed;顺序反了钉选仍生效,但 dsh-clinepass 可能报 hook: "foreign"。
离线手装(Windows 示例,不用 pnpm)¶
$prof = "$env:USERPROFILE\.dsh\profiles\desktop"
Copy-Item . "$prof\plugins\dsh-clinepass-pin" -Recurse
New-Item -ItemType Junction -Path "$prof\node_modules\dsh-clinepass-pin" -Target "$prof\plugins\dsh-clinepass-pin"
在 $prof\package.json 的 dsh.profile.bundles 中加入 "dsh-clinepass-pin"(同样建议排在 dsh-clinepass 之前),然后重启。
配置¶
在 profile 的 cordis.patch.yml 中修改(patch 为整行替换 config):
- id: clinepass-pin
config:
models: [cline-pass/deepseek-v4.1-flash-1017]
only: [deepseek]
| 键 | 默认 | 作用 |
|---|---|---|
upstream |
https://api.cline.bot |
网关 origin;路由自行拼接 /api/v1/chat/completions |
models |
['cline-pass/deepseek-v4.1-flash-1017'] |
仅这些 model id 会被加钉 |
only |
['deepseek'] |
允许的上游列表,必须非空 |
statusFile |
$DSH_HOME/dsh-clinepass-pin-status.json |
运行证据;false 关闭 |
log |
true |
宿主日志 |
验证¶
仓库内离线测试(不需要网络也不需要 dsh):
npm test
运行 DSH 后查看状态文件(Windows 示例):
Get-Content "$env:USERPROFILE\.dsh\dsh-clinepass-pin-status.json"
期望类似:
{ "hook": "installed", "counters": { "pinned": 12, "skippedRequestShape": 0, "errors": 0 } }
pinned 递增表示请求被改写;hook 不是 installed 说明另有插件先占用了 globalThis.fetch。
适用场景与注意¶
- 适合:已通过 Cline Pass 走 DSH,且需要固定第一方
deepseek(或明确白名单上游),并与dsh-clinepass做「写 + 观」组合的用户。 - 不适合:希望网关自动在多上游间故障转移、又不想接受 500 的场景。
- 安全:插件在当前 dsh 进程的权限下运行,会 hook
globalThis.fetch并改写部分出站 JSON。安装前请阅读 源码与 LICENSE,自行判断是否信任维护者 liujuntao123。
卸载:从 dsh.profile.bundles 去掉 dsh-clinepass-pin → 删除 node_modules\dsh-clinepass-pin junction → 删除插件目录 → 重启。
结尾¶
dsh-clinepass-pin 用请求体里的 providerOptions.gateway.only 绕开 Desktop 上无法落地的官方网关路由配置,把 cline-pass 钉到指定上游;与观测型插件 dsh-clinepass 搭配时,先装本插件、后装观测插件即可。DSH 生态强调「一切皆插件」;社区目录 SkillHub 插件页 与 DeepSeek / 幻方无官方从属关系。详情与 issue 见 GitHub:liujuntao123/dsh-clinepass-pin。