← 返回列表
未验证
dsh-delegate 🐋
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/9 · 已提供中文文档
dsh-delegate: model-aware subagent delegation for DeepSeek Harness — per-call models, depends_on dependency gating, per-child personas, a durable run roster, audit events, and conversation-flow tool cards. | 给 DeepSeek Harness 的子代理委派加上:按次选模型、依赖门控、角色人设、任务花名册。
综合分
30.6
GitHub 分
30.6
用户评分
—
★ Stars
2
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add FEOH333/dsh-delegate该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/18(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-settings@deepseek-ai/dsh-subagent@deepseek-ai/dsh-tools@deepseek-ai/schemastery用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-delegate 🐋
⚠️ 暂停维护 / DEPRECATED(2026-09):DeepSeek Harness 官方已原生提供 Subagent 模型选择——设置中可为 Agent 授权「为每个 Subagent 选择提供方、模型与推理强度」(仅影响新会话)。本插件的核心功能(按次选模型)已被官方覆盖。本仓库进入仅存档状态:不再新增功能、不再适配新版本;已有版本与全部文档保留供参考。感谢所有使用者与贡献者 🐋
模型感知的子代理委派工具包 — 给 DeepSeek Harness 的 subagent / subagent_fork 加上:按次选模型、依赖门控、角色人设、任务花名册、审计事件与对话流卡片。
Model-aware subagent delegation for DeepSeek Harness: per-call models, dependency gating, personas, a durable run roster, audit events, and conversation-flow tool cards.
version
license
topic: dsh-plugin
仓库名 dsh-delegate 是品牌名;npm 包名保持 dsh-tool-subagent-model(与既有安装兼容,安装命令见下文)。
为什么需要它
官方 subagent / subagent_fork 工具的子代理模型跟随主 agent,无法按次指定。多步委派时,"先做 A 再做 B"只能靠模型自己在对话里记忆,容易乱序、漏等、重复。
本插件在官方工具的语义之上加了两层:
1. 按次选模型:每个子代理可以指定不同模型(快模型做机械活、强模型做关键活),自动路由到正确的提供商;
2. 轻量治理层(v0.3.0+):任务花名册(subagent_status)、task_id / depends_on 依赖门控、persona 角色人设、审计事件、对话流卡片——协调状态落在磁盘上,不再烧主 agent 上下文。
无遥测、无外部网络请求(仅调用你已配置的模型提供商)。
✨ 功能一览
- 按次选模型:model 参数枚举来自当前真正可路由的提供商路由(ctx.llm 的 listProviders() + listModels(),部署无关),provider 自动路由(优先主 agent 路由,唯一路由自动选中,多路由歧义时显式报错并列出选项);模型列表随设置与适配器拓扑热更新。优先级:调用参数 > 设置默认值 > 继承主模型。
- 模型来源标注(v0.3.3+):花名册与对话流卡片直接标注每条委派的模型来源(arg 显式指定 / default 默认值 / inherited 继承),一眼看出"为什么是这个模型"。
- 锁定默认模型(v0.3.3+):设置卡片开关或行配置 lockDefaultModel——开启且配置了默认模型时,忽略每次调用指定的 model,强制使用默认值(结果会带 note 提示)。
- 依赖门控:task_id 命名一次委派,depends_on 声明依赖——依赖未满足时工具拒绝启动并列出未满足项(含当前状态),把"按顺序执行"变成确定性约束。
- 角色人设:persona 参数给子代理注入自定义人设,随子代理 descriptor 持久化,冷恢复时重新应用。
- 任务花名册:subagent_status 工具输出当前工作区的全部委派记录(task_id / 状态 / 模型 / 驻留活动 / 依赖链 / 结果摘要)。
- 审计事件:每次委派向会话日志追加 subagent-model/run-started | run-settled 事件(只进日志、不进模型历史),可审计、可复盘。
- 对话流卡片:浏览器端为委派工具渲染状态卡片(实时状态徽章、依赖、人设、结果摘要、一键打开子会话),为花名册工具渲染表格视图。
- 设置卡片:设置 → 插件 → 插件配置里编辑默认子代理模型 / 默认 max tokens / 委派深度上限 / 锁定默认模型。
- 总开关:trackRuns: false 一键回到纯委派模式(v0.2.x 行为)。
📦 安装
前置要求:Node.js ^22.19 或 >=24,已安装 DeepSeek Harness(dsh ≥ 0.1.1-rc.2;0.1.2-rc.1 已实测适配)。
第 1 步 · 安装插件包:
dsh plugin --profile web add github:FEOH333/dsh-delegate
第 2 步 · 在 profile 的 cordis.patch.yml 里挂两个工具实例($DSH_HOME/profiles/web/cordis.patch.yml):
- insert:
- id: subagent-model
name: dsh-tool-subagent-model
config:
provider: spawn # 全新上下文的子代理
toolName: subagent_with_model
backgroundMode: continuable
- id: subagent-fork-model
name: dsh-tool-subagent-model
config:
provider: fork # 继承当前对话的子代理
toolName: subagent_fork_with_model
backgroundMode: continuable
第 3 步 · 重启 dsh web 并刷新页面(host 改动需要重启进程;浏览器强刷即可加载客户端)。
工具注册在宿主全局层,所有会话、所有预设的 agent 都能看到(子代理自身的嵌套委派受 maxDepth 限制,默认 3)。
卸载:从 cordis.patch.yml 删除两个 insert 行并重启;注册表目录 .dsh-subagents/ 留在各工作区,可手动清理。
🚀 使用
工具一览
| 工具名 | 提供商 | 用途 |
|---|---|---|
| subagent_with_model | spawn | 全新上下文的子代理,可指定模型 |
| subagent_fork_with_model | fork | 继承当前对话上下文的子代理,可指定模型 |
| subagent_status | —(进程级共享)| 查看当前工作区的委派花名册 |
调用参数
| 参数 | 说明 |
|---|---|
| description / prompt / run_in_background | 与官方 subagent 工具语义一致 |
| model(可选)| 子代理模型 id(枚举来自模型页);省略 → 设置卡片默认值 → 继承主 agent 模型;锁定默认模型开启且默认值存在时,此参数被忽略 |
| provider(可选)| 提供商路由;省略时自动解析(优先当前路由 → 唯一路由 → 歧义报错列出选项) |
| max_tokens(可选)| 子代理最大输出 token;省略 → 设置卡片默认值 |
| task_id(可选)| 给本次委派起名(如 t-research);省略时等于 run id;其他委派可用它做 depends_on |
| depends_on(可选)| 依赖的 task_id 列表:全部满足(completed / idle)才启动,否则报错列出未满足项 |
| persona(可选)| 子代理角色人设:替换该子代理的部署人设(continuable 子代理持久化并在冷恢复时重应用);提供商需支持 persona 能力 |
示例
subagent_with_model(description="整理日志", prompt="……", model="")
subagent_fork_with_model(
description="评审方案", prompt="……",
task_id="t-review", depends_on=["t-research"],
persona="你是一名资深代码评审,只指出真实缺陷,不客套。"
)
subagent_status() # 查看所有委派的状态与 task_id
运行状态语义
| 状态 | 含义 | 满足 depends_on |
|---|---|---|
| running | 子代理正在工作 | 否 |
| idle | continuable 子代理干净结束一轮(仍可被继续唤醒)| ✅ |
| completed | 前台 / 后台一次性任务完成 | ✅ |
| failed / cancelled | 失败 / 取消(终态,不可回退)| 否 |
注册表文件
每次委派追加一条记录到 /.dsh-subagents/runs.jsonl(追加式 JSONL,按 runId last-write-wins 折叠,超 400 行自动压缩为"活跃 + 近期终态")。每条记录含 modelSource(模型来源:arg / default / inherited)。目录名可用 stateDir 配置;stateDir: "" 为纯内存模式,不写任何文件。多进程同时写同一工作区不保证一致(单 dsh 进程内已用 promise 链锁串行化)。
⚙️ 配置项(每个实例)
| 键 | 默认 | 含义 |
|---|---|---|
| provider | 必填 | ctx.subagents 提供商名(spawn / fork / …) |
| toolName | subagent_with_model | 模型可见的工具名,每个实例必须不同 |
| backgroundMode | continuable | continuable(默认后台、返回持久子代理 id)或 one-shot |
| maxDepth | 3 | 委派深度上限;0 禁止委派;provider-managed 交给提供商 |
| stateDir | .dsh-subagents | 注册表目录名(工作区下);"" = 纯内存跟踪 |
| statusToolName | subagent_status | 花名册工具名;"" 禁用;进程内只注册一次(首个实例生效) |
| trackRuns | true | 总开关:false 完全关闭注册表 / 事件 / 门控 / 花名册,回到 v0.2.x 行为 |
| lockDefaultModel | false | 锁定默认模型:开启且默认模型已配置时,忽略每次调用指定的 model(设置卡片开关与之等效,任一开启即生效) |
🖥️ Web UI
- 设置页签 + 卡片(设置 → 侧栏「子代理模型」页,以及 设置 → 插件 → 插件配置卡片):编辑省略参数时的默认值(默认模型 / 默认 max tokens / 委派深度上限 / 锁定默认模型)。数据走插件自己的 /api/subagent-model/ 路由,写路由带 loopback + 同源信任围栏。
- 委派卡片:对话流中 subagent_with_model / subagent_fork_with_model 的工具调用渲染为状态卡(标签 / 模型 / 模型来源 / 状态徽章 / task / 依赖 / 人设折叠 / 结果摘要 / 打开子会话),2.5s 轮询花名册路由,状态终态后自动停止。
- 花名册卡片:subagent_status 工具调用渲染为实时表格视图。
- 若未来 shell 缺少相关 slot / 服务,卡片自动降级(仅隐藏跳转按钮),不影响设置页签。
🏗️ 工作原理
模型调用 subagent_with_model(...)
│
├─ 依赖门控:depends_on 全部满足才放行(否则报错列出未满足项)
├─ 路由解析:model/provider → 提供商路由(自动,歧义显式报错)
│ └─ 目录来源:ctx.llm listProviders/listModels(实时可路由)→ 回退 llm-pi-ai 设置节
├─ 启动:subagents.start / startContinuable(官方公开接缝)
├─ 注册表:/.dsh-subagents/runs.jsonl 追加记录(锁内读写)
├─ 审计:parent.session.append('subagent-model/run-started', …)
│
├─ 前台:settle 后同步落盘 completed/failed + run-settled 事件
├─ 后台任务:任务结算时经 done 包装落盘
└─ continuable:进程级 subagent/end 监听(只认自己索引过的 child id)
└─ 干净收尾 → idle;异常 → failed/cancelled
浏览器端(客户端半区):
设置:settings.section 独立页签(list 槽,注册即渲染)+ settings.plugin.item 卡片(keyed,按设置命名空间分发)
委派卡片 / 花名册卡片 ──2.5s 轮询──▶ GET /api/subagent-model/runs?cwd=&sessionId=
(磁盘真相 + listChildren 实时驻留状态,只读)
关键设计(详见源码注释):
- 咨询性:注册表、事件、驻留查询都是咨询性路径,任何失败都降级(内存回退 / 跳过),绝不打断委派;只有显式 depends_on 把注册表当权威。
- single-flight 纪律:插件按两个实例挂载(spawn + fork),进程级共享资源(路由族、花名册工具、subagent/end 监听器、settings 命名空间)都只注册一次。
- 注入纪律:只访问 inject 声明的服务属性;可选服务一律 ctx.get(...) 并处理 undefined(v0.3.0 教训,见 CHANGELOG)。
🛡️ 兼容性设计(防 dsh 升级失效)
当前要求 dsh ≥ 0.1.1-rc.2,并已针对 0.1.2-rc.1 实测适配:
- settings.plugin.item 为 keyed 插槽(旧版按 id 注册的 list 槽已不存在,v0.3.4 起按新契约注册;settings.section 页签为 list 槽,v0.3.6 双保险);
- 0.1.2-rc.1 移除了 @deepseek-ai/dsh-settings 的 installSettingsSection / settingsNamespace 导出——静态 import 会在加载阶段抛 SyntaxError 并中断整个 profile 启动。v0.3.8 改为直接调用底层公开接缝 ctx.inject(['settings'], sctx => sctx.settings.register(ns, schema, { base }))(旧包装器的内部实现,签名跨两个版本未变);
- 模型目录不再绑定 llm-pi-ai 设置节,而是优先读 ctx.llm 的实时可路由路由(v0.3.8),因此 llm-deepseek 或自定义适配器的部署同样能列出模型;
- 设置命名空间注册只用 ctx.inject 等待服务(不再用 ctx.get 预检),避免并发挂载时命名空间永久缺失(v0.3.8)。
1. 只用公开接缝:ctx.tools.register、ctx.subagents(start / startContinuable / listChildren / subagent/start|end 事件)、ctx.llm(可选读 listProviders / listModels)、ctx.systemPrompt.section、ctx.settings(可选读 / ctx.inject 注册)、ctx.webServer.register(可选,仅浏览器卡片)、Session.append、llm/adapters-updated 事件。不 import 内部模块。inject 只声明 tools / subagents / systemPrompt——webServer 不注入,否则 headless / TUI profile 里整行永不激活、委派工具根本不挂载。
2. 依赖从宿主解析:只声明 peerDependencies,运行时经 profile 的扁平 node_modules 解析到当前安装的 dsh 自带版本,不锁版本、不随包分发、不漂移。
3. 镜像官方模式:注册时机(provider 出现/移除)、前后台路由、stop-reason 处理、输出渲染与官方 dsh-tool-subagent 同构。
4. 防御性解析:设置节任何形状都不会让插件崩溃,最坏退化为继承行为。
5. 客户端按能力探测:toolview 卡片注册套 try/catch;设置卡片按 keyed 契约注册(自带 try/catch 防御),host 注册 subagent-model 设置命名空间(新版插件配置页按命名空间分发卡片,v0.3.5);另有独立设置页签(settings.section list 槽,注册即渲染,v0.3.6 双保险);sessions 服务走 ctx.get() 每次点击时可选读取(v0.3.8 起不再在 apply 时捕获,避免控制器晚激活导致按钮永久失效),缺失只隐藏“打开子会话”按钮;清单只声明 loader 必需契约(dsh.client.platform: "web" + exports["./client"])。
6. 失效方式明确:接缝变更时加载 / 调用阶段报出可读错误,不静默出错。
🌐 dsh-std 生态适配(Experimental)
本仓库携带符合 dsh-std Community v0.15 的 dsh-plugin.json(manifestVersion: "0.15"),并通过 dsh-ecosystem-spec 的官方准入评估器验证:
sh
在 dsh-ecosystem-spec 检出内:
npm run validate:manifest -- --manifest /path/to/dsh-delegate/dsh-plugin.json
→ {"valid":true,"decision":"compatible","missingOptional":[]}
- 实验适配声明:规范当前为 Draft/Experimental,本插件以实验级身份参与,不宣称任何 Candidate/Stable 认证。
- 声明闭包诚实:插件未实现任何 dsh-std 公共协议(commands / messages / storage / presentation 均为空声明),其能力全部走 DSH 公开接缝(tools / subagents / settings.section / tool.call.toolview),通过宿主 adapter 层(如 dsh-TUI 的 @dsh-std/adapter-dsh)与生态共存——清单的 x-experimental 字段详细说明此边界。
- revision:source.revision 指向清单生成时的仓库基线提交,随每个发布轮次更新,不代表 Verified claim(未生成 artifact digest)。
🧪 开发与测试
lib/
index.js 宿主半区:工具注册、路由解析、执行流、end 监听、提示段
client.js 浏览器半区:设置页签 + 设置卡片 + 三个 toolview 卡片(手写、无构建)
settings-ns.js 设置命名空间注册(single-flight,v0.3.5)
registry.js 运行注册表:JSONL 折叠、锁、压缩、内存回退
status-tool.js 花名册工具(进程级 single-flight)
events.js 会话审计事件(含失败遏制)
routes.js /api/subagent-model/ 路由族(single-flight + 信任围栏)
config-store.js 用户默认值存储(原子写入,$DSH_HOME/subagent-model.json,默认 ~/.dsh)
scripts/
verify.mjs 一键验证:语法检查 + 两套冒烟测试
test/
smoke.mjs 宿主冒烟测试(真实 dsh-tools schema 校验 + 注入纪律 Proxy mock)
client-smoke.mjs 客户端冒烟测试(web shell 加载方式 + SSR 渲染)
运行测试需要 dsh 包可解析(@deepseek-ai/dsh-tools 等,不随仓库分发):
任选其一:
a) 把 $DSH_HOME/profiles/node_modules 链接为 node_modules(本地开发)
b) 在已安装 dsh 的 profile 环境里运行
npm run verify # 一键:语法检查 + 两套冒烟测试
npm test # 只跑两套冒烟测试
node test/smoke.mjs
node test/client-smoke.mjs
两个 mock ctx 都带注入纪律 Proxy:访问未在 inject 声明的服务属性会抛与真实环境一致的 cannot get property ... without inject,此类错误在测试阶段即暴露。
变更历史
见 CHANGELOG.md。
致谢
- 官方 dsh-tool-subagent 的成熟模式(注册时机、前后台路由、stop-reason 语义);
- dsh-plugin 社区生态的公开设计思想:状态出上下文(磁盘真相 + 按需读取)、依赖门控、失败遏制(如 dsh-agent-teams)——本仓库为独立实现,非 fork。
License
MIT © 2026 FEOH333
English Summary
dsh-delegate (npm package: dsh-tool-subagent-model) extends the official subagent / subagent_fork tools for DeepSeek Harness with:
- Per-call model choice with automatic provider routing, sourced from the live routable routes (ctx.llm.listProviders() / listModels()), so any adapter family — llm-pi-ai, llm-deepseek, custom — works; the llm-pi-ai settings section is only a fallback;
- Model provenance labels (arg / default / inherited) in the roster and tool cards;
- Lockable default model (Settings card switch or lockDefaultModel row config) that overrides per-call model when a default is configured;
- Dependency gating via task_id / depends_on (deterministic ordering, refuses with the unsatisfied list);
- Per-child personas (persisted and reapplied on continuable resume);
- A durable run roster (subagent_status + /.dsh-subagents/runs.jsonl) and typed audit events;
- 对话流工具卡片(状态徽章、依赖详情、子会话导航)以及用于默认值的设置卡片;
- trackRuns: false 可恢复普通委托行为。
已针对 dsh 0.1.2-rc.1 验证:@deepseek-ai/dsh-settings 包装器的导出(installSettingsSection、settingsNamespace)在该版本中已被移除,因此 v0.3.8 改为调用底层公共接缝(ctx.inject(['settings'], sctx => sctx.settings.register(ns, schema, { base }))),而非静态导入它们——旧的导入会在链接时触发 SyntaxError,导致整个 profile 启动中止。设置命名空间注册也不再预先检查 ctx.get('settings'),该检查会与并发的行挂载产生竞态,并可能永久静默丢弃该命名空间。
dsh plugin --profile web add github:FEOH333/dsh-delegate
然后在你的 profile 的 cordis.patch.yml 中挂载两行(spawn + fork)(参见上文的安装部分),重启 dsh,并刷新浏览器。
所有追踪接缝在设计上都是建议性的——文件系统或事件故障绝不会中断委托。该插件仅使用公共 DSH 接缝,从宿主安装中解析其依赖,并且其冒烟测试通过代理 mock 强制执行 Cordis 注入纪律。扫码进群