dsh-foreman-node:把本机 DSH 接进 foreman 派活链路

前言

在 DSH 里做智能体开发,往往只有「这一台机器上的会话」;若主 loop 在别处选任务、记账本、做策略,执行端仍需有人把任务落到具体目录、跑模型、把进度回传。把整套 foreman 逻辑装进每台笔记本既不合适,也让 NAT 后的设备难以被稳定访问。dsh-foreman-node 是 foreman 体系的设备侧插件:本机主动连出去接单,在本地建受限会话干活,用统一协议回报状态,工单与决策仍留在主 loop 的 dsh-foreman 一侧。

这是什么

  • 名称与维护者:GitHub 仓库 niechao136/dsh-foreman-node,作者 niechao136;非 DeepSeek 官方产品。
  • 定位:装在「要被主 loop 派活」的机器上(公司笔记本、宿舍电脑等)。不做工单、评估、决策、策略、数据库或 SQLite;「这事该不该做」由主 loop 判断。
  • 当前状态:README 标明早期开发中;协议、连接、接单与回报工具已落地,测试 15 项。package.json 版本为 0.6.1,许可 MIT。

主 loop 与设备的关系可概括为:主 loop 负责账本与下发;设备通过出站 WebSocket 连接,在本地维护 job-<assignmentId> 会话并回报。

┌──────────── 主 loop(另一台机器)────────────┐
│  dsh-foreman:唯一账本、选设备、下发、收回报     │
└────────────────────┬─────────────────────────┘
                     │  设备主动外连(wss)
                     ▼
     ┌───────────────────────────────┐
     │  dsh-foreman-node(本机)      │
     │  job-<id> 会话,权限受限       │
     │  你自己的 DSH 一切照常         │
     └───────────────────────────────┘

核心功能

下面按 README 描述的三件事说明插件在设备上实际做什么。

连出去

设备侧通过 wss 连到主 loop 提供的稳定域名,断线后指数退避重连。连接方向是出站,公司 NAT 后面一般也能用。若配置了 SSH 隧道,插件会自行拉起 ssh -N -L 并在断开时自动重连,无需再手开 ssh -L。

接单

收到 assign 后,在帧里指定的目录创建或复用会话 job-<assignmentId>,把渲染好的任务文本作为用户消息投入;requestId 保证幂等,重投不会产生 duplicate 消息。会话会挂上 foreman_report 工具,供模型回报进度。主 loop 在收到 accepted 后才把 assignment 记为 started。

接单时会话权限为 workspace-write(不是主 loop 常用的 danger-full-access):无人值守机器上弹审批容易卡死;需要越界时设备侧不报弹窗,而是通过 blocked 由人决定放宽 root 或换设备。

回报

在 job 会话上注册的 foreman_report 支持 progress、ready、blocked、failed 及可选提问,转成 report 帧发回主 loop。协议约定 report 的 state 不含 dropped——那是主 loop 的判断,设备没有判断权。

协议要点

帧定义在仓库 src/protocol.ts,README 称该文件为协议唯一权威;主 loop 包 dsh-foreman 从 dsh-foreman-node/protocol 导入,避免两侧漂移。约定包括:一条 WebSocket 文本消息一个 JSON 帧,v 为协议版本并在握手时校验;单帧上限 256 KiB;带副作用的帧带 frameId 供去重。

安装与启用

DSH 生态里插件常以 profile 的 cordis.patch.yml 声明。README 给出的装法如下:在本机 profile 中加入插件条目并填好连接与项目路径,然后重启本机 DSH。主 loop 无需因设备表变更而重启(设备表在主 loop 数据库,不在其插件配置里)。

# 本机 profile 的 cordis.patch.yml
- id: dsh-foreman-node
  config:
    url: wss://foreman.example.com     # 主 loop 的稳定域名(隧道后面)
    deviceId: laptop                   # 主 loop 上 scripts/add-device.mjs 登记的那个 id
    token: <登记时打印的那一枚>
    roots:
      - project: shop
        path: 'D:\工作\shop'            # 本机自己的绝对路径,原样写

装进 profile 后,设置里会出现「设置 › 设备连接」:可从本机 ~/.ssh 选密钥、填枢纽主机与用户、点「测试连接」,再把枢纽登记设备时给出的 deviceId、token 与项目名到本机路径的映射填齐。插件详情页不再单独提供配置入口。

也可直接编辑 cordis.patch.yml 写全量配置,例如开启 SSH 隧道:

- id: dsh-foreman-node
  config:
    url: wss://foreman.example.com   # 隧道开着时不参与连接
    deviceId: laptop
    token: <枢纽登记设备时给出的令牌>
    roots:
      - project: shop
        path: 'D:\工作\shop'
    ssh:
      enabled: true
      host: 203.0.113.10
      port: 22
      user: ubuntu
      keyPath: /home/me/.ssh/id_ed25519

「默认对话策略」为下拉框,选项来自本机权限服务 permissionPresets.catalog(),不要手填名字;未知预设名保存后页面会标出,任务下发时可能退回 workspace-write 并仅警告。

SSH 限制:不支持密码登录(自动重连依赖 BatchMode=yes),也不支持带口令的私钥,请把密钥放进 ssh-agent。

运行环境:package.json 要求 Node ^22.19.0 || >=24.0.0,DSH 引擎 ^0.2.1-alpha.2。

典型用法:从配置到接单

  1. 在主 loop 侧用 scripts/add-device.mjs 登记设备,记下 deviceId 与 token。
  2. 在本机 profile 写入上述 cordis.patch.yml(或用设置页等价配置),roots 里 project 与主 loop 任务里用到的项目名一致,path 为本机绝对路径。
  3. 重启本机 DSH,确认 wss(或 SSH 隧道)连通。
  4. 主 loop 下发 assign 后,侧栏出现 job-<assignmentId>;在会话内照常使用 DSH,模型通过 foreman_report 更新状态。
  5. 遇到权限边界,用 blocked 回报,由人在主 loop 或策略侧处理,而不是在本机强行开全权限。

适用场景与注意

适合谁:已有或计划部署 dsh-foreman 主 loop,希望多台机器以「出站连接 + 本地 workspace-write 会话」方式接任务、回传进度的团队或个人。

设计边界:设备侧故意不承载账本与策略,避免把领域内核铺到每台笔记本;架构思想 README 归因于 DeepSeek Harness 团队《Super-agent 设计探索》中的「计算与执行环境分离」,实现参考了 dsh-superagent-local 与 dsh-superagent-prototype(均为 MIT)。

安全与信任:插件在本机 DSH 进程权限下运行,安装与启用前应阅读仓库源码与 MIT 许可证,确认 token、SSH 密钥与 roots 路径符合你的安全策略。社区目录 SkillHub 插件页 与 GitHub 为独立信息来源,与 DeepSeek / 幻方无官方从属关系。

结尾

dsh-foreman-node 把「连出去、接单、回报」收拢成设备侧最小闭环,与主 loop 的 dsh-foreman 分工明确。若要查配置字段与协议细节,以仓库 README 与 src/protocol.ts 为准。

  • 目录页:https://www.skillhub.cn/plugins/niechao136/dsh-foreman-node
  • GitHub:https://github.com/niechao136/dsh-foreman-node
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜