dsh-acp-enhanced 0.7.0 → 0.9.1
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-zh.md +324 -67
- package/README.md +371 -80
- package/cordis.patch.yml +658 -10
- package/lib/codec.js +211 -3
- package/lib/index.js +690 -294
- package/lib/stored-titles.js +228 -0
- package/lib/terminal-codec.js +52 -16
- package/package.json +36 -30
- package/profile/cordis.yml +17 -2
- package/scripts/acp-doctor.mjs +401 -0
- package/scripts/dsh-acp-zed.sh +135 -65
- package/scripts/init-acp-home.sh +343 -0
- package/scripts/lib/dsh-version.mjs +118 -0
package/README-zh.md
CHANGED
|
@@ -13,11 +13,19 @@ ACP 线上。
|
|
|
13
13
|
### 输出与遥测
|
|
14
14
|
|
|
15
15
|
- **块级流式 + 推理流式**:文本块与思考过程实时到达(`agent_message_chunk` /
|
|
16
|
-
`agent_thought_chunk
|
|
16
|
+
`agent_thought_chunk`),取消/重试不留半截输出。在 acp-enhanced 行设置
|
|
17
|
+
`streamDeltas: true` 可切换为**逐 token 流式**——回复边生成边渲染(75ms 合并一次
|
|
18
|
+
上线),代价是中途重试无法收回已发出的半截文本,会以可见的
|
|
19
|
+
`_[stream interrupted — retrying]_` 标记隔开(默认关闭)
|
|
17
20
|
- **完整遥测**:上下文用量环 + 缓存命中率 / TPS / 输入-输出-推理 token / 工具耗时 /
|
|
18
|
-
轮次计数(`usage_update._meta`
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
轮次计数(`usage_update._meta` 携带全量明细)。环的分母是被路由模型声明的
|
|
22
|
+
`contextWindow`,从会话日志折叠而来,因此恢复(resume)的线程也能保留——harness 只在
|
|
23
|
+
路由变化时记录一次 `request/context`,路由不变不会重新发出。dsh 自带的
|
|
24
|
+
`dsh-compaction-basic` 行会在该窗口约 80% 时自动压缩,`standard` / `ptc` / `cordis`
|
|
25
|
+
预设默认挂载(`minimal` 不挂);`/compact` 可手动触发。适配器未声明 `contextWindow` 的路由没有分母,
|
|
26
|
+
此时环报告 `used === size`。
|
|
27
|
+
- **图片支持(多模态)**:当 dsh 组合挂载了附件存储(`dsh-base` 默认装配
|
|
28
|
+
`dsh-attachment-local`)时,会声明 `promptCapabilities.image` 并把粘贴/
|
|
21
29
|
上传的图片持久化进 harness 附件存储——支持视觉的模型(如 `deepseek-v4-flash-vision-exp`)
|
|
22
30
|
可按线序原生读取,图文交替不乱序。旧版栈(无附件存储)自动降级:不声明 image、
|
|
23
31
|
收到图片 prompt 明确报错。
|
|
@@ -31,13 +39,15 @@ ACP 线上。
|
|
|
31
39
|
绝不出现空的 "unknown" 选择
|
|
32
40
|
- **权限预设**:read-only / workspace-write / full-access 三种会话模式
|
|
33
41
|
- **审批**:工具调用弹出原生 allow-once / reject-once 审批
|
|
34
|
-
- **Agent 预设**:每个会话的模型侧组合(工具 + 提示词段)来自 dsh agent-
|
|
35
|
-
名册。`standard` 为完整编码 agent(默认),`minimal`(极简模式)只有裸 shell
|
|
36
|
-
|
|
37
|
-
host 层工具;`
|
|
38
|
-
|
|
42
|
+
- **Agent 预设**:每个会话的模型侧组合(工具 + 提示词段)来自 dsh agent-preset
|
|
43
|
+
名册。`standard` 为完整编码 agent(默认),`minimal`(极简模式)只有裸 shell
|
|
44
|
+
(持久终端),**不含** subagent/web/todo/plan 等工具——极简 agent 不会泄漏任何
|
|
45
|
+
host 层工具;`ptc` 与 `cordis` 随 dsh CLI 附带。**自建预设写在 profile 里**
|
|
46
|
+
(见「自建 preset」)——dsh 0.1.7 起不再扫描 `~/.dsh/.agent-presets`。
|
|
47
|
+
通过 `agent_preset` 配置项、`/preset` 命令或
|
|
39
48
|
`DSH_ACP_PRESET` 环境变量(会话默认)选择;**仅空会话可切换**(还没跑过对话),
|
|
40
|
-
|
|
49
|
+
历史记录永远不会横跨两套工具面。配置了一个本名册已没有的 preset 不会把面板弄死:
|
|
50
|
+
空会话会改用名册默认值组合,并在 stderr 说明。
|
|
41
51
|
|
|
42
52
|
### Zed 深度集成
|
|
43
53
|
|
|
@@ -58,8 +68,10 @@ ACP 线上。
|
|
|
58
68
|
|
|
59
69
|
### 会话
|
|
60
70
|
|
|
61
|
-
- **恢复与归档**:`session/load` 恢复历史线程(完整回放);`session/list`
|
|
62
|
-
|
|
71
|
+
- **恢复与归档**:`session/load` 恢复历史线程(完整回放);`session/list` 列出线程
|
|
72
|
+
归档(带标题、按更新时间排序);`session/close` 释放内存中的会话记录,之后的
|
|
73
|
+
`session/load` 会从持久化日志完整恢复;标题实时推送。`session/delete` **有意不广播**——
|
|
74
|
+
harness 未声明公开的持久化删除接口(见「兼容性」)
|
|
63
75
|
- **多根工作区**:`sessionCapabilities.additionalDirectories` 已声明,Zed 不再提示
|
|
64
76
|
"This agent doesn't currently support multi-root workspaces",而是把所有工作区根
|
|
65
77
|
通过 `session/new` / `session/load` 传入。所有根都会写进系统提示词并在
|
|
@@ -91,6 +103,10 @@ ACP 线上。
|
|
|
91
103
|
|
|
92
104
|
## 快速开始
|
|
93
105
|
|
|
106
|
+
**需要 `dsh ≥ 0.1.5-rc.2`**(`npm install -g @deepseek-ai/dsh@0.1.5-rc.2`,或下方 peer 范围内的
|
|
107
|
+
任意版本):本桥在每条受支持线(0.1.5-rc.2 直到 0.1.7)上只消费同一套已声明表面,不在运行期
|
|
108
|
+
探测更老的代际。
|
|
109
|
+
|
|
94
110
|
本包遵循 dsh 官方插件规范(声明了 `dsh.bundle`),安装与官方组合包一致:**一条命令**
|
|
95
111
|
完成,自动初始化 profile、安装包、追加 bundle 层,全程无需手写 profile YAML。
|
|
96
112
|
|
|
@@ -183,7 +199,8 @@ Zed 会热重载设置。打开 **AI Agent 面板**(`Cmd+Shift+A`)→ agent
|
|
|
183
199
|
本地验证(无需 Zed):
|
|
184
200
|
|
|
185
201
|
```sh
|
|
186
|
-
node scripts/acp-
|
|
202
|
+
node <pkg>/scripts/acp-doctor.mjs # bundle + 版本、peer 范围,并真实启动一次
|
|
203
|
+
node scripts/acp-client.mjs # 仅限仓库检出:完整 ACP 端到端,期望 ALL CHECKS PASSED
|
|
187
204
|
DSH_ACP_PROVIDER=... DSH_ACP_MODEL=... node scripts/acp-client.mjs # 自定义路由时再传
|
|
188
205
|
```
|
|
189
206
|
|
|
@@ -195,11 +212,18 @@ seam 的 `searchProvider`,往 profile 里挂任意 `ctx.web` provider 即可
|
|
|
195
212
|
走用户层 `insert` 挂载(见下节)。你的 dsh 部署里有哪些 provider 是 profile 层的
|
|
196
213
|
事,与 bridge 无关。
|
|
197
214
|
|
|
215
|
+
代价要说清楚:provider bundle 位于**每个 ACP 线程的启动路径**上,一旦加载失败整个
|
|
216
|
+
profile 都会挂掉,Zed 侧表现为无输出的卡死。若插件只是新增模型侧工具,优先放进 preset
|
|
217
|
+
composition(见[保持 profile 最小化](#保持-profile-最小化));而必须配置宿主 `web` 行的
|
|
218
|
+
provider 只能待在宿主组合(即 profile)里——那就明确接受这一风险,并在每次改动后重跑
|
|
219
|
+
doctor。
|
|
220
|
+
|
|
198
221
|
### 管理 profile 的插件
|
|
199
222
|
|
|
200
|
-
dsh-acp-enhanced 跑在**独立的 profile** 里——`acp-enhanced
|
|
201
|
-
`~/.dsh/profiles/acp-enhanced
|
|
202
|
-
|
|
223
|
+
dsh-acp-enhanced 跑在**独立的 profile** 里——`acp-enhanced`,位于
|
|
224
|
+
`~/.dsh/profiles/acp-enhanced/`,与 `dsh web` 同处一个 dsh home。被隔离的是**组合**
|
|
225
|
+
本身,所以在
|
|
226
|
+
这里增删改插件不会影响 web 侧的配置,而凭据、设置、会话与 preset 仍是共享的。
|
|
203
227
|
|
|
204
228
|
profile 的插件树由三层组合而成,后层修补前层:
|
|
205
229
|
|
|
@@ -239,73 +263,294 @@ dsh --profile acp-enhanced --dump-config # 查看组合后的完整
|
|
|
239
263
|
改动在**下一个**进程生效:Zed 为每个 agent 线程拉起一个全新的
|
|
240
264
|
`dsh --profile acp-enhanced`,编辑 profile 后新开 agent 线程(或重启 Zed)即可。
|
|
241
265
|
|
|
242
|
-
|
|
266
|
+
#### 保持 profile 最小化
|
|
267
|
+
|
|
268
|
+
profile 是一个**单一故障域**:`cordis-plugin-loader` 会等待每个条目,并把第一个 reject
|
|
269
|
+
原样抛出,因此只要有一行加载失败,整棵插件树就会中止——进程甚至可能先正常应答 ACP
|
|
270
|
+
`initialize` 再立刻退出,客户端只会表现为无输出的卡死,而不是报错。
|
|
271
|
+
|
|
272
|
+
把 `dsh.profile.bundles` 控制在这两行以内,它们的版本不可能与启动它的 CLI 不匹配:
|
|
273
|
+
|
|
274
|
+
```json
|
|
275
|
+
"bundles": ["@deepseek-ai/dsh-base", "dsh-acp-enhanced"]
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
`@deepseek-ai/dsh-base` 随 CLI 一起发布,版本天然等同于启动它的 CLI;其他任何 bundle 都是
|
|
279
|
+
第三方,其依赖闭包可能漂移。额外插件请挂到「坏了只废掉一个 preset」的位置:
|
|
280
|
+
|
|
281
|
+
- **只新增模型侧工具/命令的插件** → 把行写进某个 preset composition。**0.1.7 线**上是
|
|
282
|
+
profile 用户层里的一条 `@deepseek-ai/dsh-agent-preset` 行(见「自建 preset」);
|
|
283
|
+
0.1.5/0.1.6 上是 `$DSH_HOME/.agent-presets/<id>/` 目录(组合写 `agent.cordis.yml`,
|
|
284
|
+
选择器里的名称写 `preset.yml`)。两种方式下 ACP 的 `agent_preset` 下拉都会列出它;
|
|
285
|
+
组合加载失败的 preset 只会被标记为 broken 并从列表里剔除,不会拖垮进程。
|
|
286
|
+
- **需要配置宿主服务的插件**(例如要覆写宿主 `web` 行 `searchProvider` 的搜索 provider)
|
|
287
|
+
→ 它属于宿主组合,也就是 profile。这是有意的取舍:接受启动路径上的风险,并在每次改动
|
|
288
|
+
后重跑 doctor。
|
|
289
|
+
|
|
290
|
+
改动后先验证再信任:
|
|
291
|
+
|
|
292
|
+
```sh
|
|
293
|
+
node <pkg>/scripts/acp-doctor.mjs # bundle 与版本、peer 范围,并真实启动一次
|
|
294
|
+
dsh --profile acp-enhanced --dump-config # 每一行来自哪一层
|
|
295
|
+
```
|
|
243
296
|
|
|
244
|
-
|
|
245
|
-
API,桥在运行期同时吸收各代——不分叉、不加版本开关:
|
|
297
|
+
## 兼容性
|
|
246
298
|
|
|
247
|
-
|
|
299
|
+
同一个桥只对应**一套已声明的 harness 表面**:**dsh ≥ 0.1.5-rc.2**(peer 范围
|
|
300
|
+
`^0.1.5-rc.2 || ^0.1.6-alpha.1 || ^0.1.7-alpha.1`)。该范围内的**三条线**每次 CI 都会做真实启动
|
|
301
|
+
验证——握手、profile settle 与真实 `session/new`——另有跨代链接检查。桥只消费 harness
|
|
302
|
+
**已声明**的表面:`docs/capability-seams.md` 里的服务、`docs/event-producer-consumer.md` 里的
|
|
303
|
+
事件、以及已发布包的导出。`scripts/api-surface-check.mjs` 会对其他一切报错(CI 的阻塞步骤)。
|
|
304
|
+
这里没有特性嗅探,也没有代际矩阵:0.1.7 只需要两处适配——一处**成员探测**
|
|
305
|
+
(`presets.resolveMountable` 在 0.1.6 及以前是私有成员、0.1.7 直接删除,改用 `resolve()` 加该行
|
|
306
|
+
自身的 `broken` 判定),以及 `cordis.patch.yml` 里一行**代际门控行**(agent-preset roster 被上游
|
|
307
|
+
重新打包,门控读取正在启动的安装自身 manifest 的版本,见下)。缺少任一者时会回退到旧形状,
|
|
308
|
+
两条路径都不会让启动失败。
|
|
309
|
+
|
|
310
|
+
### 支持策略
|
|
311
|
+
|
|
312
|
+
| 桥版本 | 支持的 dsh 线 | 变化 |
|
|
313
|
+
|---|---|---|
|
|
314
|
+
| **0.9.1** | `^0.1.5-rc.2 \|\| ^0.1.6-alpha.1 \|\| ^0.1.7-alpha.1` | 支持 0.1.7:agent-preset roster 上游换包,桥同时下发两种形状(代际门控行),并把四个 preset 声明内联进来 |
|
|
315
|
+
| **0.9.0** | `^0.1.5-rc.2 \|\| ^0.1.6-alpha.1` | 只消费已声明表面;下限 0.1.5-rc.2;移除 `session/delete` |
|
|
316
|
+
| 0.8.x | `^0.1.0-rc.6 … ^0.1.6-alpha.1`(未发布) | 0.1.3+ 实时 seam;0.1.5 持久化 handle API |
|
|
317
|
+
| 0.7.x 及更早 | ≤ 0.1.2-rc.1 | 运行期同时探测两代 |
|
|
318
|
+
|
|
319
|
+
这张表背后的规则:
|
|
320
|
+
|
|
321
|
+
- **新的 dsh API 线对应一次新的桥发布,而不是把运行期探测写得更宽。** 0.7.x 正是靠探测吞下
|
|
322
|
+
0.1.1 → 0.1.5,也正是它悄悄腐烂的原因。0.1.7 属于重新打包而非新的 API 线,所以 0.9.1 用
|
|
323
|
+
一个 patch 版本吸收它——所需的探测只有一次成员检查,而不是一张代际矩阵。
|
|
324
|
+
- **下限只随桥的 minor 移动,且绝不静默**:CLI 低于范围时启动器会在启动前告警,doctor 会以
|
|
325
|
+
`RESULT FAIL — CLI too old` 停下。
|
|
326
|
+
- **放弃某条线的方式是发布一个明确这么说的桥**;旧线留在 `feat/dsh-0.1.3-plus-support` 分支上,
|
|
327
|
+
供无法迁移的用户使用。
|
|
328
|
+
- **在下一条线发布之前就盯住它**:定时 `canary` workflow 会安装 `alpha` dist-tag 并跑表面守卫、
|
|
329
|
+
链接检查与启动冒烟,因此破坏性变更表现为 canary 变红,而不是用户侧故障。
|
|
330
|
+
|
|
331
|
+
### 0.9.0 的破坏性变更
|
|
332
|
+
|
|
333
|
+
| 变更 | 影响 | 中招了怎么办 |
|
|
334
|
+
|---|---|---|
|
|
335
|
+
| 下限提升到 dsh **≥ 0.1.5-rc.2** | 更老的宿主在挂载期就以具名错误失败,而不是静默降级 | 升级 CLI(`npm install -g @deepseek-ai/dsh@0.1.5-rc.2`),或留在 `feat/dsh-0.1.3-plus-support` 分支(≤ 0.1.2-rc.1) |
|
|
336
|
+
| **移除 `session/delete`** | 不再广播该能力,也永不删除已持久化的会话——harness 未声明公开的持久化删除接口 | 文件仍在 `$DSH_HOME/sessions/<slug>/<id>/`,确有需要请手工删除。上游已有 issue 追踪公开删除 API |
|
|
337
|
+
| 启动器**不再改写 `DSH_HOME`** | ACP profile 在启动器所处的 home 中启动(`${DSH_HOME:-$HOME/.dsh}`),与 `dsh web` 共享凭据、设置、会话与 preset | 之前用的是隐式隔离的 `~/.dsh-acp`?在 Zed 的 `agent_servers.env` 里显式指回它(`"DSH_HOME": "<home>/.dsh-acp"`),或迁回共享 home |
|
|
338
|
+
| `assistant/chunk` seam 移除 | 实时流只剩 `agent/assistant-stream`(下限已覆盖该代) | 升级 CLI;完全不发流的宿主仍由已提交的 `assistant/message` 兜底 |
|
|
339
|
+
|
|
340
|
+
### 0.9.1 的变更(增量:支持 dsh 0.1.7)
|
|
341
|
+
|
|
342
|
+
`dsh` 0.1.7 **重新打包了 agent-preset roster**。`@deepseek-ai/dsh-agent-presets`(把
|
|
343
|
+
standard/ptc/minimal/cordis 组合打进去、并作为只读 `system` root 前置的那个包)在 0.1.7 线
|
|
344
|
+
完全没有发布;该线改为 `@deepseek-ai/dsh-agent-preset-registry` 加上每个 preset 一条
|
|
345
|
+
`@deepseek-ai/dsh-agent-preset` 声明行。三处表面发生了位移,桥在不放弃任何受支持线的前提下
|
|
346
|
+
全部吸收:
|
|
347
|
+
|
|
348
|
+
| 表面 | ≤ 0.1.6 | ≥ 0.1.7 | 桥的做法 |
|
|
248
349
|
|---|---|---|---|
|
|
249
|
-
|
|
|
250
|
-
| preset
|
|
251
|
-
| `
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
350
|
+
| roster 行 | `@deepseek-ai/dsh-agent-presets` + `config.default` | `@deepseek-ai/dsh-agent-preset-registry` + `config.default` | 两行都下发,各自由代际门控 `disabled`,因此恰好只有一行激活(两者提供同一个服务名,第二次 `provide` 会抛错) |
|
|
351
|
+
| 随包 preset | 打在 roster 包内(`system` root) | 每个 preset 一条 `@deepseek-ai/dsh-agent-preset` 声明,谁需要谁下发(`@deepseek-ai/dsh-web-app` 以 `presets/*.patch.yml` 层下发) | 四条声明按 web-app 组合包原样(MIT,0.1.7-rc.2)内联进 `cordis.patch.yml`,并补回旧 roster 每个 preset 的 `preset.yml` 里的展示元数据——0.1.7 对内置 id 不再发布 `name` |
|
|
352
|
+
| 可挂载解析 | 私有 `presets.resolveMountable(id)` | `presets.resolve(id)` 会**故意**返回损坏行;各挂载路径在解析之后才拒绝 | 成员探测:有 `resolveMountable` 就用它,否则 `resolve()` 加该行自身的 `broken` 理由 |
|
|
353
|
+
|
|
354
|
+
门控读的是**正在启动的这套安装自身的身份**:打开 `profileContext.installAnchor`(即运行中 CLI
|
|
355
|
+
自己的 `package.json`),用它的 `version` 决定形状(registry roster 从 0.1.x 线的 0.1.7 开始)。
|
|
356
|
+
0.1.5 上根本没有 `profileContext`,这本身就已经是「≤ 0.1.6」的答案;任何读不到、解析不了、
|
|
357
|
+
归类不了的情况都保留旧行。`!!js` 表达式以 `with (ctx)` 在 loader context 加全局上求值,因此版本
|
|
358
|
+
只能「读」而不能「问」——作用域里没有任何东西暴露它。
|
|
359
|
+
|
|
360
|
+
最初的做法是解析器探测(`ctx.pluginPackages.packageOf(…, <profile URL>)`),它对 `link:`
|
|
361
|
+
安装的桥是**错的**:那种解析从 profile 出发,能够触达*被 link 的检出目录*自己的依赖树,于是
|
|
362
|
+
一个带着 0.1.7 包的开发检出会让 0.1.6 宿主误以为 registry 存在——它禁用了本来可用的 roster 行,
|
|
363
|
+
随后五个 0.1.7 行全部导入失败(`agent-preset-registry: failed to import`)。安装锚点没有这种
|
|
364
|
+
触达范围:它是运行中 CLI 内部的固定路径,与 profile、link 目标、以及布局(npm 扁平或 pnpm 严格)
|
|
365
|
+
都无关。这里没有任何一处能让启动失败——最坏情况就是 0.1.7 在本版之前本来就有的优雅降级(只是
|
|
366
|
+
不提供 `agent_preset`)。
|
|
367
|
+
|
|
368
|
+
`DSH_ACP_PRESET`、`agent_preset` 配置项与 `/preset` 在每条线上行为一致。
|
|
369
|
+
|
|
370
|
+
#### 自建 preset
|
|
371
|
+
|
|
372
|
+
0.1.7 起名册变成了由声明行喂给 registry:它**不扫描任何用户目录**,因此
|
|
373
|
+
`$DSH_HOME/.agent-presets/<id>/` 不再被收录,profile 默认值指向这类 preset 时每个
|
|
374
|
+
`session/new` 都会以 `Unknown agent preset: <id>` 失败。把预设写在 registry 真正读的地方:
|
|
375
|
+
|
|
376
|
+
```yaml
|
|
377
|
+
# ~/.dsh/profiles/acp-enhanced/cordis.patch.yml
|
|
378
|
+
- insert:
|
|
379
|
+
- id: preset-my-agent
|
|
380
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
381
|
+
config:
|
|
382
|
+
id: my-agent # DSH_ACP_PRESET / 下拉框使用的 id
|
|
383
|
+
name: 我的 agent # 可选;0.1.7 只本地化内置 id 的展示名
|
|
384
|
+
description: … # 可选
|
|
385
|
+
order: 5 # 可选
|
|
386
|
+
plugins: # 整套组合,形状同官方 preset
|
|
387
|
+
- id: persona
|
|
388
|
+
name: '@deepseek-ai/dsh-persona'
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
官方 `presets/*.patch.yml` 层(以及本桥内联的那四条)遵循的两条规则,因为 preset 就是
|
|
392
|
+
loader 要挂载的数据:
|
|
393
|
+
|
|
394
|
+
- **整装重述。** preset 行携带完整的 `config.plugins` 列表——不存在「只 patch 已有 preset
|
|
395
|
+
的某个子行」——所以 fork `standard` 必须按新代的行集重新 baseline(0.1.6 把
|
|
396
|
+
`workflow-worker-thread` 换成了 `workflow-ptc` 运行时)。差异只在配置(模型路由、审批、沙箱)时
|
|
397
|
+
优先放在宿主面:只有**工具集**不同才值得 fork。
|
|
398
|
+
- **默认值写在当代读它的地方。** 0.1.7 上是 `agent-preset-registry.config.default`,
|
|
399
|
+
≤ 0.1.6 上是 `agent-presets.config.default`(或 Settings 里的 `selectedDefault`)。
|
|
400
|
+
profile 指向一个已不存在的 preset 时:*空*会话仍可用(改用名册默认值并在 stderr 说明),
|
|
401
|
+
但**恢复**一个跑过它的会话仍会失败——把另一套工具面接到已有转录上,正是「仅空会话可切换」
|
|
402
|
+
这条规则要防的事。
|
|
403
|
+
|
|
404
|
+
#### 0.1.7 对「会话库很大」意味着什么
|
|
405
|
+
|
|
406
|
+
0.1.7 上读一个已存会话日志的代价高得多(约 217ms/个,0.1.5 约 9ms),而 `session/list` 需要
|
|
407
|
+
给每个已存会话一个标题。修复前,这个调用会对每个会话同时做 `stat()` **和**一次完整解码,
|
|
408
|
+
于是几百个会话的库会让该调用耗时约 **60 秒**——超过客户端 30 秒的线路超时,侧边栏会话列表
|
|
409
|
+
因此空白。临时 profile 看不到这个问题:全新的 home 会话太少。
|
|
410
|
+
|
|
411
|
+
现在列表只从**一次**存储遍历里取每个会话的体积与 revision,并且只解码「短预算」内放行的
|
|
412
|
+
那些日志,**按最近活动优先**(也就是侧边栏展示的顺序)。预算没覆盖到的部分会继续在后台解析,
|
|
413
|
+
以 `session_info_update` 逐条送达;标题按 revision 缓存,因此再次列取就是一次 map 查找。在真实
|
|
414
|
+
的 302 会话库上实测:每次调用 **60s → 2.7s**,其余标题随后陆续到达。可用
|
|
415
|
+
`DSH_ACP_LIST_BUDGET_MS` 调整预算(默认 2500)。
|
|
416
|
+
|
|
417
|
+
#### 升级到 0.1.7 前要检查的两件事
|
|
418
|
+
|
|
419
|
+
两者出错时都是静默的:
|
|
255
420
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
421
|
+
- **`dsh-free-search` 必须 ≥ 0.4.39**。更早的版本 import `SettingsProvider`,而 0.1.7 的
|
|
422
|
+
`dsh-settings` 把它换成了 `SettingsForms`;该条目 import 失败、loader 继续跑,`web_search`
|
|
423
|
+
就这么消失了。`scripts/acp-doctor.mjs` 现在会把这种启动报告成降级(`RESULT DEGRADED` 并列出
|
|
424
|
+
条目名、退出码 1),而不是 `RESULT READY`。
|
|
425
|
+
- **`$DSH_HOME/.agent-presets/` 里的自建 preset 不再被发现**——见上文「自建 preset」。
|
|
259
426
|
|
|
260
|
-
|
|
427
|
+
### 从已发布的 ≤ 0.7.0 升级
|
|
428
|
+
|
|
429
|
+
npm 上的 `latest` 是 **0.7.0**,属于 0.1.3 之前的 API 线,因此桥和 CLI **必须一起动**——只升一半,
|
|
430
|
+
两种顺序都会坏:
|
|
431
|
+
|
|
432
|
+
| 顺序 | 结果 |
|
|
433
|
+
|---|---|
|
|
434
|
+
| 先升 CLI,桥留在 0.7.0 | profile 能启动、`initialize` 也成功,但**每个 `session/new` 都失败**(Internal error:`tool-subagent: modelSelectionSettings requires … in the Host scope`)。我们无法给出任何提示——那份桥代码已经装好了;而且 0.7.0 既没有 `agent/assistant-stream` seam 也没有 `assistant/message` 兜底,回复同样渲染不出来 |
|
|
435
|
+
| 先升桥,CLI 留在旧版 | profile 在加载期就死(`… subpath './model-selection-settings' is not defined by "exports"`)。启动器会在它**之前**向 stderr 告警,`scripts/acp-doctor.mjs` 则以 `RESULT FAIL — CLI too old` 直接停下 |
|
|
436
|
+
| 两者一起升 | 受支持的状态 |
|
|
437
|
+
|
|
438
|
+
升级清单:
|
|
439
|
+
|
|
440
|
+
1. `npm install -g @deepseek-ai/dsh@0.1.5-rc.2`(或上面 peer 范围内的任意版本)。
|
|
441
|
+
2. `dsh plugin --profile acp-enhanced add dsh-acp-enhanced@0.9.1`。升级桥是显式动作:profile 里的依赖
|
|
442
|
+
是对 0.x 的 caret,所以 `dsh plugin update` **不会**自行把你带到新的 minor。
|
|
443
|
+
3. 以前是从检出目录启动、或设过 `DSH_PATH`?旧启动器会自行切到 `~/.dsh-acp`,现在不会了。请在 Zed 的
|
|
444
|
+
`agent_servers.env` 里设 `DSH_HOME=<那个 home>`,或在默认 home 里重建 profile。启动器若在那里
|
|
445
|
+
发现 profile,会主动提示。
|
|
446
|
+
4. 以前照旧 README 在 profile 用户层里塞过 `subagent-model-selection-settings`?把它删掉:现在由桥的
|
|
447
|
+
patch 提供该行,重复 id 会让启动中止。`scripts/init-acp-home.sh` 会自动清理;启动器会告警,doctor
|
|
448
|
+
会点名该 id。
|
|
449
|
+
5. 确认 profile 里的第三方 bundle 支持你要升到的那条线(`dsh-free-search` 在 0.1.5 上 ≥ 0.4.24
|
|
450
|
+
已验证;在 0.1.7 上需要 ≥ 0.4.39,见「升级到 0.1.7 前要检查的两件事」)——profile 是单一故障域。
|
|
451
|
+
6. 重启 Zed(或新开一个 agent 线程);先用 `node <pkg>/scripts/acp-doctor.mjs` 验证整条链路(它现在连
|
|
452
|
+
开线程都会实测)。
|
|
453
|
+
|
|
454
|
+
### 一个 home 只跑一个 CLI 代际
|
|
455
|
+
|
|
456
|
+
`$DSH_HOME/profiles/node_modules` 是同 home 下所有 profile 共享的**同一个**依赖闭包,
|
|
457
|
+
dsh 每次启动都会把它 heal 成最后启动的那个 CLI。因此:
|
|
458
|
+
|
|
459
|
+
> 这是 **0.1.5 线**的行为。到 0.1.6-alpha.2 及之后,这个共享闭包已完全不存在(harness 从 CLI
|
|
460
|
+
> 自身的安装位置解析;profile 的 `node_modules` 只放外部插件),所以启动器的漂移检查是「按线」
|
|
461
|
+
> 的,路径消失时会静默跳过。
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
- **不要让两个 CLI 代际同时跑在一个 home 下。** 第二次启动会在第一个进程运行期间翻转闭包,
|
|
466
|
+
那个进程随后会惰性地解析到不匹配的模块。启动器会把闭包里的 `dsh-agent` 版本与即将启动的
|
|
467
|
+
CLI 对比,不一致时向 **stderr** 告警——遇到这种启动后,请重启该 home 下其他 dsh 进程
|
|
468
|
+
(`dsh web` 等)。
|
|
469
|
+
- **逃生阀是 CLI,不是 home。** 用 `DSH_PATH=<dsh>`(或下面的仓库锁定)指定启动哪个 dsh:
|
|
470
|
+
启动器只决定*用哪个 dsh*,绝不决定*用哪个 home*。
|
|
471
|
+
|
|
472
|
+
当前解析结果随时可查:
|
|
261
473
|
|
|
262
474
|
```sh
|
|
263
|
-
node scripts/compat-check.mjs #
|
|
475
|
+
node scripts/compat-check.mjs # 仅限仓库检出:分别安装 0.1.5-rc.2、0.1.6-alpha.2、0.1.7-rc.2 三套,逐一导入本桥
|
|
476
|
+
node <pkg>/scripts/acp-doctor.mjs # CLI 与闭包版本、bundle 列表,并真实启动一次(随包发布)
|
|
264
477
|
```
|
|
265
478
|
|
|
266
|
-
### 开发检出:仓库锁定 CLI +
|
|
479
|
+
### 开发检出:仓库锁定 CLI + 共享 home
|
|
267
480
|
|
|
268
481
|
启动器**从检出目录**(`link:` 安装)运行时,按以下顺序解析 dsh CLI:
|
|
269
482
|
|
|
270
483
|
1. `$DSH_PATH` —— 显式指定的 dsh 二进制,或其 `node_modules/.bin/dsh` 内含 dsh 的目录
|
|
271
484
|
2. 仓库锁定的 CLI —— `<repo>/node_modules/.bin/dsh`(本包的 `@deepseek-ai/dsh`
|
|
272
|
-
devDependency,当前 0.1.
|
|
273
|
-
3. 全局兜底 —— PATH / npx 缓存 / npm 前缀 里的 `dsh
|
|
274
|
-
|
|
275
|
-
命中 (1) 或 (2) 时,profile 在**独立 home**(`DSH_ACP_HOME`,默认 `~/.dsh-acp`)下启动:dsh
|
|
276
|
-
每次启动都会把自身依赖闭包 heal 进 `$DSH_HOME/profiles/node_modules`——该目录被同 home 下所有
|
|
277
|
-
profile 共享、内容随最后启动的 CLI 翻转——因此第二个 CLI 代际不得与运行中的 `dsh web`
|
|
278
|
-
等共享 home。此路径永不触碰默认 home。harness 注入到子进程的 `DSH_HOME=$HOME/.dsh`
|
|
279
|
-
(dsh 会向每个 agent/工具进程导出它)会被识别并覆盖而非沿用;只有指向默认 home 之外的
|
|
280
|
-
`DSH_HOME` 才被尊重;确要将锁定 CLI 跑在默认 home 上,请显式设 `DSH_ACP_HOME=$HOME/.dsh`。
|
|
485
|
+
devDependency,当前 0.1.7-rc.2)
|
|
486
|
+
3. 全局兜底 —— PATH / npx 缓存 / npm 前缀 里的 `dsh`(未 `pnpm install` 的全新检出退化为它)
|
|
281
487
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
`subagent-model-selection-settings` 宿主服务、关闭 DeepSeek 插件清单上报):
|
|
488
|
+
命中任何一个,profile `acp-enhanced` 都在**启动器所处的 home**(`${DSH_HOME:-$HOME/.dsh}`)中启动。
|
|
489
|
+
home 永不被改写。若想让桥跑在自己的依赖闭包上,请另建一个 home 并显式指过去:
|
|
285
490
|
|
|
286
491
|
```sh
|
|
287
|
-
scripts/init-acp-home.sh
|
|
492
|
+
DSH_ACP_HOME=~/.dsh-acp scripts/init-acp-home.sh # 可选、幂等:创建并填充一个独立 home
|
|
493
|
+
# 然后在 Zed 的 agent_servers env 里: "DSH_HOME": "/Users/you/.dsh-acp"
|
|
288
494
|
```
|
|
289
495
|
|
|
290
|
-
|
|
496
|
+
独立 home 是明确的可选项,不是默认值:profile 必须存在于启动器实际使用的 home 里,否则启动器
|
|
497
|
+
会以 127 退出,并打印出创建它的那条 `dsh plugin … add link:` 命令。`init-acp-home.sh` 会逐字移植旧
|
|
498
|
+
profile 的用户层行、复制凭据/设置、关闭 DeepSeek 插件清单上报,并从用户层清掉遗留的
|
|
499
|
+
`subagent-model-selection-settings` 行——该宿主行现在由 bridge 的 bundle patch 插入,再留一份会以
|
|
500
|
+
`duplicate loader entry id` 中止启动。
|
|
501
|
+
|
|
502
|
+
两种 home 都把会话持久化在 `$DSH_HOME/sessions/<slug>/<id>/session.jsonl.zstd`;默认不在 home 之间
|
|
503
|
+
拷贝任何东西,因为默认 home 的目录里还有全部 web profile 会话。迁移既有环境时请加
|
|
504
|
+
`--copy-sessions`(或直接执行脚本打印的 `rsync`)。
|
|
291
505
|
|
|
292
506
|
## 故障排查
|
|
293
507
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
508
|
+
先跑 doctor:它会完全按 Zed 的方式启动一次 profile,并指出失败层、出问题的 bundle 与修法。
|
|
509
|
+
|
|
510
|
+
```sh
|
|
511
|
+
node <pkg>/scripts/acp-doctor.mjs # 已安装副本
|
|
512
|
+
node scripts/acp-doctor.mjs # 仓库检出(npm run doctor)
|
|
513
|
+
node <pkg>/scripts/acp-doctor.mjs --profile <name> --home <dsh-home> --timeout 60000
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
它会打印 CLI 与版本、home、profile、每个 bundle 及其版本、支持的 peer 范围与共享闭包版本,
|
|
517
|
+
然后把启动失败归入三层之一:
|
|
518
|
+
|
|
519
|
+
| 层 | `dsh` stderr 里的特征 | 含义 | 修法 |
|
|
520
|
+
|---|---|---|---|
|
|
521
|
+
| **link-time** | `does not provide an export named …`、`SyntaxError: The requested module …` | 启动的 CLI 闭包无法满足本桥的某个 import | 见 doctor 的 `LAYER link-time`:对齐代次——重启该 home 下其他 dsh 进程(共享闭包会愈合到最后启动的那个 CLI),或用 `DSH_PATH=<匹配的 dsh>` 锁定本启动器 |
|
|
522
|
+
| **mount-time** | `failed to apply loader entry …`、`… requires … in the Host scope`、`duplicate loader entry id: …` | loader 拒绝了某一个条目并向上抛出,整棵插件树因此中止 | doctor 会打印 `SUBJECT <条目> (<模块>)`——补装缺失模块、在用户层禁用该行(`- id: <条目>` + `disabled: true`),或把 `dsh.profile.bundles` 收敛为 `@deepseek-ai/dsh-base` + `dsh-acp-enhanced`;若为重复 id,请从用户层删除该行(它归 bundle patch 所有) |
|
|
523
|
+
| **run-time** | 握手成功后出现 `… is not a function` | 桥调用到了该 CLI 代次不提供的 harness 服务方法 | `npm install -g @deepseek-ai/dsh@<支持范围内的版本>`(见[兼容性](#兼容性)) |
|
|
524
|
+
|
|
525
|
+
启动器在 Zed 启动过程中会把同样三类特征翻译到 **stderr**(stdout 是 ACP 协议线),
|
|
526
|
+
所以 agent 日志里已经带有失败层与修法。
|
|
527
|
+
|
|
528
|
+
| 症状 | 定位 | 处理 |
|
|
529
|
+
|---|---|---|
|
|
530
|
+
| Zed 卡死无输出、线程始终不应答 | `node <pkg>/scripts/acp-doctor.mjs` | 会打印 `BOOT FAILED` 与 `LAYER`/`SUBJECT`/`FIX`,照 `FIX` 做即可。先应答 `initialize` 再立刻退出的 profile 也会被如实报出 |
|
|
531
|
+
| `exec: dsh: not found`(status 127) | `which dsh` | 用随附 `dsh-acp-zed.sh` 启动器(自定位 node/dsh),或安装 CLI |
|
|
532
|
+
| `no API key for provider route "xxx"` | `ls -l $DSH_HOME/.credentials.yaml` | 写入 `~/.dsh/.credentials.yaml`,或在 agent_servers 里设 `env.DEEPSEEK_API_KEY` |
|
|
533
|
+
| `SyntaxError: … 'PresetMountError'` | agent 日志里的桥版本 | 你在 0.1.5 宿主上跑 0.9.0 之前的桥副本——升级本包 |
|
|
534
|
+
| `modelSelectionSettings requires … in the Host scope` | `dsh --profile acp-enhanced --dump-config \| grep subagent-model-selection` | `standard` preset 需要的宿主行缺失——该行由 bridge 的 bundle patch 提供,请重装/升级 bridge(`dsh plugin --profile acp-enhanced add dsh-acp-enhanced`),并检查用户层没有把它 `disabled: true` |
|
|
535
|
+
| `duplicate loader entry id: <行>` | doctor 会打印 `LAYER mount-time` 与该 id | 两层都插了同一行。请从 profile 用户层(`$DSH_HOME/profiles/acp-enhanced/cordis.patch.yml`)删掉它——这类宿主行归 bundle patch 所有;`scripts/init-acp-home.sh` 会自动清掉遗留的 `subagent-model-selection-settings` 副本 |
|
|
536
|
+
| 宿主升级后旧线程变空白 | `ls $DSH_HOME/sessions` | 会话存放在 `$DSH_HOME/sessions/<slug>/`;把旧 home 的历史拷进来(`scripts/init-acp-home.sh --copy-sessions`)即可继续 |
|
|
537
|
+
| 旧线程打不开:`Internal error … dsh-session-format-v0-to-v1 refuses this format v0 Session: … source summary requires notice form … (raw log: <路径>)` | 报错里的 `raw log` 路径 | 这是 dsh CLI 内置 frozen v0→v1 迁移在拒绝旧第三方 bundle 写进会话的数据——所有 dsh 客户端都会遇到,并非只有经本桥的 ACP,且迁移绝不改写原文件。已知案例:`dsh-mnemon` ≤0.5.6(注入带 `form`+`summary` 的消息)与 `dsh-message-edit` 的 `message-edit/version` 事件。`dsh-mnemon` ≥0.5.7 自带 `bin/repair-legacy-session.mjs`(输出修复副本,原件保留);升级写入方 bundle 后新会话不再携带该写法 |
|
|
538
|
+
| 无法切换模型 | `ACP_DEBUG=1 dsh --profile acp-enhanced`,然后尝试切换 | 携带的 `reasoning_effort` 在目标模型上不受支持:本桥按模型记住上次使用的强度(随 profile 持久化),会回退到该模型默认值而不是让切换失败。另检查路由是否真实——幽灵 provider 会被过滤,只广播 `config.provider` 的模型 |
|
|
539
|
+
| 上下文用量不显示 | 线程里执行 `/status` | 选到了不可路由的"幽灵 provider";确认 profile 的 provider 指向真实路由 |
|
|
540
|
+
| 轮次以 usage 结束但**面板没有回复文本**(空白) | `ACP_DEBUG=1`,看是否有 `agent/assistant-stream frame=chunk` | 0.9.0 起唯一的实时 seam 是 `agent/assistant-stream` 帧,某个 step 完全没有上线文本时由已提交的 `assistant/message` 兜底。有帧却无文本 = 客户端渲染问题;完全没有帧 = 正在走兜底路径(桥太旧就升级) |
|
|
541
|
+
| 升级 dsh 后报 `Unknown agent preset: <id>` | `ls $DSH_HOME/.agent-presets` 与 profile 的 `cordis.patch.yml` | 该 preset 已不在名册里——0.1.7 起不再扫描 `$DSH_HOME/.agent-presets`。把它改成一条 `@deepseek-ai/dsh-agent-preset` 声明行(见「自建 preset」);0.9.1 下*空*会话会先用名册默认值打开(stderr 有说明),但恢复已跑过它的线程在补上行之前仍然失败 |
|
|
542
|
+
| profile 以前有的能力静默消失(例如 `web_search`) | `node <pkg>/scripts/acp-doctor.mjs`——降级启动会打印 `DEGRADED <n> loader entries never activated` 并列出条目名 | 某个 entry 导入失败不会拖垮 profile,它只是不存在。给这条 dsh 线升级该 bundle——`dsh-free-search` 在 0.1.7 上需要 ≥ 0.4.39,因为 0.4.24 import 的 `SettingsProvider` 已被 `dsh-settings` 删除——或直接移除它 |
|
|
543
|
+
| 会话侧边栏空白或迟迟不出现(dsh 0.1.7 上的 ≤ 0.9.0 桥) | `ls $DSH_HOME/sessions \| wc -l`,以及 agent stderr 里的 `timeout: session/list` | 修复前的列表会解码每一个已存日志(见「0.1.7 对『会话库很大』意味着什么」);几百个会话就会超过 30s 线路超时。升级桥到 ≥ 0.9.1——现在秒级返回,其余标题以 `session_info_update` 陆续送达 |
|
|
544
|
+
| 改了插件却不生效 | profile `cordis.patch.yml` 的 mtime | 改动只在**下一个**进程生效:新开 agent 线程(或重启 Zed) |
|
|
545
|
+
| 需要详细诊断 | — | `ACP_DEBUG=1`(stderr 生命周期 trace)与 `ACP_LOG=/tmp/acp.jsonl`(逐事件 JSONL,带耗时) |
|
|
304
546
|
|
|
305
547
|
## 开发
|
|
306
548
|
|
|
307
549
|
```sh
|
|
308
|
-
|
|
550
|
+
pnpm install # 安装开发依赖(仓库锁定 CLI 与测试脚本)
|
|
551
|
+
node scripts/compat-check.mjs # 支持线上的链接检查(0.1.5-rc.2 / 0.1.6-alpha.2 / 0.1.7-rc.2 临时安装)
|
|
552
|
+
node scripts/api-surface-check.mjs # 公开表面守卫:不得使用未声明的 harness API(CI 阻塞步骤)
|
|
553
|
+
node scripts/pack-check.mjs # 包完整性:入口文件、权限位、所引用文件是否都随包发布(CI 阻塞步骤)
|
|
309
554
|
node scripts/acp-client.mjs # 端到端冒烟(需要 API key)
|
|
310
555
|
node scripts/acp-client-tools.mjs # 客户端工具测试(模拟 Zed 的 fs/terminal/elicitation/plan)
|
|
311
556
|
node scripts/acp-mcp-test.mjs # MCP 挂载测试(无模型调用)
|
|
@@ -313,12 +558,21 @@ node scripts/acp-smoke-keyless.mjs # keyless 冒烟(CI 用)
|
|
|
313
558
|
node scripts/acp-resume-test.mjs # 会话恢复测试
|
|
314
559
|
node scripts/codec-image-test.mjs # 图片编解码单元测试(无网络,假 store)
|
|
315
560
|
node scripts/terminal-codec-test.mjs # 终端卡片编解码单元测试(无网络)
|
|
561
|
+
node scripts/stored-titles-test.mjs # session/list 标题读取器:读取量受预算约束、不做 per-session stat()、按 revision 缓存(无网络)
|
|
562
|
+
node scripts/session-facts-test.mjs # 会话日志折叠:runningPreset/isBlank,live 与 stored 共享同一契约(无网络)
|
|
563
|
+
node scripts/context-window-test.mjs # request/context 折叠:恢复后的环保留分母(无网络)
|
|
564
|
+
node scripts/tool-result-test.mjs # tool/result 的 id 与正文提取,覆盖各支持代的形状(无网络)
|
|
565
|
+
node scripts/replay-order-test.mjs # 重放/回退的分块顺序:思考块先于它产出的回复(无网络)
|
|
316
566
|
node scripts/acp-image-e2e.mjs # 图片能力端到端(vision 模型段需 API key)
|
|
317
|
-
scripts/
|
|
567
|
+
node scripts/acp-message-fallback-test.mjs # 实时 seam + assistant/message 回退:seam 确实触发且回复恰好到达一次
|
|
568
|
+
node scripts/acp-launcher-test.mjs # 启动器契约:home 不被改写、代次漂移告警、启动失败翻译
|
|
569
|
+
node scripts/acp-doctor.mjs # 真实启动一次 profile,指出失败层与出问题的 bundle
|
|
570
|
+
scripts/init-acp-home.sh # 可选:引导**独立** home(启动器不会自行切过去)
|
|
318
571
|
```
|
|
319
572
|
|
|
320
|
-
harness 包的 devDependency
|
|
321
|
-
|
|
573
|
+
harness 包的 devDependency 用该线的 prerelease range(当前 `^0.1.7-alpha.1`,会解析到
|
|
574
|
+
锁定的 `@deepseek-ai/dsh` CLI 自己声明的精确闭包),让仓库依赖树与全新 CLI 安装解析出
|
|
575
|
+
同一个连贯家族——在此用精确 patch
|
|
322
576
|
锁定、与 CLI 的 range 闭包混存会得到分裂闭包(同名包两个版本),profile 启动时报
|
|
323
577
|
export-not-found。改这些锁定后务必整体重建 lockfile(`rm -rf node_modules pnpm-lock.yaml
|
|
324
578
|
&& pnpm install`):原地增量安装既会留下污染 profile heal 的残留 store 条目,还会保留
|
|
@@ -331,10 +585,12 @@ undefined (reading 'length')`(PersistenceCoordinator)崩掉。`pnpm-workspac
|
|
|
331
585
|
|
|
332
586
|
## 已知限制
|
|
333
587
|
|
|
334
|
-
不支持音频附件(不声明 audio
|
|
335
|
-
prompt。MCP 支持 stdio
|
|
336
|
-
|
|
337
|
-
|
|
588
|
+
不支持音频附件(不声明 audio 能力)、文本默认按块粒度流式(`streamDeltas: true`
|
|
589
|
+
可切换为逐 token 流式,见「特性」)、每会话同时一个 in-flight prompt。MCP 支持 stdio
|
|
590
|
+
与 streamable HTTP(不声明 legacy SSE / `acp` 传输)。
|
|
591
|
+
`session/fork` / `session/resume` 未实现(不声明能力,合规客户端
|
|
592
|
+
不会调用)。`session/delete` 同样不广播:harness 未声明公开的持久化删除接口,因此本桥
|
|
593
|
+
永不删除已持久化的会话(见「兼容性」)。
|
|
338
594
|
|
|
339
595
|
多根工作区已声明、模型可见所有根,但 dsh 沙箱策略每会话只解析**一个可写根**(主
|
|
340
596
|
`cwd`,即 `session.header.cwd`),本地沙箱也只为该根开放写权限。读操作在所有根均可
|
|
@@ -344,10 +600,11 @@ prompt。MCP 支持 stdio 与 streamable HTTP(不声明 legacy SSE / `acp` 传
|
|
|
344
600
|
|
|
345
601
|
Agent 预设接管了模型侧相关行:自带 `cordis.patch.yml` 会禁用 preset 拥有的 dsh-base
|
|
346
602
|
行(tool-bash/fs/subagent/todo/web/…——与官方 dsh-web-app/tui 清单逐行一致,仅少
|
|
347
|
-
`hmr
|
|
348
|
-
随 dsh CLI
|
|
603
|
+
`hmr`;清单保持跨代通用:某一代没有的行会被 patch applier 告警并跳过),并挂载 `agent-presets` 名册(默认 `standard`;`ptc`/`minimal`/`cordis`
|
|
604
|
+
随 dsh CLI 附带;自建预设从 0.1.7 起写成 `@deepseek-ai/dsh-agent-preset` 声明行,见「自建 preset」)。bundle 自带
|
|
349
605
|
patch 会自动装配(package.json `dsh.bundle.patch`)——**不要**把它复制进 profile
|
|
350
606
|
的用户层 `cordis.patch.yml`,否则 loader 在启动时因重复 entry id 拒绝装配。**升级**
|
|
351
607
|
一个已有自定义用户层 patch 的 profile 时,用户层只保留你自己的定制行(例如
|
|
352
608
|
acp-enhanced 行的 `includeAllProviders: true`,同时 restate provider/model/preset——
|
|
353
|
-
patch
|
|
609
|
+
patch 条目是整体替换、不做合并)。会话恢复时用日志里记的 preset(最后一条 `agent-preset/selected`,
|
|
610
|
+
否则取创建时的 header);只有日志里什么都没记的会话才落到名册默认预设上。
|