dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
按 Provider 决定 DSH 的模型请求走不走代理:需要翻墙才能访问的 Provider(Gemini、OpenRouter 等)走代理,国内可直连的 Provider(DeepSeek、Kimi、MiniMax、GLM 等)保持直连。代理地址与「哪些 Provider 走代理」都在 DSH 设置页里配置。
DSH 里同时挂了很多家模型。把代理塞进进程环境变量(HTTPS_PROXY)是全局的:一旦设上,DeepSeek 这类本来直连更快、更稳的请求也会被绕进代理,延迟变高,还多一层失败点。反过来不设代理,Gemini、OpenRouter 又完全用不了。
本插件把「走不走代理」变成按请求主机名判断的逐条规则,并且规则可以在界面上改,改完立即生效、不用重启。
一次请求按下面的顺序判定,先命中先算:
localhost、127.0.0.1、::1、*.local)→ 直连。主机规则来自两处,按顺序拼接:
generativelanguage.googleapis.com,OpenRouter 是 openrouter.ai 与 *.openrouter.ai。每行还可以追加自定义主机名(内网网关、自建反代)。* 通配。主机名支持三种写法:精确匹配 api.openai.com;子域通配 *.openrouter.ai(不匹配裸域);全通配 *。
无论配置怎么写,下面这些 Provider 永远不会走代理:deepseek、deepseek-official、ollama、lmstudio。
打包目录本身就是可安装的 bundle:
plugin_manager install_bundle <包目录绝对路径>
安装后若 DSH 报告 restart-required,重启一次 DSH 即可。bundle 的 patch 只插入一行 Host 条目,不碰 profile 里其它任何配置。
设置 → 模型 分组下的「LLM 代理路由」页:
| 区域 | 作用 |
|---|---|
| 总开关 | 关掉后所有请求立即恢复直连,配置保留 |
| 代理地址 | http://127.0.0.1:7890 这类地址,省略协议时按 http:// 处理;支持 http://用户:口令@主机:端口 |
| 测试代理 | 向代理发起一次真实的 CONNECT 隧道握手并回报结果与耗时,不经过任何第三方探测服务 |
| Provider 列表 | 逐行勾选是否走代理;显示该行当前覆盖的主机名,可追加自定义主机名 |
| 额外主机规则 | 独立的主机名条目,可单条停用 |
| 状态行 | 当前生效的代理地址与规则条数 |
保存即落盘、立即生效。配置写在 $DSH_HOME/llm-proxy-router/config.json(原子写入),不写 profile 的 patch 层,因此升级不会冲掉它。
{
"enabled": true,
"proxyUrl": "http://127.0.0.1:7890",
"providers": {
"gemini": { "enabled": true, "extraHosts": [] },
"openrouter": { "enabled": true, "extraHosts": ["openrouter.internal"] },
"deepseek": { "enabled": false, "extraHosts": [] }
},
"hosts": [
{ "pattern": "*.openrouter.ai", "enabled": true, "note": "" }
]
}
行配置可以给一个初始值(用户第一次保存后以配置文件为准):
- id: llm-proxy-router
name: 'dsh-llm-proxy-router'
config:
enabled: false
proxyUrl: ''
configPath: ''
defaultEnabledProviders: []
reportPath: ''
Host 半边在进程的 globalThis.fetch 上装一层路由补丁。选这个接入点的原因有两条:
globalThis.fetch——pi-ai 的 OpenAI / Anthropic / Google 三条协议、DSH 自己的 DeepSeek 适配器、各家 SDK 都一样,一个口子覆盖全部。fetch(源码里明确判断 options.fetch !== globalThis.fetch 就抛错),所以没法用「给适配器塞自定义 fetch」这种更局部的办法。命中代理规则时,请求交给 undici 的 ProxyAgent 走 CONNECT 隧道;未命中的请求原样交回进程原来的 fetch,不做任何包装。补丁在插件卸载时完整还原。
undici 从运行中应用自己的 node_modules 解析,而不是从 profile。原因是 fetch 只认「装上了全局 dispatcher 的那个 undici 实例」造出来的 dispatcher:另装一份 undici 属于不同实例,它造的 ProxyAgent 会被 fetch 以 UND_ERR_INVALID_ARG 拒绝。同理,工作区目录安装的插件按真实路径解析模块,所以 undici、@deepseek-ai/schemastery 这类依赖不能用裸模块名导入,必须从应用目录解析。
浏览器半边是一个自包含的客户端模块(无构建步骤,React 通过浏览器模块表取得,不导入任何 @deepseek-ai/dsh-client-* 包),在 settings.section 槽位注册设置页,通过 /api/dsh-llm-proxy-router/* 读写配置。
Host 暴露的接口:
| 方法 | 路径 | 作用 |
|---|---|---|
| GET | /state | 配置、Provider 列表、生效主机规则、运行状态 |
| POST | /config | 保存配置并立即生效 |
| POST | /test | 测试代理连通性 |
| POST | /reset | 恢复默认配置 |
| POST | /selftest | 用一次真实请求验证路由补丁的判定 |
| GET | /diagnostics | 解析结果、补丁统计、最近判定记录 |
requestTls.rejectUnauthorized: false)。走私有 MITM 代理时这是必要的,代价是这一层不做证书校验。DSH_LLM_PROXY_ROUTER_UNDICI="<undici 目录>/" node --test "test/*.test.mjs" # 22 项
node client/selfcheck.mjs # 50 项
test/core.test.mjs 覆盖纯路由判定、配置归一化与容错;test/routing.test.mjs 起本地源站与本地代理,验证走代理的请求确实进了代理、直连的请求代理一条都没看到、关闭开关后恢复直连、fetch 补丁卸载后完整还原。DSH_LLM_PROXY_ROUTER_UNDICI 只在应用外跑测试时需要,用来指认一份已安装的 undici。
host/core.js 纯路由判定与配置归一化(无 I/O,可独立测试)
host/proxy.js undici 解析、ProxyAgent 池、代理连通性探测、fetch 补丁
host/config.js 配置文档的原子读写
host/index.js 插件入口:装配补丁、注册 HTTP 接口
client/client.js 设置页(浏览器模块,无构建步骤)
locale/ 插件在插件列表里的中英文标题与描述