Back to home

jinsiyu

dsh-webproxy-router-plugin

一个deepseek harness webfetch的代理插件,让llm也能科学上网

Stars
1
Language
JavaScript
Created
Aug 14, 2026
Updated
Aug 14, 2026

Introduction

Proxy Router — 静态插件(官方 npm 包形态)

ctx.web 抓取请求按 hostname 规则路由到 HTTP/SOCKS 代理的静态插件:host 插件 + dsh.client 声明的 client bundle(设置卡片),经 profile 组合加载,参数经官方 settings 服务持久化。

包结构

dsh-webproxy-router-plugin/
  package.json         main lib/index.js;types lib/types/index.d.ts;
                      exports: {".", "./client", "./package.json"};dsh.bundle + dsh.client {platform: web}
  src/index.ts        插件源码(TS):name / inject / apply
  src/env.d.ts        裸环境类型声明(tsc 用)
  lib/index.js        构建产物(host 插件入口;git 忽略,由 build.mjs 生成)
  lib/types/index.d.ts 构建产物(声明文件,官方布局;git 忽略)
  lib/client.js       手写 client bundle(官方格式 window.__ModuleLoader__.load),设置卡片;git 保留
  build.mjs           构建脚本(两遍 tsc:lib/index.js + lib/types/index.d.ts)
  tsconfig.json       类型检查配置
  .gitignore          忽略 node_modules / 构建产物 / *.tgz / 缓存
  node_modules/       开发期依赖(npm install;运行期依赖由 profile 安装 tarball 时物化)
  *.tgz               pnpm pack 产出的分发包(dsh-webproxy-router-plugin-0.1.0.tgz)

服务与扩展点

能力机制
请求路由ctx.web.registerFetchProvider({id:'proxy-router'}):命中规则的 hostname 走代理,其余直连
请求引擎node-fetch + https-proxy-agent(http/https 代理)/ socks-proxy-agent(socks);CONNECT 隧道、TLS、chunked、重定向跟随由库处理;200KB 截断 + 超时由宿主封装
管理工具ctx.tools.register:proxy_manage(set_proxy / clear_proxy / add / remove / list / test)
配置持久化ctx.settings.register('proxy-router', z.object({proxy, rules}));变更经 scope.update 写入 settings 文档;scope.watch 同步外部修改
设置卡片client bundle 在 settings.plugin.item(设置→插件→插件配置)注册折叠卡片(id proxy-router,order 30);数据通道走官方 ctx.webServer JSON API(GET/POST /proxy-router/configPOST /proxy-router/test)——当前 DSH 版本的配置客户端边界(dsh-host-apiproxyWEB_SETTINGS_NAMESPACES 白名单,注释声明插件自行暴露配置为延后工作)不暴露第三方命名空间,settingsScope/describe 对 proxy-router 返回 unavailable,故卡片不依赖它;表单按官方模式构建:GET 响应附带序列化 schema → 官方 rehydrateSchema 还原活校验器、setPath/deletePath 编辑草稿、validateDraft 校验(与宿主同一份 schema),控件用官方 primitives Input/Button,写入由宿主权威校验;卡片外壳复刻内置 PluginCard 外观(内嵌发行包 CSS 类 YyYd_a_* / At1oFq_* 排版,展开箭头用官方 IconChevronDownOutline14)
模型上下文ctx.systemPrompt.section({name:'proxy-router', order:100})静态系统提示词段:不携带当前配置(代理地址/规则列表均不进提示词),只告知模型如何用 proxy_manage 工具查询(action "list")与修改(set_proxy / clear_proxy / add / remove / test);文本字节级静态,配置变化不影响系统前缀缓存

打包与安装

本包是官方教程定义的组合包(bundle):一个附带配置层的 npm 包——package.jsondsh.bundle 声明配置层文件(cordis.patch.yml),profile 安装它时按包名激活插件行。参考 publish 教程

打包

cd dsh-webproxy-router-plugin
pnpm pack          # prepare 脚本自动执行 node build.mjs,产出 dsh-webproxy-router-plugin-0.1.0.tgz

安装方式(任选其一)

方式一:源码 checkout 链接(开发期,改动即时生效)

# 绝对路径,避免 pnpm 自链接
dsh plugin --profile web add C:\path\to\dsh-webproxy-router-plugin

方式二:tarball(发布产物,推荐交付;无需构建授权)

dsh plugin --profile web add ./dsh-webproxy-router-plugin-0.1.0.tgz

方式三:npm 注册表(发布后)

npm publish        # 或 pnpm publish(发布前自动构建 lib/)
dsh plugin --profile web add dsh-webproxy-router-plugin

方式四:GitHub 源码安装

dsh plugin --profile web add github:<user>/<repo>#<sha>

git 安装拉取的是源码,安装时会运行 prepare 脚本(node build.mjs)构建产物;pnpm ≥10 默认拒绝运行 git 依赖的 prepare 脚本,首次 add 会失败——把 pnpm 提示的包键加入该 profile 的 pnpm-workspace.yamlallowBuilds 后重新 add(仅对可信源码授权,并锁定 commit)。

卸载

dsh plugin --profile web remove dsh-webproxy-router-plugin   # 同时移除依赖与对应配置层

效果与层顺序

安装后:pnpm 将包加入 profiles/web/node_modules,dshdsh-webproxy-router-plugin 追加到 dsh.profile.bundles;启动时 bundle 的 cordis.patch.yml 插入插件行(name: dsh-webproxy-router-plugin,按包名解析)。

生效配置按以下顺序逐层组合(后应用的层按行胜出,整行替换 config 而非深合并):每个 bundle 的 patch(按 bundles 列表顺序)→ profile 自己的 cordis.patch.yml → 全局 $DSH_HOME/cordis.patch.yml--patch overlay。用户可在自己 profile 的 cordis.patch.yml 中覆盖本包的行,无需改动包。

插件本体:inject: ['tools','web','webServer','settings','systemPrompt'] 硬依赖避免启动竞态。

构建与校验

npm run typecheck   # tsc -p tsconfig.json(strict,零依赖环境声明)
npm run build       # node build.mjs → lib/index.js + lib/types/index.d.ts
  • client bundle(lib/client.js)为直接维护的手写产物(官方格式 window.__ModuleLoader__.load),内置 PluginCard 外观 CSS(YyYd_a_* / At1oFq_*)为从安装的 dsh 发行包原样复制内嵌;改动后需重启 dsh web 生效(client-modules 启动时计算 bundle rev 与 manifest)
  • dsh 升级导致内置样式哈希变化时,手动从发行包 dsh-client-ui-settings-plugins/lib/client.js 重新复制 css$1(卡片)/ css$2(字段)两段 CSS 到 lib/client.js 即可
  • 官方 checklist(adding-a-package.md)针对 monorepo 内包(pnpm constraints / tsdown / hygiene);本包为独立 npm 包形态,构建用两遍 tsc 复刻官方产物布局(lib/index.js + lib/types/**/*.d.ts)

Model Experience

代理路由指导(静态系统提示词段)

Request context and condition

ctx.systemPrompt.section({name:'proxy-router', order:100}) 注册的静态系统提示词段不携带任何当前配置——代理地址与规则列表都不进入提示词;模型需要时自行用 proxy_manage 工具查询(action "list")与修改(set_proxy / clear_proxy / add / remove / test)。文本为编译期写死的常量字符串,不引用任何运行状态。

What the model sees

系统提示词内一段固定英文指引(约 490 字符,保持精简),内容为:存在按 hostname 规则走本地代理的路由、如何用 proxy_manage 查询/修改、被墙站点应直接用 web_fetch 抓取而非判死、抓取失败可 add 对应 hostname 后重试。

Token effect

Always-on, constant。静态文本每次 step 恒定占用(约 490 字符 ≈ 120–160 token);不随配置变化增减,无快照、无去重逻辑。

KV Cache effect

Prefix-stable,完全静态。文本字节级不变,配置变化不产生任何提示词差异,系统前缀缓存永不失效;不再有用户消息侧的运行时快照消息。

Known Limitations and Deferred Work

  • 第三方命名空间不在配置客户端白名单dsh-host-apiproxyWEB_SETTINGS_NAMESPACES 硬编码名单(官方注释:让插件经 settings.register() 自行暴露配置是延后工作)不包含 proxy-router,故浏览器 settingsScope/describe 对其返回 unavailable、写入返回 settings-not-exposed;设置卡片因此走 ctx.webServer JSON API 读写。若未来 DSH 版本开放插件自行暴露,可改回 settingsScope 绑定。
  • out-of-repo 构建偏差 — 官方 checklist 的 pnpm constraints / tsdown / hygiene 校验依赖 monorepo 工具链,本包以两遍 tsc 复刻产物布局;peerDependencies(cordis/react)为声明性,未随 npm install 物化(运行时由宿主/浏览器提供,非必需)。
  • 动态插件桥限制 — 动态插件调用 settings 服务的结构化参数会被桥破坏(update/replace/mutate 均被拒),故参数持久化必须由静态插件同进程完成;若未来恢复动态形态需绕开 settings 服务。
  • 代理中继延迟 — 8099 等 HTTP 代理中继本身的延迟波动会造成请求时长起伏,与引擎无关。
  • Google 学术反爬scholar.google.com 搜索接口会 302 到 /sorry/ 验证页(Google 对代理出口 IP 的反爬),插件无法绕过;首页与详情页可正常抓取。