DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

FlanceVoV /

FlanceVoV/dsh-sub-agent

Verified

This plugin has no description yet.

★ 0 Stars0 Forks0 Issues5 Community rating0 Confirmed installs
View on GitHub
READMESource: master@e8d1d6d9

dsh-subagent-hub — DSH 子智能体枢纽

把一个你已经配好的模型发布成可 @、可观测、可评价的子智能体,直接长在当前 DSH 页面上。

子智能体不是「另一个模型写的一段回答」,而是真正的 DSH agent:它跑在同一套 agent 运行时上, 有自己的会话、工具、文件系统与沙箱,只是把 provider / model 换成你在配置页里指定的那一个。


长什么样

左侧是主对话,右侧是插件的悬浮球面板(已展开)。图是实际运行的截图,点开可看原尺寸。

评分排名表 —— 面板列出全部已配置的子 agent(各自的模型与工具策略),并显示谁在跑、哪个已归档:

悬浮球面板与评分排名表

实时输出详情 —— 点开某次运行即进入详情:逐 token 输出、tool 调用与产出文件,底部可确认该次运行的状态:

悬浮球面板与实时输出详情

图里的 agent 名、模型 ID 与评测分数都是真实运行产生的数据。本插件不附带任何预设配置,第一次打开时列表是空的。


版本兼容性(先读这一节)

本插件大量使用 DSH 的内部接口 —— ctx.subagents.start、session/event 的 {global:true} 语义、 客户端 bundle 的装配约定等。这些都不是公开 API,而 DSH 本体还处在 0.x 阶段,内部结构随时可能变。

开发并验证过的版本 @deepseek-ai/dsh@0.1.2-rc.1
声明兼容区间 >=0.1.2-rc.1 <0.2.0(package.json 里写作 peerDependencies 的 ^0.1.2-rc.1)
区间外怎么办 仍然加载,只警告。不会阻止你启动

区间外只警告、不阻止,是和插件的整体姿态一致的:它横跨 DSH 的多个子系统, 所以对每一项能力都用 ctx.get() 防御式取用 —— 取不到就关掉那项能力并说清楚关了什么, 而不是让整个插件起不来。版本不符时你会看到:

  • 启动日志一条醒目的警告(含检测到的版本、来源、声明区间)
  • /sub-agent/api/health 里的 harness 字段
curl.exe -sS http://127.0.0.1:3080/sub-agent/api/health
"harness": {
  "detected": "0.1.2-rc.1",        // 实际检测到的版本
  "source": "dsh entry",           // 从哪判出来的
  "tested": "0.1.2-rc.1",          // 本插件验证过的版本
  "supported": ">=0.1.2-rc.1 <0.2.0",
  "compatible": true,              // true 兼容 / false 超出区间 / null 无法判定
  "reason": null                   // 无法判定时说明原因
}

compatible 是三态的:true / false / null。null 表示判不出来—— DSH 没有把版本做成服务(已核实:没有 ctx.get('version'),pluginInventory 的 snapshot 也不带版本), 唯一可靠来源是磁盘上的 package.json。探测不到时它如实说「无法判定」并给出原因, 不猜、也不假设通过 —— 把「不知道」折叠成 true 是在编造结论。

如果你在 0.2.x 或更高版本上使用,请先看 /health 的 capabilities: 某项是 false 就说明那个能力被自动关掉了。这时插件的行为是降级并说明,不是崩溃。


安装

本插件未发布到 npm。 请按下面的方式从 GitHub 安装,npm i dsh-subagent-hub 这类命令不会成功。

从 GitHub 安装(需要本机有 git,pnpm 靠它取仓库):

dsh plugin --profile web add github:FlanceVoV/dsh-sub-agent

dsh plugin 本质是 pnpm 的薄封装(它在 profile 目录里跑 pnpm <args...>,再按装出来的实际包名 对账 dsh.profile.bundles),所以 pnpm 认识的 spec 它都收:github: 简写、完整 git URL、 tarball、link:/file: 本地路径。

等价的完整写法,以及锁定版本的写法:

dsh plugin --profile web add https://github.com/FlanceVoV/dsh-sub-agent.git
dsh plugin --profile web add github:FlanceVoV/dsh-sub-agent#<tag 或 commit>

注意上面的 #<tag 或 commit> 是你自己要填的——本仓库目前没有打过 tag。 不写 #… 就是每次重装都拿最新的 master,介意漂移的话请先打 tag 再用。

从本地目录安装(二次开发时用,改完代码热更新):

dsh plugin --profile web add link:<本插件目录的绝对路径>

装完必须重启一次 dsh web:新的 loader entry 与客户端 bundle 都只在启动时装配。

重启后确认它活着:

curl.exe -sS http://127.0.0.1:3080/sub-agent/api/health

返回 ok:true 且 initError 为 null 即正常。404 说明插件没被装配, 应检查 profile 的 dsh.profile.bundles 里有没有加上本插件。

顺手看一眼版本兼容性(见上一节):

curl.exe -sS http://127.0.0.1:3080/sub-agent/api/health
# 重点看 harness.compatible 与 capabilities 里有没有 false

卸载:

dsh plugin --profile web remove dsh-subagent-hub
# 然后重启 dsh web

怎么用

1. 打开开关

在输入框那一行的 @ 开关上启用。这是全局开关,打开一次对所有对话生效—— 子 agent 的配置本来就是全局的(一张表、所有对话共用),开关的作用域必须和它一致。

开关状态走实时流:在任一窗口打开,其它窗口会立刻跟着变,不需要刷新页面。

2. 看悬浮球

启用后每个窗口右下角都会出现悬浮球:

  • 收起:显示谁在跑 + 实时 tok/s
  • 展开:列表(忙 / 闲、速率、最近结束)
  • 点某一项:进入详情页,看是哪个会话、实时输入输出

tok/s 带 ~ 前缀表示这是估算值(流式进行中只能按字符数推算); 不带 ~ 的是权威值,由上一个已完成步骤的 token 用量算出。

3. 用 @ 委派

在消息里直接写 @名字,或者打 @ 从原生候选里选:

@研究员 查一下 X 的现状,给出可核对的结论

可以 @ 多个——主对话会为每个名字各发起一次委派。

忙的子 agent 不能被 @,这条规则在三个地方体现:候选菜单里直接不出现、 悬浮球一直列着谁忙谁闲、以及工具边界的硬拒绝。UI 只是礼貌,规则在工具边界。

4. 读评分

主对话拿到子 agent 的产出后会按四个维度打分(正确性 / 完整性 / 效率 / 成本), 分数进入排名表与跨轮回归表。回归表用于比较同一任务在不同轮次的表现, 所以同一个任务应当复用同一个任务标识。


配置子 agent

设置 →「子 agent」。同一个模型可以添加多次(例如同一个模型分别配「全工具」和「只读」两个角色)。

字段 说明
名称 @ 的句柄,必须唯一(归档后重名的会被拒绝)
agent 提供商 子 agent 的传输实现;只有支持 agentOptions 的才会出现在这里
模型提供商 模型路由(已激活的、有模型清单的排在前面)
模型 ID 该路由下的模型;换提供商时会同时重新选模型
模型最大上下文 本插件的输入预算闸,见下
单次输出上限 传给模型的单次输出 token 上限
工具策略 继承父级(全工具)/ 只读(fail-closed 白名单)/ 无工具
推理档位 留空 = 用模型默认
api 地址 留空 = 用 DSH 该路由的配置
凭据引用 留空 = 用该路由的默认凭据;只报「配没配」,不显示值
备注 可选
人格 / 系统提示词 可选,留空则沿用 DSH 的默认人格

归档不是删除:归档只把配置从 @ 候选里移走,历史运行与评价都还在, 设置页底部有「已归档」区块可以恢复。恢复时如果名字已被新配置占用会如实拒绝。

⚠ 「模型最大上下文」不是模型窗口。AgentOptions 只有 {provider, model, reasoningEffort, maxTokens},没有上下文窗口字段, 窗口是模型目录的属性,无法按子 agent 单独调小。 所以这个字段被诚实地用作本插件的输入预算闸:预估超限就拒绝启动并说明原因, 而不会假装改了模型窗口。


运行护栏

设置 →「子 agent」→「运行护栏」。改动立刻生效并写进用户层配置文件。

键 默认 含义 能否热改
maxConcurrentRuns 2 同时最多几个子 agent(真实费用护栏),超出排队而不是失败 ✅
maxParallelPerSession 3 同一父会话同时最多被 @ 几个 ✅
runTimeoutMs 900000 单次运行上限,到时取消并记为 timeout ✅
outputTailChars 20000 运行记录里保留的输出正文上限 ✅
retentionDays 0 运行记录保留天数,0 = 永久 ✅
tokPerSecondWindowMs 3000 速率采样窗口 ✅
readonlyToolAllow [] = 内置默认 「只读」策略的白名单 ✅
dbPath 空 = $DSH_HOME/subagent-hub/subagent-hub.db sqlite 路径 需重启
logToStdout true 是否把插件日志接到 stdout 需重启

配置来源,后者覆盖前者:内置默认值 → cordis.patch.yml 的 config(部署层)→ $DSH_HOME/subagent-hub/config.json(用户层)。

写配置的姿态是刻意不对称的:读的宽容降级(未知键打 warning 并保留默认值, 配置写错不该让插件起不来),写的严格拒绝(写下去的东西会持久化, 静默纠正一个写错的值等于把错误固化)。

「需重启」的项在界面里显示为禁用并说明该改哪个文件,不会假装保存成功。

调大 maxConcurrentRuns 后已经排队的任务会立刻被放行——否则用户看到的会是「改了没用」。 护栏区块里显示的「排队中 N」就是让这件事看得见。


数据

$DSH_HOME/subagent-hub/subagent-hub.db(sqlite,用 Node 内置的 node:sqlite,无需额外依赖)。

表:agents / runs / rounds / evaluations / settings。

只存有界输出正文(outputTail,默认 2 万字符),更长的正文靠 session_id 回查 DSH 自己的会话日志——本插件刻意不复制对话正文,只存指针。

数据库带 application_id = 0x53554241('SUBA'):拿错文件会直接拒绝打开, 绝不往别人的库里写。


API

前缀 /sub-agent/api,是宿主与面板之间的唯一接口。

方法 路径 用途
GET /health 存活、能力自检、DSH 版本与兼容性(harness)
GET /state?sessionId= 当前状态(含 agents 与 archivedAgents)
GET /stream SSE 实时流(常开)
POST /enable 开关
GET / PATCH /config 运行护栏
POST /model-detail 查某个模型的推理档位等细节
GET / POST /agents 列表 / 新建
PATCH / DELETE /agents/:id 修改 / 归档
POST /agents/:id/restore 从归档恢复
GET /runs 运行记录列表
POST /run 直接发起一次委派
GET /runs/:id、/runs/:id/detail 运行摘要 / 详情(增量)
POST /runs/:id/cancel 取消
GET /runs/:id/evaluations 该次运行的评价
POST /evaluate 打分
GET /leaderboard、/regression 排名 / 跨轮回归
GET / POST /rounds 轮次

模型侧另有三个工具:subagent_run、subagent_evaluate、subagent_roster。


日常开发

node scripts/build-client.mjs         # 把 lib/parts/*.js 拼成 lib/client.js
node scripts/build-client.mjs --check  # 只校验「产物 == 分片」
node --test "tests/*.test.mjs"        # 单元 + 集成(假 DSH 上下文跑通全链路)
node scripts/verify-client.mjs        # 用真 React 加载并 SSR 渲染客户端 bundle
node scripts/dev-server.mjs           # 真 HTTP + 真 sqlite 的离线宿主(127.0.0.1:8791)
node scripts/check-publish.mjs        # 体检:扫绝对路径 / 用户名 / 密钥痕迹
node scripts/pack.mjs                 # 自检 → 打包 → 列出包内容

改宿主代码时优先用 dev-server 或集成测试验证,不要为了试一次就重启 DSH。

客户端源码的读写规则

客户端 bundle 必须是单文件(DSH 的客户端模块系统只暴露少量种子模块), 所以源码放在 lib/parts/*.js(按文件名顺序拼接),lib/client.js 是构建产物。

分片是唯一的真相来源。 契约测试会重算并比对,直接改产物会让测试立刻变红, 提示你「改分片,然后跑构建」。

lib/parts/*.js 单独看不构成合法 JS(第一片开 factory,最后一片才收尾), 所以对它们跑 node --check 会报错——这是预期,不是问题。同理, 改完 lib/parts/*.js 必须跑一次 build-client.mjs。

热更新边界

改了什么 生效方式
lib/parts/*.js + build-client.mjs 热更新(不用刷新页面)
lib/host.js、lib/src/*.js 需要重启 dsh web
cordis.patch.yml、package.json 的 dsh 字段 需要重启 dsh web

排错

「dsh web 卡住了」

通常不是卡住。dsh web 是前台服务器,启动时打完那两行就不再输出, 在你按 Ctrl+C 之前它一直占着终端——「没有新输出」和「死住了」看起来一样。

按这个顺序判断它是活的还是死的:

# 1. 服务是不是真的在应答(这条最决定性)
curl.exe -sS http://127.0.0.1:3080/sub-agent/api/health

# 2. 每个客户端 bundle 是否都送得出去(都该是 200)
curl.exe -sS http://127.0.0.1:3080/plugins/events

# 3. 端口有没有被监听
Get-NetTCPConnection -LocalPort 3080 -State Listen

1 和 2 都正常就说明服务是好的,问题在终端或浏览器那一侧:

  • Windows 控制台 QuickEdit:在窗口里点一下(比如为了选中文字去复制)会让控制台进入选择模式, 进程输出被暂停,看起来就是「卡死」。按 Esc 或 Enter 退出即可。 根治办法:窗口标题栏右键 → 属性 → 取消勾选「快速编辑模式」。
  • 浏览器页面本身:如果标签页是空白的,看它自己的控制台——服务端 bundle 都是 200 的话, 问题在页面内,不在宿主。

插件路由全部 404

先确认你挂在哪个 profile 上:

Get-CimInstance Win32_Process -Filter "Name='node.exe'" | ForEach-Object { $_.CommandLine }

safemode 是救援 profile,设计目标就是零第三方插件——在那个 profile 下, 本插件与所有第三方插件的路由都会 404,/ 还会要求登录,那不是插件坏了。 回到正常工作状态就是重新跑 dsh web(即 web profile)。

「能打开,但有些功能是空的 / 不出现在界面上」

先查这两处,它们的顺序不能反:

curl.exe -sS http://127.0.0.1:3080/sub-agent/api/health
  1. 看 harness.compatible。 如果是 false,说明 DSH 版本超出了已验证区间 (harness.detected 是实际版本)——这是最可能的原因。
  2. 看 capabilities 里哪一项是 false。 每一项对应一个 DSH 服务: subagents / agents / tools / systemPrompt / llm / settings / credentials / sessions。 某一项为 false 就是某项能力被自动关掉了,而对应用户可见的症状是固定的:
能力 关掉之后你会看到
subagents @ 委派跑不起来,悬浮球永远没有任务
tools 主对话看不到 subagent_run 等三个工具(面板仍能用)
systemPrompt @ 的注入协议段没进系统提示词,主对话不知道该怎么处理 @
credentials 配置页的凭据引用拿不到状态
llm / settings / sessions 模型清单、设置读写、会话查询相应降级

harness.compatible 是 null 则表示无法判定版本(harness.reason 会说明原因)—— 这时不要据此认为兼容,去看 capabilities 的实际结果。

关于终端日志

logToStdout(默认开)在宿主启动时会往 stdout 打一行本插件的信息。 它只打本插件自己的:cordis 的 exporter 是全局的,不过滤就会把所有插件的日志都灌进终端。


目录

lib/host.js            生命周期与装配(无领域逻辑)
lib/src/store.js       sqlite:agents / runs / rounds / evaluations / settings
lib/src/discovery.js   自发现:路由、模型、窗口、传输、凭据(只问状态不问值)
lib/src/registry.js    校验与翻译:配置 → AgentOptions / ToolRestriction(纯逻辑)
lib/src/runtime.js     运行时:起子 agent、折遥测、守并发与超时
lib/src/tools.js       模型侧入口:三个工具 + 系统提示词协议段
lib/src/http.js        JSON + SSE 接口层
lib/src/version.js     DSH 版本探测与兼容性判定(零 DSH 依赖,只读 package.json)
lib/parts/*.js         客户端分片(唯一真相来源)
lib/client.js          客户端 bundle(构建产物,勿手改)
tests/                 单元 / 集成测试
scripts/               build-client / verify-client / dev-server / check-publish / pack
assets/screenshots/    README 用的界面截图(仅供展示,不参与构建与打包)

已知限制

  1. 「模型最大上下文」不是模型窗口,只是本插件的输入预算闸(见上)。界面上也这么写。
  2. 只保留有界输出正文:运行记录里存 outputTail(默认 2 万字符), 更长的正文靠 session_id 回查 DSH 的会话日志。这是刻意的,不复制权威副本。
  3. 改宿主代码需要重启 dsh web(DSH 的 HMR 不监听模块路径)。客户端改动是热更新的。
  4. 本插件走一次性运行,不支持续聊路径。
  5. 版本兼容性是已知的真实风险:本插件针对 @deepseek-ai/dsh@0.1.2-rc.1 开发, 依赖的是 DSH 的内部接口。区间外的版本会加载但可能降级 —— 见「版本兼容性」一节, 以及 /sub-agent/api/health 的 harness 与 capabilities 字段。
5/ 5

1 ratings

Verified DSH bundle

Commit e8d1d6d9960f

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout