npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@anpiluo/dsh-proxy

v2.1.0

Published

DSH 模型代理插件:按模型走代理(Clash 等)+ 失败自动重试 + 直连失败自动回退代理,设置页实时生效。

Readme

@anpiluo/dsh-proxy

npm

Fork 自 @superfish058/dsh-llm-proxy(v1.1.0)。

支持 DSH 0.1.2-rc.1,新增「直连失败自动回退代理」(参考@sg88/dsh-proxy-switch),~~由 @leg-anpiluo 维护。~~ ~~并不会维护~~

DSH 模型代理插件:给请求按「目标域名」分流——选中的模型走代理,其余直连并在直连失败时自动回退代理,另带失败自动重试。

它是干嘛的

  • 按模型走代理:在 DSH 设置页(插件 → 可配置插件 → 模型代理)勾选需要走代理的模型(如 deepseek-v4-flash),该模型的请求自动经 proxyHost:proxyPort(默认 127.0.0.1:7897,即 Clash)转发;未勾选的模型(DeepSeek、小米、通义等国内 API)保持直连。路由按模型的 API 地址(baseURL host) 生效:选中一个模型后,同一地址下的所有模型都会走代理(例如 B.AI 的 deepseek-v4-flash 与 deepseek-v4-flash-vision-exp 共享 api.b.ai)。
  • 直连失败自动回退(v2.0.0):所有没有走代理的请求——网络搜索、web_fetch、国内模型 API 等一切走全局 fetch 的目标——直连传输层失败(连接拒绝 / DNS 失败 / 超时 / 连接重置,且响应尚未开始)时,自动经回退代理重发一次。回退端点默认复用主代理(proxyHost:proxyPort),可用 failoverProxy 指定专用地址(http:// / https:// / socks5://)。走代理的模型不参与回退(它们本就没有直连路径);本机服务(localhost / 127.0.0.1 / ::1)永不回退;流式请求体不可重放时不回退。
  • 失败主机负缓存:某地址回退成功后,在 negativeCacheTtlMs 窗口内(默认 60s)直接走代理,不再重复支付直连超时;窗口内直连一旦成功立即恢复直连优先。
  • 失败自动重试:对断连(连接已建立后的 ECONNRESET 等)、HTTP 429 限流、5xx 错误自动重试(默认 3 次、间隔 1s),减少免费额度被瞬时错误打断。CONNECT 级失败由回退层处理,重试只管「已连上后」的中途断开与状态码,不会反复锤打死路径。
  • 模型列表与官方一致:只配了 apiKeyEnv、没写 models 的 provider(如 xiaomi),其模型从 pi-ai 内置目录(@earendil-works/pi-ai)回退补齐;llm-deepseek 命名空间即使保持默认空文档(llm-deepseek: {})也回退官方内置目录(https://api.deepseek.com + DEEPSEEK_API_KEY),deepseek-official/* 模型开箱可用。勾选列表与 DSH 官方模型选择器完全同步。
  • retryPolicy 镜像:卡片上的 retries/retryIntervalMs 会镜像进被勾选 provider 的官方 retryPolicy(驱动设置页可见的 (retry/maximum) 提示),取消勾选自动还原官方默认值——一套配置同时驱动传输层重试与官方重试 UI。
  • 多模态模型镜像:DSH 官方模型声明里,部分支持图像识别的模型(如 deepseek-v4-flash-vision-exp)没有可供用户勾选「图像输入」的配置入口,选中后发图会被 DSH 以 UNSUPPORTED_CONTENT 拒绝。在设置卡「多模态模型」区勾选这些模型后,插件把 image 写进所属 provider 的模型声明(pi-ai 的 models[].input / 目录型 modelOverrides[].input,官方 DeepSeek 的 models[].inputModalities),使 DSH 允许对该模型发图;取消勾选自动还原官方默认。注意:该功能只对真正支持图像输入的模型(如 vision 模型)有意义,纯文本模型(如 deepseek-v4-flash)勾选后 DSH 虽放行,实际请求仍会因模型不支持图像而报错。
  • 测试连接:走代理的模型列表每行新增「测试连接」按钮,探测请求走插件自己的全局 dispatcher(即真实代理路径:勾选模型经代理、其余直连),返回 HTTP 状态 / 耗时 / 经代理或直连 / 多模态开启状态;失败时直接显示提供方返回的错误 body(脱敏、截断),如 B.AI 的 max_tokens 限制一眼可见。注意:测试走已保存的配置——改了勾选后请先点「保存」再测试。
  • 保存即生效,无需重启:设置写入 llm-proxy 命名空间后运行时整体替换 dispatcher,不碰 settings.yaml 里的供应商配置。冷启动时若 provider 命名空间(llm-pi-ai/llm-deepseek)尚未注册,插件会带退避重试直到可解析代理域名,不再需要手动"恢复默认再保存"。

用什么技术

  • undici 全局 Dispatcher 注入:RetryAgent(FailoverDispatcher(RoutingDispatcher)) 挂到 Node 全局——RoutingDispatcher(按 hostname 路由:选中模型 host → ProxyAgent,其余直连)、FailoverDispatcher(直连路径的回退 + 负缓存)、官方 RetryAgent(429/5xx 与中途断开重试)。LLM 请求与搜索、web_fetch 等(OpenAI SDK → undici fetch)自动经过它,位于 LLM 适配器之下、供应商之上。
  • Cordis 插件:宿主侧注册 llm-proxy 设置命名空间(lib/settings.js);浏览器侧设置卡片(src/client/,挂 settings.plugin.item slot,走官方 transport、bridge 兜底)。
  • 客户端构建:tsdown(Rolldown)打包 lib/client.js,经 window.__ModuleLoader__ 注入前端。

适合什么场景

  • 国内网络访问境外模型 API(如 api.b.ai)超时/不可达——代理已就绪,只想让特定模型走。
  • 免费额度被 429/5xx 打断,需要自动重试扛过限流窗口。
  • 直连不稳定:搜索 / web_fetch / 国内 API 偶发连接失败,希望自动经代理兜底而不用改系统代理。
  • 想按模型粒度控制代理,而不是全局开代理连累国内直连 API。

安装

# 推荐:npm 包(最新版,预构建 lib,秒装)
dsh plugin --profile web add @anpiluo/dsh-proxy

# 本地源码联调(改源码后需 npm run build 重建)
dsh plugin --profile web add C:/path/to/dsh-llm-proxy

若提示 build 授权,把 @anpiluo/dsh-proxy 加进 profile 的 pnpm-workspace.yaml → onlyBuiltDependencies。装完重启 dsh web(托盘退出 → 启动)。

版本兼容

| 组件 | 要求 | 说明 | |---|---|---| | 客户端设置卡(DSH ≥ 0.1.7,含 0.2.0) | 插件页根列表槽位 plugins.item | 设置文档不再是「注册的命名空间」,而是由插件 volatile() 后的 Config 派生、按 loader entry id dsh-proxy 寻址;浏览器半边经官方 configForms 服务读写它,配置改动由 loader 就地提交并触发 loader/volatile-update | | 客户端设置卡(DSH 0.1.2–0.1.6) | 可配置插件 tab 的 keyed 槽位 settings.plugin.item | 继续走 settings.register('llm-proxy');同一条 bundle 两代宿主都能用 | | 宿主半边(dispatcher / 设置桥 / 路由) | DSH ≥ 0.1.0-rc.7 | 纯 Node ESM。≥ 0.1.7 上宿主不再有 settings.register(),插件把它适配成同一套读/监听面(volatileDocumentSeam),install/热更新逻辑两代共用 | | 与官方出站代理共存 | DSH ≥ 0.1.3 | 宿主在插件加载前已装好 @deepseek-ai/dsh-http-proxy 的全局 dispatcher(读 HTTP_PROXY/HTTPS_PROXY)。插件不再用私有 Agent 覆盖直连路径,而是链接到它——本机出站策略继续生效,插件只接管「走代理的模型」那部分 host;卸载时也绝不关闭宿主的 dispatcher | | @earendil-works/pi-ai | 可选(peer) | 宿主(dsh-llm-pi-ai)提供时模型目录与官方选择器同步;未提供时目录型 provider 显示占位行 |

多模态镜像的适用范围:multimodalModels 只在 DSH ≤ 0.1.6 生效。≥ 0.1.7 的官方模型设置页自己拥有 inputModalities,插件会主动让位(日志 owns model input modalities),避免两个写者互相覆盖;请用官方页配置。该字段在新宿主上保留但不再写入。

配置

| 字段 | 默认 | 说明 | |---|---|---| | proxyHost / proxyPort | 127.0.0.1:7897 | 代理地址(Clash 等),可不在本机。proxyHost 也接受整条 URL(http://10.0.0.9:1080、socks5://host)或裸 host:port,scheme 与内嵌端口会一并采用(socks5 走 SOCKS agent) | | proxiedModels | [] | 走代理的模型,<providerId>/<modelId>,其余直连 | | multimodalModels | [] | 多模态镜像(仅 DSH ≤ 0.1.6):勾选支持图像识别但官方声明/UI 没有图像输入入口的模型(如 deepseek-v4-flash-vision-exp),插件在所属 provider 声明中标记支持图片输入(pi-ai 写 input、官方 DeepSeek 写 inputModalities),发图不再被 DSH 拒绝;纯文本模型(如 deepseek-v4-flash)勾选无意义;取消勾选自动还原。DSH ≥ 0.1.7 上由官方模型设置页接管,此字段失效 | | retries / retryIntervalMs | 3 / 1000 | 失败重试次数与间隔(ms) | | failoverEnabled | true | 直连失败自动回退:非代理目标的直连传输层失败时经代理重发一次 | | failoverProxy | ''(复用主代理) | 专用回退端点,http:// / https:// / socks5:// URL | | negativeCacheTtlMs | 60000 | 回退成功后该地址跳过直连的时长(ms),0 关闭缓存 | | trustedOrigins | [] | 反向代理部署时额外信任的公网 origin(如 https://dsh.example.com)。默认只信本机;填写后公网域名可达设置桥,但仍强制同源校验(跨站页面拿不到数据) |

验证

最快方式:设置页(DSH ≤ 0.1.6:插件 → 可配置插件 → 模型代理;DSH ≥ 0.1.7:插件 → 模型代理)的「走代理的模型」列表里,每行有「测试连接」按钮,点击即向该模型发一次最小探测请求(走插件自己的全局 dispatcher,即真实代理路径):

  • ✓ 连接成功:显示 状态 · 耗时 · 经代理/直连 · 多模态已开启(如 ✓ 连接成功 · 200 · 38ms · 经代理 · 多模态已开启)
  • ✗ 连接失败:直接显示脱敏后的提供方错误原因(认证失败、限流、max_tokens 限制等),一眼定位问题

注意:测试走的是已保存的配置——改了代理勾选/代理地址后,先点「保存」再测试;测试只验证一次非流式探测,流式/长对话仍建议用真实会话确认。

日志方式:重启后日志出现:

dsh-proxy: global dispatcher → RetryAgent(FailoverDispatcher(RoutingDispatcher)) (proxy=127.0.0.1:7897, proxiedHosts=[...], retries=3×1000ms, failover=on (main-proxy), negCacheTtl=60000ms)

直连失败触发回退时,日志出现 dsh-proxy: direct → <host> failed (<错误码>) — retrying via main-proxy failover proxy。模型选择器里选中代理模型,流式响应正常、仅该模型域名走代理即成功。

遇到问题?让大模型帮你排查

插件出问题时,可在 DSH 中让其他模型帮忙排查——把下面这段提示词发给模型即可,模型会自行排查,无需用户提供报错信息或执行任何操作:

检查当前 DSH 插件 @anpiluo/dsh-proxy 是否正常可用,按以下步骤自行排查:

1. 查看插件配置确定当前代理端口号,自行通过该端口访问外网(如 github.com 等)判断端口是否连通,并确认本机可访问的端口和域名;
2. 检查「走代理的模型」是否已勾选;
3. 检查已勾选模型能否连通(可通过设置页「测试连接」验证);
4. 检查 dsh web 日志中 dsh-proxy 相关输出。

根据排查结果判断插件是否可用;如不可用,给出全面修复方案。

测试

npm test                    # 单元测试(路由 + 回退 + 重试镜像等,无网络)
npm run test:smoke          # 路由端到端(真实 undici + 本地服务器)
npm run test:smoke:failover # 回退端到端(直连死亡 → 代理重发、负缓存、禁用、流式)