dsh-mcp
omp-dsh-workers
从你的 oh-my-pi 会话中运行 DeepSeek Harness (DSH) 工作进程。oh-my-pi (OMP) 是一个终端编码代理;DeepSeek Harness (dsh) 是 DeepSeek 的代理运行时。该会话成为指挥者:它通过 dsh_spawn 分发任务简报,每个工作进程作为持久的 dsh --profile headless 会话运行,工作进程的问题和结果以由脚本中继的原生消息形式返回。
实验性 v0.1:接口已在 docs/contracts/ 中冻结,但这里的一切都尚未经过公开发布周期。
为什么
OMP 的 harness 每个任务都很昂贵,而原生子代理会在每个任务上付出这一成本。在这里,该成本只在指挥者层面支付一次;实际工作在 DSH 中运行,快速且节省 token,两者之间只有一个脚本:每个任务的模型 token 为零。DSH 让运行持久化(在真实会话 id 上使用 --resume)。当你不需要 DSH 时,原生子代理仍然是正确的选择。
Related MCP server: deepseek-subagent-mcp
工作原理
两个模型层级,刻意分开:
层级 | 谁 | 模型来源 |
1 | 指挥者 — 你的主 OMP 会话,处于 | 你的 OMP 会话模型 |
2 | DSH 执行者 — 每次运行一个 DSH headless 进程 |
|
因此,当 dsh_spawn 没有 model 时,@dsh 指定执行者继承的模型——监视器是代码,而不是模型。
flowchart TD
D["Director<br/>main OMP session, /dvibe on"]
B["dsh-bridge<br/>argv spawn · run registry · steer channel"]
X["DSH headless run<br/>+ resume plugin"]
L["relay.ts<br/>script representative, in-process"]
D -->|"dsh_spawn — brief, label, model"| B
B -->|"dsh --profile headless [--resume]"| X
X -->|"Envelope v1 (last stdout line)"| B
B -->|"pollRun, 1s"| L
L -->|"⟨label⟩ question / result / failure (followUp)"| D
D -->|"dsh_answer — resumes the session"| B
D -.->|"steering: dsh_list → dsh_send / dsh_wait by runId"| B
D -.->|"dsh_kill by runId"| B指挥者使用 dsh_spawn 启动,用 dsh_answer 回答,用 dsh_send 引导,用 dsh_wait 等待,用 dsh_kill 取消;dsh_list 将标签解析为 runId。
组件
路径 | 说明 |
| OMP 扩展: |
| bridge-core:在独立的分离进程组中启动、运行注册表、Envelope v1、引导通道、所有者租约和回收。Node ≥ 22,纯 ESM JavaScript,无依赖,无构建步骤。 |
| DSH headless 配置文件中的 Cordis 插件:添加 |
| 安装:符号链接到实际使用的 OMP 目录、DSH 配置文件补丁、插件依赖链接。 |
要求
oh-my-pi v18 — 已针对 18.0.3 / 18.0.4 验证;
@oh-my-pi/*固定为^18.0.4。DSH ≥ 0.1.1-rc.2 位于
PATH上,且存在headless配置文件。bun 用于测试脚本;Node ≥ 22 用于 bridge-core。
在你的 DSH 设置中配置了模型提供商;该扩展与提供商无关:它向 DSH 传递
<provider>/<model>[:<effort>]字符串。
DSH 处于发布候选阶段。 恢复插件按 entry id 挂载,因此重命名这些 id 的发布会让补丁静默停止生效。每次 DSH 升级后重新运行 dsh --profile headless --help:如果 --resume 消失了,说明插件未挂载;docs/dsh-update-checklist.md 中有完整清单。
安装
该仓库是事实来源;实际使用的目录只会收到指向它的符号链接。
1. 将扩展链接到 OMP。
scripts/install-omp-links.sh [--dry-run] [--uninstall] [--omp-dir DIR]在 $OMP_DIR(默认 $HOME/.omp/agent)下创建符号链接 extensions/dsh-task。幂等——同源的链接保持不变,指向其他位置的链接会被重新指向,而目标位置存在真实文件时脚本会中止。--uninstall 只移除指向此处的链接。
2. 将恢复插件挂载到 DSH headless 配置文件中。
scripts/install-resume-plugin.sh # install
scripts/install-resume-plugin.sh --uninstall # remove每次更改前都会备份;需要 dsh 位于 PATH 上,并且存在 ${DSH_HOME:-$HOME/.dsh}/profiles/headless。然后:
将
@deepseek-ai和commander从$DSH_MODULES符号链接到插件的node_modules。添加插件:
dsh plugin --profile headless add link:<plugin dir>,在备份package.json之后。追加一个
cordis.patch.yml块,禁用headless-startup/headless-runner,并插入headless-resume-startup/headless-resume-runner。验证:仅当
dsh --profile headless --help提到--resume时才成功。
3.(仅测试) scripts/link-plugin-deps.sh 自行链接依赖;bun run test:resume 会调用它。
用法
指挥者模式
/dvibe切换指挥者模式;/dvibe on//dvibe off是显式形式。模型也可以通过dvibe工具(action: "on" | "off")切换它,该工具保留在收窄后的工具集中。开启后,工具集收窄为
read、todo、dsh_spawn、dsh_answer、dsh_send、dsh_wait、dsh_list、dsh_kill、dvibe,外加一条追加到系统提示中的指挥者指令。dvibe工具在其结果中返回该指令:模型在before_agent_start运行后调用它,因此回合提示无法携带这些规则。任务简报原样进入
dsh_spawn。工作进程的问题以来自relay.ts的⟨label⟩消息到达,用dsh_answer回答;结果以相同方式到达。投递是至少一次:事件每 120 秒重新宣布一次,直到匹配的
message_start证明 followUp 已进入回合上下文;每个事件最多尝试 3 次。已投递的need_input会一直保持监视,直到dsh_answer。分发完工作了?结束回合:事件会自行作为消息到达。
dsh_wait是同步替代方案,仅当下一步阻塞在该特定运行上且没有其他工作可分发时使用;以这种方式读取的信封绝不会到达两次。在
/dvibe off、关闭或进程内会话切换时,恢复之前的工具集。
任务简报、模型、恢复
为每个任务指定一个简短的
label,并可选择指定model,两者都作为dsh_spawn参数;该标签稍后可在dsh_list、dsh_answer、dsh_send中找到该运行。模型记法为
<provider>/<model>[:<effort>];effort 级别:off、minimal、low、medium、high、xhigh、max。最后一个:之后的后缀仅当它是其中之一时才计为 effort,否则冒号属于模型名称。不允许空白或控制字符;provider/model 各 ≤ 200 字符,spec ≤ 512;格式错误的 spec 会在启动前失败:error [invalid_model]。没有
model时,运行继承 OMP 的@dsh角色(modelRoles.dsh),回退到你会话的模型,再回退到 DSH 自己的默认值。恢复:传入
resumeFromRunId;bridge 查找其sessionId。不要将runId放入resumeSessionId:它们是不同的标识符,你会得到resume_not_found。一旦运行在磁盘上留下了信封,恢复即可工作;没有信封时
dsh_spawn会抛出has no session to resume——无论运行仍在进行中还是已经消失(被提前杀死、启动时崩溃、被清理)。在做出反应前先检查是哪种情况:为仍在工作的运行发送新简报会重复工作。模型覆盖不粘滞:没有
model的恢复会重新计算模型。dsh_answer根本没有model参数;要在另一个模型上继续,请使用带resumeFromRunId和显式model的dsh_spawn。
指挥者看到的内容
工具卡片为人类渲染,与模型接收到的文本分开:▶ dsh spawn → <label>、✓ started <label> (<runId8>) · pid …,然后是带最后输出行的 ⏳ still running,或 ✓ completed · model: … · session: … 加上首批结果行。在跟踪运行期间,编辑器上方会有一个 dsh runs 面板,页脚显示 dsh: N running · M done。工具的文本输出不变:它仍然是契约。
工具
工具 | 参数 | 调用者获得的文本 |
|
|
|
|
|
|
|
| 该运行的结果,或 |
|
|
|
|
|
|
| — |
|
|
| 该运行的结果(阻塞式,一次性) |
dsh_wait 超时是正常的:运行保持存活,可以再次等待;中止等待绝不会停止运行。dsh_send 返回 pending 意味着写入已到达通道,并且重新检查时运行仍然存活——并非确认投递;请等待而不是重新发送。dsh_task 不留下信封,因此其运行无法继续;链式操作通过 dsh_spawn 进行。
指挥者可以依赖的行
这些行会进入工具的文本输出,而不仅仅是 details,因此阅读纯文本的指挥者可以验证执行者、连续性和错误代码:
model: <provider>/<model>[:<effort>]
session: <sessionId>
error [<code>]: <message>
# and one line per run from dsh_list:
<runId> state=<state> label=<label|-> model=<spec|default> started=<ISO-8601>错误代码
每次失败都会以带有信封代码的显式错误回合返回,绝不会是部分成功。
Envelope code | Meaning |
| DSH 二进制文件未能启动。 |
| 运行以失败退出码结束。 |
| 运行未在截止时间内完成。 |
| 运行被取消。 |
| DSH 未返回有效的 Envelope v1。 |
| 不存在可恢复的会话。 |
| 持久化的会话已损坏或不受支持。 |
| 会话已处于活动状态,或其持久化的准备内容已被占用。 |
| 没有人续订运行的租约;看门狗已回收它。 |
| 运行超过了截止时间并被回收。 |
| 提供商/模型不在 DSH 的目录中。 |
| 模型存在,但 effort 或元数据与其不匹配。 |
默认值:运行截止时间 30 分钟;所有者租约 5 分钟,由每个 dsh_wait 窗口续订。
Tests
bun run test # unit + integration + bridge = 370 tests, no installed DSH needed
bun run test:resume # resume plugin — needs an installed DSH已验证此树上的数量:195 个单元测试 + 11 个集成测试 + 164 个桥接测试 = 370 个测试,在未安装 DSH 的情况下全部通过。单元测试模拟 bridge-core;集成测试和桥接测试针对通过 DSH_BINARY 注入的假 dsh 二进制运行。CI 在 typecheck、lint、format:check(严格 tsc、Biome)之后,使用干净的 HOME 运行相同的三个套件。test:resume 在运行时导入 @deepseek-ai/* —— 必须安装 DSH。
Limitations
孤儿进程会被清除,而非预防。 DSH 运行比 OMP 会话存活得更久;清除发生在加载时以及每 30 秒。在干净的
session_shutdown时,扩展会终止自己的运行(SIGTERM同步,SIGKILL尽力而为),但不会清除注册表。无进行中崩溃恢复:回合中途的死亡不会被恢复;只有 DSH 会话 可以恢复。
恢复时的压缩会读取上一次运行的头部,直到写入第一个新的请求头部。
信封中的
model是尽力而为的:最后准备的请求配置,而非派发的证明。模型覆盖是按运行生效的,不会跨
resumeFromRunId继承。Hub 指标看不到 DSH 令牌。
Status, history, license
实验性 v0.1(0.1.0)。接口契约位于 docs/contracts/;docs/dsh-update-checklist.md 涵盖 DSH 升级。用户或模型阅读的所有内容均为英文;代码内注释和测试名称为俄文。MIT 许可证.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Build Apps and run code in 30 languages — sandboxed, with persistent sessions for agent loops.
Shared control plane for AI coding agents — tasks, memory, decisions, file locks. 12 tools.
Work on your own computers from Claude or ChatGPT: run commands, edit and search files.
Live SEO workflow tools for Claude Code, Codex, and AI agents.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables dispatching work to DeepSeek Harness agents from Claude Code/Codex, with native progress UI, tier policy, and vision/image generation through MCP tools.569 npm199MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents like Claude Code or Codex to delegate tasks to a DeepSeek Harness subagent with its own context window, providing tools for task delegation, result waiting, continuation, and supervision with sandboxed execution.6MIT
- AlicenseAqualityBmaintenanceEnables Codex and Claude Code to delegate implementation, research, debugging, and long-log work to DeepSeek Harness, then observe, continue, or cancel those sessions without leaving the primary workflow.153MIT
- AlicenseNot gradedqualityCmaintenanceEnables an interactive Claude Code session to delegate blocking tasks to headless pi and OpenCode workers, and lets all three peers exchange messages and list paired sessions over a shared local file bus. It exposes 18 tools covering sync/async asks, steering, abort, session lifecycle, state inspection, and cross-agent messaging.216 npm1MIT