dsh-paoding 0.3.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/README_en.md +6 -1
- package/bin/dsh-paoding.mjs +23 -0
- package/docs/architecture.md +4 -3
- package/docs/architecture_en.md +6 -4
- package/docs/configuration.md +85 -12
- package/docs/configuration_en.md +88 -13
- package/docs/installation.md +18 -6
- package/docs/installation_en.md +18 -6
- package/docs/orchestration.md +4 -0
- package/docs/orchestration_en.md +4 -0
- package/package.json +1 -1
- package/plugins/paoding-config-ui/api-core.mjs +107 -4
- package/plugins/paoding-config-ui/index.mjs +93 -28
- package/plugins/paoding-config-ui/lib/client.js +941 -237
- package/plugins/paoding-config-ui/package.json +1 -1
- package/presets/orchestrator/agent.cordis.yml +13 -0
- package/presets/orchestrator/delegation-labels.mjs +80 -0
- package/tools/lib/cli.mjs +91 -13
- package/tools/lib/compose.mjs +103 -16
- package/tools/lib/doctor.mjs +245 -0
- package/tools/lib/glob.mjs +76 -0
- package/tools/lib/health.mjs +298 -0
- package/tools/lib/preset-system.mjs +29 -11
- package/tools/lib/state.mjs +24 -6
package/README.md
CHANGED
|
@@ -14,10 +14,15 @@ dsh-paoding(中文品牌「庖丁」,典出《庄子》——庖丁顺纹理
|
|
|
14
14
|
- **帮手能继承对话开工**:把某个角色的「启动方式」切成继承对话(fork),帮手带着主 agent 已完成的对话轮次直接开工,省得在委派时把上下文复述一遍;默认全员全新启动,不开启就一切照旧。
|
|
15
15
|
- **帮手能就地续修**:把某个角色的「会话模式」切成可续(continuable),活干砸了或干得不满意,主 agent 用 `send_message` 在同一个子会话接着修,不用从头重派;默认全员一次性(one-shot)用完即弃,不开启就一切照旧。
|
|
16
16
|
- **省钱省上下文**:帮手的工具只在被叫到时才加载,用一次付一次;主 agent 每次请求的工具开销约降三分之二,上下文只收摘要,不再被搜索结果和代码改动撑爆。
|
|
17
|
-
- **角色随改随用**:删掉用不上的内置角色、给角色改显示名、给主 agent
|
|
17
|
+
- **角色随改随用**:删掉用不上的内置角色、给角色改显示名、给主 agent 配显示名,都是配置里一行的事;配了显示名的角色,派出的子代理标签自动带上角色名(「民工码农 · 修复标签显示」),任务管理页、子代理目录树、后台任务列表一眼可辨。改完在面板点一次「保存并应用」,预设即时重生成,重启 DSH / 新建会话后生效。
|
|
18
18
|
- **装了什么都能认出来**:MCP 服务器、本地插件、已装技能,安装与配置时全程检测;默认只装 dsh 基础工具,检测到的 host 工具在「庖丁配置」里按需勾选;停用哪个,重新应用后相关工具自动剔除。
|
|
19
19
|
- **按工作区各有各的班底**:不同项目可以配不同的主/子 agent——「庖丁配置」里选定工作区单独配置,每个工作区生成自己的预设(`orchestrator-<目录名>`),新建会话时选对应预设即可,全局默认不受影响。
|
|
20
20
|
- **图形界面配置**:不习惯改配置文件的话,点开左侧栏底部动作条(设置行上方)的「庖丁配置」入口,整页点选即可,「保存并应用」即时重生成预设——与首装自动化同一条生成管线。
|
|
21
|
+
- **工具条目支持通配符**:`*` 与 `?` 在生成期展开成具体工具名——`mcp__tavily__tavily_*` 一行顶五行,MCP 工具族不必逐个点名;零匹配有提醒,产物与运行时行为不变。
|
|
22
|
+
- **保存前先体检**:预览/应用时自动过一遍检查——配置了但未挂载的工具、零工具角色、查无此名的模型、预设落后于配置,分级提示一目了然;CLI 侧 `dsh-paoding doctor` 六项只读自检(配置可解析、安装轨道、声明行托管块、孤儿目录、版本标记、预设漂移),一条命令查全身。
|
|
23
|
+
- **场景模板一键换班底**:轻量(只留实现)、调研(只留检索)、全开(全员到齐、主 agent 带满检测库存)三档点一下就切,只动「谁在场 + 主 agent 额外带什么」,精调过的角色配置分毫不动。
|
|
24
|
+
- **配置可导出可导入**:面板「更多」菜单一键下载 `dsh-paoding.config.yml`,换机迁移、备份整份拷走;导入先验格式,覆盖整体配置(含工作区段)需二次确认。
|
|
25
|
+
- **面板中英双语**:界面文案 zh/en 全覆盖,语言随浏览器自动识别,「更多」菜单一键切换。
|
|
21
26
|
- **版本更新有提醒,面板一键升级**:面板会对比 npm registry(npmmirror 镜像、GitHub release 依次兜底)上的最新版本,发现新版就地提示并附上发布页链接;点「升级」就地换上新版(profile 自动探测:普通 profile 走 `dsh plugin update dsh-paoding`;desktop profile 被 dsh CLI 的 Electron 专属守卫挡住,改在 profile 目录直跑 `pnpm add dsh-paoding@<版本>`),重启 DSH 后生效,编排预设会在重启时按新版自动重生成。开发检出的 link 形态无法就地升级,面板会提示切回 registry 版的办法;检测失败时页头留一行「版本检测失败 · 重试」(完整原因与代理排查提示在悬浮提示里),不弹窗打扰。
|
|
22
27
|
- **来去自由**:不改 DSH 一行源码;装完新会话即用,卸载即删目录。
|
|
23
28
|
- **两代宿主都兼容**:DSH 0.1.5 – 0.2.0-rc.2 全支持(0.1.5 / 0.1.6 / 0.1.7-rc.1 / 0.1.7-rc.2 / 0.2.0-rc.1 / 0.2.0-rc.2)——两代宿主发现预设的机制不同(目录扫描 vs patch 声明行),安装器自动检测宿主版本选对落点;编排组合里的 workflow worker 行也按宿主版本自动适配(0.1.5 用 workflow-worker-thread,0.1.6+ 换 workflow-ptc——旧包 0.1.6 起已删除,残留行正是 0.2.0 面板上「加载失败」的元凶),宿主升级、降级后的首次保存/自愈自动迁移,全程无感。
|
package/README_en.md
CHANGED
|
@@ -14,10 +14,15 @@ dsh-paoding (Chinese brand 「庖丁」/ Pao Ding, from the Zhuangzi parable of
|
|
|
14
14
|
- **Helpers that inherit the conversation**: flip a role's start mode to fork and the helper starts from the main agent's already-completed turns — no restating the context inside every delegation prompt. Every role defaults to a fresh start, so nothing changes until you flip it.
|
|
15
15
|
- **Helpers that finish the job in place**: flip a role's session mode to continuable and, when a run fails or disappoints, the main agent resumes the same child conversation with `send_message` instead of re-delegating from scratch. Every role defaults to one-shot — run and discard — so nothing changes until you flip it.
|
|
16
16
|
- **Cheaper requests, cleaner context**: a helper's tools load only when it is called — pay per use. The main agent's per-request tool overhead drops by roughly two-thirds, and it keeps only summaries instead of accumulating search dumps and diffs.
|
|
17
|
-
- **Roles bend to your setup**: delete built-in roles you don't need, give roles display names, set a display name for the main agent — all one line of config;
|
|
17
|
+
- **Roles bend to your setup**: delete built-in roles you don't need, give roles display names, set a display name for the main agent — all one line of config; a role with a display name also stamps its sub-agent labels with that name (e.g.「民工码农 · 修复标签显示」), so the task-management page, the sub-agent tree and the background-job list all show who is doing what at a glance. Hit Save & Apply in the panel once and the preset regenerates on the spot, taking effect after a DSH restart or a new session.
|
|
18
18
|
- **Whatever you've installed, it's recognized**: MCP servers, local plugins, installed skills — detected throughout install and configuration; the default install carries only DSH base tools, and detected host tools are opted into per tool in **Paoding Config**; disable one, re-apply, and its tools drop out on their own.
|
|
19
19
|
- **A different lineup per workspace**: each project can carry its own main/sub-agent setup — pick the workspace in 庖丁配置, configure it separately, and it gets its own preset (`orchestrator-<basename>`); choose that preset when starting a session. The global default stays untouched.
|
|
20
20
|
- **A visual configurator**: prefer clicking to editing YAML? the 庖丁配置 (Paoding Config) entry in the sidebar bottom action bar (above the Settings row) covers everything; Save & Apply regenerates the preset on the spot — the same generation pipeline as first-install automation.
|
|
21
|
+
- **Tool entries support wildcards**: `*` and `?` expand into concrete tool names at generation time — one `mcp__tavily__tavily_*` line covers the whole family; zero-match patterns get a warning, and artifacts and runtime behavior stay unchanged.
|
|
22
|
+
- **A health check before every save**: preview/apply runs a built-in check — tools configured but not mounted, zero-tool roles, unknown model names, a preset lagging behind the config — each flagged by severity; on the CLI side, `dsh-paoding doctor` runs six read-only checks (config parses, install track, managed declaration block, orphan directories, version marker, preset drift) in one command.
|
|
23
|
+
- **Scenario templates swap the roster in one click**: Lite (implement only), Research (search roles only), and Full (everyone on deck, main agent carrying the whole detected inventory) — templates only touch who is present and what the main agent carries; hand-tuned role settings are never touched.
|
|
24
|
+
- **Config export & import**: download `dsh-paoding.config.yml` from the panel's More menu for migration or backup; imports are validated first, and overwriting the whole config (workspaces included) asks for confirmation.
|
|
25
|
+
- **Panel in English and Chinese**: every UI string ships in both languages, auto-detected from the browser, switchable from the More menu.
|
|
21
26
|
- **Notified of new releases, one-click upgrade in the panel**: the panel compares your local version against the latest npm registry publish (npmmirror and GitHub release as successive fallbacks) and points to the release page when a newer one is out. The Upgrade button swaps in the new version in place (profile auto-detected): regular profiles go through `dsh plugin update dsh-paoding`, while the Electron-owned desktop profile — which the dsh CLI guards against — gets a direct `pnpm add dsh-paoding@<version>` run in the profile directory; a DSH restart applies it, and the orchestrator preset regenerates itself against the new version on startup. A dev checkout in link: form cannot be upgraded in place — the panel tells you how to switch back to the registry version. If the check fails (offline, rate-limited), a subdued "version check failed · retry" row stays in the header (full causes and proxy hints in its tooltip) without popping anything up.
|
|
22
27
|
- **Installs and uninstalls cleanly**: no DSH source changes; active in a new session right after install, gone when you delete one directory.
|
|
23
28
|
- **Works on both host generations**: DSH 0.1.5 through 0.2.0-rc.2 are all supported (0.1.5 / 0.1.6 / 0.1.7-rc.1 / 0.1.7-rc.2 / 0.2.0-rc.1 / 0.2.0-rc.2) — the two generations discover presets differently (directory scan vs patch declaration rows), and the installer picks the right landing automatically; from 0.2.0 the workflow worker row in the orchestration composition also adapts to the host version at generation time (0.1.5 uses workflow-worker-thread, 0.1.6+ swaps to workflow-ptc). Migration happens on the first save/self-heal after a host upgrade or downgrade, all without user action.
|
package/bin/dsh-paoding.mjs
CHANGED
|
@@ -15,9 +15,16 @@ const REFUSE =
|
|
|
15
15
|
const usage = `dsh-paoding 安装快捷方式(等价于 dsh plugin --profile <name> add dsh-paoding@<version>)
|
|
16
16
|
|
|
17
17
|
用法:npx dsh-paoding@latest [--profile <name>]
|
|
18
|
+
npx dsh-paoding@latest doctor [--profile <name>] [--config <file>]
|
|
19
|
+
|
|
20
|
+
子命令:
|
|
21
|
+
doctor 本机安装体检(只读):配置文件 / 预设轨道 / 托管声明行 /
|
|
22
|
+
孤儿工作区预设 / 预设漂移 / 版本标记,结尾给汇总;
|
|
23
|
+
有错误级发现时退出码 1。
|
|
18
24
|
|
|
19
25
|
选项:
|
|
20
26
|
--profile <name> 插件装入的 profile,默认 web(dsh web 的默认 profile)
|
|
27
|
+
--config <file> 配置文件路径(仅 doctor 子命令使用)
|
|
21
28
|
--help 显示本帮助
|
|
22
29
|
--version 显示包版本
|
|
23
30
|
|
|
@@ -28,6 +35,22 @@ ${REFUSE}`;
|
|
|
28
35
|
const { version } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
29
36
|
|
|
30
37
|
const argv = process.argv.slice(2);
|
|
38
|
+
|
|
39
|
+
// doctor 子命令:包不再携带独立 CLI,但 tools/ 随包发布(package.json files),
|
|
40
|
+
// 体检逻辑本体在 tools/lib/cli.mjs——这里 dynamic import 转发(--profile /
|
|
41
|
+
// --config 等参数原样透传,由它自己的 parseArgs 解析),退出码语义:
|
|
42
|
+
// 无错误 0,有 error 级发现 1。放在参数循环之前:doctor 的参数不用本入口的
|
|
43
|
+
// profile 解析兜底。
|
|
44
|
+
if (argv.includes('doctor')) {
|
|
45
|
+
try {
|
|
46
|
+
const { main } = await import('../tools/lib/cli.mjs');
|
|
47
|
+
process.exit((await main({ argv })) ?? 0);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
console.error(`doctor 运行失败:${err?.message ?? err}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
31
54
|
let profile;
|
|
32
55
|
for (let i = 0; i < argv.length; i++) {
|
|
33
56
|
const arg = argv[i];
|
package/docs/architecture.md
CHANGED
|
@@ -191,7 +191,7 @@ dsh-paoding(中文品牌「庖丁」,取庖丁解牛之意)是 DSH(DeepS
|
|
|
191
191
|
|
|
192
192
|
> 注:`codegraph` 与 `memory_search` 已于 2026-09-02 从该角色移除——二者对应插件(codegraph MCP /
|
|
193
193
|
> magic-memory)停用时不在子 agent 可见注册面内,`tools.restrict()` 会以 unknown tools 拒绝创建该角色;
|
|
194
|
-
>
|
|
194
|
+
> 重新启用插件后按需加回即可(工具条目支持 `*` / `?` 通配,生成期展开,见「已知边界」一节)。
|
|
195
195
|
|
|
196
196
|
## 原理:对应 DSH 原生机制
|
|
197
197
|
|
|
@@ -293,8 +293,9 @@ DSH 0.1.7 起宿主默认升到 65536,显式值让 0.1.5 – 0.2.0-rc.2 全系
|
|
|
293
293
|
- **角色工具面是静态绑定的**(由配置/`toolFilter.allow` 决定),不是模型在运行时任意指定;
|
|
294
294
|
「选角色工具 = 选工具面」对固定分工恰好是优点,但无法在对话中临时给某个角色加工具
|
|
295
295
|
(要加需改配置/静态源后重跑生成器)。
|
|
296
|
-
- **`toolFilter.allow`
|
|
297
|
-
|
|
296
|
+
- **`toolFilter.allow` 支持 `*` / `?` 通配,但只在生成期展开**:tavily 的 5 个工具可以写成一行
|
|
297
|
+
`mcp__tavily__tavily_*`,生成器按候选工具面展开成具体名写入产物,运行时仍是精确名匹配——
|
|
298
|
+
语义零变化;完整 glob 语法(字符类、转义等)不在此列。
|
|
298
299
|
- **主 agent 白名单里未挂载的工具不会报错**:瀑布过滤只在已解析的 `assembly.tools` 里按名匹配,
|
|
299
300
|
某工具(如被注释的 MCP)不在其中就只是不出现,生成与运行都静默通过——配置意图与实际挂载
|
|
300
301
|
靠生成期检测对齐,改动 host patch 后在「庖丁配置」点「保存并应用」同步即可(「预览生成」可先看清单)。
|
package/docs/architecture_en.md
CHANGED
|
@@ -248,8 +248,8 @@ note for that role below; see
|
|
|
248
248
|
> Note: `codegraph` and `memory_search` were removed from this role on 2026-09-02 — when their plugins
|
|
249
249
|
> (codegraph MCP / magic-memory) are disabled they are outside the sub-agent's visible registry, and
|
|
250
250
|
> `tools.restrict()` would refuse to create the role with unknown tools. Re-add them on demand after
|
|
251
|
-
> re-enabling the plugins (
|
|
252
|
-
> section below).
|
|
251
|
+
> re-enabling the plugins (tool entries accept `*` / `?` wildcards, expanded at generation time — see the
|
|
252
|
+
> "Known limitations" section below).
|
|
253
253
|
|
|
254
254
|
## Under the hood
|
|
255
255
|
|
|
@@ -380,8 +380,10 @@ composition:
|
|
|
380
380
|
arbitrarily by the model at runtime. "Picking a role tool picks a tool surface" is an advantage for fixed
|
|
381
381
|
division of labor, but a tool cannot be granted to a role mid-conversation — changing it requires editing
|
|
382
382
|
the configuration / static source and re-running the generator.
|
|
383
|
-
- **`toolFilter.allow`
|
|
384
|
-
|
|
383
|
+
- **`toolFilter.allow` accepts `*` / `?` wildcards, but they expand only at generation time**: the five
|
|
384
|
+
tavily tools fit on one line as `mcp__tavily__tavily_*`; the generator expands patterns against the
|
|
385
|
+
candidate tool surface into concrete names in the generated preset, so runtime matching stays exact-name —
|
|
386
|
+
semantics unchanged. Full glob syntax (character classes, escapes, …) is not in scope.
|
|
385
387
|
- **Tools absent from the main-agent whitelist raise no error**: the waterfall filter only matches by name
|
|
386
388
|
against the resolved `assembly.tools`, so a tool that is not mounted (e.g. a commented-out MCP) simply
|
|
387
389
|
never appears — generation and runtime both pass silently. Config intent and actual mounts are reconciled
|
package/docs/configuration.md
CHANGED
|
@@ -48,7 +48,7 @@ dsh-paoding 把「按角色分工的编排 preset」做成**配置驱动**:你
|
|
|
48
48
|
|
|
49
49
|
- `roles.<toolName>.persona`:非空字符串**整体替换**该角色的部署 persona(含 `''` 与缺省 = 保留静态默认)。自定义角色缺省 persona 为 `You are the <toolName> agent. Handle tasks delegated to this role.`
|
|
50
50
|
- `roles.<toolName>.tools`:`toolName` 属内置三角色时**全量覆盖**该角色 `toolFilter.allow` 的意图(安装器再对 host 依赖的名字做检测求交);缺省 = 保留静态 allow。三角色若最终 allow 为空,安装直接报错(拒绝安装零工具角色)。
|
|
51
|
-
- `roles.<toolName>.name
|
|
51
|
+
- `roles.<toolName>.name`:可选 `string | null` 显示名(内置与自定义角色条目同收;缺省 `null` = 内置三角色用默认身份)。内置角色用它替换该角色**默认** persona 首行身份句的主语——design 默认 `You are the design agent.`,配 `name: UI 设计` 后为 `You are the UI 设计 agent.`;凡配了名字的角色,委派标签一律加前缀(「角色名 · 任务短语」,见 2.4)——自定义角色只有标签效果(persona 本就是你写的原文)。约束、边界与示例见 2.4。
|
|
52
52
|
- `roles.<toolName>.model`:该角色的专用模型 id(可选 `string`)。配置后,该角色派出的每个子 agent 都固定用这个模型,不再随主 agent 会话当前模型走;缺省 = 不注入 `agentOptions`,子 agent 继承主 agent 的模型(详见 2.5)。
|
|
53
53
|
- `roles.<toolName>.provider`:该角色模型所在的 provider 路由(可选 `string`)。须与 `model` 成对配置才生效,只配 `provider` 会被安装器告警并忽略;只配 `model` 时沿用主 agent 的 provider 路由(详见 2.5)。
|
|
54
54
|
- `roles.<toolName>.background_mode`:该角色的会话模式(可选 `'one-shot' | 'continuable'`,缺省 `one-shot`)——一次性用完即弃,或可续:子会话跨轮保留,主 agent 用 `send_message` 就地续修。内置角色与自定义角色同语义;continuable 的前置、代价与面板路径见 2.6。
|
|
@@ -131,7 +131,17 @@ skills: # skill -> 分配给的角色(写进角色 persona 的
|
|
|
131
131
|
|
|
132
132
|
- `persona`:整体替换部署 persona。写入后该文本会进入 `dsh-tool-subagent` 实例的 `persona` 字段 —— 即子 agent 的 **deployment persona**(子 agent 会话里看到的身份与行为指引),不是追加。静态 persona 里内置的「失败汇报协议 / 行为边界」段落也会被一并替换——要保留请把原文(见 `presets/orchestrator/agent.cordis.yml` 对应块)并入你的文本。
|
|
133
133
|
- `tools`:**全量重写**该角色的 `toolFilter.allow` 意图。一句话关系:`agent.cordis.yml` 里的 allow 是静态意图,安装器以实际检测结果重写它;配置里的 `roles.<name>.tools` 就是你要覆盖的新意图 —— 检测后能留多少留多少。
|
|
134
|
-
-
|
|
134
|
+
- 工具条目支持 `*` 与 `?` 通配(`*` 匹配任意长字符段、可为空,`?` 恰好一个字符)。展开发生在**生成期**:生成器把模式条目对候选工具面(preset 自带工具面 ∪ 检测清单)展开成具体名写进产物,运行时白名单语义与逐个写全完全一致——命中名仍按既有规则过滤(未检测到的 MCP 工具不会因命中模式而回填),某模式一个名字都没匹配上时会告警并忽略该条目。tavily 五个工具因此可以写成一行:
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
roles:
|
|
138
|
+
search_external:
|
|
139
|
+
tools:
|
|
140
|
+
- web_search
|
|
141
|
+
- mcp__tavily__tavily_* # 生成时展开为 search/crawl/extract/map/research(以实际检测为准)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`main_agent_extra` 与自定义角色的 `tools` 同样支持。配置文件里模式条目原样存取(配置面板回显不受影响),只有生成的 preset 里落的是展开后的具体名。
|
|
135
145
|
|
|
136
146
|
示例(替换 `implement` 的 persona 与 tools):下方 tools 与静态默认一致——注意它不含 `str_replace_editor`(原因见 8.2)。显式写出 tools 等于固定意图:将来静态源怎么改都不再影响本角色:
|
|
137
147
|
|
|
@@ -201,24 +211,36 @@ roles_remove:
|
|
|
201
211
|
|
|
202
212
|
### 2.4 内置角色显示名:roles.\<toolName>.name
|
|
203
213
|
|
|
204
|
-
内置三角色(`search_external` / `design` / `implement`)的条目下可写可选子键 `name`(`string | null`;缺省 / `null` =
|
|
214
|
+
内置三角色(`search_external` / `design` / `implement`)的条目下可写可选子键 `name`(`string | null`;缺省 / `null` = 用该角色**内置默认身份**)。它有两处生效点,共用同一个配置:
|
|
215
|
+
|
|
216
|
+
- **persona 身份句**:只替换该角色默认 persona 首行身份句的主语——身份句其余文字(职责描述、行为边界等)原样不动,工具面与委派机制一概不碰。
|
|
217
|
+
- **委派标签前缀**:安装器把名字写进预设的 `delegation-labels` 插件行,该角色派出的每个子会话,其持久标签都会变成 `角色名 · 原任务短语`(详见下文「委派标签带角色名」)。
|
|
205
218
|
|
|
206
|
-
例:design 默认身份句是 `You are the design agent.`,配 `name: UI 设计` 后生成 `You are the UI 设计 agent
|
|
219
|
+
例:design 默认身份句是 `You are the design agent.`,配 `name: UI 设计` 后生成 `You are the UI 设计 agent.`,同时该角色的委派标签形如「UI 设计 · 首页视觉方案」:
|
|
207
220
|
|
|
208
221
|
```yaml
|
|
209
222
|
roles:
|
|
210
223
|
design:
|
|
211
|
-
name: UI 设计 #
|
|
224
|
+
name: UI 设计 # 换 persona 身份句主语 + 委派标签前缀;tools 可省(回落默认工具面)
|
|
212
225
|
```
|
|
213
226
|
|
|
214
|
-
约束:trim 后 1–60 字符、不可含换行;空字符串 / 缺省 =
|
|
227
|
+
约束:trim 后 1–60 字符、不可含换行;空字符串 / 缺省 = 用该角色内置默认身份、标签不加前缀(不写此子键时,身份句是 SRC 原文,安装器不做任何替换)。
|
|
215
228
|
|
|
216
229
|
边界:
|
|
217
230
|
|
|
218
|
-
-
|
|
219
|
-
-
|
|
220
|
-
-
|
|
221
|
-
-
|
|
231
|
+
- **标签只加前缀,不动正文**:任务管理页、会话头子代理目录树与后台任务列表展示的就是委派时的 `description`,安装器不在其中改写任何任务语义。
|
|
232
|
+
- **改名不碰机制面**:工具注册名与委派调用名(toolName)不变——主 agent 仍按 `search_external` / `design` / `implement` 委派;`restrict allow` 与主 agent persona 里的委派指引(如 `delegate to design`)也都不变。
|
|
233
|
+
- **persona 被自定义时身份句不生效、标签前缀照常生效**:同一条目写了非空 `persona`(覆盖默认 persona)时,安装器在生成时忽略 `name` 的身份句替换并告警——想让名字显出来,直接写进自定义 persona 首行;但标签前缀不依赖 persona,配置后照常生效。
|
|
234
|
+
- **被删除的角色不涉及**:`roles_remove` 整条删除的角色没有 persona,也没有委派可打标签(见 2.3)。
|
|
235
|
+
- **静态角色不在列**:`search_internal_deep` 不在安装器管理的三角色内,无此子键,标签保持原样(见 2.2)。
|
|
236
|
+
|
|
237
|
+
#### 委派标签带角色名
|
|
238
|
+
|
|
239
|
+
委派工具调用的 `description` 参数会随子会话持久化,成为三处展示面的标签:侧栏任务管理页、会话头的子代理目录树、后台任务列表。编排模型随手写的 description 只是一句任务短语,多角色并行时扫一眼分不清谁在干活。安装器据此把配置了名字的角色的委派调用统一改写成 `角色名 · 原任务短语`——改写发生在工具执行的瀑布上(`delegation-labels.mjs`,随预设一起安装),不依赖提示词配合,主 agent 无感知。几点口径:
|
|
240
|
+
|
|
241
|
+
- **幂等**:已带前缀的标签不会重复加前缀;
|
|
242
|
+
- **只对新委派生效**:改配置之前已经开出去的子会话不追溯;
|
|
243
|
+
- **自定义角色同享**:`roles` 键下任何角色(内置或自定义,见第 6 节)配了 `name` 都进这套前缀。
|
|
222
244
|
|
|
223
245
|
生效方式与主 agent 显示名同款(见 5.1):
|
|
224
246
|
|
|
@@ -453,7 +475,7 @@ main_agent_display_name: 庖丁 # 仅 preset 显示名换成「庖丁」,per
|
|
|
453
475
|
|
|
454
476
|
- **手编**:写键后在「庖丁配置」点「保存并应用」,再重启 GUI / 新会话生效。
|
|
455
477
|
- **面板**:左侧栏「庖丁配置」→ 主 agent 卡「主 agent 显示名(仅 preset 显示名)」输入框(带「恢复默认」按钮),点「保存并应用」后**重启 GUI / 新会话**生效。
|
|
456
|
-
- **对照**:显示名线共两条、互不牵连:`main_agent_display_name`(仅主 agent 的 preset 显示名,见 5.1)、`roles.<toolName>.name
|
|
478
|
+
- **对照**:显示名线共两条、互不牵连:`main_agent_display_name`(仅主 agent 的 preset 显示名,见 5.1)、`roles.<toolName>.name`(角色 persona 身份句主语 + 委派标签前缀,不改工具调用名,见 2.4),可各自独立配置。
|
|
457
479
|
|
|
458
480
|
### 5.2 追加三态语义:main_agent_persona_extra
|
|
459
481
|
|
|
@@ -497,6 +519,10 @@ main_agent_display_name: 庖丁 # 仅 preset 显示名换成「庖丁」,per
|
|
|
497
519
|
<toolName>.`,紧跟既有委派行之后)——主 agent 全靠这行知道什么活该派给谁,因此建议把 persona 首行
|
|
498
520
|
写成一句简短职责(例如「你的职责就是查找符合用户要求的技能」)。
|
|
499
521
|
|
|
522
|
+
另有一个可选子键:自定义角色条目同样支持 `name`——它不参与 persona 身份句替换(自定义角色的
|
|
523
|
+
persona 就是你写的原文),唯一作用是**委派标签前缀**(见 2.4「委派标签带角色名」):配了名字,这个
|
|
524
|
+
角色派出的子会话标签就是「名字 · 任务短语」,多个自定义角色并行时一眼可辨。
|
|
525
|
+
|
|
500
526
|
### 6.1 路径一:庖丁配置面板(推荐)
|
|
501
527
|
|
|
502
528
|
面板流程(左侧栏「庖丁配置」→「Agent 工具分配」→ 底部「新建自定义 agent 角色」):
|
|
@@ -621,7 +647,7 @@ skills:
|
|
|
621
647
|
### 8.2 平台注册面细节
|
|
622
648
|
|
|
623
649
|
- **`str_replace_editor` 刻意未列入 `implement`**:部分部署的注册面没有该工具,一旦列入 allow,子 agent 创建时 `tools.restrict()` 会以 unknown tools 拒绝。确认你的部署确实注册后再自行加回(静态源 implement allow,或配置 `roles.implement.tools`)。
|
|
624
|
-
- 白名单 / allow
|
|
650
|
+
- 白名单 / allow 的工具条目支持 `*` / `?` 通配,生成期展开成具体名(见 2.1);逐个写精确名自然也行。
|
|
625
651
|
- 主 agent 白名单里未挂载的名字不报错(瀑布只在已解析工具里按名匹配)。
|
|
626
652
|
|
|
627
653
|
### 8.3 停用 MCP / 插件后的同步
|
|
@@ -677,3 +703,50 @@ workspaces:
|
|
|
677
703
|
- 只装在某个项目里的技能(比如知识库项目里的 `bento-slides`),在全局配置里不可见、配不上;选中那个工作区后出现在技能网格里,带「项目」角标,可分配给该工作区预设的主 agent 或角色。
|
|
678
704
|
- 生成时技能解析同口径:工作区预设能写出项目级技能的 SKILL.md 绝对路径(主 agent 用 `read` 按需读,路径在盘上就能读);全局预设只解析用户级,配了项目级技能名会告警跳过——全局预设要在所有项目通用,引用单一项目的技能本就不该写进去。
|
|
679
705
|
- 兜底 CLI 没有工作区概念,只扫用户级两根(与全局默认一致)。
|
|
706
|
+
|
|
707
|
+
## 10. 场景模板(轻量 / 调研 / 全开)
|
|
708
|
+
|
|
709
|
+
「角色与工具」组顶部有一排**场景模板**快捷按钮。三个档位对应三种典型用法,点击即改当前配置视角的本地草稿(**不自动保存**,预览随之作废,toast 会提醒「保存并应用后生效」):
|
|
710
|
+
|
|
711
|
+
| 档位 | `roles_remove` | `main_agent_extra` | 典型场景 |
|
|
712
|
+
| --- | --- | --- | --- |
|
|
713
|
+
| 轻量档 | `search_external`、`design` | 清空 | 纯写代码:只留实现角色,主 agent 不额外带工具 |
|
|
714
|
+
| 调研档 | `design`、`implement` | 清空 | 只查不做:留检索角色(含深搜),去掉设计与实现 |
|
|
715
|
+
| 全开档 | `[]`(全留) | 勾上检测到的全部库存工具 | 完整编排:四个内置角色全在,主 agent 全副武装 |
|
|
716
|
+
|
|
717
|
+
模板刻意**只动这两个键**,其余一概不碰:
|
|
718
|
+
|
|
719
|
+
- 角色工具面、显示名、persona、角色专用模型、会话/启动方式、`main_agent_remove`、技能分配全部原样;
|
|
720
|
+
- 自定义角色不受影响;
|
|
721
|
+
- `search_internal_deep` 是静态委派工具,不在配置层 `roles_remove` 的管辖范围(见 §2.2),三档都保留——调研档「留深搜」正是靠它,无需任何配置动作;
|
|
722
|
+
- 档位是**确定态**而不是「在现状上增减」:重复点同一档结果幂等;轻量/调研切回全开时,此前给被删角色精调的 persona / 模型 / 工具面原样复原(被删角色的条目键仍保留,卡片只是隐藏)。
|
|
723
|
+
|
|
724
|
+
## 11. 配置导出与导入
|
|
725
|
+
|
|
726
|
+
页头「更多」菜单提供整份配置文件的导出与导入(配置文件即 §1 的 `dsh-paoding.config.yml`,路径可用 `DSH_PAODING_CONFIG` 指到别处)。
|
|
727
|
+
|
|
728
|
+
**导出**:下载配置文件**原文**(字节不动,手编注释与排版原样保留)。文件不存在时回落为基础模板文本——与首装自愈写入的内容同源,导出永远是「当前生效配置」的忠实快照;文件名取实际配置文件名(默认 `dsh-paoding.config.yml`)。
|
|
729
|
+
|
|
730
|
+
**导入**:选一份 YAML 配置文件,确认弹窗(红色确认钮)后**整体覆盖**当前配置文件——注意工作区视角也不例外:`workspaces` 段(§9)随整份文件一起被替换,确认文案里已明说。流程与边界:
|
|
731
|
+
|
|
732
|
+
- 解析校验与 `loadConfig` 同口径:解析失败或顶层不是键值映射(空文件、列表、标量)一律 422 拒绝,**不写盘**;面板弹出失败 toast,原配置原封不动。
|
|
733
|
+
- 通过校验后走与面板 / CLI 每次保存相同的单一写盘路径(规范化 + 头注释 + `0600` 权限)。
|
|
734
|
+
- **往返取舍(有意为之)**:导入会把内容规范化后落盘,注释、未知键与排版不保留;全部 schema 字段保留,含「缺省 vs 显式空表」语义(如 `main_agent_extra: []` 的显式空表标记,见 §3)。
|
|
735
|
+
- 落盘即改 mtime,面板的检测状态缓存按对账自动失效,视图随后按新配置重建。
|
|
736
|
+
- 与「保存并应用」共用同一把写盘互斥闸:应用进行中导入(或反过来)会收到 409,稍后重试即可。
|
|
737
|
+
|
|
738
|
+
## 12. 检查提示(体检)
|
|
739
|
+
|
|
740
|
+
预览或应用后,若服务端体检发现问题,预览区上方会出现一张**检查提示**卡:逐条列出示意,红(error)/ 琥珀(warn)/ 中性(info)三色分级,悬停可见检查项代号(排障用)。没有问题就没有这张卡,零占位。
|
|
741
|
+
|
|
742
|
+
条目来自结构化体检(`tools/lib/health.mjs`),代号与分级:
|
|
743
|
+
|
|
744
|
+
| 代号 | 级别 | 含义 |
|
|
745
|
+
| --- | --- | --- |
|
|
746
|
+
| `zero_tool_role` | error | 某角色过滤后没有任何可用工具——零工具角色会被拒绝安装,应用必失败;按提示补工具或 `roles_remove` 删除该角色 |
|
|
747
|
+
| `unmounted_tool` | warn | 配置里勾了当前未挂载的工具(如 MCP 服务没起),生成时会过滤掉 |
|
|
748
|
+
| `unknown_model` | warn | `roles.<tool>.model` 不在当前模型目录中(名单以设置页模型选择器为准),配错会被静默回落 |
|
|
749
|
+
| `preset_drift` | info | 已安装预设落后于当前配置(或尚未安装),重新应用即同步 |
|
|
750
|
+
| `generation` | warn | 生成器自身的提示信息(如默认值回退) |
|
|
751
|
+
|
|
752
|
+
作废口径:**预览**产生的提示随配置草稿的任何改动一并作废(与预览同一逻辑);**应用**产生的提示描述的是已落盘结果,保留到下一次预览或应用。应用失败时错误 toast 照旧,同时卡片给出每条失败原因;应用成功但存在 warn/error 级提示时,成功 toast 会换成琥珀档「有 N 条检查提示,见下方」。
|
package/docs/configuration_en.md
CHANGED
|
@@ -33,7 +33,7 @@ The key names below match `normalizeConfig` in `tools/lib/config.mjs` — the si
|
|
|
33
33
|
| Top-level key | Type | Semantics |
|
|
34
34
|
|---|---|---|
|
|
35
35
|
| `profile` | string | Which profile's patch layer (`$DSH_HOME/profiles/<profile>/cordis.patch.yml`) is scanned during detection; default `web` |
|
|
36
|
-
| `roles` | map | `toolName` → `{ persona?, name?, tools[], model?, provider?, start_mode?, background_mode? }`. For the three built-in roles (`search_external` / `design` / `implement`): overrides the persona and the allow intent, and may carry a `name` display name (rewrites
|
|
36
|
+
| `roles` | map | `toolName` → `{ persona?, name?, tools[], model?, provider?, start_mode?, background_mode? }`. For the three built-in roles (`search_external` / `design` / `implement`): overrides the persona and the allow intent, and may carry a `name` display name (rewrites the subject of that role's default persona identity sentence and prefixes its delegation labels — see 2.4), a dedicated model (`model` / `provider`, see 2.5), a session mode (`background_mode`, see 2.6) and a start mode (`start_mode`, see 2.7). Any other key is a **custom role**: the installer emits a fresh `delegation-<toolName>` block and injects the toolName into the main agent's `config.allow` (sections 2 and 6) |
|
|
37
37
|
| `roles_remove` | string[] | toolNames of built-in roles deleted wholesale (only `search_external` / `design` / `implement` are accepted; other names are ignored with a warning; default `[]`). Deleting means the delegation block / tool surface / role persona / main-agent delegation guidance are no longer generated (see 2.3) |
|
|
38
38
|
| `skills` | map | `skill` → the list of role toolNames the skill is assigned to; the installer appends an `Available skills: …` guidance sentence to those roles' personas (section 7) |
|
|
39
39
|
| `main_agent_extra` | string[] | Tools appended to the main-agent allow list (host tools such as `mcp__codegraph__codegraph_explore`, `memory_search`, `mnemon_*`); names are checked against the preset's own tool face ∪ the detection inventory — a name in neither is not injected |
|
|
@@ -48,7 +48,7 @@ The key names below match `normalizeConfig` in `tools/lib/config.mjs` — the si
|
|
|
48
48
|
|
|
49
49
|
- `roles.<toolName>.persona`: a non-empty string **replaces the role's deployment persona wholesale** (`''` or absent keeps the static default). A custom role without a persona gets `You are the <toolName> agent. Handle tasks delegated to this role.`
|
|
50
50
|
- `roles.<toolName>.tools`: when `toolName` is one of the three built-ins this **fully overrides the intent** of that role's `toolFilter.allow` (the installer then intersects host-dependent names with what was actually detected); absent keeps the static allow. If a built-in role would end up with an empty allow, the install aborts (a zero-tool role is refused).
|
|
51
|
-
- `roles.<toolName>.name`: an optional `string | null` display name
|
|
51
|
+
- `roles.<toolName>.name`: an optional `string | null` display name (built-in and custom role entries alike; absent / `null` = the built-in trio keeps its default identity). For built-ins it rewrites the **subject of that role's default persona identity sentence** — design's default `You are the design agent.` with `name: UI 设计` becomes `You are the UI 设计 agent.` — and for every named role it prefixes the role's delegation labels (`role name · task phrase`, see 2.4); custom roles only get the label effect, since their persona is your text. Constraints, boundaries and an example are in 2.4.
|
|
52
52
|
- `roles.<toolName>.model`: a dedicated model id for the role (optional `string`). When set, every sub-agent the role spawns runs on that model instead of following the main agent's current session model; absent = nothing is injected and the child inherits the main agent's model (see 2.5).
|
|
53
53
|
- `roles.<toolName>.provider`: the provider route the role's model lives on (optional `string`). It only takes effect paired with `model`; a lone `provider` is warned about and ignored by the installer, while a lone `model` rides the main agent's provider route (see 2.5).
|
|
54
54
|
- `roles.<toolName>.background_mode`: the role's session mode (optional `'one-shot' | 'continuable'`; default `one-shot`) — run-and-discard, or continuable: the child conversation is kept across turns so the main agent can resume in place with `send_message`. Built-in and custom role entries share the semantics; the continuable prerequisites, costs and panel path are in 2.6.
|
|
@@ -131,7 +131,17 @@ Of the four built-in delegation roles, the installer (the `ROLES` constant) mana
|
|
|
131
131
|
|
|
132
132
|
- `persona`: **replaces the deployment persona wholesale**. The text lands in the `dsh-tool-subagent` instance's `persona` field — the child's **deployment persona** (the identity and behavior guidance the subagent sees in its session), not an appendix. The static persona's built-in "failure-report protocol / behavior boundary" paragraphs are replaced too — if you want to keep them, include the original text (see the matching block in `presets/orchestrator/agent.cordis.yml`) in yours.
|
|
133
133
|
- `tools`: **fully overrides the intent** of that role's `toolFilter.allow`. The relationship in one sentence: the allow lists in `agent.cordis.yml` are static intent that the installer rewrites against actual detection results; the `tools` you write under `roles.<name>` are the new intent — whatever survives detection is what stays.
|
|
134
|
-
-
|
|
134
|
+
- Tool entries accept `*` and `?` wildcards (`*` matches any run of characters including none, `?` exactly one). Expansion happens at **generation time**: the generator expands pattern entries against the candidate tool surface (the preset's built-in surface ∪ the detection inventory) into concrete names in the generated preset, so runtime whitelist semantics are identical to spelling every name out — matched names still go through the regular filtering (an undetected MCP tool is not resurrected by a pattern), and a pattern that matches nothing warns and is dropped. The five tavily tools therefore fit on one line:
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
roles:
|
|
138
|
+
search_external:
|
|
139
|
+
tools:
|
|
140
|
+
- web_search
|
|
141
|
+
- mcp__tavily__tavily_* # expanded at generation to search/crawl/extract/map/research (per actual detection)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`main_agent_extra` and custom-role `tools` support them too. Pattern entries are stored and read back verbatim in the config file (the config panel renders them fine); only the generated preset contains the expanded concrete names.
|
|
135
145
|
|
|
136
146
|
Example — replacing `implement`'s persona and tools. The `tools` below match the static default — note that it does **not** contain `str_replace_editor` (why: see 8.2). Writing `tools` out explicitly freezes the intent: later changes to the static source no longer affect this role:
|
|
137
147
|
|
|
@@ -201,24 +211,36 @@ Restoring:
|
|
|
201
211
|
|
|
202
212
|
### 2.4 Built-in role display names: roles.\<toolName>.name
|
|
203
213
|
|
|
204
|
-
Entries of the built-in trio (`search_external` / `design` / `implement`) may carry an optional `name` sub-key (`string | null`; absent / `null` = the role's **built-in default identity**).
|
|
214
|
+
Entries of the built-in trio (`search_external` / `design` / `implement`) may carry an optional `name` sub-key (`string | null`; absent / `null` = the role's **built-in default identity**). It takes effect in two places off a single setting:
|
|
215
|
+
|
|
216
|
+
- **Persona identity sentence**: rewrites only the subject of that role's default persona identity sentence at the head of the persona — the rest of the sentence (job description, behavior boundaries, …) stays verbatim, and the tool surface / delegation machinery are never touched.
|
|
217
|
+
- **Delegation label prefix**: the installer writes the name into the preset's `delegation-labels` plugin row; every sub-session the role spawns gets a persistent label of the form `role name · original task phrase` (see "Delegation labels carry the role name" below).
|
|
205
218
|
|
|
206
|
-
Example: design's default identity sentence is `You are the design agent.`; with `name: UI 设计` it is generated as `You are the UI 设计 agent
|
|
219
|
+
Example: design's default identity sentence is `You are the design agent.`; with `name: UI 设计` it is generated as `You are the UI 设计 agent.`, and that role's delegation labels look like「UI 设计 · 首页视觉方案」:
|
|
207
220
|
|
|
208
221
|
```yaml
|
|
209
222
|
roles:
|
|
210
223
|
design:
|
|
211
|
-
name: UI 设计 # rewrites
|
|
224
|
+
name: UI 设计 # rewrites the persona identity sentence subject + delegation label prefix; tools may be omitted (the default tool surface applies)
|
|
212
225
|
```
|
|
213
226
|
|
|
214
|
-
Constraints: trimmed, 1–60 characters, no newlines; an empty string / an absent key = the role's built-in default identity (without the sub-key the identity sentence stays verbatim from the SRC — the installer substitutes nothing).
|
|
227
|
+
Constraints: trimmed, 1–60 characters, no newlines; an empty string / an absent key = the role's built-in default identity and no label prefix (without the sub-key the identity sentence stays verbatim from the SRC — the installer substitutes nothing).
|
|
215
228
|
|
|
216
229
|
Boundaries:
|
|
217
230
|
|
|
218
|
-
- **
|
|
219
|
-
-
|
|
220
|
-
- **
|
|
221
|
-
- **
|
|
231
|
+
- **Labels only get a prefix; the body is never rewritten**: the task-management page, the sub-agent tree in the session header and the background-job list all show the `description` captured at delegation time — the installer rewrites no task semantics inside it.
|
|
232
|
+
- **Renaming never touches the machinery**: the tool registration name and the delegation call name (toolName) stay unchanged — the main agent still delegates to `search_external` / `design` / `implement`; `restrict allow` and the delegation guidance in the main-agent persona (e.g. `delegate to design`) are untouched too.
|
|
233
|
+
- **With a custom persona the identity sentence is skipped but the label prefix still applies**: when the same entry carries a non-empty `persona` (overriding the default), the installer skips the `name` identity-sentence rewrite at generation with a warning — to surface the name, write it directly into the first line of the custom persona; the label prefix does not depend on the persona and applies as configured.
|
|
234
|
+
- **Deleted roles are not involved**: a role deleted wholesale by `roles_remove` has no persona left and no delegations left to label (see 2.3).
|
|
235
|
+
- **The static role is out of scope**: `search_internal_deep` is outside the installer-managed trio and has no such sub-key; its labels stay as written (see 2.2).
|
|
236
|
+
|
|
237
|
+
#### Delegation labels carry the role name
|
|
238
|
+
|
|
239
|
+
The `description` argument of a delegation tool call persists with the sub-session and becomes the label shown in three places: the sidebar task-management page, the sub-agent tree in the session header, and the background-job list. A task phrase the orchestrator jots down says nothing about who is doing the work once several roles run in parallel. For every role with a configured name, the installer therefore rewrites its delegation calls to `role name · original task phrase` — the rewrite happens in-place on the tools/pre-execute waterfall (`delegation-labels.mjs`, installed with the preset), with no reliance on prompt cooperation and no awareness required from the main agent. Ground rules:
|
|
240
|
+
|
|
241
|
+
- **Idempotent**: a label that already carries the prefix never gets a second one;
|
|
242
|
+
- **New delegations only**: sub-sessions spawned before the configuration change are not relabeled;
|
|
243
|
+
- **Custom roles included**: any role under the `roles` key (built-in or custom, see section 6) with a `name` joins this prefixing.
|
|
222
244
|
|
|
223
245
|
Applying it works just like the main-agent display name (see 5.1):
|
|
224
246
|
|
|
@@ -453,7 +475,7 @@ Where to set it:
|
|
|
453
475
|
|
|
454
476
|
- **Hand-editing**: write the key and hit Save & Apply in 庖丁配置, then restart the GUI or open a new session.
|
|
455
477
|
- **Panel**: 庖丁配置 (left sidebar) → main-agent card, the「主 agent 显示名(仅 preset 显示名)」("main agent display name (preset display name only)") input, with its「恢复默认」("restore default") button; after「保存并应用」(save & apply) it takes effect on a **GUI restart / new session**.
|
|
456
|
-
- For contrast: there are two independent naming lines that never interfere with each other: `main_agent_display_name` (the main agent's preset display name only, see 5.1) and `roles.<toolName>.name` (
|
|
478
|
+
- For contrast: there are two independent naming lines that never interfere with each other: `main_agent_display_name` (the main agent's preset display name only, see 5.1) and `roles.<toolName>.name` (a role's persona identity-sentence subject + delegation label prefix, never the tool call name — see 2.4). Configure each on its own.
|
|
457
479
|
|
|
458
480
|
### 5.2 Persona extra: three-state semantics
|
|
459
481
|
|
|
@@ -503,6 +525,12 @@ row** (`- <duty>: delegate to <toolName>.`, right after the existing delegation
|
|
|
503
525
|
main agent's only routing hint for the role, so make the persona's first line a short duty sentence
|
|
504
526
|
(e.g. "Find the skill that matches the user's need").
|
|
505
527
|
|
|
528
|
+
One optional sub-key on top: custom role entries accept `name` too — it takes no part in the persona
|
|
529
|
+
identity-sentence rewrite (a custom role's persona is verbatim what you wrote) and its only effect is
|
|
530
|
+
the **delegation label prefix** (see 2.4, "Delegation labels carry the role name"): with a name set,
|
|
531
|
+
this role's sub-session labels read `name · task phrase`, easy to tell apart when several custom roles
|
|
532
|
+
run in parallel.
|
|
533
|
+
|
|
506
534
|
### 6.1 Path 1: the 庖丁配置 panel (recommended)
|
|
507
535
|
|
|
508
536
|
The panel flow (庖丁配置 in the left sidebar → agent tool assignment → "Create a custom agent role" at the bottom):
|
|
@@ -631,7 +659,7 @@ Omitting `agentOptions` means inheriting the main agent's model. The config sub-
|
|
|
631
659
|
### 8.2 Platform / registry details
|
|
632
660
|
|
|
633
661
|
- **`str_replace_editor` is deliberately not in `implement`'s allow**: some deployments' registries do not provide it, and a child created with it in the allow would be rejected by `tools.restrict()` as an unknown tool. Add it back only after confirming your deployment registers it (edit the static implement allow, or `roles.implement.tools` in the config).
|
|
634
|
-
- Allow
|
|
662
|
+
- Allow-list tool entries accept `*` / `?` wildcards, expanded to concrete names at generation time (see 2.1); spelling out exact names works as before.
|
|
635
663
|
- Unmounted names in the main-agent allow never error (the waterfall matches names only against already-resolved tools).
|
|
636
664
|
|
|
637
665
|
### 8.3 Syncing after disabling MCPs / plugins
|
|
@@ -687,3 +715,50 @@ Skill candidates do not follow the directory the GUI was launched from: the **gl
|
|
|
687
715
|
- A skill installed only inside one project (say `bento-slides` living in a knowledge-base repo) is invisible — and unassignable — in the global config; select that workspace and it appears in the skill grid with a "project" badge, assignable to that workspace preset's main agent or roles.
|
|
688
716
|
- Generation resolves skills through the same lens: a workspace preset can emit the absolute SKILL.md path of a project-local skill (the main agent reads it on demand with `read` — any on-disk path is readable); the global preset resolves user roots only and warns-and-skips project-local skill names — a global preset travels across all projects and should not reference a single project's skill anyway.
|
|
689
717
|
- The fallback CLI has no workspace concept and scans the two user roots only (same as the global default).
|
|
718
|
+
|
|
719
|
+
## 10. Scenario templates (Lite / Research / Full)
|
|
720
|
+
|
|
721
|
+
The top of the "Roles & tools" group carries a row of **scenario template** quick buttons. The three presets map to three typical workflows; clicking one edits the local draft of the current config view (**nothing is saved automatically** — the preview is invalidated as usual and a toast reminds you that it takes effect after "save & apply"):
|
|
722
|
+
|
|
723
|
+
| Preset | `roles_remove` | `main_agent_extra` | Typical use |
|
|
724
|
+
| --- | --- | --- | --- |
|
|
725
|
+
| Lite | `search_external`, `design` | cleared | Pure coding: keep only the implement role, no extra main-agent tools |
|
|
726
|
+
| Research | `design`, `implement` | cleared | Look things up, build nothing: keep the search role (deep search included), drop design and implement |
|
|
727
|
+
| Full | `[]` (keep all) | check every inventoried tool | Full orchestration: all four built-in roles, fully armed main agent |
|
|
728
|
+
|
|
729
|
+
A template deliberately touches **only these two keys** and nothing else:
|
|
730
|
+
|
|
731
|
+
- Role tool surfaces, display names, personas, per-role models, session/start modes, `main_agent_remove`, and skill assignments are all left as they are;
|
|
732
|
+
- Custom roles are unaffected;
|
|
733
|
+
- `search_internal_deep` is a static delegation tool, outside the reach of `roles_remove` (see §2.2); all three presets keep it — the Research preset's "deep search stays" leans on exactly that, no config action needed;
|
|
734
|
+
- A preset is a **determined state**, not a delta on top of the current draft: clicking the same preset twice is idempotent, and switching Lite/Research back to Full restores the personas / models / tool surfaces you tuned for the previously removed roles (removed roles keep their entry keys; the cards are merely hidden).
|
|
735
|
+
|
|
736
|
+
## 11. Exporting and importing the config
|
|
737
|
+
|
|
738
|
+
The header "More" menu offers export and import of the whole config file (the §1 `dsh-paoding.config.yml`; point `DSH_PAODING_CONFIG` elsewhere to relocate it).
|
|
739
|
+
|
|
740
|
+
**Export** downloads the config file **verbatim** (byte-for-byte — hand-written comments and formatting travel with it). When the file does not exist, the export falls back to the base-template text — the same content a fresh install would write, so an export is always a faithful snapshot of "what is in effect". The download name follows the actual config file name (default `dsh-paoding.config.yml`).
|
|
741
|
+
|
|
742
|
+
**Import** picks a YAML config file and, after a confirmation dialog with a red confirm button, **overwrites the entire config file** — the workspace view is no exception: the `workspaces` section (§9) is replaced together with the rest of the file, and the confirmation copy says so explicitly. Flow and boundaries:
|
|
743
|
+
|
|
744
|
+
- Validation follows the same rules as `loadConfig`: unparsable content or a non-mapping top level (empty file, list, scalar) is rejected with 422 and **nothing is written**; the panel shows a failure toast and the previous config stays untouched.
|
|
745
|
+
- Content that passes validation is written through the same single save path used by every panel / CLI save (normalized + header comment + `0600` mode).
|
|
746
|
+
- **Round-trip tradeoff (by design)**: import normalizes before writing — comments, unknown keys, and formatting are not preserved; every schema field survives, including the "absent vs explicitly empty" semantics (e.g. the explicit-empty marker for `main_agent_extra: []`, see §3).
|
|
747
|
+
- Writing changes the file's mtime, so the panel's detection-state cache invalidates automatically through the existing reconciliation, and the view rebuilds from the new config.
|
|
748
|
+
- Import shares the same in-flight write gate as "save & apply": applying during an import (or the reverse) answers 409 — retry shortly.
|
|
749
|
+
|
|
750
|
+
## 12. Check messages (health review)
|
|
751
|
+
|
|
752
|
+
After a preview or an apply, if the server-side health review finds problems, a **check messages** card appears above the preview area: one row per finding, color-coded red (error) / amber (warn) / neutral (info), with the check code available on hover for troubleshooting. No findings — no card, zero footprint.
|
|
753
|
+
|
|
754
|
+
Entries come from the structured health review (`tools/lib/health.mjs`); codes and levels:
|
|
755
|
+
|
|
756
|
+
| Code | Level | Meaning |
|
|
757
|
+
| --- | --- | --- |
|
|
758
|
+
| `zero_tool_role` | error | A role ends up with no usable tools after filtering — zero-tool roles are refused at install time, so apply will fail; add tools or remove the role via `roles_remove` |
|
|
759
|
+
| `unmounted_tool` | warn | A configured tool is currently not mounted (e.g. its MCP server is down); it is filtered out at generation |
|
|
760
|
+
| `unknown_model` | warn | `roles.<tool>.model` is not in the current model directory (the list mirrors the settings-page model picker); a mismatch silently falls back |
|
|
761
|
+
| `preset_drift` | info | The installed preset lags behind the current config (or is not installed yet); re-apply to sync |
|
|
762
|
+
| `generation` | warn | Generator's own notices (e.g. default-value fallbacks) |
|
|
763
|
+
|
|
764
|
+
Invalidation scope: messages from a **preview** are discarded together with the draft on any config edit (same rule as the preview itself); messages from an **apply** describe what has already been written and survive until the next preview or apply. When an apply fails, the error toast stays as usual and the card lists every reason; when an apply succeeds but warn/error-level findings exist, the success toast switches to the amber variant "N check messages, see below".
|
package/docs/installation.md
CHANGED
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
|---|---|---|
|
|
20
20
|
| `$DSH_HOME` | `~/.dsh` | DSH 家目录(认环境变量 `DSH_HOME`,缺省 `$HOME/.dsh`)。host 层配置 `cordis.patch.yml`、`node_modules`、`profiles/<name>/cordis.patch.yml`、插件 profile 目录都在其下 |
|
|
21
21
|
| preset roster 根目录 | `$DSH_HOME/.agent-presets/` | DSH ≤ 0.1.6 由 `dsh-agent-presets` 扫描此目录发现本地 authored presets;DSH ≥ 0.1.7 宿主不再扫目录,此目录退为预设文件存放处(见第 2 节「版本支持与预设落点双轨」) |
|
|
22
|
-
| 本预设安装目标 | `$DSH_HOME/.agent-presets/orchestrator` | 生成产物:`agent.cordis.yml`(重写后的角色配置)、`preset.yml`、`restrict.mjs`、`.generator-version` 版本与轨道标记,是一个静态目录;按工作区配置生成的预设落同一父目录下的 `orchestrator-<slug>` |
|
|
22
|
+
| 本预设安装目标 | `$DSH_HOME/.agent-presets/orchestrator` | 生成产物:`agent.cordis.yml`(重写后的角色配置)、`preset.yml`、`restrict.mjs`、`delegation-labels.mjs`、`.generator-version` 版本与轨道标记,是一个静态目录;按工作区配置生成的预设落同一父目录下的 `orchestrator-<slug>` |
|
|
23
23
|
| 声明行托管块(仅 DSH ≥ 0.1.7) | `$DSH_HOME/cordis.patch.yml` 内的托管块 | 以 `# --- dsh-paoding presets (auto-generated; do not edit) ---` 起始、配套 end 标记收尾,块内 `- insert:` 写 `@deepseek-ai/dsh-agent-preset` 声明行;安装器自动维护,详见第 2 节 |
|
|
24
24
|
| 配置文件 | `$DSH_HOME/dsh-paoding.config.yml` | 「庖丁配置」面板「保存并应用」写入的角色与工具分配(`0o600`,可手编);首装自动化同样读写它 |
|
|
25
25
|
|
|
26
26
|
- **环境变量**:`DSH_HOME` 覆盖 DSH 家目录(默认 `~/.dsh`);`DSH_PAODING_CONFIG` 覆盖配置文件路径(面板认它;仓库内兜底 CLI 则用 `--config <file>` 指定)。
|
|
27
27
|
|
|
28
|
-
仓库内 `presets/orchestrator/` 是静态预设源(生成管线读取并重写 `agent.cordis.yml`;`preset.yml`、`restrict.mjs` 原样复制——唯一例外是配置了 `main_agent_display_name`(或工作区派生显示名)时会改写 `preset.yml` 的 `name:` 行),`tools/` 是生成器本体(面板与兜底 CLI 共用),`plugins/paoding-config-ui/` 是「庖丁配置」面板插件本体。只想正常使用的话,这些都不用碰——见下一节。
|
|
28
|
+
仓库内 `presets/orchestrator/` 是静态预设源(生成管线读取并重写 `agent.cordis.yml`;`preset.yml`、`restrict.mjs`、`delegation-labels.mjs` 原样复制——唯一例外是配置了 `main_agent_display_name`(或工作区派生显示名)时会改写 `preset.yml` 的 `name:` 行),`tools/` 是生成器本体(面板与兜底 CLI 共用),`plugins/paoding-config-ui/` 是「庖丁配置」面板插件本体。只想正常使用的话,这些都不用碰——见下一节。
|
|
29
29
|
|
|
30
30
|
## 2. 安装:唯一官方通道
|
|
31
31
|
|
|
@@ -56,8 +56,8 @@ dsh plugin --profile web add dsh-paoding
|
|
|
56
56
|
|
|
57
57
|
两代宿主发现「本地 authored preset」的机制不同,安装器据此分双轨落点,宿主检测全自动、用户无感:
|
|
58
58
|
|
|
59
|
-
- **目录轨(DSH ≤ 0.1.6)**:宿主扫描 `$DSH_HOME/.agent-presets/` 下的目录来发现 preset,目录即注册。安装器照旧把产物写成 `$DSH_HOME/.agent-presets/orchestrator/`(`agent.cordis.yml` + `preset.yml` + `restrict.mjs`);按工作区配置生成的预设落同目录下的 `orchestrator-<slug>`。
|
|
60
|
-
- **声明行轨(DSH ≥ 0.1.7)**:宿主不再扫目录,改为读取 patch 里的 `@deepseek-ai/dsh-agent-preset` 声明行。安装器在 `$DSH_HOME/cordis.patch.yml` 里维护一个托管块——以 `# --- dsh-paoding presets (auto-generated; do not edit) ---` 起始、以配套的 end 标记收尾——块内用 `- insert:` 写声明行:全局预设 `config.id: orchestrator`,工作区预设 `config.id: orchestrator-<slug>`,各自的 `plugins` 内联全部插件行;`restrict.mjs` 以绝对 `file:` URL
|
|
59
|
+
- **目录轨(DSH ≤ 0.1.6)**:宿主扫描 `$DSH_HOME/.agent-presets/` 下的目录来发现 preset,目录即注册。安装器照旧把产物写成 `$DSH_HOME/.agent-presets/orchestrator/`(`agent.cordis.yml` + `preset.yml` + `restrict.mjs` + `delegation-labels.mjs`);按工作区配置生成的预设落同目录下的 `orchestrator-<slug>`。
|
|
60
|
+
- **声明行轨(DSH ≥ 0.1.7)**:宿主不再扫目录,改为读取 patch 里的 `@deepseek-ai/dsh-agent-preset` 声明行。安装器在 `$DSH_HOME/cordis.patch.yml` 里维护一个托管块——以 `# --- dsh-paoding presets (auto-generated; do not edit) ---` 起始、以配套的 end 标记收尾——块内用 `- insert:` 写声明行:全局预设 `config.id: orchestrator`,工作区预设 `config.id: orchestrator-<slug>`,各自的 `plugins` 内联全部插件行;`restrict.mjs` / `delegation-labels.mjs` 以绝对 `file:` URL 引用。产物四件套仍落在 `.agent-presets/<id>/`,只是从「目录即注册」变成「文件存放处」。托管块之外的用户内容一字节不动;块内带 do not edit 标记,手改块内内容会在下次保存时被覆盖。
|
|
61
61
|
|
|
62
62
|
安装器按下面的顺序判定走哪条轨:
|
|
63
63
|
|
|
@@ -135,7 +135,7 @@ dsh plugin --profile web add link:"$PWD"
|
|
|
135
135
|
|
|
136
136
|
包直接落在仓库目录上,改动经 HMR 或重启生效,无需反复重装。此形态无法就地升级(见第 3 节);想切回 registry 版,`dsh plugin --profile web add dsh-paoding@latest` 即可。
|
|
137
137
|
|
|
138
|
-
**仓库内兜底 CLI**(不宣传,仅限克隆了仓库的开发者):`node tools/install.mjs --auto`(有配置应用配置,没有写基础模板)、`--dry-run
|
|
138
|
+
**仓库内兜底 CLI**(不宣传,仅限克隆了仓库的开发者):`node tools/install.mjs --auto`(有配置应用配置,没有写基础模板)、`--dry-run`(只打印检测报告、将生成的 allow 与配置体检,不写盘)、`--config <file>`(指定配置文件)、`--suggest`(fresh 安装无配置时按智能默认分配 host 工具;默认基础模板不写 host 工具)、`--profile <name>`(指定扫描哪个 profile 的 patch 层,默认 `web`)、`doctor`(只读安装体检,用法见第 8 节开头)。不带 `--auto`(且非只读的 `--dry-run` / `doctor`)会被拒绝并提示——交互式安装已移除,可视化配置一律走插件通道自带的 Web 面板。
|
|
139
139
|
|
|
140
140
|
## 5. host patch 检测机制
|
|
141
141
|
|
|
@@ -155,7 +155,7 @@ dsh plugin --profile web add link:"$PWD"
|
|
|
155
155
|
|
|
156
156
|
- **启用判定**:patch 条目未被禁用(`enabled !== false` 且无 `disabled`)即视为启用;插件另查 `config.enabled`。
|
|
157
157
|
- **MCP 服务器识别**:条目名的包名段**精确等于** `dsh-mcp-client`(scoped/子路径形式按 `/` 取末段比对,`not-dsh-mcp-client-foo` 这类不会误判),或配置含 `serverName` 且 transport 为 `stdio` / `streamable-http` / `sse`(或有 `command`)。
|
|
158
|
-
-
|
|
158
|
+
- **精确工具名解析**(检测与产物按精确名对账;配置条目可写 `*`/`?` 通配,生成期展开成具体名,见配置文档):检测顺序是**所有 `stdio` / `streamable-http` 服务器一律先实时 JSON-RPC 握手**(stdio 拉起进程发 `initialize` + `tools/list`;streamable-http 走 POST;**15 秒超时**),把返回的工具名解析成 `mcp__<server>__<tool>`;静态已知表(`tavily` → 5 个工具 `tavily_search` / `tavily_crawl` / `tavily_extract` / `tavily_map` / `tavily_research`,`codegraph` → `codegraph_explore`)只是已知服务器**握手失败时的降级兜底**——工具按表保留,报告标注 static table,不丢工具;未知服务器握手失败才整服务器跳过。
|
|
159
159
|
- **本地工具插件**:按白名单匹配 patch 条目名并登记其工具,如 `magic-memory` → `memory_search`(新增插件需扩展白名单,见 `tools/lib/host.mjs` 的 `KNOWN_HOST_PLUGINS`)。
|
|
160
160
|
- **跳过不报错**:「握手失败、超时、`sse` 等不支持实时发现的服务器被跳过」只适用于**未知服务器**——整服务器跳过,对应角色只是缺这些工具,生成不报错(报告里会标注 `handshake failed` 及原因,URL/密钥会被打码);已知服务器握手失败回落静态表、工具保留,不在此列。
|
|
161
161
|
|
|
@@ -218,6 +218,18 @@ rm -rf "${DSH_HOME:-$HOME/.dsh}/.agent-presets"/orchestrator-*
|
|
|
218
218
|
|
|
219
219
|
## 8. 常见问题与排查
|
|
220
220
|
|
|
221
|
+
**先跑一遍体检**
|
|
222
|
+
|
|
223
|
+
多数「装不上 / 不出现 / 行为怪」都能用只读体检直接定位:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npx dsh-paoding@latest doctor # 或仓库内:node tools/install.mjs doctor
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
doctor 不改任何文件,逐项检查并给出 `✔ 正常 / ⚠ 警告 / ✘ 错误 / – 跳过` 四档结论:配置文件能否解析、预设安装轨道与宿主版本是否匹配、托管声明行有无孤儿行或损坏块、`.agent-presets/orchestrator-*` 有没有配置里已不引用的孤儿目录、已装预设与当前配置的再生成结果有无漂移、`.generator-version` 版本标记是否对得上。结尾有汇总;出现 ✘ 时退出码为 1,⚠ 与 – 不影响使用(跳过多见于全新机器,属正常)。`--config` / `--profile` 与安装时同义。
|
|
230
|
+
|
|
231
|
+
面板侧也有同源的保存时体检:每次「预览生成 / 保存并应用」的响应都带 `warnings` 字段(配置了未挂载工具、零工具角色、角色专用模型不在模型目录、预设落后于配置等),按条目提示处理即可,不用等运行时报错。
|
|
232
|
+
|
|
221
233
|
**pnpm 缺失**
|
|
222
234
|
|
|
223
235
|
`dsh plugin add` 报 pnpm 相关错误:`dsh plugin` 依赖 pnpm 装包。`npm i -g pnpm`(或 `corepack enable`)装好后重试。
|