把多个子插件聚合成一个统一能力对外提供
29.8/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/wangmuy/dsh-provider-dispatcher.git状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 聚合多个子插件
- 统一能力对外提供
- 调度子插件协同工作
DeepSeek Harness 的通用服务商调度器,让多个子插件(普通 DSH 插件)在同一能力背后协同工作。
README
由 DeepSeek 最新模型翻译生成@wangmuy/dsh-provider-dispatcher
一个用于 DeepSeek Harness 的通用 provider 分发器,让多个子插件在同一个能力后共存并协同工作。每个子插件就是普通的 DSH 插件——沿用相同的 inject/apply/Config 约定,享有相同的生命周期——被挂载在私有 isolate 作用域中。子插件发出的每一个 register 调用都被捕获,然后由用户提供的 setup 脚本构建一个代理 provider,把一次操作分发给所有被记录的子 provider。
框架本身与具体能力无关:它不内置对 web 搜索、web 抓取、LSP、子代理或任何其他能力的偏好。由 setup 脚本决定要隔离哪些 service、提供哪些 registry、注册什么样的代理。
框架附带两个 setup 脚本作为示例:
- web-search-setup — 分发 registerSearchProvider 调用。
支持 parallel(并发运行所有子插件,合并结果)和 bail(顺序尝试,第一个成功者胜出)。
- web-fetch-setup — 分发 registerFetchProvider 调用。
支持 parallel(并发竞速,第一个成功者胜出)和 bail(顺序尝试,第一个成功者胜出)。
展开完整文档(README 剩余 1 节)
@wangmuy/dsh-provider-dispatcher
一个用于 DeepSeek Harness 的通用 provider 分发器,让多个子插件在同一个能力后共存并协同工作。每个子插件就是普通的 DSH 插件——沿用相同的 inject/apply/Config 约定,享有相同的生命周期——被挂载在私有 isolate 作用域中。子插件发出的每一个 register 调用都被捕获,然后由用户提供的 setup 脚本构建一个代理 provider,把一次操作分发给所有被记录的子 provider。
框架本身与具体能力无关:它不内置对 web 搜索、web 抓取、LSP、子代理或任何其他能力的偏好。由 setup 脚本决定要隔离哪些 service、提供哪些 registry、注册什么样的代理。
框架附带两个 setup 脚本作为示例:
- web-search-setup — 分发 registerSearchProvider 调用。
支持 parallel(并发运行所有子插件,合并结果)和 bail(顺序尝试,第一个成功者胜出)。
- web-fetch-setup — 分发 registerFetchProvider 调用。
支持 parallel(并发竞速,第一个成功者胜出)和 bail(顺序尝试,第一个成功者胜出)。
strategy 和子插件组合逻辑属于 setup 脚本,不属于框架本身。编写自定义 setup 脚本即可定义自己的组合行为。
快速上手
从 npm 安装
dsh plugin --profile web add @wangmuy/dsh-provider-dispatcher
从源码安装
dsh plugin --profile web add file:E:/path/to/dsh-plugins/provider-dispatcher
重要:同时是 bundle 的子插件必须从 dsh.profile.bundles 中移除。 如果子插件(如 @liustack/modsearch)同时出现在 bundles 和 children 中,其 bundle 层仍会直接注册进全局 ctx.web/ctx.tools,绕过分发代理。请将其从 bundles 中移除,只保留在 children 中。
内置的 cordis.patch.yml 会 insert 一个默认的 provider-dispatcher 行。在 profile 的 cordis.patch.yml 中覆盖或增加更多行:
重新启用顶层 tool-web(dsh-web-app 默认禁用了它)。
- id: tool-web
disabled: false
config:
search: true
fetch: true
把 web seam 的搜索和抓取能力路由到分发代理。
- id: web
config:
searchProvider: dispatcher-search
fetchProvider: dispatcher-fetch
分发 web 搜索 provider。
- id: provider-dispatcher
config:
inject: ['web']
setup: '@wangmuy/dsh-provider-dispatcher/web-search-setup'
params:
providerId: dispatcher-search
strategy: parallel
merge: '@wangmuy/dsh-provider-dispatcher/web-search-merge'
tolerateFailures: true
children:
- name: '@liustack/modsearch'
config:
xSearch: false
readPage: false
分发 web 抓取 provider(curl 和 pwsh 竞速,取最快的结果)。
- insert:
- id: dispatcher-fetch
name: '@wangmuy/dsh-provider-dispatcher'
config:
inject: ['web']
setup: '@wangmuy/dsh-provider-dispatcher/web-fetch-setup'
params:
providerId: dispatcher-fetch
strategy: parallel
tolerateFailures: true
children:
- name: './fetch-curl-child/index.js'
config:
proxy: 'http://proxy:80'
insecure: true
- name: './fetch-pwsh-child/index.js'
config:
proxy: 'http://proxy:80'
insecure: true
工作原理
1. 框架等待 config.inject 声明的 service(例如 ['web'])。
2. 加载 config.setup 指定的模块,调用 setup(ctx, config, helpers)。
3. setup 脚本全权负责:隔离 service、创建 recording registry、挂载子插件,并在全局 ctx.web 上注册代理 provider。
4. 执行时,代理把一次调用分发给所有被记录的子 provider,再合并结果。
配置
插件接受以下顶层字段:
| 字段 | 必填 | 含义 |
| inject | 是 | setup 运行前要注入的 service(例如 ['web'])。 |
| setup | 是 | 默认导出 setup(ctx, config, helpers) 函数的模块路径。 |
| children | 否 | { name, config } 数组 — 要挂载的子插件。name 是由 import() 解析的模块路径(绝对路径、相对路径或裸包名)。 |
| params | 否 | 原样传给 setup 脚本。具体结构由 setup 脚本的约定决定。 |
如果缺少 inject 或 setup,插件会在加载时报 schema 错误。
params 携带的配置字段(web-search-setup)
内置的 web-search-setup.js 从 params 读取以下字段:
| 字段 | 默认值 | 含义 |
| providerId | dispatcher-search | 代理在 ctx.web 上注册的 id。 |
| strategy | parallel | parallel(全部运行、合并全部)、bail(遇到第一个非空就停),或 bail(遇到第一个结果就停)。 |
| merge | (首个非空) | 默认导出合并函数的模块路径。 |
| tolerateFailures | true | 跳过抛错的子 provider,而不是让整个分发失败。 |
| toolRemap | (无) | 原始工具名 → 新名称的映射。当子插件通过 ctx.tools.register 注册了匹配某个 key 的工具时,该工具会以新名称重新注册到全局工具注册表中。未列出的工具保持屏蔽。 |
params 携带的配置字段(web-fetch-setup)
内置的 web-fetch-setup.js 从 params 读取以下字段:
| 字段 | 默认值 | 含义 |
| providerId | dispatcher-fetch | 代理在 ctx.web 上注册的 id。 |
| strategy | parallel | parallel(竞速,第一个成功胜出)、bail/bail(顺序尝试,第一个成功胜出)。 |
| tolerateFailures | true | 跳过抛错的子 provider,而不是让整个分发失败。 |
Setup 脚本约定
setup 脚本是一个默认导出以下函数的模块:
export default async function setup(ctx, config, helpers) {
// ctx — Cordis 上下文,config.inject 声明的 service 已可用。
// config — provider-dispatcher 的完整配置(params、children、inject、setup)。
// helpers — { createRecordingRegistry, mountChildren, loadModuleDefault } }
setup 函数全权负责隔离、recording registry 创建、子插件挂载和代理注册。框架只负责调用它。
Helpers
- createRecordingRegistry() — 返回一个 Proxy 对象,其 register 方法会记录每一次调用。通过 registry.registrations(一个 Map)枚举被记录的 provider。
- mountChildren(ctx, children) — 在 ctx 下导入并挂载每个子插件,返回该上下文。
- loadModuleDefault(spec) — 导入一个模块,返回其默认导出(若没有默认导出则返回模块本身)。
内置的 setup 脚本
| 脚本 | 分发什么 |
| @wangmuy/dsh-provider-dispatcher/web-search-setup | Web 搜索 provider(registerSearchProvider)。 |
| @wangmuy/dsh-provider-dispatcher/web-fetch-setup | Web 抓取 provider(registerFetchProvider)。 |
内置的 merge 函数
| 脚本 | 合并什么 |
| @wangmuy/dsh-provider-dispatcher/web-search-merge | Web 搜索结果(按 URL 去重、按 maxResults 截断)。 |
web-fetch setup 不需要专用的 merge 函数:parallel 竞速取最快结果,bail/bail 返回第一个成功。
子插件约定
搜索 provider 子插件
子插件就是一个普通的 DSH 插件,调用 ctx.web.registerSearchProvider:
export const name = 'my-search-child'
export const inject = ['web']
export function apply(ctx, config) {
ctx.web.registerSearchProvider({
id: 'my-engine',
available() { return true },
async search(request, signal) {
return { sources: [...], truncated: false }
},
})
}
子插件的 ctx.web 是 setup 脚本提供的 recording registry。子插件永远不会触碰全局 ctx.web — 只有代理会。
抓取 provider 子插件
同样的模式,只是调用 ctx.web.registerFetchProvider,并使用 web-fetch-setup 脚本。
其他任意能力
写一个自定义 setup 脚本,隔离目标 service,提供 recording registry,并注册一个把操作分发给所有被记录子 provider 的代理。RecordingRegistry 会捕获任何 register* 方法。
写一个自定义 setup 脚本
// my-setup.js
export default async function setup(ctx, config, helpers) {
const params = config.params ?? {}
const recording = helpers.createRecordingRegistry()
const globalService = ctx.web // 或 ctx.lsp、ctx.subagents 等
// 隔离 service,提供 recording registry,挂载子插件。
const privateCtx = ctx.isolate('web')
privateCtx.provide('web', recording)
await helpers.mountChildren(privateCtx, config.children ?? [])
// 在全局 service 上注册代理。
globalService.registerSearchProvider({
id: params.providerId ?? 'my-proxy',
available() { return true },
async search(request, signal) {
const providers = recording.registrations.get('registerSearchProvider') ?? []
const results = await Promise.allSettled(
providers.map(p => p.search(request, signal))
)
// 合并结果 ... }, }) }
文件布局
src/
├── index.js # 通用框架(不内置任何能力) ├── web-search-setup.js # setup 脚本:web 搜索分发 ├── web-search-merge.js # 合并函数:web 搜索(按 URL 去重、按 maxResults 截断) └── web-fetch-setup.js # setup 脚本:web 抓取分发(竞速、短路、顺序)
测试
pnpm run test
单元测试覆盖核心逻辑(createRecordingRegistry、applyToolRemap)和子插件生命周期(挂载、卸载、重新挂载)。测试独立运行,无需 DeepSeek Harness 仓库环境。
已知限制
- ctx.isolate('web') + provide('web', ...) 可能通过 Cordis 的 trace proxying 影响 ctx.web。 内置的 setup 脚本在 isolate 之前保存 const globalWeb = ctx.web 来规避此问题。新的 setup 脚本应遵循同样的模式。
- 框架本身不附带任何子 provider。 子 provider 是用户配置的外部插件。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
wangmuy/dsh-provider-dispatcher
把多个子插件聚合成一个统一能力对外提供
相关插件 · 模型接入
API 中继安全审计toby-bridges/api-relay-audit
面向 AI API 中转与 LLM 代理的本地安全审计。
★ 897已汉化DSH
69.4
免费搜索插件DDDMUC/dsh-free-search
DeepSeek Harness 免费搜索插件 —— 无需 API key,零成本,多引擎可切换。 一个给…
★ 938已汉化DSH
69
免费联网搜索liustack/modsearch
在官方 App 里模型能联网,切到 API 就不能了。ModSearch 把联网补回来:网页搜索、X…
★ 863已汉化DSH
68.5
WorkBuddy 账号池XDTrees/dsh-xdpool
把你能白嫖的模型额度接进 DSH 同一个池:WorkBuddy 多账号自动容错、十三家扫码登录、76…
★ 441已汉化DSH
67.9
OpenCode 免费模型FishBottle7/opencode2dsh
在 DSHDeepSeek Harness里原生使用 OpenCode Zen 的免费匿名模型。
★ 387已汉化DSH
67.8
AI 模型网关tingly-dev/tingly-box
Tingly Box Web UI 演示
★ 373已汉化DSH
67.4
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。