dsh-paoding 0.3.0 → 0.3.2
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 +7 -16
- package/README_en.md +7 -16
- package/bin/dsh-paoding.mjs +2 -2
- package/docs/architecture.md +7 -5
- package/docs/architecture_en.md +14 -7
- package/docs/configuration.md +13 -13
- package/docs/configuration_en.md +11 -11
- package/docs/images/1.png +0 -0
- package/docs/installation.md +24 -23
- package/docs/installation_en.md +24 -23
- package/docs/orchestration.md +20 -24
- package/docs/orchestration_en.md +20 -24
- package/package.json +1 -1
- package/plugins/paoding-config-ui/index.mjs +4 -3
- package/plugins/paoding-config-ui/lib/client.js +3 -3
- package/plugins/paoding-config-ui/package.json +1 -1
- package/tools/lib/alloc.mjs +2 -2
- package/tools/lib/cli.mjs +7 -6
- package/tools/lib/config.mjs +1 -1
- package/docs/images/2.png +0 -0
- package/docs/images/3.png +0 -0
- package/docs/images/4.png +0 -0
- package/docs/images/5.png +0 -0
- package/docs/images/6.png +0 -0
package/docs/installation.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
- **Node.js ≥ 18**。DSH host 与插件链路都跑在 Node 上;版本过低时 `dsh` 本身就起不来。可用 `node --version` 自查。
|
|
14
14
|
- **pnpm 可用**。`dsh plugin` 是 pnpm 的透明转发器:插件包装进 profile 时由 pnpm 完成。缺失时安装命令会报 pnpm 相关错误,装好 pnpm(`npm i -g pnpm` 或 `corepack enable`)后重试。
|
|
15
|
-
- **已安装 DSH host**(`dsh` 可用,含其 Web/agent
|
|
15
|
+
- **已安装 DSH host**(`dsh` 可用,含其 Web/agent 运行时;**@deepseek-ai/dsh ≥ 0.1.5**,最低支持版本)。本插件不改 DSH 源码,只往 DSH 的 preset roster 写入编排预设、并把「庖丁配置」面板挂进 Web 左侧栏,因此先要有可用的 DSH 家目录。
|
|
16
16
|
- **路径事实**(生成管线内建常量,写死前先了解它们):
|
|
17
17
|
|
|
18
18
|
| 项 | 默认值 | 说明 |
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
- **环境变量**:`DSH_HOME` 覆盖 DSH 家目录(默认 `~/.dsh`);`DSH_PAODING_CONFIG` 覆盖配置文件路径(面板认它;仓库内兜底 CLI 则用 `--config <file>` 指定)。
|
|
26
26
|
|
|
27
|
-
仓库内 `presets/orchestrator/` 是静态预设源(生成管线读取并重写 `agent.cordis.yml
|
|
27
|
+
仓库内 `presets/orchestrator/` 是静态预设源(生成管线读取并重写 `agent.cordis.yml`;`preset.yml`、`restrict.mjs` 原样复制——唯一例外是配置了 `main_agent_display_name`(或工作区派生显示名)时会改写 `preset.yml` 的 `name:` 行),`tools/` 是生成器本体(面板与兜底 CLI 共用),`plugins/paoding-config-ui/` 是「庖丁配置」面板插件本体。只想正常使用的话,这些都不用碰——见下一节。
|
|
28
28
|
|
|
29
29
|
## 2. 安装:唯一官方通道
|
|
30
30
|
|
|
@@ -41,7 +41,7 @@ dsh plugin --profile web add dsh-paoding
|
|
|
41
41
|
这条命令背后是两步:
|
|
42
42
|
|
|
43
43
|
1. `dsh plugin` 作为 pnpm 透明转发器,把 npm 包 `dsh-paoding` 用 pnpm 装进指定 profile 的 `node_modules`;
|
|
44
|
-
2. 包根声明的 `dsh.bundle.patch`(一份 `cordis.patch.yml`,一行 insert:`id: paoding-config-ui` / `name: dsh-paoding`)由 `reconcilePlugins` 并入该 profile 的启动层,boot 时把「庖丁配置」面板挂进 Web
|
|
44
|
+
2. 包根声明的 `dsh.bundle.patch`(一份 `cordis.patch.yml`,一行 insert:`id: paoding-config-ui` / `name: dsh-paoding`)由 `reconcilePlugins` 并入该 profile 的启动层,boot 时把「庖丁配置」面板挂进 Web 左侧栏底部动作条(设置行上方)。
|
|
45
45
|
|
|
46
46
|
编排预设不用单独装——插件启动时会自动补上,见下面的首装自动化。
|
|
47
47
|
|
|
@@ -51,13 +51,13 @@ dsh plugin --profile web add dsh-paoding
|
|
|
51
51
|
|
|
52
52
|
### 首装自动化:重启即完整安装
|
|
53
53
|
|
|
54
|
-
插件启动时自动检测编排预设是否就位:`$DSH_HOME/.agent-presets/orchestrator` 目录缺失,或其中的 `.generator-version` 标记与插件包版本不符时,自动执行一次等价 `--auto` 的安装——`~/.dsh/dsh-paoding.config.yml` 已存在就按配置应用;没有就写基础模板(只含 DSH
|
|
54
|
+
插件启动时自动检测编排预设是否就位:`$DSH_HOME/.agent-presets/orchestrator` 目录缺失,或其中的 `.generator-version` 标记与插件包版本不符时,自动执行一次等价 `--auto` 的安装——`~/.dsh/dsh-paoding.config.yml` 已存在就按配置应用;没有就写基础模板(只含 DSH 自带的基础工具,见下)。它走的是与面板「保存并应用」同一条检测/生成管线(`collectState` / `generateAndInstall`)——同一管线,但启动自愈的检测是纯文件扫描、不带运行时检测事实,面板则带;host 上装有 bundle 形态插件时,两者的检测库存可能不同,产物随之略有差异。
|
|
55
55
|
|
|
56
56
|
所以 **`dsh plugin add` + 重启 = 完整安装**:预设生成、配置模板落盘、面板可点,一步到位。自动生成失败不会拖垮插件启动——只在 DSH 日志里记一条告警,可到面板手动「保存并应用」补上。
|
|
57
57
|
|
|
58
58
|
### 版本标记与自动重生成
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
`.generator-version` 标记(内容 = 生成器版本)由插件启动自愈在生成 preset 后写入。面板「保存并应用」与兜底 CLI 的生成走整目录重建、不写回标记——重建即移除旧标记,下次 DSH 启动自愈发现标记缺失会多补跑一次生成并重写标记(产物相同,只是多跑一轮)。版本不符触发重生成的语义不变:插件升级后标记与包版本不符,下次 DSH 启动自动按新版重生成,「升级后 preset 还是旧版产物」的漂移就此消除。标记只在缺失或版本不符时触发重生成,面板不监视配置文件改动;想立刻按当前配置重新生成,点面板「保存并应用」。
|
|
61
61
|
|
|
62
62
|
### 基础模板与工具勾选
|
|
63
63
|
|
|
@@ -71,7 +71,7 @@ dsh plugin --profile web add dsh-paoding
|
|
|
71
71
|
2. 在**新会话的预设选择器**里选「**编排模式 (Orchestrator)**」。
|
|
72
72
|
3. 想让它成为每次新会话的默认预设:**Settings → Agent Presets** 里设置默认。
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
**手编配置后怎么应用**:打开左侧栏底部动作条(设置行上方)的「庖丁配置」入口——面板会把手编后的配置文件加载为当前值——然后点「**保存并应用**」。这是纯插件用户唯一的应用触发;版本标记只在新版时自动重生成,面板不会盯着配置文件的变化。
|
|
75
75
|
|
|
76
76
|
## 3. 升级
|
|
77
77
|
|
|
@@ -85,7 +85,7 @@ dsh plugin --profile <name> update dsh-paoding
|
|
|
85
85
|
|
|
86
86
|
手动升级等价:直接在终端跑上面这条 `dsh plugin update` 命令,同样重启生效。
|
|
87
87
|
|
|
88
|
-
**开发 link 形态**(见第 4
|
|
88
|
+
**开发 link 形态**(见第 4 节)版本比较照常(更新卡有新版照常提示),但无法就地升级——升级器要求包真实装在某个 profile 的 node_modules 下,link 直连仓库匹配不到;点「升级」会如实报这一点,并提示手动跑 `dsh plugin add dsh-paoding@latest` 切回 registry 版。
|
|
89
89
|
|
|
90
90
|
检测失败(断网、限流)时静默跳过,不影响任何使用。
|
|
91
91
|
|
|
@@ -101,7 +101,7 @@ dsh plugin --profile web add link:"$PWD"
|
|
|
101
101
|
|
|
102
102
|
包直接落在仓库目录上,改动经 HMR 或重启生效,无需反复重装。此形态无法就地升级(见第 3 节);想切回 registry 版,`dsh plugin --profile web add dsh-paoding@latest` 即可。
|
|
103
103
|
|
|
104
|
-
**仓库内兜底 CLI**(不宣传,仅限克隆了仓库的开发者):`node tools/install.mjs --auto`(有配置应用配置,没有写基础模板)、`--dry-run`(只打印检测报告与将生成的 allow,不写盘)、`--config <file
|
|
104
|
+
**仓库内兜底 CLI**(不宣传,仅限克隆了仓库的开发者):`node tools/install.mjs --auto`(有配置应用配置,没有写基础模板)、`--dry-run`(只打印检测报告与将生成的 allow,不写盘)、`--config <file>`(指定配置文件)、`--suggest`(fresh 安装无配置时按智能默认分配 host 工具;默认基础模板不写 host 工具)、`--profile <name>`(指定扫描哪个 profile 的 patch 层,默认 `web`)。不带 `--auto`(且非只读的 `--dry-run`)会被拒绝并提示——交互式安装已移除,可视化配置一律走插件通道自带的 Web 面板。
|
|
105
105
|
|
|
106
106
|
## 5. host patch 检测机制
|
|
107
107
|
|
|
@@ -120,14 +120,14 @@ dsh plugin --profile web add link:"$PWD"
|
|
|
120
120
|
### MCP 与本地插件的检测
|
|
121
121
|
|
|
122
122
|
- **启用判定**:patch 条目未被禁用(`enabled !== false` 且无 `disabled`)即视为启用;插件另查 `config.enabled`。
|
|
123
|
-
- **MCP
|
|
124
|
-
- **精确工具名解析**(`toolFilter.allow` 是精确名匹配、不支持 glob
|
|
123
|
+
- **MCP 服务器识别**:条目名的包名段**精确等于** `dsh-mcp-client`(scoped/子路径形式按 `/` 取末段比对,`not-dsh-mcp-client-foo` 这类不会误判),或配置含 `serverName` 且 transport 为 `stdio` / `streamable-http` / `sse`(或有 `command`)。
|
|
124
|
+
- **精确工具名解析**(`toolFilter.allow` 是精确名匹配、不支持 glob,名字必须拼全):检测顺序是**所有 `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,不丢工具;未知服务器握手失败才整服务器跳过。
|
|
125
125
|
- **本地工具插件**:按白名单匹配 patch 条目名并登记其工具,如 `magic-memory` → `memory_search`(新增插件需扩展白名单,见 `tools/lib/host.mjs` 的 `KNOWN_HOST_PLUGINS`)。
|
|
126
|
-
-
|
|
126
|
+
- **跳过不报错**:「握手失败、超时、`sse` 等不支持实时发现的服务器被跳过」只适用于**未知服务器**——整服务器跳过,对应角色只是缺这些工具,生成不报错(报告里会标注 `handshake failed` 及原因,URL/密钥会被打码);已知服务器握手失败回落静态表、工具保留,不在此列。
|
|
127
127
|
|
|
128
128
|
### allow 重写规则
|
|
129
129
|
|
|
130
|
-
对每个被重写的角色:allow 里的名字按**白名单**对账,必须落在 **preset 自带工具面**(`restrict.mjs` 主 agent 白名单 ∪ 源 preset 各角色静态 allow)或**检测库存**之一,两头都不占的名字(插件停用后残留的 `mnemon_
|
|
130
|
+
对每个被重写的角色:allow 里的名字按**白名单**对账,必须落在 **preset 自带工具面**(`restrict.mjs` 主 agent 白名单 ∪ 源 preset 各角色静态 allow)或**检测库存**之一,两头都不占的名字(插件停用后残留的 `mnemon_*`、拼写错误等)一律剔除,「预览生成」/兜底 CLI 报告的 removed 列表会给出原因。其中 **host 依赖名**(`mcp__*` 与已知插件工具)即便写在源 preset 里,也必须真实检测到才保留;`mnemon_*` 这类插件直注册、无 `mcp__` 前缀的工具同样按检测库存对账;standard 组合保证的核心工具(read/write/edit/glob/grep/bash/skill/web_search 等)本就在 preset 自带面内,不依赖检测直接保留。结果 = 配置意图 ∩ 实际启用工具:停用的 host 工具名自动剔除,保证 `tools.restrict()` 永不报 unknown tools。主 agent 侧同理:`restrict.mjs` 的 base allow 里 host 依赖名按检测结果过滤,`main_agent_extra` 追加的 host 工具与自定义角色 toolName 注入 `config.allow`,`main_agent_remove` 剔除(移除结果为空列表会**拒绝安装**,防止运行时空 allow 拒载)。静态 preset 中不由生成器重写的其它委派行(如 `search_internal_deep`)原样保留。
|
|
131
131
|
|
|
132
132
|
**重新应用的时机**:改动了 patch 配置(启用/停用 MCP 服务器或插件、增删额外 patch 文件)后,到「庖丁配置」点一次「保存并应用」同步 allow——想先看将发生的剔除清单,点「预览生成」,或用兜底 CLI 的 `--dry-run`。兜底 CLI 还会比较 patch 文件与上次生成结果的时间戳,发现 patch 更新过会打印提醒。
|
|
133
133
|
|
|
@@ -141,26 +141,26 @@ patch 与配置文件用 **`yaml` 包**解析——通过 `createRequire` 从 `$
|
|
|
141
141
|
|
|
142
142
|
例 2——插件停用:停用 magic-memory 后重新应用一次,各角色 allow 中的 `memory_search` 自动剔除;此后想恢复就重新启用插件再应用。
|
|
143
143
|
|
|
144
|
-
例 3——额外的 patch
|
|
144
|
+
例 3——额外的 patch 文件(仅限兜底 CLI,克隆仓库的开发者):把额外的 MCP/插件配置放独立文件,检测时用 `--patch <file>` 一并纳入(不必动 home/profile 层文件);面板检测只读 home/profile 两层,无对应入口。
|
|
145
145
|
|
|
146
146
|
## 6. 庖丁配置面板
|
|
147
147
|
|
|
148
|
-
不想手编 `dsh-paoding.config.yml`
|
|
148
|
+
不想手编 `dsh-paoding.config.yml` 的话,点开左侧栏底部动作条(设置行上方)的**「庖丁配置」**入口进入整页配置。它与首装自动化、兜底 CLI 共用同一条检测/生成管线(`collectState` / `generateAndInstall`),所见即所得;面板随插件通道自带,装好插件就有,无需另外挂载。
|
|
149
149
|
|
|
150
150
|
### 加载机制
|
|
151
151
|
|
|
152
152
|
- cordis 经 profile 目录的 `node_modules` 解析 patch 行里的包名 `dsh-paoding`;
|
|
153
153
|
- DSH 的 client-modules 节点半扫描该包 `package.json` 的 `dsh.client` 声明与 `exports["./client"]`,把 `lib/client.js` 编入浏览器的 `__DSH_BOOT__`(以 `/plugins/paoding-config-ui/client.js` 下发);
|
|
154
154
|
- 浏览器内核为清单里的每个插件创建 loader 条目并激活(bundle 以 `window.__ModuleLoader__.load({ id: "paoding-config-ui", factory })` 注册,id 等于 patch 行的 id);
|
|
155
|
-
- 客户端 `apply()`
|
|
155
|
+
- 客户端 `apply()` 把「庖丁配置」入口经宿主 `sidebar.footer.action` 键控槽注册(`slots.register`,与插件广场 cordis 徽章同槽位,渲染在设置行上方的动作条里),不自行 DOM 注入侧栏;MutationObserver 仅用于工作区「…」菜单桥接(认出菜单 DOM、注入「庖丁配置」深链入口)。点击后容器(`data-dsh-paoding-view`)挂进会话中栏、`createRoot` 渲染整页配置页,打开态由 `html[data-dsh-paoding-active]` 驱动,与记忆系统 / taskboard / ssh 等全页面板互斥。
|
|
156
156
|
|
|
157
157
|
### 数据接口与安全
|
|
158
158
|
|
|
159
|
-
面板数据走**同源 `/api/paoding/*`**:Node 侧注册前缀路由——`GET /api/paoding/state`(带缓存的检测状态)、`POST /api/paoding/rescan`(强制重检测,含 MCP 握手)、`POST /api/paoding/preview`(不写盘生成)、`POST /api/paoding/apply`(安装并保存配置)、`POST /api/paoding/upgrade`(就地 `dsh plugin update
|
|
159
|
+
面板数据走**同源 `/api/paoding/*`**:Node 侧注册前缀路由——`GET /api/paoding/state`(带缓存的检测状态)、`GET /api/paoding/version`(最新版检测,版本/更新卡的数据源)、`GET /api/paoding/models`(宿主模型运行时的模型清单)、`GET` + `POST /api/paoding/workspaces`(工作区列表 / 添加工作区)、`POST /api/paoding/rescan`(强制重检测,含 MCP 握手)、`POST /api/paoding/preview`(不写盘生成)、`POST /api/paoding/apply`(安装并保存配置)、`POST /api/paoding/upgrade`(就地 `dsh plugin update`)、`GET /api/paoding/client.css`(面板样式静态下发)——复用 `tools/` 的检测与生成管线(`plugins/paoding-config-ui/api-core.mjs`)。路由自带**浏览器信任围栏**:Host 必须回环或落在 `webRuntime.trustedHosts`,并拒绝 cross-site 请求(复刻 DSH `/api` 网关围栏语义,因为 `/api/paoding` 前缀更长会命中本插件而绕开网关)。面板**没有独立服务端/端口**:DSH Web 端口只监听 `127.0.0.1`,不对外网暴露。
|
|
160
160
|
|
|
161
161
|
### 面板能力
|
|
162
162
|
|
|
163
|
-
-
|
|
163
|
+
- **状态与操作**:页头是标题 + 版本/更新卡(新版就地提示与一键升级)+ 副标题,正文直接就是工作区与角色卡,没有单独的检测摘要与 chips 区;操作按钮「**保存并应用**」「预览生成」「重新检测」固定在面板底部悬浮操作坞(sticky bottom),滚动任意位置都可直接点击。
|
|
164
164
|
- **Agent 工具分配卡片**:主 agent 一张固定卡(基础工具取消勾选 = 加入 `main_agent_remove` 从主 agent 剔除;MCP / 插件工具勾选 = 加入 `main_agent_extra`;技能「read 按需」与「内联全文」两组勾选;另有「人设追加」编辑区,可改、清空、恢复默认)+ `search_external` / `design` / `implement` 三张内置角色卡 + 任意自定义角色卡(带删除按钮);每张角色卡把工具按「基础工具 / MCP 工具 / 插件工具」三组呈现、可逐项勾选,并可编辑 persona。底部「新建自定义 agent 角色」。
|
|
165
165
|
- **技能分配**:每个 skill 一行,勾选分配给哪些 agent(写入对应 persona 的 `Available skills` 软引导;角色技能软引导,主 agent 技能另有 read 按需/内联两组)。
|
|
166
166
|
- **预览生成**:不写盘生成 `agent.cordis.yml`,显示每个角色 allow 的 intent → kept 计数与生成全文。
|
|
@@ -168,14 +168,15 @@ patch 与配置文件用 **`yaml` 包**解析——通过 `createRequire` 从 `$
|
|
|
168
168
|
|
|
169
169
|
## 7. 卸载
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
三条命令,删得干干净净:
|
|
172
172
|
|
|
173
173
|
```bash
|
|
174
174
|
dsh plugin --profile web remove dsh-paoding
|
|
175
175
|
rm -rf "${DSH_HOME:-$HOME/.dsh}/.agent-presets/orchestrator"
|
|
176
|
+
rm -rf "${DSH_HOME:-$HOME/.dsh}/.agent-presets"/orchestrator-*
|
|
176
177
|
```
|
|
177
178
|
|
|
178
|
-
第一条摘掉插件与侧栏面板(只影响指定 profile
|
|
179
|
+
第一条摘掉插件与侧栏面板(只影响指定 profile),第二条删掉编排预设目录,第三条清掉按工作区配置时生成的各工作区预设目录(`orchestrator-<目录名>`;没用过按工作区配置就没有这类目录,通配不命中、无害)——基础 `orchestrator` 目录已由上一条命令删掉,不含在这个通配里。配置文件 `~/.dsh/dsh-paoding.config.yml` 不随之上删——留着或删掉都不影响 DSH 其它配置,重装时首装自动化会再次按它应用。
|
|
179
180
|
|
|
180
181
|
卸载不影响 host 的其它内容(MCP、插件、会话等),与 DSH 源码零耦合;之后新建会话时「编排模式 (Orchestrator)」不再出现在预设选择器里。
|
|
181
182
|
|
|
@@ -199,19 +200,19 @@ allow 名单里出现了子 agent 注册面上不存在的名字——最常见
|
|
|
199
200
|
|
|
200
201
|
**角色里少了某个 MCP 工具**
|
|
201
202
|
|
|
202
|
-
|
|
203
|
+
检测时所有 stdio / streamable-http 服务器都先实时握手:未知服务器握手失败会被整服务器跳过(报告标注 `handshake failed`),对应角色只是缺这些工具,生成不报错;已知服务器(tavily、codegraph)握手失败会回落静态表、工具保留,报告标注 static table——看到该标注说明检测时连不上该服务器、表里的工具面可能过时。检查该服务器能否独立启动/连通后重新应用。
|
|
203
204
|
|
|
204
205
|
**技能没写进 persona**
|
|
205
206
|
|
|
206
|
-
|
|
207
|
+
技能可以分给任意角色——生成层会为每个被分配的角色在 persona 里追加 `Available skills:` 软引导行;但角色要真正加载技能,得自备 `skill` / `read` 工具(没带 `skill` 工具的角色分了技能,也只是一行引导,不会实际装载)。主 agent 技能走 `main_agent_skills`(软行)或 `main_agent_skills_inline`(内联)。找不到 SKILL.md(按配置对象对应口径查找:全局只查用户级两根,工作区另查该工作区目录的项目级根,见配置指南第 9 节)会被警告并跳过——确认 skill 已装在对应根目录之一。
|
|
207
208
|
|
|
208
209
|
**手编了配置文件,怎么让它生效**
|
|
209
210
|
|
|
210
|
-
|
|
211
|
+
打开左侧栏底部动作条(设置行上方)的「庖丁配置」入口(面板会把手编后的配置文件作为当前值加载),点「保存并应用」。面板不监视配置文件改动,手编不会自动生效;版本标记也只在新版时才触发自动重生成。
|
|
211
212
|
|
|
212
213
|
**配置文件在哪里**
|
|
213
214
|
|
|
214
|
-
面板「保存并应用」写到 `$DSH_HOME/dsh-paoding.config.yml`(默认 `~/.dsh/dsh-paoding.config.yml`,可用环境变量 `DSH_PAODING_CONFIG` 改到别处;兜底 CLI 用 `--config <file
|
|
215
|
+
面板「保存并应用」写到 `$DSH_HOME/dsh-paoding.config.yml`(默认 `~/.dsh/dsh-paoding.config.yml`,可用环境变量 `DSH_PAODING_CONFIG` 改到别处;兜底 CLI 用 `--config <file>`)。想重置全部选择:删除该文件后重启 DSH,首装自动化按无配置处理、写回基础模板。
|
|
215
216
|
|
|
216
217
|
**旧版 npx/npm 安装的残留怎么清理**
|
|
217
218
|
|
package/docs/installation_en.md
CHANGED
|
@@ -12,7 +12,7 @@ Check the following before installing:
|
|
|
12
12
|
|
|
13
13
|
- **Node.js ≥ 18**. The DSH host and the plugin chain both run on Node; with an older version `dsh` won't start in the first place. Check with `node --version`.
|
|
14
14
|
- **pnpm available**. `dsh plugin` is a transparent pass-through to pnpm: installing a plugin package into a profile is done by pnpm. If pnpm is missing the install command fails with a pnpm error — install pnpm (`npm i -g pnpm` or `corepack enable`) and retry.
|
|
15
|
-
- **A working DSH host** (the `dsh` command, including its Web/agent runtime). This plugin does not modify DSH source code; it only writes the orchestrator preset into DSH's preset roster and mounts the Paoding Config page into the Web sidebar, so a usable DSH home directory must exist first.
|
|
15
|
+
- **A working DSH host** (the `dsh` command, including its Web/agent runtime; **@deepseek-ai/dsh ≥ 0.1.5**, the minimum supported version). This plugin does not modify DSH source code; it only writes the orchestrator preset into DSH's preset roster and mounts the Paoding Config page into the Web sidebar, so a usable DSH home directory must exist first.
|
|
16
16
|
- **Path facts** (constants built into the generation pipeline; know them before customizing):
|
|
17
17
|
|
|
18
18
|
| Item | Default | Description |
|
|
@@ -24,7 +24,7 @@ Check the following before installing:
|
|
|
24
24
|
|
|
25
25
|
- **Environment variables**: `DSH_HOME` overrides the DSH home directory (default `~/.dsh`); `DSH_PAODING_CONFIG` overrides the config-file path (honored by the panel; the in-repo fallback CLI uses `--config <file>` instead).
|
|
26
26
|
|
|
27
|
-
Inside the repository, `presets/orchestrator/` is the static preset source (the pipeline reads and rewrites `agent.cordis.yml
|
|
27
|
+
Inside the repository, `presets/orchestrator/` is the static preset source (the pipeline reads and rewrites `agent.cordis.yml`; `preset.yml` and `restrict.mjs` are copied as-is — the one exception: when `main_agent_display_name` (or a workspace-derived display name) is configured, the `name:` line of `preset.yml` is rewritten), `tools/` is the generator itself (shared by the panel and the fallback CLI), and `plugins/paoding-config-ui/` is the Paoding Config panel plugin. For plain usage you never need to touch any of these — see the next section.
|
|
28
28
|
|
|
29
29
|
## 2. Install: the single official channel
|
|
30
30
|
|
|
@@ -41,7 +41,7 @@ After installing, **restart DSH (`dsh web`)** and you're done — no further ins
|
|
|
41
41
|
Behind the scenes the command does two things:
|
|
42
42
|
|
|
43
43
|
1. `dsh plugin`, a transparent pass-through to pnpm, installs the npm package `dsh-paoding` into the given profile's `node_modules`;
|
|
44
|
-
2. the `dsh.bundle.patch` declared at the package root (a `cordis.patch.yml` with a single insert: `id: paoding-config-ui` / `name: dsh-paoding`) is merged by `reconcilePlugins` into that profile's startup layer, and at boot the Paoding Config page is mounted into the Web
|
|
44
|
+
2. the `dsh.bundle.patch` declared at the package root (a `cordis.patch.yml` with a single insert: `id: paoding-config-ui` / `name: dsh-paoding`) is merged by `reconcilePlugins` into that profile's startup layer, and at boot the Paoding Config page is mounted into the Web sidebar's bottom action bar (above the Settings row).
|
|
45
45
|
|
|
46
46
|
The orchestrator preset needs no separate install — the plugin fills it in automatically at startup; see first-install automation below.
|
|
47
47
|
|
|
@@ -51,13 +51,13 @@ The orchestrator preset needs no separate install — the plugin fills it in aut
|
|
|
51
51
|
|
|
52
52
|
### First-install automation: restart = full install
|
|
53
53
|
|
|
54
|
-
At startup the plugin checks whether the orchestrator preset is in place: if the `$DSH_HOME/.agent-presets/orchestrator` directory is missing, or its `.generator-version` marker does not match the plugin package version, it automatically performs one install equivalent to `--auto` — applying `~/.dsh/dsh-paoding.config.yml` when it exists, writing the base template otherwise (DSH base tools only; see below). It runs the
|
|
54
|
+
At startup the plugin checks whether the orchestrator preset is in place: if the `$DSH_HOME/.agent-presets/orchestrator` directory is missing, or its `.generator-version` marker does not match the plugin package version, it automatically performs one install equivalent to `--auto` — applying `~/.dsh/dsh-paoding.config.yml` when it exists, writing the base template otherwise (DSH base tools only; see below). It runs the same detection/generation pipeline as the panel's Save & Apply (`collectState` / `generateAndInstall`) — the same pipeline, but the startup self-heal detects with a pure file scan and no runtime detection facts while the panel detects with them; when a bundle-form plugin is installed on the host, the two detection inventories may differ, and the outputs differ slightly with them.
|
|
55
55
|
|
|
56
56
|
So **`dsh plugin add` + restart = a complete install**: preset generated, config template on disk, panel ready — all in one step. If the automatic generation fails it never takes the plugin down — a warning is logged, and you can apply manually from the panel.
|
|
57
57
|
|
|
58
58
|
### The version marker and auto-regeneration
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
The `.generator-version` marker (its content = the generator version) is written by the plugin's startup self-heal after it generates the preset. The panel's Save & Apply (and the fallback CLI) do a full-directory rebuild and write no marker — the rebuild removes the old marker, so the next DSH start's self-heal finds it missing, runs one extra generation, and rewrites the marker (same output, just one extra round). The version-mismatch trigger is unchanged: after a plugin upgrade the marker no longer matches the package version, so the next DSH start regenerates the preset against the new version — the "upgraded the plugin but the preset is stale" drift is eliminated. The marker triggers regeneration only when missing or version-mismatched, and the panel does not watch the config file; to regenerate from the current config right away, hit Save & Apply.
|
|
61
61
|
|
|
62
62
|
### Base template and tool opt-in
|
|
63
63
|
|
|
@@ -71,7 +71,7 @@ Once installed:
|
|
|
71
71
|
2. Pick「**编排模式 (Orchestrator)**」in the **new-session preset selector**.
|
|
72
72
|
3. To make it the default for every new session: set it in **Settings → Agent Presets**.
|
|
73
73
|
|
|
74
|
-
**Applied a hand-edited config — now what?** Open
|
|
74
|
+
**Applied a hand-edited config — now what?** Open the 庖丁配置 (Paoding Config) entry in the sidebar bottom action bar (above the Settings row) — the panel loads the hand-edited config file as its current values — then hit「**保存并应用**」(Save & Apply). That is the only apply trigger for a pure plugin user; the panel does not watch the config file, and the version marker only triggers auto-regeneration on new versions.
|
|
75
75
|
|
|
76
76
|
## 3. Upgrading
|
|
77
77
|
|
|
@@ -85,7 +85,7 @@ dsh plugin --profile <name> update dsh-paoding
|
|
|
85
85
|
|
|
86
86
|
Manual equivalent: run the `dsh plugin update` command above yourself, restart, done.
|
|
87
87
|
|
|
88
|
-
A **dev link: checkout** (see §4)
|
|
88
|
+
A **dev link: checkout** (see §4) still gets version checks (the update card appears when a newer version exists) but cannot be upgraded in place — the upgrader requires the package to really live under a profile's node_modules, which a link straight into the repo never matches. Hitting Upgrade reports exactly that and suggests running `dsh plugin add dsh-paoding@latest` to switch back to the registry version.
|
|
89
89
|
|
|
90
90
|
If the check fails (offline, rate-limited), it stays silent and nothing is interrupted.
|
|
91
91
|
|
|
@@ -101,7 +101,7 @@ dsh plugin --profile web add link:"$PWD"
|
|
|
101
101
|
|
|
102
102
|
The package sits directly on the repository directory; changes go live via HMR or a restart, with no reinstalls. This form cannot be upgraded in place (see §3); to switch back to the registry version, run `dsh plugin --profile web add dsh-paoding@latest`.
|
|
103
103
|
|
|
104
|
-
An **in-repo fallback CLI** also exists (not advertised; for developers who cloned the repo): `node tools/install.mjs --auto` (apply the config if present, else write the base template), `--dry-run` (print the detection report and the would-be allow lists without writing anything), `--config <file>` (select a config file). Without `--auto` (and without the read-only `--dry-run`) it refuses to run — interactive install has been removed; visual configuration belongs to the Web panel that ships with the plugin channel.
|
|
104
|
+
An **in-repo fallback CLI** also exists (not advertised; for developers who cloned the repo): `node tools/install.mjs --auto` (apply the config if present, else write the base template), `--dry-run` (print the detection report and the would-be allow lists without writing anything), `--config <file>` (select a config file), `--suggest` (on a fresh install without a config file, seed smart defaults that assign host tools; the default base template leaves host tools out), `--profile <name>` (which profile's patch layer to scan, default `web`). Without `--auto` (and without the read-only `--dry-run`) it refuses to run — interactive install has been removed; visual configuration belongs to the Web panel that ships with the plugin channel.
|
|
105
105
|
|
|
106
106
|
## 5. Host patch detection
|
|
107
107
|
|
|
@@ -120,14 +120,14 @@ All layers are **included** (detection unions the enabled entries across layers)
|
|
|
120
120
|
### MCP servers and local tool plugins
|
|
121
121
|
|
|
122
122
|
- **Enabled test**: a patch entry counts as enabled unless disabled (`enabled !== false` and no `disabled`); plugins additionally check `config.enabled`.
|
|
123
|
-
- **MCP server recognition**: the entry name
|
|
124
|
-
- **Exact tool-name resolution** (`toolFilter.allow` matches exact names, no globs — names must be spelled out):
|
|
123
|
+
- **MCP server recognition**: the entry's package-name segment **exactly equals** `dsh-mcp-client` (scoped/sub-path forms compare the last `/` segment; a name like `not-dsh-mcp-client-foo` does not match), or the config carries a `serverName` with transport `stdio` / `streamable-http` / `sse` (or has a `command`).
|
|
124
|
+
- **Exact tool-name resolution** (`toolFilter.allow` matches exact names, no globs — names must be spelled out): the detection order is that **every `stdio` / `streamable-http` server gets a live JSON-RPC handshake first** (stdio spawns the process and sends `initialize` + `tools/list`; streamable-http POSTs; **15-second timeout**), and the returned tools become `mcp__<server>__<tool>` names; the static known table (`tavily` → 5 tools `tavily_search` / `tavily_crawl` / `tavily_extract` / `tavily_map` / `tavily_research`, `codegraph` → `codegraph_explore`) is only the degraded fallback when a **known** server's handshake fails — tools are kept per the table, the report flags a static table, and no tools are lost; only an unknown server that fails the handshake is skipped entirely.
|
|
125
125
|
- **Local tool plugins**: matched against a whitelist of patch entry names, registering their tools, e.g. `magic-memory` → `memory_search` (new plugins extend the whitelist — `KNOWN_HOST_PLUGINS` in `tools/lib/host.mjs`).
|
|
126
|
-
- **Skipped, not fatal**: servers whose handshake fails, times out, or uses
|
|
126
|
+
- **Skipped, not fatal**: "servers whose handshake fails, times out, or uses a transport without live discovery (`sse`) are skipped" applies to **unknown servers** only — such a server is skipped entirely, the role simply lacks those tools, and generation raises no error (the report flags `handshake failed` with the reason; URLs and keys are masked); known servers fall back to the static table on a failed handshake and keep their tools, so they never land here.
|
|
127
127
|
|
|
128
128
|
### Allow-rewrite rules
|
|
129
129
|
|
|
130
|
-
For each rewritten role, every allow name is checked against a **whitelist**: it must belong to the **preset's own tool face** (the `restrict.mjs` main-agent allow ∪ the static role allows in the source preset) or to the **detection inventory**; a name in neither (a `mnemon_*` left over from a disabled plugin, a typo) is dropped, and the removed list in the Preview
|
|
130
|
+
For each rewritten role, every allow name is checked against a **whitelist**: it must belong to the **preset's own tool face** (the `restrict.mjs` main-agent allow ∪ the static role allows in the source preset) or to the **detection inventory**; a name in neither (a `mnemon_*` left over from a disabled plugin, a typo) is dropped, and the removed list in the Preview (or fallback CLI) report says why. Within that, names that **depend on the host** (`mcp__*` and known plugin tools) survive only when actually detected, even when they are part of the source preset; plugin tools registered directly under their own names (such as `mnemon_*`, no `mcp__` prefix) are reconciled against the detection inventory the same way; the **base tools guaranteed by the standard composition** (read/write/edit/glob/grep/bash/skill/web_search etc.) are already part of the preset face and pass without detection. The result = configured intent ∩ actually enabled tools: disabled host tools drop out automatically, so `tools.restrict()` never hits unknown tools. The main-agent side works the same way: host-dependent names in `restrict.mjs`'s base allow are filtered by detection, host tools added via `main_agent_extra` and custom-role toolNames are injected into `config.allow`, and `main_agent_remove` removes entries (an empty removal result is **rejected**, guarding against an empty runtime allow that would refuse to load). Delegation rows the generator does not rewrite (e.g. `search_internal_deep`) are kept as-is.
|
|
131
131
|
|
|
132
132
|
**When to re-apply**: after changing patch configuration (enabling/disabling MCP servers or plugins, adding/removing extra patch files), hit Save & Apply once in 庖丁配置 to sync the allows — to preview what would be dropped first, use Preview, or the fallback CLI's `--dry-run`. The fallback CLI also compares patch-file timestamps against the last generation and prints a reminder when a patch has changed since.
|
|
133
133
|
|
|
@@ -141,26 +141,26 @@ Example 1 — disabling tavily: after commenting out tavily's mount rows in `$DS
|
|
|
141
141
|
|
|
142
142
|
Example 2 — disabling a plugin: disable magic-memory and re-apply; `memory_search` drops out of every role allow automatically. To restore, re-enable the plugin and re-apply.
|
|
143
143
|
|
|
144
|
-
Example 3 — extra patch files: put extra MCP/plugin config in a separate file and include it at detection time with
|
|
144
|
+
Example 3 — extra patch files (fallback CLI only, for developers who cloned the repo): put extra MCP/plugin config in a separate file and include it at detection time with `--patch <file>` (no need to touch the home/profile layer files); panel detection reads only the home/profile layers and has no equivalent entry.
|
|
145
145
|
|
|
146
146
|
## 6. The Paoding Config panel
|
|
147
147
|
|
|
148
|
-
If you'd rather not hand-edit `dsh-paoding.config.yml`, open the **庖丁配置 (Paoding Config)** entry
|
|
148
|
+
If you'd rather not hand-edit `dsh-paoding.config.yml`, open the **庖丁配置 (Paoding Config)** entry in the sidebar bottom action bar (above the Settings row). It shares the exact same detection/generation pipeline (`collectState` / `generateAndInstall`) as the first-install automation and the fallback CLI — what you see is what gets written; the panel ships with the plugin channel, so installing the plugin is all it takes.
|
|
149
149
|
|
|
150
150
|
### Loading mechanism
|
|
151
151
|
|
|
152
152
|
- cordis resolves the package name `dsh-paoding` from the patch row against the profile's `node_modules`;
|
|
153
153
|
- DSH's client-modules node half-scan reads the package's `dsh.client` declaration and `exports["./client"]`, compiling `lib/client.js` into the browser's `__DSH_BOOT__` (served as `/plugins/paoding-config-ui/client.js`);
|
|
154
154
|
- the browser core creates and activates a loader entry for every plugin in the manifest (the bundle registers as `window.__ModuleLoader__.load({ id: "paoding-config-ui", factory })`; the id equals the patch row's id);
|
|
155
|
-
- the client `apply()`
|
|
155
|
+
- the client `apply()` registers the 庖丁配置 entry through the host's `sidebar.footer.action` keyed slot (`slots.register`, the same slot as the plugin-hub cordis badge, rendered in the action bar above the Settings row) rather than injecting sidebar DOM itself; the MutationObserver is only used to bridge the workspace "…" menu (recognizing the menu DOM and adding a 庖丁-config deep-link item). Clicking mounts the container (`data-dsh-paoding-view`) into the session's middle column and renders the full-page configurator with `createRoot`, the open state driven by `html[data-dsh-paoding-active]`, mutually exclusive with the memory / taskboard / ssh full-page panels.
|
|
156
156
|
|
|
157
157
|
### Data interface and security
|
|
158
158
|
|
|
159
|
-
Panel data goes over the **same-origin `/api/paoding/*`**: the Node side registers prefix routes — `GET /api/paoding/state` (cached detection state), `POST /api/paoding/rescan` (forced re-detection, MCP handshakes included), `POST /api/paoding/preview` (generate without writing), `POST /api/paoding/apply` (install and save config), `POST /api/paoding/upgrade` (in-place `dsh plugin update`) — reusing the detection/generation pipeline in `tools/` (`plugins/paoding-config-ui/api-core.mjs`). The routes carry a **browser trust fence**: the Host must be loopback or listed in `webRuntime.trustedHosts`, and cross-site requests are rejected (mirroring DSH's `/api` gateway fence semantics, since the longer `/api/paoding` prefix would otherwise hit this plugin and bypass the gateway). The panel has **no separate server or port**: the DSH Web port listens on `127.0.0.1` only and is never exposed to the outside.
|
|
159
|
+
Panel data goes over the **same-origin `/api/paoding/*`**: the Node side registers prefix routes — `GET /api/paoding/state` (cached detection state), `GET /api/paoding/version` (latest-version check, the data source of the version/update card), `GET /api/paoding/models` (model list from the host LLM runtime), `GET` + `POST /api/paoding/workspaces` (list / add workspaces), `POST /api/paoding/rescan` (forced re-detection, MCP handshakes included), `POST /api/paoding/preview` (generate without writing), `POST /api/paoding/apply` (install and save config), `POST /api/paoding/upgrade` (in-place `dsh plugin update`), `GET /api/paoding/client.css` (statically served panel stylesheet) — reusing the detection/generation pipeline in `tools/` (`plugins/paoding-config-ui/api-core.mjs`). The routes carry a **browser trust fence**: the Host must be loopback or listed in `webRuntime.trustedHosts`, and cross-site requests are rejected (mirroring DSH's `/api` gateway fence semantics, since the longer `/api/paoding` prefix would otherwise hit this plugin and bypass the gateway). The panel has **no separate server or port**: the DSH Web port listens on `127.0.0.1` only and is never exposed to the outside.
|
|
160
160
|
|
|
161
161
|
### Panel capabilities
|
|
162
162
|
|
|
163
|
-
- **State and actions**: a
|
|
163
|
+
- **State and actions**: the page header is a title + version/update card (in-place new-version notice and one-click upgrade) + subtitle, and the body goes straight to the workspace and role cards with no separate detection-summary/chips section; the action buttons「**保存并应用**」(Save & Apply), Preview, and Rescan sit in a sticky bottom dock, clickable from any scroll position.
|
|
164
164
|
- **Agent tool-assignment cards**: one fixed card for the main agent (unchecking a base tool adds it to `main_agent_remove`, dropping it from the main agent; checking an MCP / plugin tool adds it to `main_agent_extra`; skills in two groups, "read on demand" and "inline full text"; plus a "persona extra" editor — edit, clear, or restore the default) + three built-in role cards (`search_external` / `design` / `implement`) + any number of custom role cards (with a delete button); every role card presents its tools in three groups — base / MCP / plugin — with per-item checkboxes, and the persona is editable. "Create a custom agent role" at the bottom.
|
|
165
165
|
- **Skill assignment**: one row per skill, check which agents it goes to (written into the matching personas as `Available skills` soft guidance; role skills are soft guidance, main-agent skills have the read-on-demand/inline groups).
|
|
166
166
|
- **Preview**: generates `agent.cordis.yml` without writing, showing each role's intent → kept counts plus the full generated text.
|
|
@@ -168,14 +168,15 @@ Panel data goes over the **same-origin `/api/paoding/*`**: the Node side registe
|
|
|
168
168
|
|
|
169
169
|
## 7. Uninstalling
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
Three commands, and it's gone cleanly:
|
|
172
172
|
|
|
173
173
|
```bash
|
|
174
174
|
dsh plugin --profile web remove dsh-paoding
|
|
175
175
|
rm -rf "${DSH_HOME:-$HOME/.dsh}/.agent-presets/orchestrator"
|
|
176
|
+
rm -rf "${DSH_HOME:-$HOME/.dsh}/.agent-presets"/orchestrator-*
|
|
176
177
|
```
|
|
177
178
|
|
|
178
|
-
The first removes the plugin and the sidebar panel (scoped to the given profile), the second deletes the orchestrator preset directory. The config file `~/.dsh/dsh-paoding.config.yml` is not removed with them — keep it or delete it, it does not affect any other DSH configuration, and a reinstall's first-install automation would apply it again.
|
|
179
|
+
The first removes the plugin and the sidebar panel (scoped to the given profile), the second deletes the orchestrator preset directory, and the third removes the per-workspace preset directories (`orchestrator-<basename>`) created when you configured individual workspaces (if you never did, the glob matches nothing and it's harmless) — the base `orchestrator` directory is already gone with the previous command and is not covered by that glob. The config file `~/.dsh/dsh-paoding.config.yml` is not removed with them — keep it or delete it, it does not affect any other DSH configuration, and a reinstall's first-install automation would apply it again.
|
|
179
180
|
|
|
180
181
|
Uninstalling touches nothing else on the host (MCP, plugins, sessions), and stays decoupled from DSH source code; "编排模式 (Orchestrator)" disappears from the preset selector for new sessions.
|
|
181
182
|
|
|
@@ -199,19 +200,19 @@ First confirm the plugin is installed into the profile your DSH actually runs wi
|
|
|
199
200
|
|
|
200
201
|
**An MCP tool is missing from a role**
|
|
201
202
|
|
|
202
|
-
|
|
203
|
+
At detection every stdio / streamable-http server gets a live handshake first: an unknown server whose handshake fails is skipped entirely (the report flags `handshake failed`) and the role simply lacks those tools — generation raises no error. Known servers (tavily, codegraph) fall back to the static table when their handshake fails and keep their tools, with the report flagging a static table — seeing that flag means the server was unreachable at detection time and the table's tool face may be stale. Check the server can start/connect on its own, then re-apply.
|
|
203
204
|
|
|
204
205
|
**Skills not written into a persona**
|
|
205
206
|
|
|
206
|
-
|
|
207
|
+
Skills can be assigned to any role — the generation layer appends an `Available skills:` soft-guidance line to each assigned role's persona; but to actually load a skill a role needs `skill` / `read` tools of its own (a role without the `skill` tool only gets the guidance line — nothing loads). Main-agent skills use `main_agent_skills` (soft rows) or `main_agent_skills_inline` (inline). A skill whose SKILL.md cannot be found (looked up per the configuration target: global scans the two user roots only, workspaces add the project-level roots — configuration guide §9) is warned about and skipped — make sure the skill is installed under one of the matching roots.
|
|
207
208
|
|
|
208
209
|
**I hand-edited the config file — how do I apply it?**
|
|
209
210
|
|
|
210
|
-
Open
|
|
211
|
+
Open the 庖丁配置 (Paoding Config) entry in the sidebar bottom action bar (above the Settings row) — the panel loads the hand-edited file as its current values — and hit Save & Apply. The panel does not watch the config file, so hand edits do not take effect on their own; the version marker likewise only triggers auto-regeneration on new versions.
|
|
211
212
|
|
|
212
213
|
**Where is the config file?**
|
|
213
214
|
|
|
214
|
-
The panel's Save & Apply writes to `$DSH_HOME/dsh-paoding.config.yml` (default `~/.dsh/dsh-paoding.config.yml`; move it with the `DSH_PAODING_CONFIG` environment variable; the fallback CLI uses `--config <file>`)
|
|
215
|
+
The panel's Save & Apply writes to `$DSH_HOME/dsh-paoding.config.yml` (default `~/.dsh/dsh-paoding.config.yml`; move it with the `DSH_PAODING_CONFIG` environment variable; the fallback CLI uses `--config <file>`). To reset every choice: delete the file and restart DSH — first-install automation treats it as "no config" and writes the base template.
|
|
215
216
|
|
|
216
217
|
**Cleaning up leftovers from the old npx/npm installs**
|
|
217
218
|
|
package/docs/orchestration.md
CHANGED
|
@@ -22,19 +22,19 @@ dsh-paoding 把 DSH 从「单体 agent 全量加载工具」改造成「主 agen
|
|
|
22
22
|
| 子 agent 管理 | `send_message` / `list_agents` / `interrupt_agent` |
|
|
23
23
|
| 内部搜索(热路径) | `glob` / `grep` / `read` / `read_image` / `bash` |
|
|
24
24
|
| 协调 | `todo_write` / `ask_user_question` / `get_goal` / `create_goal` / `update_goal` / `exit_plan_mode` / `job_output` / `job_list` / `job_kill` |
|
|
25
|
-
| 主 agent
|
|
25
|
+
| 主 agent 刻意看不到(节选,全文见 `restrict.mjs` 头注释) | `web_search`、`mcp__tavily__*`、`write` / `edit` / `str_replace_editor`、`skill`、`workflow`、`ralph`、`ssh_*`、`mcp__tablepro__*`、`describe_image`、裸 `subagent` / `subagent_fork` |
|
|
26
26
|
|
|
27
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
|
|
|
31
|
-
来自 `presets/orchestrator/agent.cordis.yml` 的 `- id: persona` 行(YAML `
|
|
31
|
+
来自 `presets/orchestrator/agent.cordis.yml` 的 `- id: persona` 行(YAML `prefix: |-` 块标量,内容行缩进 6 空格;v0.3.0 起 persona 配置键为 `prefix`,`text` 是生成器兼容的旧名)。编排与委派的总指引(persona 原文为英文,照录如下):
|
|
32
32
|
|
|
33
33
|
```text
|
|
34
34
|
You are the orchestrator agent powered by the {{model}} model. Your working directory is {{cwd}}.
|
|
35
35
|
|
|
36
36
|
Decompose the task, delegate to role agents, integrate results.
|
|
37
|
-
- Internal file questions (finding code, references, reading files): solve yourself with glob/grep/read
|
|
37
|
+
- Internal file questions (finding code, references, reading files): solve yourself with glob/grep/read (and codegraph if enabled) — never delegate them.
|
|
38
38
|
- External research: delegate to search_external.
|
|
39
39
|
- UI/design work: delegate to design.
|
|
40
40
|
- Code implementation: delegate to implement.
|
|
@@ -44,7 +44,7 @@ Keep your own context lean; integrate only summaries. Use todo_write to plan, an
|
|
|
44
44
|
中文释意:
|
|
45
45
|
|
|
46
46
|
- 主 agent 是编排者:**拆解 → 委派 → 集成**三步循环,而不是自己把活全干完。
|
|
47
|
-
- 「内部文件问题(找代码、查引用、读文件)自己用 glob/grep/read
|
|
47
|
+
- 「内部文件问题(找代码、查引用、读文件)自己用 glob/grep/read(启用 codegraph 时含 codegraph)解决,**绝不委派**」——内部搜索是热路径,委派有往返与冷启动成本,主 agent 自带全套只读工具,直达即可。(注:`codegraph` 属 host MCP 工具,需安装期检测到并经 `main_agent_extra` 显式注入才可用,见上。)
|
|
48
48
|
- 任务纹理决定去向:联网 → `search_external`;UI/设计 → `design`;代码 → `implement`(全仓探索 → `search_internal_deep`)。
|
|
49
49
|
- **保持自己上下文精简**:只集成摘要;用 `todo_write` 规划;`ask_user_question` 只用于用户拥有的选择,可自查的问题不打扰用户。
|
|
50
50
|
- 失败处理 SOP 内联在 persona 里,随会话天然生效、无需额外配置——见下节。
|
|
@@ -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 在生成期消除这类失败:生成器(面板「保存并应用」与兜底 CLI 共用同一管线)读取 host patch 层(home / profile / `--patch`),检测实际启用的 MCP
|
|
64
|
+
本 preset 在生成期消除这类失败:生成器(面板「保存并应用」与兜底 CLI 共用同一管线)读取 host patch 层(home / profile / `--patch`),检测实际启用的 MCP 服务器与本地工具插件,解析出精确工具名(一律先实时 JSON-RPC 握手,已知服务器握手失败才回落静态表兜底),然后把 search_external / design / implement 三个可配角色的 allow 重写为「静态意图 ∩ 实际检测到的工具」——组合保证的基础工具原样保留,未启用/无法解析的 host 工具被剔除。未知服务器握手失败或 transport 不支持才整服务器跳过(已知服务器握手失败回落静态表、工具保留):对应角色只是缺这些工具,应用不报错。宿主停用/启用了 MCP 或插件后,到「庖丁配置」点一次「保存并应用」即可同步 allow(「预览生成」先看清单)。细节见[安装](installation.md)。
|
|
65
65
|
|
|
66
|
-
注意:生成器的 allow 重写只覆盖三个内置角色(`search_external` / `design` / `implement`,`tools/
|
|
66
|
+
注意:生成器的 allow 重写只覆盖三个内置角色(`search_external` / `design` / `implement`,`tools/lib/util.mjs` 的 `ROLES` 常量,`tools/install.mjs` 转出口)。手写新增的 `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
|
|
|
@@ -94,6 +94,11 @@ Delegation failure handling (SOP):
|
|
|
94
94
|
· aborted → only re-delegate when the cancellation was accidental.
|
|
95
95
|
· completed but poor output → re-delegate with concrete missing points, or send_message
|
|
96
96
|
to ask a continuable child to finish the gaps.
|
|
97
|
+
- Continuable roles (background_mode: continuable): when a delegated run fails or
|
|
98
|
+
the output falls short, first send_message in the SAME child session to continue
|
|
99
|
+
and fix in place — resuming keeps the child's accumulated context, while
|
|
100
|
+
re-delegating starts a cold task and repeats finished work. Only re-delegate
|
|
101
|
+
when the child session is gone or the task needs a different role.
|
|
97
102
|
- If the same task fails twice, stop retrying: report to the user what failed, why,
|
|
98
103
|
and what you already tried. Never loop a failing delegation.
|
|
99
104
|
- When re-delegating (fresh task or continuation), always include your integration
|
|
@@ -113,9 +118,9 @@ Delegation failure handling (SOP):
|
|
|
113
118
|
| 同一任务失败 **2 次** | 停止重试,向用户报告失败原因与已尝试方案;绝不循环一个失败的委派 |
|
|
114
119
|
| 任何重委派 | **必须携带上次的集成摘要**:做了什么 / 败在哪 / 从哪接续——子 agent 无需从冷上下文重新推导 |
|
|
115
120
|
|
|
116
|
-
continuable
|
|
121
|
+
continuable 分支:失败或产出不满、**且该角色已配成 continuable** 时,先 `send_message` 在同一子会话续修——子 agent 记得自己做到哪,就地补完;子会话已不在、或任务需要换角色时才重委派(即 persona SOP 中 Continuable roles 条目的口径);续修无效再回到上表按停止原因重委派(重委派从首选退为退路)。
|
|
117
122
|
|
|
118
|
-
设计要点:SOP 是 persona 文本而非代码逻辑,因此可以按需编辑——直接改 `presets/orchestrator/agent.cordis.yml` 中 persona 段落(YAML 块标量,内容行缩进
|
|
123
|
+
设计要点:SOP 是 persona 文本而非代码逻辑,因此可以按需编辑——直接改 `presets/orchestrator/agent.cordis.yml` 中 persona 段落(YAML 块标量,内容行缩进 6 空格,注意保持缩进),再到「庖丁配置」点「保存并应用」重新生成。例如想让失败任务更频繁地退回主 agent 自己做、或对某个角色采用不同的重试上限,都可在此调整。
|
|
119
124
|
|
|
120
125
|
## one-shot 与多轮迭代
|
|
121
126
|
|
|
@@ -153,7 +158,7 @@ continuable 不是免费的,启用前请确认以下四点:
|
|
|
153
158
|
|
|
154
159
|
## 进阶:免面板手编 implement_cont
|
|
155
160
|
|
|
156
|
-
路径 B 的主路径在面板与配置键——角色卡「会话模式」一键可达(见[配置](configuration.md) 2.6)。本节是等价的免面板手编路径,共 5 步,供想看清生成层到底写了什么、或在不起面板的环境里操作时使用。默认 preset **不含** `implement_cont`——需要时自行启用,用完可整体移除。所有 YAML
|
|
161
|
+
路径 B 的主路径在面板与配置键——角色卡「会话模式」一键可达(见[配置](configuration.md) 2.6)。本节是等价的免面板手编路径,共 5 步,供想看清生成层到底写了什么、或在不起面板的环境里操作时使用。默认 preset **不含** `implement_cont`——需要时自行启用,用完可整体移除。所有 YAML 均为配置原文(与 preset 内 delegation 块结构一致,已与源码核对)。
|
|
157
162
|
|
|
158
163
|
### 第 1 步 —— host 层挂 persistence 后端(机器级,全局生效)
|
|
159
164
|
|
|
@@ -214,28 +219,19 @@ continuable 不是免费的,启用前请确认以下四点:
|
|
|
214
219
|
- `memory_search` 依赖 host 层的 magic-memory 插件:**插件未启用时必须从 allow 删去该行**,否则子 agent 创建时 `tools.restrict()` 以 unknown tools 拒绝创建。这与 2026-09-02 起各角色 allow 剔除 `memory_search` / `mcp__codegraph__codegraph_explore` 的决策一致(见 `agent.cordis.yml` 内注释);且安装器的 allow 重写只覆盖三个内置角色,**手写的 `implement_cont` 块不会被自动清洗**——它自己的 allow 必须手工与宿主实际启用的插件保持同步。
|
|
215
220
|
- persona 用 YAML `|-` 块标量,内容行缩进 10 空格,改文本时保持缩进。
|
|
216
221
|
|
|
217
|
-
### 第 3 步 —— 让主 agent 能调 `implement_cont
|
|
222
|
+
### 第 3 步 —— 让主 agent 能调 `implement_cont`(编辑 restrict 常量)
|
|
218
223
|
|
|
219
|
-
主 agent
|
|
224
|
+
主 agent 只能调用白名单内的工具。首选直接编辑 `presets/orchestrator/restrict.mjs` 的 `MAIN_AGENT_ALLOW`(21 项白名单常量,`new Set([...])`),在其中加一行 `'implement_cont'`(改的是 SRC,改完需重新应用,见第 4 步)。
|
|
220
225
|
|
|
221
|
-
|
|
226
|
+
为什么不走配置文件:`main_agent_extra` 的注入走白名单对账——名字必须落在 **presetUniverse**(`restrict.mjs` 主 agent 白名单 ∪ 源 preset 各角色 allow)或**检测库存**里才会保留,两头都不占的名字一律剔除。`implement_cont` 这类自定义委派名恰好两头都不占:写进 `main_agent_extra` 会被生成器丢弃(兜底 CLI 输出只汇总数量、不列明细),面板「主 agent」卡也勾不到它。想让配置层路径生效,手写名必须先存在于 presetUniverse / 检测库存之中。
|
|
222
227
|
|
|
223
|
-
|
|
224
|
-
main_agent_extra:
|
|
225
|
-
- implement_cont
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
应用时 `implement_cont`(非 host 依赖名)会被并入生成的 `config.allow`。也可在面板(设置 → **庖丁配置** → 主 agent 卡)勾选,见[配置](configuration.md)。
|
|
229
|
-
|
|
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`,运行时以它为准、常量只作回退。
|
|
231
|
-
|
|
232
|
-
无论哪条路,改完都需要重新应用(见第 4 步)。
|
|
228
|
+
注意**覆盖语义**:运行时 `allow = config.allow ?? MAIN_AGENT_ALLOW`(空 allow 拒绝加载)。生成器从 `restrict.mjs` 源码现场解析该常量作为 base,生成 `config.allow = (base + main_agent_extra − main_agent_remove) ∩ (presetUniverse ∪ inventory)`,且**只在结果与 base 不同时才注入** `config.allow` 行。因此:改完常量必须重新应用(base 重新解析、安装副本刷新);若运行中的 `agent.cordis.yml` 已有注入的 `config.allow`,运行时以它为准、常量只作回退。
|
|
233
229
|
|
|
234
230
|
### 第 4 步 —— 应用
|
|
235
231
|
|
|
236
|
-
|
|
232
|
+
打开左侧栏底部动作条(设置行上方)的「**庖丁配置**」入口,点「**保存并应用**」——重新生成 preset(含新 delegation 块与白名单变更),并把手编改动一并应用。
|
|
237
233
|
|
|
238
|
-
然后**重启 host
|
|
234
|
+
然后**重启 host 或新建会话**生效。之后改动配置同样在「庖丁配置」点「保存并应用」幂等应用(克隆了仓库的开发者也可用兜底 CLI `node tools/install.mjs --auto`)。
|
|
239
235
|
|
|
240
236
|
### 第 5 步 —— 用后清理
|
|
241
237
|
|