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

dsh-model-proxy

v1.0.0

Published

Route DeepSeek Harness model API requests through a local HTTP proxy, with local-port probing and a settings section.

Readme

dsh-model-proxy

DeepSeek Harness (DSH)模型 API 请求走本地代理端口、并在请求失败命中指定词汇时无限重试的插件,带本地端口探测和设置页。

面向的场景:你的模型 API 需要经过本地代理(Clash、v2rayN、Clash Verge、Privoxy 等)才能访问时,不用在系统层面改环境变量,直接在 DSH 设置里点几下就切过去。

功能特性

  • 真正的流量路由:在 host 进程里把 undici 全局 dispatcher 指到代理端口。模型适配器(如 dsh-llm-deepseek)用的是 Node 内置 fetch,走的正是这个 dispatcher,所以模型请求会被真正改走代理。
  • 快速端口探测:只探测常见代理软件的预设端口(Clash 7890/7891、Clash Verge 7897/7898、v2rayN 10808/10809、Shadowsocks 1080、Privoxy 8118、Sing-box 2080),并行做 TCP → HTTP/SOCKS5 三级判断,响应快,只显示确实能转发流量的代理并给出延迟。
  • 关键词无限重试:请求失败信息命中指定词汇/句子(支持逗号或换行分隔多个)时,把默认的有限重试改成无限重试,等待时间可配置。
  • 设置页:打开「设置 → 模型请求 (Model)」自动探测;用明确的开关一键启用/禁用代理,点结果即可切换端口;下方独立配置重试规则。
  • 持久化:代理与重试规则都写入包内 config.json,重启 DSH 后自动恢复。

原理

DSH 的模型适配器直接调用全局 fetch(),而 Node 22 的 fetch(undici)默认不理会 HTTP_PROXY/HTTPS_PROXY 环境变量,也没有任何代理挂钩。要拦截它,唯一干净的办法是安装一个 undici ProxyAgent 作为进程全局 dispatcher:

import { ProxyAgent, setGlobalDispatcher } from 'undici'
setGlobalDispatcher(new ProxyAgent('http://127.0.0.1:7890'))

这必须发生在 host 进程里,所以本插件是一个 host 平面的 composition 行(和模型路由同一平面),不是一个 agent preset,也不是临时动态插件。

关键词无限重试的原理:DSH 在每次模型请求失败时触发 agent/request-error waterfall。内置的 dsh-llm-retry 按重试策略(默认有限次)处理,超限后把决策交给后续监听器。本插件注册在它之后,检查失败信息的 message/code/status 是否命中关键词,命中则等待配置的时长后返回 { kind: 'retry' },从而持续重试,直到成功或用户中止(尊重 turn 的 abort signal)。

目录结构

dsh-model-proxy/
├── package.json        # 包清单;dsh.client 声明 + exports["./client"]
├── lib/
│   ├── index.js        # host 半边:代理 dispatcher + 端口探测 + /model-proxy/* JSON RPC
│   └── client.js       # 浏览器半边:设置页(settings.section)
├── README.md
├── LICENSE
└── .gitignore

安装到 DSH

环境要求:DSH >= 0.1.0-rc.6web profile(本插件注入 webServer 并注册设置页)。

dsh plugin --profile web add dsh-model-proxy

然后编辑 <DSH_HOME>/profiles/web/cordis.patch.ymlDSH_HOME 默认 ~/.dsh),加一行 insert:

- insert:
    - id: model-proxy
      name: dsh-model-proxy

重启 DSH,打开 设置 → 模型请求 (Model)

使用

  1. 打开 DSH 设置,进入「模型请求 (Model)」——页面会自动探测预设端口。
  2. 在结果列表点某个端口的 使用(或手动填端口后点 应用)。
  3. 用顶部开关切换 启用/禁用:绿色「已启用」表示代理已生效,状态区会显示 已生效 · http://127.0.0.1:7890
  4. 之后模型请求就会走这个代理;关闭开关即恢复直连。
  5. 在「重试规则」里填命中词汇(多个用逗号/换行分隔)和等待毫秒数,点 保存重试规则。之后一旦失败信息命中,就会按该间隔无限重试。

探测逻辑

  • 候选端口 = 固定预设列表(见 lib/index.jsPROXY_PORTS),仅 9 个,因此探测很快:
    • Clash 7890 / 7891、Clash Verge 7897 / 7898、v2rayN 10808 / 10809、Shadowsocks 1080、Privoxy 8118、Sing-box 2080。
  • 全部端口并行做 500ms TCP 连通测试,只对「开放」端口继续。
  • 对开放端口并行做两类实测(各 2s 超时,通常几十毫秒内出结果):
    • HTTP:向代理发绝对 URI 的 GET http://www.baidu.com/,返回 2xx 即视为可用 HTTP 代理。
    • SOCKS5:原始 socket 完成 greeting + CONNECT 握手,REP=0 即视为可用 SOCKS5 代理。
  • 测试目标 www.baidu.com(纯 HTTP、无需 TLS、国内可达),可用 TEST_HOST 常量替换;预设端口可在 PROXY_PORTS 里增删。

配置与持久化

运行期状态保存在包内 config.json(已加入 .gitignore):

{
  "enabled": true,
  "port": 7890,
  "type": "http",
  "retryKeywords": ["rate limit", "429", "timeout"],
  "retryDelayMs": 3000
}

host 插件启动时读取并应用它,因此重启 DSH 会自动恢复。禁用代理时写入 enabled: false 并恢复初始 dispatcher。

限制

  • 只支持 HTTP/HTTPS 代理路由undici v6 没有 SOCKS5 dispatcher(Socks5ProxyAgent),所以 SOCKS5 端口只探测展示、不参与路由;应用 SOCKS5 会返回明确错误。要支持 SOCKS5 路由,需升级到带 Socks5ProxyAgent 的 undici 版本或加一个 SOCKS→HTTP 转发层。
  • 只适用于 web profile(依赖 webServer 服务和浏览器设置页)。
  • 代理一旦启用是进程全局的:DSH 进程内所有走 fetch 的请求(模型、以及任何用 Node fetch 的组件)都会走该代理。
  • 无限重试会一直进行直到成功或用户中止:命中关键词且请求持续失败时会反复重试(尊重 turn 的 abort signal,用户停止对话即可中断)。

兼容性

| 依赖 | 说明 | | --- | --- | | undici ^6 | 唯一运行时依赖,通过 setGlobalDispatcher 接管 Node 内置 fetch | | @deepseek-ai/cordis ^4 | 宿主提供(运行时注入 ctx) | | @deepseek-ai/dsh-host-webserver | 宿主提供 webServer 服务 | | @deepseek-ai/dsh-client-runtime / @deepseek-ai/dsh-client-ui-settings | 浏览器侧提供 slots 服务与 settings.section 槽位 |

License

MIT