dsh-paoding 0.2.2 → 0.3.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 +26 -22
- package/README_en.md +26 -22
- package/bin/dsh-paoding.mjs +73 -11
- package/docs/architecture.md +36 -31
- package/docs/architecture_en.md +54 -38
- package/docs/configuration.md +151 -57
- package/docs/configuration_en.md +155 -60
- package/docs/installation.md +96 -234
- package/docs/installation_en.md +111 -252
- package/docs/orchestration.md +24 -24
- package/docs/orchestration_en.md +24 -24
- package/package.json +8 -5
- package/plugins/paoding-config-ui/api-core.mjs +215 -18
- package/plugins/paoding-config-ui/index.mjs +413 -154
- package/plugins/paoding-config-ui/lib/base.css +1083 -42
- package/plugins/paoding-config-ui/lib/client.js +2266 -252
- package/plugins/paoding-config-ui/package.json +2 -2
- package/plugins/paoding-config-ui/runtime-inventory.mjs +27 -26
- package/presets/orchestrator/agent.cordis.yml +19 -9
- package/presets/orchestrator/preset.yml +3 -2
- package/presets/orchestrator/restrict.mjs +2 -1
- package/tools/install.mjs +9 -4
- package/tools/lib/alloc.mjs +60 -29
- package/tools/lib/cli.mjs +127 -279
- package/tools/lib/compose.mjs +261 -95
- package/tools/lib/config.mjs +266 -86
- package/tools/lib/host.mjs +55 -24
- package/tools/lib/skills.mjs +72 -45
- package/tools/lib/state.mjs +172 -40
- package/tools/lib/upgrade.mjs +170 -0
- package/tools/lib/util.mjs +7 -0
- package/tools/lib/version.mjs +233 -0
- package/tools/lib/workspaces.mjs +74 -0
- package/tools/lib/yaml.mjs +92 -15
- package/install.sh +0 -31
- package/tools/lib/wizard.mjs +0 -516
package/docs/orchestration.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# 编排
|
|
5
5
|
|
|
6
|
-
编排行为是 dsh-paoding 的核心:主 agent 拆解任务、沿任务纹理委派、集成结果;子 agent 按角色只带必要工具、跑完即弃。本文面向想了解或调优这些行为的用户:失败如何被发现与恢复、one-shot 与多轮迭代(continuable
|
|
6
|
+
编排行为是 dsh-paoding 的核心:主 agent 拆解任务、沿任务纹理委派、集成结果;子 agent 按角色只带必要工具、跑完即弃。本文面向想了解或调优这些行为的用户:失败如何被发现与恢复、one-shot 与多轮迭代(continuable)的取舍、会话模式如何按角色切换——面板与配置键直达,`implement_cont` 手编路径作为免面板的进阶保留。与源码冲突处一律以源码为准;本文所有配置引用均取自 `presets/orchestrator/agent.cordis.yml` 与 `presets/orchestrator/restrict.mjs`。
|
|
7
7
|
|
|
8
8
|
## 编排总览
|
|
9
9
|
|
|
@@ -24,7 +24,7 @@ dsh-paoding 把 DSH 从「单体 agent 全量加载工具」改造成「主 agen
|
|
|
24
24
|
| 协调 | `todo_write` / `ask_user_question` / `get_goal` / `create_goal` / `update_goal` / `exit_plan_mode` / `job_output` / `job_list` / `job_kill` |
|
|
25
25
|
| 主 agent 刻意看不到 | `web_search`、`mcp__tavily__*`、`write` / `edit`、`skill`、`workflow`、`ralph`、裸 `subagent` / `subagent_fork` |
|
|
26
26
|
|
|
27
|
-
每请求工具开销(估算,随注册面浮动):主 agent 全量 ~16.2k tokens → 白名单后 ~5.5k;`search_external` ~3.0k / `design` ~3.
|
|
27
|
+
每请求工具开销(估算,随注册面浮动):主 agent 全量 ~16.2k tokens → 白名单后 ~5.5k;`search_external` ~3.0k / `design` ~3.3k / `implement` ~3.8k,仅在真正委派时发生(数值来源:`agent.cordis.yml` 头部注释)。
|
|
28
28
|
|
|
29
29
|
### 主 agent persona(编排人设)原文摘录
|
|
30
30
|
|
|
@@ -61,9 +61,9 @@ DSH 没有原生自动重试——恢复是编排层的职责,具体地说就
|
|
|
61
61
|
|
|
62
62
|
子 agent 创建时,DSH 会对 `toolFilter.allow` 做 `tools.restrict()` 校验:allow 里的每个名字必须存在于子 agent 可见注册面(= 本组合注册全量 + host 层 MCP/插件工具)内,否则**创建被拒**(`tools.restrict() ... unknown tools`)。
|
|
63
63
|
|
|
64
|
-
本 preset
|
|
64
|
+
本 preset 在生成期消除这类失败:生成器(面板「保存并应用」与兜底 CLI 共用同一管线)读取 host patch 层(home / profile / `--patch`),检测实际启用的 MCP 服务器与本地工具插件,解析出精确工具名(静态已知表优先,未知服务器走实时 JSON-RPC 握手),然后把各角色 allow 重写为「静态意图 ∩ 实际检测到的工具」——组合保证的基础工具原样保留,未启用/无法解析的 host 工具被剔除。握手失败或 transport 不支持的 MCP 会被跳过:对应角色只是缺这些工具,应用不报错。宿主停用/启用了 MCP 或插件后,到「庖丁配置」点一次「保存并应用」即可同步 allow(「预览生成」先看清单)。细节见[安装](installation.md)。
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
注意:生成器的 allow 重写只覆盖三个内置角色(`search_external` / `design` / `implement`,`tools/install.mjs` 的 `ROLES` 常量)。手写新增的 `delegation-*` 块(例如第 4 节手编的 `implement_cont`)**原样生效、不会被自动清洗**——其中的 host 依赖工具名必须自己与宿主实际启用的插件保持同步,否则创建被拒。这正是 2026-09-02 起各角色 allow 剔除 `memory_search` / `mcp__codegraph__codegraph_explore` 的原因(插件停用时这些名字不在注册面;重开插件时按需加回,见 `agent.cordis.yml` 中 `delegation-search-internal-deep` 的注释)。
|
|
67
67
|
|
|
68
68
|
### 第 2 层:检测
|
|
69
69
|
|
|
@@ -109,49 +109,51 @@ Delegation failure handling (SOP):
|
|
|
109
109
|
| `max-tokens` | 把任务拆小再重委派,或要求子 agent 分步输出 |
|
|
110
110
|
| `refusal` | **不重试同一任务**:调整任务范围/表述、换角色,或自己处理——refusal 是策略决定,不是瞬时错误 |
|
|
111
111
|
| `aborted` | 仅当取消是意外才重委派 |
|
|
112
|
-
| completed 但产出差 |
|
|
112
|
+
| completed 但产出差 | 带具体缺失点重委派;角色为 continuable 时走下方的 continuable 分支 |
|
|
113
113
|
| 同一任务失败 **2 次** | 停止重试,向用户报告失败原因与已尝试方案;绝不循环一个失败的委派 |
|
|
114
114
|
| 任何重委派 | **必须携带上次的集成摘要**:做了什么 / 败在哪 / 从哪接续——子 agent 无需从冷上下文重新推导 |
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
continuable 分支(SOP 新增):失败或产出不满、**且该角色已配成 continuable** 时,先 `send_message` 在同一子会话续修——子 agent 记得自己做到哪,就地补完;续修无效再回到上表按停止原因重委派(重委派从首选退为退路)。
|
|
117
|
+
|
|
118
|
+
设计要点:SOP 是 persona 文本而非代码逻辑,因此可以按需编辑——直接改 `presets/orchestrator/agent.cordis.yml` 中 persona 段落(YAML 块标量,内容行缩进 10 空格,注意保持缩进),再到「庖丁配置」点「保存并应用」重新生成。例如想让失败任务更频繁地退回主 agent 自己做、或对某个角色采用不同的重试上限,都可在此调整。
|
|
117
119
|
|
|
118
120
|
## one-shot 与多轮迭代
|
|
119
121
|
|
|
120
122
|
### 默认:one-shot(用完即弃)
|
|
121
123
|
|
|
122
|
-
四个角色委派实例(`delegation-search-external` / `delegation-design` / `delegation-implement` / `delegation-search-internal-deep
|
|
124
|
+
四个角色委派实例(`delegation-search-external` / `delegation-design` / `delegation-implement` / `delegation-search-internal-deep`)的会话模式都是 one-shot——基础模板把四个内置角色显式写明(委派块里的 `backgroundMode: one-shot` 行,纯为可见性,省得打开文件猜默认值),语义与 `dsh-tool-subagent` 的配置默认值一致。会话模式按角色可配:任一角色(含自定义角色)经 `roles.<toolName>.background_mode` 切成 `continuable`(见[配置](configuration.md) 2.6);还可经 `roles.<toolName>.model` / `.provider` 固定专用模型——配置后该角色固定用自己的模型,不随主 agent 会话切换模型而变(见[配置](configuration.md) 2.5)。含义:
|
|
123
125
|
|
|
124
126
|
- 一次委派 = 一个用完即弃的子会话。调用默认等子 agent 跑完、把结果交回主 agent(也可按工具参数 `run_in_background` 转为后台 job,用 `job_output` 收结果、`job_kill` 叫停)。
|
|
125
127
|
- 子会话在任务结束时即弃,其工具面与上下文只为该次运行而加载(**按需加载 + 上下文隔离**,这是本 preset 的核心设计)。
|
|
126
|
-
- 与组合里另外两个通用委派行不同——`tool-subagent`(`subagent`,continuable)与 `tool-subagent-fork`(`subagent_fork`,continuable)是通用、可续的委派工具,但主 agent
|
|
128
|
+
- 与组合里另外两个通用委派行不同——`tool-subagent`(`subagent`,continuable)与 `tool-subagent-fork`(`subagent_fork`,continuable)是通用、可续的委派工具,但主 agent 白名单刻意不向其暴露;模型可见的委派面只有上述角色工具(每个角色的会话模式可配,见下)。
|
|
127
129
|
|
|
128
130
|
### 需要多轮迭代时的两条路
|
|
129
131
|
|
|
130
132
|
- **路径 A(推荐,零成本):集成摘要 → 重委派。** 主 agent 手里已有上轮集成摘要,直接以摘要为起点重委派一个新 one-shot 任务。子 agent 依旧用完即弃,主 agent 的摘要就是跨轮的「记忆」,重派成本可控,不改变任何持久化/生命周期模型。这是默认 SOP 对 `error` / `completed-but-poor` 等场景的处理方式(见上节)。
|
|
131
|
-
- **路径 B
|
|
133
|
+
- **路径 B(配置直达):把任一角色设为 continuable。** 面板角色卡把「会话模式」选成「可续(continuable)」,或配置里写 `roles.<toolName>.background_mode: continuable`——内置角色、自定义角色都行,见[配置](configuration.md) 2.6;免面板的手编路径 `implement_cont` 仍保留,见第 4 节。continuable 调用的工具语义(`dsh-tool-subagent` 工具描述):默认**后台运行**、立即返回一个持久的子 agent id,子会话**跨轮保留**;该轮跑完后运行时向主 agent 发送结果通知(结果 + 最后一条 assistant 消息);之后主 agent 用 `send_message` 在**同一个子会话**开启后续轮次。收益:失败或产出不满意时无需重推——子 agent 记得自己查过什么、改到哪,`send_message` 就地续修即可;主 persona 的委派失败 SOP 已为此新增分支——可续角色失败或产出不满先同会话续修,重委派退为退路(见上节)。
|
|
132
134
|
|
|
133
135
|
### 代价与前提(如实说明)
|
|
134
136
|
|
|
135
137
|
continuable 不是免费的,启用前请确认以下四点:
|
|
136
138
|
|
|
137
|
-
1. **前置:continuable 需要 `sessionPersistence` 后端。** standard 设计把 persistence 放在 **host 层**(preset 不拥有它),所以要在 `~/.dsh/cordis.patch.yml` 挂 `@deepseek-ai/dsh-session-persistence-jsonl`(`config.root` **必填**,见插件 schema)。未挂载时 continuable 创建/续跑会直接报错:`continuable subagents require session persistence (load a dsh-session-persistence backend)`(错误码 `PERSISTENCE_UNAVAILABLE
|
|
139
|
+
1. **前置:continuable 需要 `sessionPersistence` 后端。** standard 设计把 persistence 放在 **host 层**(preset 不拥有它),所以要在 `~/.dsh/cordis.patch.yml` 挂 `@deepseek-ai/dsh-session-persistence-jsonl`(`config.root` **必填**,见插件 schema)。未挂载时 continuable 创建/续跑会直接报错:`continuable subagents require session persistence (load a dsh-session-persistence backend)`(错误码 `PERSISTENCE_UNAVAILABLE`)。「庖丁配置」面板在未探测到 `sessionPersistence` 时会就地警告但不拦截——正常顺序是先挂后端、再开 continuable。这是**机器级全局改动**——persistence 影响该机器上所有会话,不是 preset 内改动,卸载 preset 也不会撤销它。
|
|
138
140
|
2. **持久化会话无 TTL**,会持续写盘累积(`config.root` 目录下按项目/会话组织 JSONL 落盘)。需要自行 `interrupt_agent` 停用不再需要的会话、并清理落盘文件。
|
|
139
|
-
3. **token 成本随轮次上升。** continuable 子 agent 每轮携带自己累积的上下文,长期挂着每轮成本只增不减——这与「用完即弃 /
|
|
141
|
+
3. **token 成本随轮次上升。** continuable 子 agent 每轮携带自己累积的上下文,长期挂着每轮成本只增不减——这与「用完即弃 / 按需加载」的设计初衷相悖。建议只对**多轮打磨**类委派用(手编示例 `implement_cont` 的名字就是这么来的)。
|
|
140
142
|
4. **权限规则不变。** continuable 不改变 DSH 的权限语义:被拒操作依然不重试、只能换路;角色失败汇报协议与主 agent 的委派失败 SOP 对 continuable 子 agent 同样适用(SOP 里 `send_message` 分支就是为它写的)。
|
|
141
143
|
|
|
142
144
|
对照小结:
|
|
143
145
|
|
|
144
|
-
| 维度 | one-shot(默认角色) | continuable
|
|
146
|
+
| 维度 | one-shot(默认角色) | continuable(任意可续角色) |
|
|
145
147
|
|---|---|---|
|
|
146
148
|
| 会话生命周期 | 任务结束即弃 | 跨轮保留(durable subagent id) |
|
|
147
149
|
| 续修方式 | 主 agent 摘要 → 重委派新任务 | `send_message` 同一会话就地续修 |
|
|
148
150
|
| 持久化要求 | 无 | host 层 `sessionPersistence` 后端(机器级) |
|
|
149
151
|
| 长期成本 | 每轮只付新任务 | 每轮携带累积上下文,成本上升 |
|
|
150
|
-
| 适用 | 一切委派(默认) |
|
|
152
|
+
| 适用 | 一切委派(默认) | 多轮打磨类委派(按角色开启,见[配置](configuration.md) 2.6) |
|
|
151
153
|
|
|
152
|
-
## implement_cont
|
|
154
|
+
## 进阶:免面板手编 implement_cont
|
|
153
155
|
|
|
154
|
-
|
|
156
|
+
路径 B 的主路径在面板与配置键——角色卡「会话模式」一键可达(见[配置](configuration.md) 2.6)。本节是等价的免面板手编路径,共 5 步,供想看清生成层到底写了什么、或在不起面板的环境里操作时使用。默认 preset **不含** `implement_cont`——需要时自行启用,用完可整体移除。所有 YAML 均为配置原文(来自 [README.md](../README.md) 的示例,已与源码核对)。
|
|
155
157
|
|
|
156
158
|
### 第 1 步 —— host 层挂 persistence 后端(机器级,全局生效)
|
|
157
159
|
|
|
@@ -188,6 +190,7 @@ continuable 不是免费的,启用前请确认以下四点:
|
|
|
188
190
|
toolFilter:
|
|
189
191
|
allow:
|
|
190
192
|
- read
|
|
193
|
+
- read_image
|
|
191
194
|
- write
|
|
192
195
|
- edit
|
|
193
196
|
- glob
|
|
@@ -222,27 +225,24 @@ continuable 不是免费的,启用前请确认以下四点:
|
|
|
222
225
|
- implement_cont
|
|
223
226
|
```
|
|
224
227
|
|
|
225
|
-
|
|
228
|
+
应用时 `implement_cont`(非 host 依赖名)会被并入生成的 `config.allow`。也可在面板(设置 → **庖丁配置** → 主 agent 卡)勾选,见[配置](configuration.md)。
|
|
226
229
|
|
|
227
|
-
- **或:改 `restrict.mjs` 常量。** 在 `presets/orchestrator/restrict.mjs` 的 `MAIN_AGENT_ALLOW`(21 项白名单常量,`new Set([...])`)中加一行 `'implement_cont'`。注意**覆盖语义**:运行时 `allow = config.allow ?? MAIN_AGENT_ALLOW`(空 allow
|
|
230
|
+
- **或:改 `restrict.mjs` 常量。** 在 `presets/orchestrator/restrict.mjs` 的 `MAIN_AGENT_ALLOW`(21 项白名单常量,`new Set([...])`)中加一行 `'implement_cont'`。注意**覆盖语义**:运行时 `allow = config.allow ?? MAIN_AGENT_ALLOW`(空 allow 拒绝加载)。生成器从 `restrict.mjs` 源码现场解析该常量作为 base,生成 `config.allow = base + main_agent_extra(仅检测到的 host 名保留)− main_agent_remove`,且**只在结果与 base 不同时才注入** `config.allow` 行。因此:改完常量必须重新应用(base 重新解析、安装副本刷新);若运行中的 `agent.cordis.yml` 已有注入的 `config.allow`,运行时以它为准、常量只作回退。
|
|
228
231
|
|
|
229
|
-
|
|
232
|
+
无论哪条路,改完都需要重新应用(见第 4 步)。
|
|
230
233
|
|
|
231
234
|
### 第 4 步 —— 应用
|
|
232
235
|
|
|
233
|
-
|
|
234
|
-
cd dsh-paoding
|
|
235
|
-
./install.sh --auto # 重新生成 preset(含新 delegation 块与白名单变更)
|
|
236
|
-
```
|
|
236
|
+
打开 设置 → **庖丁配置**,点「**保存并应用**」——重新生成 preset(含新 delegation 块与白名单变更),并把手编改动一并应用。
|
|
237
237
|
|
|
238
|
-
然后**重启 host 或新建会话**生效。第 3 步若走了配置文件路径,配置会持久化到 `~/.dsh/dsh-paoding.config.yml
|
|
238
|
+
然后**重启 host 或新建会话**生效。第 3 步若走了配置文件路径,配置会持久化到 `~/.dsh/dsh-paoding.config.yml`,之后改动配置同样在面板点「保存并应用」幂等应用(克隆了仓库的开发者也可用兜底 CLI `node tools/install.mjs --auto`)。
|
|
239
239
|
|
|
240
240
|
### 第 5 步 —— 用后清理
|
|
241
241
|
|
|
242
242
|
continuable 会话**无 TTL**,会持续写盘累积:
|
|
243
243
|
|
|
244
244
|
- 用 `interrupt_agent` 停掉不再需要的 `implement_cont` 会话;
|
|
245
|
-
- 长期不再用时,移除第 2 步的 delegation 块与第 3
|
|
245
|
+
- 长期不再用时,移除第 2 步的 delegation 块与第 3 步的白名单项,再在面板点「保存并应用」重新生成;persistence 插件本身留在 host 层即可(机器级,见第 3 节),也可一并移除并清理 `~/.dsh/sessions/` 下的落盘文件。
|
|
246
246
|
|
|
247
247
|
## 上下文隔离
|
|
248
248
|
|
package/docs/orchestration_en.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# Orchestration
|
|
5
5
|
|
|
6
|
-
Orchestration is the core of dsh-paoding: the main agent (the orchestrator) decomposes the task, delegates along its texture, and integrates the results; role subagents carry only the tools their role needs and are discarded once their run settles. This document is for users who want to understand or tune these behaviors: how failures surface and recover, the one-shot vs multi-turn (continuable) trade-off, and how
|
|
6
|
+
Orchestration is the core of dsh-paoding: the main agent (the orchestrator) decomposes the task, delegates along its texture, and integrates the results; role subagents carry only the tools their role needs and are discarded once their run settles. This document is for users who want to understand or tune these behaviors: how failures surface and recover, the one-shot vs multi-turn (continuable) trade-off, and how each role's session mode is switched — a panel toggle or a config key, with the hand-edited `implement_cont` route kept as the panel-free advanced path. Where this document conflicts with the source code, the source wins; every configuration reference here is taken from `presets/orchestrator/agent.cordis.yml` and `presets/orchestrator/restrict.mjs`.
|
|
7
7
|
|
|
8
8
|
## Orchestration overview
|
|
9
9
|
|
|
@@ -24,7 +24,7 @@ The main agent's model-facing surface is narrowed by `restrict.mjs` on the `syst
|
|
|
24
24
|
| Coordination | `todo_write` / `ask_user_question` / `get_goal` / `create_goal` / `update_goal` / `exit_plan_mode` / `job_output` / `job_list` / `job_kill` |
|
|
25
25
|
| Deliberately hidden from the main agent | `web_search`, `mcp__tavily__*`, `write` / `edit`, `skill`, `workflow`, `ralph`, bare `subagent` / `subagent_fork` |
|
|
26
26
|
|
|
27
|
-
Per-request tool tax (estimates; they float with the registered surface): full monolithic main agent ~16.2k tokens → ~5.5k after the allow list; `search_external` ~3.0k / `design` ~3.
|
|
27
|
+
Per-request tool tax (estimates; they float with the registered surface): full monolithic main agent ~16.2k tokens → ~5.5k after the allow list; `search_external` ~3.0k / `design` ~3.3k / `implement` ~3.8k, incurred only when actually delegated (figures from the header comment of `agent.cordis.yml`).
|
|
28
28
|
|
|
29
29
|
### Main-agent persona (excerpt, verbatim)
|
|
30
30
|
|
|
@@ -61,9 +61,9 @@ A delegated run reports failure in two runtime shapes (verbatim from the persona
|
|
|
61
61
|
|
|
62
62
|
At child creation, DSH validates `toolFilter.allow` through `tools.restrict()`: every allow name must exist in the child's visible registry (= this composition's full registration plus host-layer MCP/plugin tools), otherwise creation is rejected (`tools.restrict() ... unknown tools`).
|
|
63
63
|
|
|
64
|
-
The preset eliminates this class of failure at
|
|
64
|
+
The preset eliminates this class of failure at generation time: the generator (the same pipeline behind the panel's Save & Apply and the fallback CLI) reads the host patch layers (home / profile / `--patch`), detects which MCP servers and local tool plugins are actually enabled, resolves exact tool names (a static known-tools table first, then a live JSON-RPC handshake for unknown servers), and rewrites each role's allow list as "static intent ∩ actually detected tools" — composition-guaranteed base tools stay untouched, host tools that are disabled or unresolvable are removed. MCPs that fail the handshake or use an unsupported transport are skipped: the role simply lacks those tools and applying does not error. After enabling/disabling MCPs or plugins on the host, hit Save & Apply once in 庖丁配置 to sync the allow lists (Preview shows the list first). Details in [Installation](installation_en.md).
|
|
65
65
|
|
|
66
|
-
Note that the
|
|
66
|
+
Note that the generator's allow rewriting covers only the three built-in roles (`search_external` / `design` / `implement` — the `ROLES` constant in tools/install.mjs). Hand-written extra `delegation-*` blocks (e.g. the hand-written `implement_cont` in section 4) ship **as-is and are never auto-cleaned**: host-dependent names inside them must be kept in sync with the plugins actually enabled on the host, or child creation is rejected. That is exactly why role allow lists dropped `memory_search` / `mcp__codegraph__codegraph_explore` as of 2026-09-02 (those names are not in the registry while the plugins are off; add them back when you re-enable the plugin — see the comment on `delegation-search-internal-deep` in `agent.cordis.yml`).
|
|
67
67
|
|
|
68
68
|
### Layer 2: detection
|
|
69
69
|
|
|
@@ -109,49 +109,51 @@ Behavior by stop reason (complete coverage, one-to-one with the persona):
|
|
|
109
109
|
| `max-tokens` | Split the task into smaller steps and re-delegate, or ask the child to output incrementally |
|
|
110
110
|
| `refusal` | Do **not** retry the same task: adjust the task's scope or framing, switch roles, or handle it yourself — a refusal is a policy decision, not a transient error |
|
|
111
111
|
| `aborted` | Re-delegate only when the cancellation was accidental |
|
|
112
|
-
| completed but poor output | Re-delegate with concrete missing points;
|
|
112
|
+
| completed but poor output | Re-delegate with concrete missing points; when the role is continuable, take the continuable branch below |
|
|
113
113
|
| Same task fails **twice** | Stop retrying; report to the user what failed, why, and what you already tried; never loop a failing delegation |
|
|
114
114
|
| Any re-delegation | **Always carry the previous integration summary** — what was done, what failed, what to pick up from — so the child never re-derives it from a cold context |
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
The continuable branch (new in the SOP): when a run fails or the output disappoints **and the role is configured continuable**, first resume the same child conversation with `send_message` — the child remembers where it left off and finishes in place; only if that does not help fall back to the table above and re-delegate (re-delegation drops from first choice to fallback).
|
|
117
|
+
|
|
118
|
+
Design note: the SOP is persona text, not code, so it is tunable: edit the persona block in `presets/orchestrator/agent.cordis.yml` (YAML block scalar; content lines are indented 10 spaces — keep the indentation), then hit Save & Apply in 庖丁配置 to regenerate. For example, you can make failures bounce back to the main agent more often, or give a specific role a different retry ceiling.
|
|
117
119
|
|
|
118
120
|
## One-shot vs continuable
|
|
119
121
|
|
|
120
122
|
### Default: one-shot (run-and-discard)
|
|
121
123
|
|
|
122
|
-
The four role delegation instances (`delegation-search-external` / `delegation-design` / `delegation-implement` / `delegation-search-internal-deep`)
|
|
124
|
+
The four role delegation instances (`delegation-search-external` / `delegation-design` / `delegation-implement` / `delegation-search-internal-deep`) all run in `one-shot` mode — the base template writes it out explicitly for the four built-ins (a `backgroundMode: one-shot` row in each delegation block, purely for visibility so you never have to guess the default), which matches `dsh-tool-subagent`'s config default. The session mode is per-role configurable: any role (custom roles included) can be switched to `continuable` via `roles.<toolName>.background_mode` (see [Configuration](configuration_en.md) 2.6). Any role can additionally be pinned to a dedicated model via `roles.<toolName>.model` / `.provider` — once configured, the role runs on its own model and no longer follows the main agent's session model switches (see [Configuration](configuration_en.md) 2.5). Meaning:
|
|
123
125
|
|
|
124
126
|
- One delegation = one run-and-discard child session. The call waits for the child to finish and hands the result back to the main agent by default (or becomes a background job via the tool's `run_in_background` parameter, collected with `job_output` and stopped with `job_kill`).
|
|
125
127
|
- The child session is discarded when the task settles; its tool surface and context are paid for only for that one run (**pay-per-use + context isolation** — the preset's core design).
|
|
126
|
-
- This differs from the two generic delegation rows in the composition — `tool-subagent` (`subagent`, continuable) and `tool-subagent-fork` (`subagent_fork`, continuable) are generic, continuable delegation tools, but the main-agent allow list deliberately hides them; the model-visible delegation surface is only the
|
|
128
|
+
- This differs from the two generic delegation rows in the composition — `tool-subagent` (`subagent`, continuable) and `tool-subagent-fork` (`subagent_fork`, continuable) are generic, continuable delegation tools, but the main-agent allow list deliberately hides them; the model-visible delegation surface is only the role tools above (each role's session mode is configurable, see below).
|
|
127
129
|
|
|
128
130
|
### Two paths when you need multiple iterations
|
|
129
131
|
|
|
130
132
|
- **Path A (recommended, zero cost): integration summary → re-delegate.** The main agent already holds the previous integration summary, so it simply re-delegates a fresh one-shot task seeded with that summary. The child is still run-and-discard; the main agent's summary is the cross-turn "memory"; re-delegation cost stays bounded and no persistence/lifecycle model changes. This is how the default SOP handles `error` / `completed-but-poor` and similar cases (see the previous section).
|
|
131
|
-
- **Path B (
|
|
133
|
+
- **Path B (a config toggle away): make any role continuable.** Set「会话模式」("session mode") to「可续(continuable)」on the role card in the panel, or write `roles.<toolName>.background_mode: continuable` in the config — built-in and custom roles alike (see [Configuration](configuration_en.md) 2.6; the panel-free hand-edited `implement_cont` route is kept in section 4). Continuable tool semantics (from the `dsh-tool-subagent` tool description): it runs **in the background by default**, immediately returns a durable subagent id, and **keeps the child conversation available for later turns**; when that run settles, the runtime sends the parent a notice with the outcome and final assistant message; afterwards the main agent starts later turns in the **same child conversation** with `send_message`. Payoff: on failure or unsatisfactory output there is no cold restart — the child remembers what it searched and what it changed, and `send_message` finishes the gaps in place; the main agent's delegation SOP now carries a matching branch — for a continuable role, resume in the same session first and treat re-delegation as the fallback (see the previous section).
|
|
132
134
|
|
|
133
135
|
### Costs and prerequisites
|
|
134
136
|
|
|
135
137
|
Continuable is not free; confirm all four before enabling:
|
|
136
138
|
|
|
137
|
-
1. **Prerequisite: continuable requires a `sessionPersistence` backend.** The standard design keeps persistence at the **host layer** (the preset does not own it), so you mount `@deepseek-ai/dsh-session-persistence-jsonl` in `~/.dsh/cordis.patch.yml` (`config.root` is **required**, per the plugin schema). Without it, continuable creation/resumption fails loudly: `continuable subagents require session persistence (load a dsh-session-persistence backend)` (error code `PERSISTENCE_UNAVAILABLE`). This is a **machine-level, global change** — persistence affects every session on that host, it is not a preset-local change, and uninstalling the preset does not undo it.
|
|
139
|
+
1. **Prerequisite: continuable requires a `sessionPersistence` backend.** The standard design keeps persistence at the **host layer** (the preset does not own it), so you mount `@deepseek-ai/dsh-session-persistence-jsonl` in `~/.dsh/cordis.patch.yml` (`config.root` is **required**, per the plugin schema). Without it, continuable creation/resumption fails loudly: `continuable subagents require session persistence (load a dsh-session-persistence backend)` (error code `PERSISTENCE_UNAVAILABLE`). The 庖丁配置 panel warns — without blocking — when it does not detect `sessionPersistence`: the normal order is to mount the backend first, then flip roles to continuable. This is a **machine-level, global change** — persistence affects every session on that host, it is not a preset-local change, and uninstalling the preset does not undo it.
|
|
138
140
|
2. **Persisted sessions have no TTL** and keep accumulating on disk (JSONL artifacts under `config.root`, organized by project/session). You must `interrupt_agent` sessions you no longer need and clean up the on-disk files yourself.
|
|
139
|
-
3. **Token cost grows per turn.** A continuable child carries its accumulated context on every turn, so a long-lived child only gets more expensive — which runs against the run-and-discard / pay-per-use philosophy. Use it only for
|
|
141
|
+
3. **Token cost grows per turn.** A continuable child carries its accumulated context on every turn, so a long-lived child only gets more expensive — which runs against the run-and-discard / pay-per-use philosophy. Use it only for **multi-round polishing** delegations (the name of the hand-edited example, `implement_cont`, says exactly that).
|
|
140
142
|
4. **Permission rules are unchanged.** Continuable does not alter DSH's permission semantics: a denied operation is still never retried — only a different path is taken; the role failure-reporting protocol and the main agent's delegation SOP apply to continuable children too (the SOP's `send_message` branch exists precisely for them).
|
|
141
143
|
|
|
142
144
|
Quick comparison:
|
|
143
145
|
|
|
144
|
-
| Dimension | one-shot (default roles) | continuable (
|
|
146
|
+
| Dimension | one-shot (default roles) | continuable (any continuable role) |
|
|
145
147
|
|---|---|---|
|
|
146
148
|
| Session lifetime | discarded when the task settles | kept across turns (durable subagent id) |
|
|
147
149
|
| Follow-up fixing | main-agent summary → re-delegate a fresh task | `send_message` in the same session, fix in place |
|
|
148
150
|
| Persistence required | none | host-layer `sessionPersistence` backend (machine-level) |
|
|
149
151
|
| Long-term cost | each turn pays only the new task | each turn carries the accumulated context, cost grows |
|
|
150
|
-
| Fit | every delegation (default) |
|
|
152
|
+
| Fit | every delegation (default) | multi-round polishing delegations, per role (see [Configuration](configuration_en.md) 2.6) |
|
|
151
153
|
|
|
152
|
-
##
|
|
154
|
+
## Advanced: hand-editing implement_cont (no panel)
|
|
153
155
|
|
|
154
|
-
|
|
156
|
+
The main path for Path B is the panel or the config key — one toggle on the role card's「会话模式」("session mode") control (see [Configuration](configuration_en.md) 2.6). This section is the equivalent panel-free route, in 5 steps — read it when you want to see exactly what the generation layer writes, or when working without the panel. The default preset does **not** ship `implement_cont`; enable it when you need it and remove it entirely when you no longer do. All YAML below is verbatim configuration (adapted from the example in [README.md](../README_en.md) and checked against the source).
|
|
155
157
|
|
|
156
158
|
### Step 1 — mount the persistence backend at the host layer (machine-level, global)
|
|
157
159
|
|
|
@@ -189,6 +191,7 @@ At the **end** of the delegation group's `config` list in `presets/orchestrator/
|
|
|
189
191
|
toolFilter:
|
|
190
192
|
allow:
|
|
191
193
|
- read
|
|
194
|
+
- read_image
|
|
192
195
|
- write
|
|
193
196
|
- edit
|
|
194
197
|
- glob
|
|
@@ -223,27 +226,24 @@ main_agent_extra:
|
|
|
223
226
|
- implement_cont
|
|
224
227
|
```
|
|
225
228
|
|
|
226
|
-
At
|
|
229
|
+
At apply time `implement_cont` — not a host-dependent name — is merged into the generated `config.allow`. You can equally tick it in the panel (Settings → 庖丁配置 → the main-agent card); see [Configuration](configuration_en.md).
|
|
227
230
|
|
|
228
|
-
**Alternative: edit the `restrict.mjs` constant.** Add a line `'implement_cont'` to `MAIN_AGENT_ALLOW` (the 21-entry allow constant, `new Set([...])`) in `presets/orchestrator/restrict.mjs`. Mind the **override semantics**: at runtime `allow = config.allow ?? MAIN_AGENT_ALLOW` (an empty allow refuses to load). The
|
|
231
|
+
**Alternative: edit the `restrict.mjs` constant.** Add a line `'implement_cont'` to `MAIN_AGENT_ALLOW` (the 21-entry allow constant, `new Set([...])`) in `presets/orchestrator/restrict.mjs`. Mind the **override semantics**: at runtime `allow = config.allow ?? MAIN_AGENT_ALLOW` (an empty allow refuses to load). The generator re-extracts this constant from `restrict.mjs` source as its base and generates `config.allow = base + main_agent_extra (only detected host names kept) − main_agent_remove`, injecting the `config.allow` row **only when the result differs from the base**. So after editing the constant you must re-apply (the base is re-extracted and the installed copy refreshed); and when the running `agent.cordis.yml` already has an injected `config.allow`, that generated list wins at runtime and the constant only serves as fallback.
|
|
229
232
|
|
|
230
|
-
Either way, re-
|
|
233
|
+
Either way, re-apply to take effect (next step).
|
|
231
234
|
|
|
232
235
|
### Step 4 — apply
|
|
233
236
|
|
|
234
|
-
|
|
235
|
-
cd dsh-paoding
|
|
236
|
-
./install.sh --auto # regenerate the preset (new delegation block + allow-list changes)
|
|
237
|
-
```
|
|
237
|
+
Open Settings → **庖丁配置** and hit「**保存并应用**」(Save & Apply) — the preset regenerates (new delegation block + allow-list changes), and your hand edits go live with it.
|
|
238
238
|
|
|
239
|
-
Then **restart the host or open a new session** for it to take effect. If step 3 used the config-file path, the choice is persisted in `~/.dsh/dsh-paoding.config.yml`; change it later and
|
|
239
|
+
Then **restart the host or open a new session** for it to take effect. If step 3 used the config-file path, the choice is persisted in `~/.dsh/dsh-paoding.config.yml`; change it later and hit Save & Apply in the panel again for an idempotent re-apply (developers who cloned the repo can also use the fallback CLI, `node tools/install.mjs --auto`).
|
|
240
240
|
|
|
241
241
|
### Step 5 — clean up after use
|
|
242
242
|
|
|
243
243
|
Continuable sessions have **no TTL** and keep accumulating on disk:
|
|
244
244
|
|
|
245
245
|
- `interrupt_agent` any `implement_cont` session you no longer need;
|
|
246
|
-
- when you stop using it for good, remove the delegation block from step 2 and the allow entry from step 3, then
|
|
246
|
+
- when you stop using it for good, remove the delegation block from step 2 and the allow entry from step 3, then hit Save & Apply in the panel to regenerate; the persistence plugin itself may stay at the host layer (machine-level, see section 3), or be removed together with the artifacts under `~/.dsh/sessions/`.
|
|
247
247
|
|
|
248
248
|
## Context isolation
|
|
249
249
|
|
package/package.json
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-paoding",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "庖丁 — DSH (DeepSeek Harness) 编排模式安装器:host 感知的角色工具过滤 + Web 设置页可视化配置器",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"bin": {
|
|
8
|
-
"dsh-paoding": "bin/dsh-paoding.mjs"
|
|
9
|
-
},
|
|
10
7
|
"files": [
|
|
11
8
|
"bin/",
|
|
12
9
|
"tools/",
|
|
13
10
|
"presets/",
|
|
14
11
|
"plugins/",
|
|
12
|
+
"!plugins/paoding-config-ui/src",
|
|
15
13
|
"docs/",
|
|
16
|
-
"install.sh",
|
|
17
14
|
"README.md",
|
|
18
15
|
"README_en.md",
|
|
19
16
|
"LICENSE",
|
|
@@ -22,6 +19,9 @@
|
|
|
22
19
|
"engines": {
|
|
23
20
|
"node": ">=18"
|
|
24
21
|
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"prepublishOnly": "node scripts/build-client.mjs --check"
|
|
24
|
+
},
|
|
25
25
|
"keywords": [
|
|
26
26
|
"dsh",
|
|
27
27
|
"deepseek-harness",
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"type": "git",
|
|
34
34
|
"url": "git+https://github.com/lifangjin/dsh-paoding.git"
|
|
35
35
|
},
|
|
36
|
+
"bin": {
|
|
37
|
+
"dsh-paoding": "bin/dsh-paoding.mjs"
|
|
38
|
+
},
|
|
36
39
|
"main": "plugins/paoding-config-ui/index.mjs",
|
|
37
40
|
"exports": {
|
|
38
41
|
".": "./plugins/paoding-config-ui/index.mjs",
|