dsh-acp-enhanced 0.9.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 +147 -34
- package/README.md +173 -39
- package/cordis.patch.yml +604 -6
- package/lib/codec.js +135 -3
- package/lib/index.js +345 -94
- package/lib/stored-titles.js +228 -0
- package/lib/terminal-codec.js +52 -16
- package/package.json +24 -25
- package/profile/cordis.yml +17 -2
- package/scripts/acp-doctor.mjs +54 -4
- package/scripts/dsh-acp-zed.sh +12 -5
- package/scripts/init-acp-home.sh +11 -3
package/README-zh.md
CHANGED
|
@@ -18,7 +18,12 @@ ACP 线上。
|
|
|
18
18
|
上线),代价是中途重试无法收回已发出的半截文本,会以可见的
|
|
19
19
|
`_[stream interrupted — retrying]_` 标记隔开(默认关闭)
|
|
20
20
|
- **完整遥测**:上下文用量环 + 缓存命中率 / TPS / 输入-输出-推理 token / 工具耗时 /
|
|
21
|
-
轮次计数(`usage_update._meta`
|
|
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`。
|
|
22
27
|
- **图片支持(多模态)**:当 dsh 组合挂载了附件存储(`dsh-base` 默认装配
|
|
23
28
|
`dsh-attachment-local`)时,会声明 `promptCapabilities.image` 并把粘贴/
|
|
24
29
|
上传的图片持久化进 harness 附件存储——支持视觉的模型(如 `deepseek-v4-flash-vision-exp`)
|
|
@@ -34,13 +39,15 @@ ACP 线上。
|
|
|
34
39
|
绝不出现空的 "unknown" 选择
|
|
35
40
|
- **权限预设**:read-only / workspace-write / full-access 三种会话模式
|
|
36
41
|
- **审批**:工具调用弹出原生 allow-once / reject-once 审批
|
|
37
|
-
- **Agent 预设**:每个会话的模型侧组合(工具 + 提示词段)来自 dsh agent-
|
|
38
|
-
名册。`standard` 为完整编码 agent(默认),`minimal`(极简模式)只有裸 shell
|
|
39
|
-
|
|
40
|
-
host 层工具;`
|
|
41
|
-
|
|
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` 命令或
|
|
42
48
|
`DSH_ACP_PRESET` 环境变量(会话默认)选择;**仅空会话可切换**(还没跑过对话),
|
|
43
|
-
|
|
49
|
+
历史记录永远不会横跨两套工具面。配置了一个本名册已没有的 preset 不会把面板弄死:
|
|
50
|
+
空会话会改用名册默认值组合,并在 stderr 说明。
|
|
44
51
|
|
|
45
52
|
### Zed 深度集成
|
|
46
53
|
|
|
@@ -96,8 +103,9 @@ ACP 线上。
|
|
|
96
103
|
|
|
97
104
|
## 快速开始
|
|
98
105
|
|
|
99
|
-
**需要 `dsh ≥ 0.1.5-rc.2`**(`npm install -g @deepseek-ai/dsh@0.1.5-rc.2
|
|
100
|
-
|
|
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
|
+
探测更老的代际。
|
|
101
109
|
|
|
102
110
|
本包遵循 dsh 官方插件规范(声明了 `dsh.bundle`),安装与官方组合包一致:**一条命令**
|
|
103
111
|
完成,自动初始化 profile、安装包、追加 bundle 层,全程无需手写 profile YAML。
|
|
@@ -270,10 +278,11 @@ profile 是一个**单一故障域**:`cordis-plugin-loader` 会等待每个条
|
|
|
270
278
|
`@deepseek-ai/dsh-base` 随 CLI 一起发布,版本天然等同于启动它的 CLI;其他任何 bundle 都是
|
|
271
279
|
第三方,其依赖闭包可能漂移。额外插件请挂到「坏了只废掉一个 preset」的位置:
|
|
272
280
|
|
|
273
|
-
- **只新增模型侧工具/命令的插件** → 把行写进某个 preset composition
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
preset
|
|
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 并从列表里剔除,不会拖垮进程。
|
|
277
286
|
- **需要配置宿主服务的插件**(例如要覆写宿主 `web` 行 `searchProvider` 的搜索 provider)
|
|
278
287
|
→ 它属于宿主组合,也就是 profile。这是有意的取舍:接受启动路径上的风险,并在每次改动
|
|
279
288
|
后重跑 doctor。
|
|
@@ -287,25 +296,31 @@ dsh --profile acp-enhanced --dump-config # 每一行来自哪一层
|
|
|
287
296
|
|
|
288
297
|
## 兼容性
|
|
289
298
|
|
|
290
|
-
|
|
291
|
-
`^0.1.5-rc.2 || ^0.1.6-alpha.1
|
|
292
|
-
profile settle 与真实 `session/new`——另有跨代链接检查。桥只消费 harness
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
+
两条路径都不会让启动失败。
|
|
296
309
|
|
|
297
310
|
### 支持策略
|
|
298
311
|
|
|
299
312
|
| 桥版本 | 支持的 dsh 线 | 变化 |
|
|
300
313
|
|---|---|---|
|
|
301
|
-
| **0.9.
|
|
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` |
|
|
302
316
|
| 0.8.x | `^0.1.0-rc.6 … ^0.1.6-alpha.1`(未发布) | 0.1.3+ 实时 seam;0.1.5 持久化 handle API |
|
|
303
317
|
| 0.7.x 及更早 | ≤ 0.1.2-rc.1 | 运行期同时探测两代 |
|
|
304
318
|
|
|
305
319
|
这张表背后的规则:
|
|
306
320
|
|
|
307
321
|
- **新的 dsh API 线对应一次新的桥发布,而不是把运行期探测写得更宽。** 0.7.x 正是靠探测吞下
|
|
308
|
-
0.1.1 → 0.1.5,也正是它悄悄腐烂的原因。
|
|
322
|
+
0.1.1 → 0.1.5,也正是它悄悄腐烂的原因。0.1.7 属于重新打包而非新的 API 线,所以 0.9.1 用
|
|
323
|
+
一个 patch 版本吸收它——所需的探测只有一次成员检查,而不是一张代际矩阵。
|
|
309
324
|
- **下限只随桥的 minor 移动,且绝不静默**:CLI 低于范围时启动器会在启动前告警,doctor 会以
|
|
310
325
|
`RESULT FAIL — CLI too old` 停下。
|
|
311
326
|
- **放弃某条线的方式是发布一个明确这么说的桥**;旧线留在 `feat/dsh-0.1.3-plus-support` 分支上,
|
|
@@ -322,6 +337,93 @@ profile settle 与真实 `session/new`——另有跨代链接检查。桥只消
|
|
|
322
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 |
|
|
323
338
|
| `assistant/chunk` seam 移除 | 实时流只剩 `agent/assistant-stream`(下限已覆盖该代) | 升级 CLI;完全不发流的宿主仍由已提交的 `assistant/message` 兜底 |
|
|
324
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 | 桥的做法 |
|
|
349
|
+
|---|---|---|---|
|
|
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
|
+
两者出错时都是静默的:
|
|
420
|
+
|
|
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」。
|
|
426
|
+
|
|
325
427
|
### 从已发布的 ≤ 0.7.0 升级
|
|
326
428
|
|
|
327
429
|
npm 上的 `latest` 是 **0.7.0**,属于 0.1.3 之前的 API 线,因此桥和 CLI **必须一起动**——只升一半,
|
|
@@ -336,7 +438,7 @@ npm 上的 `latest` 是 **0.7.0**,属于 0.1.3 之前的 API 线,因此桥
|
|
|
336
438
|
升级清单:
|
|
337
439
|
|
|
338
440
|
1. `npm install -g @deepseek-ai/dsh@0.1.5-rc.2`(或上面 peer 范围内的任意版本)。
|
|
339
|
-
2. `dsh plugin --profile acp-enhanced add dsh-acp-enhanced@0.9.
|
|
441
|
+
2. `dsh plugin --profile acp-enhanced add dsh-acp-enhanced@0.9.1`。升级桥是显式动作:profile 里的依赖
|
|
340
442
|
是对 0.x 的 caret,所以 `dsh plugin update` **不会**自行把你带到新的 minor。
|
|
341
443
|
3. 以前是从检出目录启动、或设过 `DSH_PATH`?旧启动器会自行切到 `~/.dsh-acp`,现在不会了。请在 Zed 的
|
|
342
444
|
`agent_servers.env` 里设 `DSH_HOME=<那个 home>`,或在默认 home 里重建 profile。启动器若在那里
|
|
@@ -344,7 +446,8 @@ npm 上的 `latest` 是 **0.7.0**,属于 0.1.3 之前的 API 线,因此桥
|
|
|
344
446
|
4. 以前照旧 README 在 profile 用户层里塞过 `subagent-model-selection-settings`?把它删掉:现在由桥的
|
|
345
447
|
patch 提供该行,重复 id 会让启动中止。`scripts/init-acp-home.sh` 会自动清理;启动器会告警,doctor
|
|
346
448
|
会点名该 id。
|
|
347
|
-
5. 确认 profile 里的第三方 bundle
|
|
449
|
+
5. 确认 profile 里的第三方 bundle 支持你要升到的那条线(`dsh-free-search` 在 0.1.5 上 ≥ 0.4.24
|
|
450
|
+
已验证;在 0.1.7 上需要 ≥ 0.4.39,见「升级到 0.1.7 前要检查的两件事」)——profile 是单一故障域。
|
|
348
451
|
6. 重启 Zed(或新开一个 agent 线程);先用 `node <pkg>/scripts/acp-doctor.mjs` 验证整条链路(它现在连
|
|
349
452
|
开线程都会实测)。
|
|
350
453
|
|
|
@@ -353,9 +456,9 @@ npm 上的 `latest` 是 **0.7.0**,属于 0.1.3 之前的 API 线,因此桥
|
|
|
353
456
|
`$DSH_HOME/profiles/node_modules` 是同 home 下所有 profile 共享的**同一个**依赖闭包,
|
|
354
457
|
dsh 每次启动都会把它 heal 成最后启动的那个 CLI。因此:
|
|
355
458
|
|
|
356
|
-
> 这是 **0.1.5 线**的行为。到 0.1.6-alpha.2
|
|
357
|
-
>
|
|
358
|
-
>
|
|
459
|
+
> 这是 **0.1.5 线**的行为。到 0.1.6-alpha.2 及之后,这个共享闭包已完全不存在(harness 从 CLI
|
|
460
|
+
> 自身的安装位置解析;profile 的 `node_modules` 只放外部插件),所以启动器的漂移检查是「按线」
|
|
461
|
+
> 的,路径消失时会静默跳过。
|
|
359
462
|
|
|
360
463
|
|
|
361
464
|
|
|
@@ -369,7 +472,7 @@ dsh 每次启动都会把它 heal 成最后启动的那个 CLI。因此:
|
|
|
369
472
|
当前解析结果随时可查:
|
|
370
473
|
|
|
371
474
|
```sh
|
|
372
|
-
node scripts/compat-check.mjs # 仅限仓库检出:分别安装 0.1.5-rc.2
|
|
475
|
+
node scripts/compat-check.mjs # 仅限仓库检出:分别安装 0.1.5-rc.2、0.1.6-alpha.2、0.1.7-rc.2 三套,逐一导入本桥
|
|
373
476
|
node <pkg>/scripts/acp-doctor.mjs # CLI 与闭包版本、bundle 列表,并真实启动一次(随包发布)
|
|
374
477
|
```
|
|
375
478
|
|
|
@@ -379,7 +482,7 @@ node <pkg>/scripts/acp-doctor.mjs # CLI 与闭包版本、bundle 列表,并
|
|
|
379
482
|
|
|
380
483
|
1. `$DSH_PATH` —— 显式指定的 dsh 二进制,或其 `node_modules/.bin/dsh` 内含 dsh 的目录
|
|
381
484
|
2. 仓库锁定的 CLI —— `<repo>/node_modules/.bin/dsh`(本包的 `@deepseek-ai/dsh`
|
|
382
|
-
devDependency,当前 0.1.
|
|
485
|
+
devDependency,当前 0.1.7-rc.2)
|
|
383
486
|
3. 全局兜底 —— PATH / npx 缓存 / npm 前缀 里的 `dsh`(未 `pnpm install` 的全新检出退化为它)
|
|
384
487
|
|
|
385
488
|
命中任何一个,profile `acp-enhanced` 都在**启动器所处的 home**(`${DSH_HOME:-$HOME/.dsh}`)中启动。
|
|
@@ -431,9 +534,13 @@ node <pkg>/scripts/acp-doctor.mjs --profile <name> --home <dsh-home> --timeout 6
|
|
|
431
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` |
|
|
432
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` 副本 |
|
|
433
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 后新会话不再携带该写法 |
|
|
434
538
|
| 无法切换模型 | `ACP_DEBUG=1 dsh --profile acp-enhanced`,然后尝试切换 | 携带的 `reasoning_effort` 在目标模型上不受支持:本桥按模型记住上次使用的强度(随 profile 持久化),会回退到该模型默认值而不是让切换失败。另检查路由是否真实——幽灵 provider 会被过滤,只广播 `config.provider` 的模型 |
|
|
435
539
|
| 上下文用量不显示 | 线程里执行 `/status` | 选到了不可路由的"幽灵 provider";确认 profile 的 provider 指向真实路由 |
|
|
436
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` 陆续送达 |
|
|
437
544
|
| 改了插件却不生效 | profile `cordis.patch.yml` 的 mtime | 改动只在**下一个**进程生效:新开 agent 线程(或重启 Zed) |
|
|
438
545
|
| 需要详细诊断 | — | `ACP_DEBUG=1`(stderr 生命周期 trace)与 `ACP_LOG=/tmp/acp.jsonl`(逐事件 JSONL,带耗时) |
|
|
439
546
|
|
|
@@ -441,7 +548,7 @@ node <pkg>/scripts/acp-doctor.mjs --profile <name> --home <dsh-home> --timeout 6
|
|
|
441
548
|
|
|
442
549
|
```sh
|
|
443
550
|
pnpm install # 安装开发依赖(仓库锁定 CLI 与测试脚本)
|
|
444
|
-
node scripts/compat-check.mjs # 支持线上的链接检查(0.1.5-rc.2 / 0.1.6-alpha.2 临时安装)
|
|
551
|
+
node scripts/compat-check.mjs # 支持线上的链接检查(0.1.5-rc.2 / 0.1.6-alpha.2 / 0.1.7-rc.2 临时安装)
|
|
445
552
|
node scripts/api-surface-check.mjs # 公开表面守卫:不得使用未声明的 harness API(CI 阻塞步骤)
|
|
446
553
|
node scripts/pack-check.mjs # 包完整性:入口文件、权限位、所引用文件是否都随包发布(CI 阻塞步骤)
|
|
447
554
|
node scripts/acp-client.mjs # 端到端冒烟(需要 API key)
|
|
@@ -451,6 +558,10 @@ node scripts/acp-smoke-keyless.mjs # keyless 冒烟(CI 用)
|
|
|
451
558
|
node scripts/acp-resume-test.mjs # 会话恢复测试
|
|
452
559
|
node scripts/codec-image-test.mjs # 图片编解码单元测试(无网络,假 store)
|
|
453
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 与正文提取,覆盖各支持代的形状(无网络)
|
|
454
565
|
node scripts/replay-order-test.mjs # 重放/回退的分块顺序:思考块先于它产出的回复(无网络)
|
|
455
566
|
node scripts/acp-image-e2e.mjs # 图片能力端到端(vision 模型段需 API key)
|
|
456
567
|
node scripts/acp-message-fallback-test.mjs # 实时 seam + assistant/message 回退:seam 确实触发且回复恰好到达一次
|
|
@@ -459,8 +570,9 @@ node scripts/acp-doctor.mjs # 真实启动一次 profile,指出失
|
|
|
459
570
|
scripts/init-acp-home.sh # 可选:引导**独立** home(启动器不会自行切过去)
|
|
460
571
|
```
|
|
461
572
|
|
|
462
|
-
harness 包的 devDependency
|
|
463
|
-
|
|
573
|
+
harness 包的 devDependency 用该线的 prerelease range(当前 `^0.1.7-alpha.1`,会解析到
|
|
574
|
+
锁定的 `@deepseek-ai/dsh` CLI 自己声明的精确闭包),让仓库依赖树与全新 CLI 安装解析出
|
|
575
|
+
同一个连贯家族——在此用精确 patch
|
|
464
576
|
锁定、与 CLI 的 range 闭包混存会得到分裂闭包(同名包两个版本),profile 启动时报
|
|
465
577
|
export-not-found。改这些锁定后务必整体重建 lockfile(`rm -rf node_modules pnpm-lock.yaml
|
|
466
578
|
&& pnpm install`):原地增量安装既会留下污染 profile heal 的残留 store 条目,还会保留
|
|
@@ -488,10 +600,11 @@ undefined (reading 'length')`(PersistenceCoordinator)崩掉。`pnpm-workspac
|
|
|
488
600
|
|
|
489
601
|
Agent 预设接管了模型侧相关行:自带 `cordis.patch.yml` 会禁用 preset 拥有的 dsh-base
|
|
490
602
|
行(tool-bash/fs/subagent/todo/web/…——与官方 dsh-web-app/tui 清单逐行一致,仅少
|
|
491
|
-
`hmr`;清单保持跨代通用:某一代没有的行会被 patch applier 告警并跳过),并挂载 `agent-presets` 名册(默认 `standard`;`
|
|
492
|
-
随 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 自带
|
|
493
605
|
patch 会自动装配(package.json `dsh.bundle.patch`)——**不要**把它复制进 profile
|
|
494
606
|
的用户层 `cordis.patch.yml`,否则 loader 在启动时因重复 entry id 拒绝装配。**升级**
|
|
495
607
|
一个已有自定义用户层 patch 的 profile 时,用户层只保留你自己的定制行(例如
|
|
496
608
|
acp-enhanced 行的 `includeAllProviders: true`,同时 restate provider/model/preset——
|
|
497
|
-
patch
|
|
609
|
+
patch 条目是整体替换、不做合并)。会话恢复时用日志里记的 preset(最后一条 `agent-preset/selected`,
|
|
610
|
+
否则取创建时的 header);只有日志里什么都没记的会话才落到名册默认预设上。
|