@aiwayds/dsh-dcp 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +18 -7
- package/README.md +13 -7
- package/icon.svg +5 -0
- package/lib/command.js +16 -9
- package/lib/config.js +1 -0
- package/lib/index.js +8 -2
- package/lib/skill.js +1 -1
- package/lib/sources.d.ts +28 -0
- package/lib/summarizer.js +45 -40
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +48 -44
- package/scripts/compare.mjs +1 -4
- package/scripts/setup.mjs +1 -1
- package/skills/dsh-dcp-config/SKILL.md +4 -3
package/README.en.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Deterministic context-compaction backend for dsh (DeepSeek Harness): **context
|
|
4
4
|
compaction without an LLM call**, works out of the box.
|
|
5
5
|
|
|
6
|
-
**Requires dsh >= 0.1.
|
|
6
|
+
**Requires dsh >= 0.1.7-rc.1** — this plugin targets the dsh RC/stable line only (CI and releases resolve the newest of the `latest`/`next` dist-tags at runtime). **The alpha line is no longer supported.**
|
|
7
7
|
|
|
8
8
|
> [简体中文](README.md) · **English**
|
|
9
9
|
|
|
@@ -131,15 +131,25 @@ Removing the package without the reverse step leaves the mount pointing at the v
|
|
|
131
131
|
|
|
132
132
|
| Command | Effect |
|
|
133
133
|
|---|---|
|
|
134
|
-
| `/dcp` |
|
|
135
|
-
| `/dcp
|
|
134
|
+
| `/dcp` | compact now (zero LLM); same as `/dcp compact` |
|
|
135
|
+
| `/dcp status` | status: config, compaction count, tokens saved |
|
|
136
|
+
| `/dcp help` / `--help` / `-h` | show the command grammar |
|
|
136
137
|
| `/dcp set <k> <v>` | adjust a knob for this session, with a persist hint |
|
|
137
138
|
|
|
138
139
|
Settable: `dedup`, `purgeErrors`, `maxItems`, `maxItemChars`,
|
|
139
140
|
`maxSummaryTokens`, `language`, `tokenEstimate`, `thresholdRatio`,
|
|
140
141
|
`roundInterval`, `notice`, `onModelSwitch`, `modelSwitchMinTokens`.
|
|
141
142
|
|
|
142
|
-
The `/dcp`
|
|
143
|
+
The bare `/dcp` and `/dcp compact` hit the same manual compaction seam:
|
|
144
|
+
the common action takes zero arguments, so nobody has to remember a
|
|
145
|
+
subcommand, while the read-only and tuning verbs stay behind explicit
|
|
146
|
+
arguments (`/dcp status` for the block, `/dcp help` for usage).
|
|
147
|
+
|
|
148
|
+
> **Behavior change in 0.11.0**: the bare `/dcp` now compacts instead of
|
|
149
|
+
> showing status; the status output moved to `/dcp status`. After
|
|
150
|
+
> upgrading, use `/dcp status` to inspect — the bare command compacts.
|
|
151
|
+
|
|
152
|
+
The `/dcp status` block also lists every session that has compacted (subagents
|
|
143
153
|
included): `per-session: session-1 (2 compactions, ~444 tokens), child
|
|
144
154
|
(1 compaction, ~22 tokens)`. Compactions count per session; disposed
|
|
145
155
|
sessions (one-shot subagents included) fall out of the overview
|
|
@@ -154,11 +164,11 @@ for the rest) so the status stays one line.
|
|
|
154
164
|
| Overflow recovery | on a provider context-window error | inherited |
|
|
155
165
|
| **Round interval** | every `roundInterval` assistant messages | added by this plugin; one round = one LLM roundtrip (each tool-iteration response counts, so one-shot subagents trigger too). **Default 50**: first compaction after message 50, then every 50 more (100, 150, …); any compaction (pressure included) restarts the clock. Fires at the first idle boundary after the count is reached (below the pressure threshold too). `0` disables; requires the default `auto: true` |
|
|
156
166
|
| **Model switch** | the session's effective provider/model route changes | added by this plugin (`onModelSwitch`). Default `notice`: appends one row suggesting `/dcp compact` first to shadow the old model's history and save tokens; `auto` compacts at the session's next idle boundary; `off` disables. Two gates: switches within 10 assistant messages of the last compaction are ignored (nothing stale to shadow), and switches while the context is below `modelSwitchMinTokens` (default 32768, `0` disables this gate) are ignored (not enough to be worth shadowing); `auto` requires the default `auto: true`, otherwise it degrades to `notice` |
|
|
157
|
-
| Manual | `/dcp compact`, `/compact` | anytime |
|
|
167
|
+
| Manual | `/dcp` (bare), `/dcp compact`, `/compact` | anytime |
|
|
158
168
|
|
|
159
169
|
- **Subagents are covered**: in-process subagents (including continuable and one-shot children) dispatch through the same events, so pressure/overflow/round/model-switch triggers count and fire per child session independently. The round trigger counts assistant messages, so a one-shot subagent whose whole run is a single turn (many tool iterations) triggers too.
|
|
160
170
|
- **How model-switch detection works**: the per-request `request/context` routing snapshot is folded per session (a provider or model change alone counts as a switch), covering every switch entry point — TUI `/model`, web clients, changed default-model settings. A session's first observed request only seeds the baseline. `notice: false` silences the compaction rows only; the switch row is controlled by `onModelSwitch` independently. The size floor is measured by the host token meter (`measure().surfaceTokens`) and fails open when unavailable.
|
|
161
|
-
- **Visibility**: after every trigger event a one-line notice row (`dcp: compacted N history items (~X tokens, trigger)`) is appended to the session; frontends render it as a collapsed row. Note the row also rides the model request context (~15–25 tokens per compaction), and it is **on by default since 0.4.0** — disable with `notice: false`. `/dcp` stats count every committed region (a pressure retry loop may commit several).
|
|
171
|
+
- **Visibility**: after every trigger event a one-line notice row (`dcp: compacted N history items (~X tokens, trigger)`) is appended to the session; frontends render it as a collapsed row. Note the row also rides the model request context (~15–25 tokens per compaction), and it is **on by default since 0.4.0** — disable with `notice: false`. `/dcp status` stats count every committed region (a pressure retry loop may commit several).
|
|
162
172
|
|
|
163
173
|
## Configuration
|
|
164
174
|
|
|
@@ -167,6 +177,7 @@ All optional, defaults work out of the box:
|
|
|
167
177
|
| Key | Default | Meaning |
|
|
168
178
|
|---|---|---|
|
|
169
179
|
| `thresholdRatio` | 0.8 | pressure trigger (inherited upstream compaction-basic default 0.8; this plugin's bundle patch mounts 0.7, recommended for CJK-heavy sessions) |
|
|
180
|
+
| `headroomTokens` | 65536 | inherited from upstream compaction-basic (new in 0.1.7): extra pressure-budget margin (non-negative integer). The pressure ceiling is context window − routed output reservation (`maxTokens`) − this margin; lower it for small-window models |
|
|
170
181
|
| `roundInterval` | 50 | compact every N assistant messages (one LLM roundtrip) (0 disables). Default 50: 50, 100, 150… — the clock restarts after every compaction |
|
|
171
182
|
| `onModelSwitch` | `notice` | after a model switch: `notice` suggests `/dcp compact` (default); `auto` compacts at the next idle boundary; `off` disables |
|
|
172
183
|
| `modelSwitchMinTokens` | 32768 | minimum priced context size (measured by the host token meter) for a model switch to be announced; `0` disables this gate. 32k default ≈ the post-compaction baseline (~16% of the window) plus some real growth |
|
|
@@ -197,7 +208,7 @@ cordis.patch.yml mount block.
|
|
|
197
208
|
## Development
|
|
198
209
|
|
|
199
210
|
```bash
|
|
200
|
-
npm install && npm test #
|
|
211
|
+
npm install && npm test # 109 tests: extractor/compaction/command/config/triggers/recover-seam/setup
|
|
201
212
|
```
|
|
202
213
|
|
|
203
214
|
## License
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
dsh(DeepSeek Harness)的确定性压缩后端:**上下文压缩不调 LLM**,开箱即用。
|
|
4
4
|
|
|
5
|
-
**要求 dsh >= 0.1.
|
|
5
|
+
**要求 dsh >= 0.1.7-rc.1** — 本插件只跟随 dsh RC/stable 线(CI 与发版在运行时解析 latest/next 中更新的 dist-tag)。**不再支持 alpha 线。**
|
|
6
6
|
|
|
7
7
|
> **简体中文** · [English](README.en.md)
|
|
8
8
|
|
|
@@ -110,13 +110,18 @@ npx dsh-dcp-setup --remove /path/to/cordis.patch.yml
|
|
|
110
110
|
|
|
111
111
|
| 命令 | 作用 |
|
|
112
112
|
|---|---|
|
|
113
|
-
| `/dcp` |
|
|
114
|
-
| `/dcp
|
|
113
|
+
| `/dcp` | 立即压缩(零 LLM);等同于 `/dcp compact` |
|
|
114
|
+
| `/dcp status` | 状态:配置、压缩次数、省下的 token |
|
|
115
|
+
| `/dcp help` / `--help` / `-h` | 显示命令用法 |
|
|
115
116
|
| `/dcp set <k> <v>` | 会话内调参,并提示如何持久化 |
|
|
116
117
|
|
|
117
118
|
可调键:`dedup`、`purgeErrors`、`maxItems`、`maxItemChars`、`maxSummaryTokens`、`language`、`tokenEstimate`、`thresholdRatio`、`roundInterval`、`notice`、`onModelSwitch`、`modelSwitchMinTokens`。
|
|
118
119
|
|
|
119
|
-
`/dcp`
|
|
120
|
+
裸 `/dcp` 与 `/dcp compact` 走同一条手动压缩缝——最常用的动作零参数直达,不必记子命令;只读或调参的动作留在显式子命令后面(看状态打 `/dcp status`,用法打 `/dcp help`)。
|
|
121
|
+
|
|
122
|
+
> **0.11.0 起语义变更**:裸 `/dcp` 由「显示状态」改为「立即压缩」,原来的状态输出移到 `/dcp status`。升级后别再用裸 `/dcp` 查状态——它会直接压一次。
|
|
123
|
+
|
|
124
|
+
`/dcp status` 还会列出每个发生过压缩的会话(per-session 概览,含子代理),例如 `per-session: session-1 (2 compactions, ~444 tokens), child (1 compaction, ~22 tokens)`。压缩按会话独立计数;已销毁的会话(含 one-shot 子代理)自动从概览消失;列表封顶一行(最多前 10 个会话,超出显示 `+N more`)。
|
|
120
125
|
|
|
121
126
|
## 触发条件
|
|
122
127
|
|
|
@@ -126,11 +131,11 @@ npx dsh-dcp-setup --remove /path/to/cordis.patch.yml
|
|
|
126
131
|
| 溢出恢复 | 模型报 context 超限时 | 继承官方 |
|
|
127
132
|
| **轮数触发** | 会话每收到 `roundInterval` 条 assistant message | 本插件新增;一条 = 一次 LLM 往返(每轮工具迭代各算一条,one-shot 子代理也能触发)。**默认 50**:第 50 条后触发第一次,之后每 50 条一次(100、150……);任何一次压缩(含压力触发)都会重置轮数时钟。到达条数后的第一个空闲点触发(阈值之下也压)。`0` 关闭;需保持 `auto: true`(默认开) |
|
|
128
133
|
| **模型切换** | 会话实际路由的 provider/model 变化时 | 本插件新增(`onModelSwitch`)。默认 `notice`:追加一行提醒"建议先执行 `/dcp compact` 压缩旧模型历史,节省 token";`auto` 在该会话下一个空闲点自动压缩;`off` 关闭。两道门控:距上次压缩不足 10 条 assistant message 忽略(没有旧账可甩),上下文不足 `modelSwitchMinTokens`(默认 32768,`0` 关闭该门)忽略(不够甩的量);`auto` 需保持 `auto: true`(默认开),否则降级为 `notice` |
|
|
129
|
-
| 手动 | `/dcp compact`、`/compact` | 随时可用 |
|
|
134
|
+
| 手动 | `/dcp`(无参数)、`/dcp compact`、`/compact` | 随时可用 |
|
|
130
135
|
|
|
131
136
|
- **subagent 同样生效**:进程内 subagent(含 continuable 与 one-shot 子代理)走同一套事件分发,压力/溢出/轮数/模型切换对子会话独立计数、独立触发。轮数触发按 assistant message 计数,所以全程只有 1 个 turn 的 one-shot 子代理(多次工具迭代)也能触发。
|
|
132
137
|
- **模型切换检测原理**:折叠每请求的 `request/context` 路由快照(provider 或 model 任一变化即判定切换),覆盖所有切换入口(TUI `/model`、Web 客户端、默认模型设置变更);会话首个请求只播种基线不告警。`notice: false` 只关压缩通知行,模型切换提醒行由 `onModelSwitch` 独立控制。上下文下限按宿主 tokenMeter 的实测计价(`measure().surfaceTokens`),测不到时 fail-open(只留轮数门控)。
|
|
133
|
-
- **压缩可见性**:每次压缩成功后,会话里追加一行 `dcp: 已压缩 N 条历史(约 X tokens,触发方式)` 通知行(前端渲染为折叠行)。注意该行也会作为上下文随请求发给模型(每次压缩约 15–25 tokens),且 **0.4.0 起默认开启**;`notice: false` 可关闭。`/dcp` 的 stats 持续累计(压力触发的多次 region 提交各计一次)。
|
|
138
|
+
- **压缩可见性**:每次压缩成功后,会话里追加一行 `dcp: 已压缩 N 条历史(约 X tokens,触发方式)` 通知行(前端渲染为折叠行)。注意该行也会作为上下文随请求发给模型(每次压缩约 15–25 tokens),且 **0.4.0 起默认开启**;`notice: false` 可关闭。`/dcp status` 的 stats 持续累计(压力触发的多次 region 提交各计一次)。
|
|
134
139
|
|
|
135
140
|
## 配置
|
|
136
141
|
|
|
@@ -139,6 +144,7 @@ npx dsh-dcp-setup --remove /path/to/cordis.patch.yml
|
|
|
139
144
|
| 键 | 默认 | 说明 |
|
|
140
145
|
|---|---|---|
|
|
141
146
|
| `thresholdRatio` | 0.8 | 压力触发阈值(继承上游 compaction-basic 默认 0.8;本插件 bundle patch 挂载时默认 0.7,中文场景建议 0.7) |
|
|
147
|
+
| `headroomTokens` | 65536 | 继承上游 compaction-basic(0.1.7 新增):压力预算额外余量(非负整数)。压力上限 = 上下文窗口 − 路由请求预留输出(`maxTokens`)− 本余量;小窗口模型建议下调 |
|
|
142
148
|
| `roundInterval` | 50 | 每 N 条 assistant message(一次 LLM 往返)触发一次压缩(0 关闭)。默认 50:50、100、150……每次压缩后重数 |
|
|
143
149
|
| `onModelSwitch` | `notice` | 模型切换后:`notice` 提醒执行 `/dcp compact`(默认);`auto` 下一个空闲点自动压缩;`off` 关闭 |
|
|
144
150
|
| `modelSwitchMinTokens` | 32768 | 模型切换提醒/自动压缩的上下文下限(按宿主 tokenMeter 实测计价):不足则忽略该次切换;`0` 关闭此门。默认 32k ≈ 压缩后基线(~16% 窗口)之上再涨一截才有得甩 |
|
|
@@ -164,7 +170,7 @@ npx dsh-dcp-setup --remove /path/to/cordis.patch.yml
|
|
|
164
170
|
## 开发
|
|
165
171
|
|
|
166
172
|
```bash
|
|
167
|
-
npm install && npm test #
|
|
173
|
+
npm install && npm test # 109 个用例:抽取/压缩/命令/配置/触发/恢复缝/安装脚本
|
|
168
174
|
```
|
|
169
175
|
|
|
170
176
|
## License
|
package/icon.svg
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M5 5.5h14M8 12h8M5 18.5h14"/>
|
|
3
|
+
<path d="m10.4 1.8 1.6 1.6 1.6-1.6"/>
|
|
4
|
+
<path d="m10.4 22.2 1.6-1.6 1.6 1.6"/>
|
|
5
|
+
</svg>
|
package/lib/command.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `/dcp` slash command:
|
|
3
|
-
* one entry point, no required arguments (design references
|
|
4
|
-
* `/dcp` panel in a dsh-idiomatic, text-only form).
|
|
2
|
+
* The `/dcp` slash command: manual compaction by default, plus status and
|
|
3
|
+
* runtime knobs — one entry point, no required arguments (design references
|
|
4
|
+
* opencode-dcp's `/dcp` panel in a dsh-idiomatic, text-only form).
|
|
5
|
+
*
|
|
6
|
+
* The bare command compacts, matching how a user reaches for `/dcp` when the
|
|
7
|
+
* context feels heavy; the infrequent read-only and tuning verbs stay behind
|
|
8
|
+
* explicit arguments (`status`, `set`), and `--help` prints the grammar.
|
|
5
9
|
*
|
|
6
10
|
* @module dsh-dcp/command
|
|
7
11
|
*/
|
|
@@ -10,8 +14,10 @@ import { ManualCompactionError } from '@deepseek-ai/dsh-compaction'
|
|
|
10
14
|
import { RUNTIME_SETTABLE } from './config.js'
|
|
11
15
|
|
|
12
16
|
const USAGE = `Usage:
|
|
13
|
-
/dcp
|
|
14
|
-
/dcp compact
|
|
17
|
+
/dcp compact now (deterministic, no LLM call)
|
|
18
|
+
/dcp compact same as the bare command
|
|
19
|
+
/dcp status show status (mode, config, compaction stats)
|
|
20
|
+
/dcp help show this help (also --help / -h)
|
|
15
21
|
/dcp set <k> <v> adjust a knob for this session (dedup, purgeErrors,
|
|
16
22
|
maxItems, maxItemChars, maxSummaryTokens, language,
|
|
17
23
|
tokenEstimate, thresholdRatio, roundInterval, notice,
|
|
@@ -127,10 +133,10 @@ async function compactNow(ctx, invocation, engine) {
|
|
|
127
133
|
export async function executeDcp(ctx, invocation, engine, version) {
|
|
128
134
|
const tokens = invocation.rawInput.trim().split(/\s+/).filter((token) => token.length > 0)
|
|
129
135
|
const [subcommand, ...rest] = tokens
|
|
130
|
-
if (subcommand === undefined) return
|
|
131
|
-
if (subcommand === 'status') return success(statusText(engine, version))
|
|
132
|
-
if (subcommand === 'help') return success(USAGE)
|
|
136
|
+
if (subcommand === undefined) return compactNow(ctx, invocation, engine)
|
|
133
137
|
if (subcommand === 'compact') return compactNow(ctx, invocation, engine)
|
|
138
|
+
if (subcommand === 'status') return success(statusText(engine, version))
|
|
139
|
+
if (subcommand === 'help' || subcommand === '--help' || subcommand === '-h') return success(USAGE)
|
|
134
140
|
if (subcommand === 'set') {
|
|
135
141
|
if (rest.length < 2) return failure(USAGE)
|
|
136
142
|
const outcome = applySet(engine, rest[0], rest.slice(1).join(' '))
|
|
@@ -149,7 +155,8 @@ export async function executeDcp(ctx, invocation, engine, version) {
|
|
|
149
155
|
export function registerDcpCommand(ctx, engine, version) {
|
|
150
156
|
return ctx.commands.register({
|
|
151
157
|
name: 'dcp',
|
|
152
|
-
description: 'dsh-dcp: deterministic
|
|
158
|
+
description: 'dsh-dcp: compact now (deterministic, zero LLM) — /dcp --help for status and controls',
|
|
159
|
+
input: { hint: '[compact|status|help|set <k> <v>]' },
|
|
153
160
|
handler: (invocation) => executeDcp(ctx, invocation, engine, version),
|
|
154
161
|
})
|
|
155
162
|
}
|
package/lib/config.js
CHANGED
package/lib/index.js
CHANGED
|
@@ -96,6 +96,7 @@ const modelPolicy = z.object({
|
|
|
96
96
|
provider: z.string().required(),
|
|
97
97
|
model: z.string().required(),
|
|
98
98
|
thresholdRatio: z.number(),
|
|
99
|
+
headroomTokens: z.number().step(1).min(0),
|
|
99
100
|
retainRatio: z.number(),
|
|
100
101
|
retainTokens: z.number().step(1).min(0),
|
|
101
102
|
summarizationProvider: z.string(),
|
|
@@ -111,6 +112,7 @@ export class DcpEngine extends BasicCompactionEngine {
|
|
|
111
112
|
static Config = z.object({
|
|
112
113
|
// compaction-basic policy keys (forwarded verbatim)
|
|
113
114
|
thresholdRatio: z.number(),
|
|
115
|
+
headroomTokens: z.number().step(1).min(0),
|
|
114
116
|
retainRatio: z.number(),
|
|
115
117
|
retainTokens: z.number().step(1).min(0),
|
|
116
118
|
summarizationProvider: z.string(),
|
|
@@ -371,7 +373,9 @@ export class DcpEngine extends BasicCompactionEngine {
|
|
|
371
373
|
try {
|
|
372
374
|
session.append('user/message', createUserMessage({
|
|
373
375
|
content: [{ type: 'text', text: summary }],
|
|
374
|
-
|
|
376
|
+
// Producer-owned kind (dsh 0.1.7 removed the 'plugin' catch-all);
|
|
377
|
+
// declared for checkJs in lib/sources.d.ts.
|
|
378
|
+
source: { kind: 'dsh-dcp', form: 'notice', summary },
|
|
375
379
|
}))
|
|
376
380
|
} catch (error) {
|
|
377
381
|
const message = error instanceof Error ? error.message : String(error)
|
|
@@ -483,7 +487,9 @@ export class DcpEngine extends BasicCompactionEngine {
|
|
|
483
487
|
try {
|
|
484
488
|
session.append('user/message', createUserMessage({
|
|
485
489
|
content: [{ type: 'text', text: summary }],
|
|
486
|
-
|
|
490
|
+
// Producer-owned kind (dsh 0.1.7 removed the 'plugin' catch-all);
|
|
491
|
+
// declared for checkJs in lib/sources.d.ts.
|
|
492
|
+
source: { kind: 'dsh-dcp', form: 'notice', summary },
|
|
487
493
|
}))
|
|
488
494
|
} catch (error) {
|
|
489
495
|
// The compaction already committed; a display-row failure must never
|
package/lib/skill.js
CHANGED
|
@@ -39,7 +39,7 @@ const SKILL_RESOURCE_BASE = {
|
|
|
39
39
|
const SKILL_INVOCATION = { modelInvocable: true, userInvocable: true }
|
|
40
40
|
|
|
41
41
|
/** Routing description; must stay identical to the SKILL.md frontmatter (asserted in tests). */
|
|
42
|
-
export const SKILL_DESCRIPTION = 'dsh 压缩引擎插件(@aiwayds/dsh-dcp)使用与配置指南。凡涉及上下文压缩、/dcp 命令、压缩调参(阈值/密度/语言/轮数触发/模型切换),或要配置 dcp
|
|
42
|
+
export const SKILL_DESCRIPTION = 'dsh 压缩引擎插件(@aiwayds/dsh-dcp)使用与配置指南。凡涉及上下文压缩、/dcp 命令、压缩调参(阈值/密度/语言/轮数触发/模型切换),或要配置 dcp 时先读本指南:裸 /dcp 即压缩、/dcp status 看状态与 /dcp set 十二个可调键、持久化到 cordis.patch.yml 挂载块 config: 段(dsh-dcp-setup 管理)、ask_user_question 调参向导、五类触发(压力/溢出/轮数/模型切换/手动)、subagent 会话独立计数生效。触发词:dcp、压缩、compaction、上下文超限、摘要、thresholdRatio、roundInterval、onModelSwitch。'
|
|
43
43
|
|
|
44
44
|
const SKILL_CANDIDATE = {
|
|
45
45
|
name: SKILL_PROVIDER_NAME,
|
package/lib/sources.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-dcp's producer-owned message source kinds.
|
|
3
|
+
*
|
|
4
|
+
* dsh 0.1.7 removed the shared `kind: 'plugin'` catch-all: MessageSourceMap is
|
|
5
|
+
* now merge-extensible and every producer declares its own `kind` in its own
|
|
6
|
+
* module (see `MessageSourceMap` in @deepseek-ai/dsh-llm/message and the
|
|
7
|
+
* bundled `webhook` producer for the canonical shape). Session-log V4 admission
|
|
8
|
+
* refuses retired `'plugin'` wrappers, so the declarations below are what lets
|
|
9
|
+
* dsh-dcp's transcript rows persist.
|
|
10
|
+
*
|
|
11
|
+
* Legacy rows: session-format V3→V4 migrates unknown third-party plugin names
|
|
12
|
+
* to `plugin:<name>` kinds, so pre-migration dsh-dcp notice rows replay as
|
|
13
|
+
* `plugin:dsh-dcp` — lib/summarizer.js skips both spellings.
|
|
14
|
+
*/
|
|
15
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
16
|
+
interface MessageSourceMap {
|
|
17
|
+
/** dsh-dcp transcript row: a one-line compaction/model-switch account. */
|
|
18
|
+
'dsh-dcp': {
|
|
19
|
+
readonly kind: 'dsh-dcp'
|
|
20
|
+
readonly form: 'notice'
|
|
21
|
+
/** The bounded one-line account, via `boundContextSummary`. */
|
|
22
|
+
readonly summary: string
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Module marker: keeps the block above an augmentation (merging), not an ambient module declaration (shadowing). */
|
|
28
|
+
export {}
|
package/lib/summarizer.js
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* @module dsh-dcp/summarizer
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import { isCompactCheckpointSource } from '@deepseek-ai/dsh-compaction'
|
|
20
|
+
|
|
19
21
|
/** Section headers shared with compaction-basic's checkpoint instruction. */
|
|
20
22
|
export const SECTIONS = Object.freeze({
|
|
21
23
|
intent: 'Primary Request and Intent',
|
|
@@ -101,11 +103,13 @@ export function estimateTextTokens(text, mode = 'cjk') {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
/**
|
|
104
|
-
* Token estimate for one message: text blocks
|
|
105
|
-
*
|
|
106
|
-
*
|
|
106
|
+
* Token estimate for one message: text blocks and tool-call arguments. Tool
|
|
107
|
+
* results are first-class role-`'tool'` messages since dsh 0.1.7 (the old
|
|
108
|
+
* user-role `'tool-result'` block is gone), so their text blocks price through
|
|
109
|
+
* the same `'text'` branch — the same content the host meter prices, minus its
|
|
110
|
+
* per-block overhead.
|
|
107
111
|
*
|
|
108
|
-
* @param {{ content?: Array<Record<string, any>> }} message - any message-shaped object.
|
|
112
|
+
* @param {{ role?: string, content?: Array<Record<string, any>> }} message - any message-shaped object.
|
|
109
113
|
* @param {'cjk'|'ascii'} [mode] - pricing mode, see {@link estimateTextTokens}.
|
|
110
114
|
* @returns {number} estimated tokens.
|
|
111
115
|
*/
|
|
@@ -114,11 +118,6 @@ export function estimateMessageTokens(message, mode = 'cjk') {
|
|
|
114
118
|
for (const block of message?.content ?? []) {
|
|
115
119
|
if (block.type === 'text') parts.push(block.text)
|
|
116
120
|
else if (block.type === 'tool-call') parts.push(block.arguments)
|
|
117
|
-
else if (block.type === 'tool-result') {
|
|
118
|
-
for (const inner of block.content ?? []) {
|
|
119
|
-
if (inner.type === 'text') parts.push(inner.text)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
121
|
}
|
|
123
122
|
return estimateTextTokens(parts.join('\n'), mode)
|
|
124
123
|
}
|
|
@@ -191,15 +190,19 @@ function textOf(message) {
|
|
|
191
190
|
|
|
192
191
|
/**
|
|
193
192
|
* Re-injected host context that appears as user-role messages every turn:
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
193
|
+
* skill catalogs, AGENTS.md-style instructions, and any producer's `snapshot`-
|
|
194
|
+
* form state (runtime context, time, tmux — dsh 0.1.7 has no shared `plugin`
|
|
195
|
+
* kind, so the snapshot form is matched generically). The host re-sends these
|
|
196
|
+
* on every request and a later snapshot supersedes an earlier one, so copying
|
|
197
|
+
* them into a checkpoint is pure waste — the model never loses them. (A prior
|
|
198
|
+
* compaction checkpoint is handled separately, and notice/relay/recall forms
|
|
199
|
+
* stay.)
|
|
198
200
|
*/
|
|
199
201
|
function isInjectedContext(message) {
|
|
200
|
-
const
|
|
202
|
+
const source = message.source
|
|
203
|
+
const kind = source?.kind
|
|
201
204
|
if (kind === 'skill-catalog' || kind === 'agent-instructions') return true
|
|
202
|
-
return
|
|
205
|
+
return source?.form === 'snapshot'
|
|
203
206
|
}
|
|
204
207
|
|
|
205
208
|
/**
|
|
@@ -215,21 +218,17 @@ function noticeSummary(message) {
|
|
|
215
218
|
return undefined
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
/**
|
|
219
|
-
function
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const text = block.content
|
|
224
|
-
.filter((inner) => inner.type === 'text')
|
|
225
|
-
.map((inner) => inner.text)
|
|
226
|
-
.join('\n')
|
|
221
|
+
/** First non-empty text line of one tool-result message, or undefined. */
|
|
222
|
+
function resultFirstLine(message) {
|
|
223
|
+
for (const block of message.content) {
|
|
224
|
+
if (block.type !== 'text') continue
|
|
225
|
+
const line = block.text
|
|
227
226
|
.split('\n')
|
|
228
|
-
.map((
|
|
229
|
-
.find((
|
|
230
|
-
if (
|
|
227
|
+
.map((part) => part.trim())
|
|
228
|
+
.find((part) => part.length > 0)
|
|
229
|
+
if (line !== undefined) return { isError: message.isError === true, line }
|
|
231
230
|
}
|
|
232
|
-
return
|
|
231
|
+
return undefined
|
|
233
232
|
}
|
|
234
233
|
|
|
235
234
|
/**
|
|
@@ -376,27 +375,33 @@ export function extractFacts(messages, language = 'en') {
|
|
|
376
375
|
continue
|
|
377
376
|
}
|
|
378
377
|
|
|
379
|
-
//
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
378
|
+
// Tool results are first-class role-'tool' messages since dsh 0.1.7
|
|
379
|
+
// (required toolCallId, message-level isError): only their error lines
|
|
380
|
+
// feed the checkpoint.
|
|
381
|
+
if (message.role === 'tool') {
|
|
382
|
+
const result = resultFirstLine(message)
|
|
383
|
+
if (result === undefined) continue
|
|
384
|
+
const isError = result.isError || errorRegexes.some((pattern) => pattern.test(result.line))
|
|
385
|
+
if (!isError) continue
|
|
386
|
+
const call = callsById.get(message.toolCallId ?? message.source?.callId)
|
|
387
|
+
const who = call === undefined ? 'tool' : call.name
|
|
388
|
+
facts.errors.push(`${who}: ${result.line}`)
|
|
389
389
|
continue
|
|
390
390
|
}
|
|
391
|
+
|
|
392
|
+
// user-role messages: prior checkpoints, real user text, display rows
|
|
391
393
|
const text = textOf(message)
|
|
392
394
|
if (text.trim().length === 0) continue
|
|
393
|
-
if (message.source
|
|
395
|
+
if (isCompactCheckpointSource(message.source)) {
|
|
394
396
|
facts.carried = parseCheckpointSections(text)
|
|
395
397
|
continue
|
|
396
398
|
}
|
|
397
399
|
// dsh-dcp's own compaction notices are transcript display rows: the model
|
|
398
400
|
// learns nothing from them the checkpoint below does not already carry.
|
|
399
|
-
|
|
401
|
+
// `plugin:dsh-dcp` is the V3→V4 session-log migration's spelling for
|
|
402
|
+
// pre-migration rows (cast: no type declares the legacy namespace).
|
|
403
|
+
const noticeKind = /** @type {string} */ (message.source?.kind)
|
|
404
|
+
if (noticeKind === 'dsh-dcp' || noticeKind === 'plugin:dsh-dcp') continue
|
|
400
405
|
if (isInjectedContext(message)) continue
|
|
401
406
|
const intentText = noticeSummary(message) ?? text
|
|
402
407
|
facts.lastUserText = intentText
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiwayds/dsh-dcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Deterministic context-pruning compaction backend for dsh (DeepSeek Harness) — zero-LLM summaries, /dcp command, works out of the box. Design references Opencode-DCP/opencode-dynamic-context-pruning.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
|
+
"icon": "./icon.svg",
|
|
7
8
|
"bin": {
|
|
8
9
|
"dsh-dcp-setup": "scripts/setup.mjs"
|
|
9
10
|
},
|
|
@@ -12,7 +13,8 @@
|
|
|
12
13
|
"./summarizer": "./lib/summarizer.js",
|
|
13
14
|
"./config": "./lib/config.js",
|
|
14
15
|
"./setup": "./lib/setup.js",
|
|
15
|
-
"./package.json": "./package.json"
|
|
16
|
+
"./package.json": "./package.json",
|
|
17
|
+
"./locale/*.json": "./locale/*.json"
|
|
16
18
|
},
|
|
17
19
|
"files": [
|
|
18
20
|
"lib",
|
|
@@ -21,7 +23,9 @@
|
|
|
21
23
|
"README.md",
|
|
22
24
|
"README.en.md",
|
|
23
25
|
"LICENSE",
|
|
24
|
-
"cordis.patch.yml"
|
|
26
|
+
"cordis.patch.yml",
|
|
27
|
+
"icon.svg",
|
|
28
|
+
"locale/*.json"
|
|
25
29
|
],
|
|
26
30
|
"scripts": {
|
|
27
31
|
"test": "node --test",
|
|
@@ -53,17 +57,17 @@
|
|
|
53
57
|
"dependencies": {},
|
|
54
58
|
"peerDependencies": {
|
|
55
59
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
56
|
-
"@deepseek-ai/dsh-agent": ">=0.1.
|
|
57
|
-
"@deepseek-ai/dsh-brand": ">=0.1.
|
|
58
|
-
"@deepseek-ai/dsh-commands": ">=0.1.
|
|
59
|
-
"@deepseek-ai/dsh-compaction": ">=0.1.
|
|
60
|
-
"@deepseek-ai/dsh-compaction-basic": ">=0.1.
|
|
61
|
-
"@deepseek-ai/dsh-compaction-tool-result-pruner": ">=0.1.
|
|
62
|
-
"@deepseek-ai/dsh-invariants": ">=0.1.
|
|
63
|
-
"@deepseek-ai/dsh-llm": ">=0.1.
|
|
64
|
-
"@deepseek-ai/dsh-session": ">=0.1.
|
|
65
|
-
"@deepseek-ai/dsh-skill": ">=0.1.
|
|
66
|
-
"@deepseek-ai/dsh-token-meter": ">=0.1.
|
|
60
|
+
"@deepseek-ai/dsh-agent": ">=0.1.7-rc.1",
|
|
61
|
+
"@deepseek-ai/dsh-brand": ">=0.1.7-rc.1",
|
|
62
|
+
"@deepseek-ai/dsh-commands": ">=0.1.7-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-compaction": ">=0.1.7-rc.1",
|
|
64
|
+
"@deepseek-ai/dsh-compaction-basic": ">=0.1.7-rc.1",
|
|
65
|
+
"@deepseek-ai/dsh-compaction-tool-result-pruner": ">=0.1.7-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-invariants": ">=0.1.7-rc.1",
|
|
67
|
+
"@deepseek-ai/dsh-llm": ">=0.1.7-rc.1",
|
|
68
|
+
"@deepseek-ai/dsh-session": ">=0.1.7-rc.1",
|
|
69
|
+
"@deepseek-ai/dsh-skill": ">=0.1.7-rc.1",
|
|
70
|
+
"@deepseek-ai/dsh-token-meter": ">=0.1.7-rc.1",
|
|
67
71
|
"@deepseek-ai/schemastery": "^3.18.2"
|
|
68
72
|
},
|
|
69
73
|
"peerDependenciesMeta": {
|
|
@@ -109,35 +113,35 @@
|
|
|
109
113
|
},
|
|
110
114
|
"devDependencies": {
|
|
111
115
|
"@types/node": "^24.0.0",
|
|
112
|
-
"@deepseek-ai/cordis": "4.0.
|
|
113
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
114
|
-
"@deepseek-ai/dsh-brand": "0.1.
|
|
115
|
-
"@deepseek-ai/dsh-commands": "0.1.
|
|
116
|
-
"@deepseek-ai/dsh-compaction": "0.1.
|
|
117
|
-
"@deepseek-ai/dsh-compaction-basic": "0.1.
|
|
118
|
-
"@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.
|
|
119
|
-
"@deepseek-ai/dsh-invariants": "0.1.
|
|
120
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
121
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
122
|
-
"@deepseek-ai/dsh-token-meter": "0.1.
|
|
116
|
+
"@deepseek-ai/cordis": "4.0.4",
|
|
117
|
+
"@deepseek-ai/dsh-agent": "0.1.7-rc.1",
|
|
118
|
+
"@deepseek-ai/dsh-brand": "0.1.7-rc.1",
|
|
119
|
+
"@deepseek-ai/dsh-commands": "0.1.7-rc.1",
|
|
120
|
+
"@deepseek-ai/dsh-compaction": "0.1.7-rc.1",
|
|
121
|
+
"@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.1",
|
|
122
|
+
"@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.1",
|
|
123
|
+
"@deepseek-ai/dsh-invariants": "0.1.7-rc.1",
|
|
124
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.1",
|
|
125
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.1",
|
|
126
|
+
"@deepseek-ai/dsh-token-meter": "0.1.7-rc.1",
|
|
123
127
|
"@deepseek-ai/schemastery": "3.18.2",
|
|
124
128
|
"typescript": "~5.9.0"
|
|
125
129
|
},
|
|
126
130
|
"overrides": {
|
|
127
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
128
|
-
"@deepseek-ai/dsh-brand": "0.1.
|
|
129
|
-
"@deepseek-ai/dsh-commands": "0.1.
|
|
130
|
-
"@deepseek-ai/dsh-compaction": "0.1.
|
|
131
|
-
"@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.
|
|
132
|
-
"@deepseek-ai/dsh-invariants": "0.1.
|
|
133
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
134
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
135
|
-
"@deepseek-ai/dsh-token-meter": "0.1.
|
|
136
|
-
"@deepseek-ai/dsh-scope": "0.1.
|
|
137
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
138
|
-
"@deepseek-ai/dsh-session-projection": "0.1.
|
|
139
|
-
"@deepseek-ai/dsh-system-prompt": "0.1.
|
|
140
|
-
"@deepseek-ai/dsh-llm-retry": "0.1.
|
|
131
|
+
"@deepseek-ai/dsh-agent": "0.1.7-rc.1",
|
|
132
|
+
"@deepseek-ai/dsh-brand": "0.1.7-rc.1",
|
|
133
|
+
"@deepseek-ai/dsh-commands": "0.1.7-rc.1",
|
|
134
|
+
"@deepseek-ai/dsh-compaction": "0.1.7-rc.1",
|
|
135
|
+
"@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.7-rc.1",
|
|
136
|
+
"@deepseek-ai/dsh-invariants": "0.1.7-rc.1",
|
|
137
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.1",
|
|
138
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.1",
|
|
139
|
+
"@deepseek-ai/dsh-token-meter": "0.1.7-rc.1",
|
|
140
|
+
"@deepseek-ai/dsh-scope": "0.1.7-rc.1",
|
|
141
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-rc.1",
|
|
142
|
+
"@deepseek-ai/dsh-session-projection": "0.1.7-rc.1",
|
|
143
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.7-rc.1",
|
|
144
|
+
"@deepseek-ai/dsh-llm-retry": "0.1.7-rc.1"
|
|
141
145
|
},
|
|
142
146
|
"dsh": {
|
|
143
147
|
"bundle": {
|
|
@@ -146,11 +150,11 @@
|
|
|
146
150
|
},
|
|
147
151
|
"pnpm": {
|
|
148
152
|
"overrides": {
|
|
149
|
-
"@deepseek-ai/dsh-scope": "0.1.
|
|
150
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
151
|
-
"@deepseek-ai/dsh-session-projection": "0.1.
|
|
152
|
-
"@deepseek-ai/dsh-system-prompt": "0.1.
|
|
153
|
-
"@deepseek-ai/dsh-llm-retry": "0.1.
|
|
153
|
+
"@deepseek-ai/dsh-scope": "0.1.7-rc.1",
|
|
154
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-rc.1",
|
|
155
|
+
"@deepseek-ai/dsh-session-projection": "0.1.7-rc.1",
|
|
156
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.7-rc.1",
|
|
157
|
+
"@deepseek-ai/dsh-llm-retry": "0.1.7-rc.1"
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
}
|
package/scripts/compare.mjs
CHANGED
|
@@ -79,9 +79,6 @@ function hostTokens(content) {
|
|
|
79
79
|
return content.reduce((total, block) => {
|
|
80
80
|
if (block.type === 'text') return total + Math.ceil(block.text.length / 4)
|
|
81
81
|
if (block.type === 'tool-call') return total + Math.ceil(block.arguments.length / 4)
|
|
82
|
-
if (block.type === 'tool-result') {
|
|
83
|
-
return total + block.content.reduce((sum, inner) => sum + (inner.type === 'text' ? Math.ceil(inner.text.length / 4) : 0), 0)
|
|
84
|
-
}
|
|
85
82
|
return total
|
|
86
83
|
}, 0)
|
|
87
84
|
}
|
|
@@ -145,7 +142,7 @@ function checkpointMessage(summaryText, compactionId) {
|
|
|
145
142
|
{ type: 'text', text: summaryText },
|
|
146
143
|
{ type: 'text', text: '</compacted-summary>' },
|
|
147
144
|
],
|
|
148
|
-
source: { kind: '
|
|
145
|
+
source: { kind: 'compact-checkpoint', compactionId },
|
|
149
146
|
}
|
|
150
147
|
}
|
|
151
148
|
|
package/scripts/setup.mjs
CHANGED
|
@@ -124,4 +124,4 @@ if (existed) {
|
|
|
124
124
|
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
125
125
|
fs.appendFileSync(target, plan.block)
|
|
126
126
|
console.log(`${plan.action === 'create' ? 'created' : 'patched'} ${target}`)
|
|
127
|
-
console.log('restart dsh, then run /dcp to verify.')
|
|
127
|
+
console.log('restart dsh, then run /dcp status to verify.')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dsh-dcp-config
|
|
3
|
-
description: "dsh 压缩引擎插件(@aiwayds/dsh-dcp)使用与配置指南。凡涉及上下文压缩、/dcp 命令、压缩调参(阈值/密度/语言/轮数触发/模型切换),或要配置 dcp
|
|
3
|
+
description: "dsh 压缩引擎插件(@aiwayds/dsh-dcp)使用与配置指南。凡涉及上下文压缩、/dcp 命令、压缩调参(阈值/密度/语言/轮数触发/模型切换),或要配置 dcp 时先读本指南:裸 /dcp 即压缩、/dcp status 看状态与 /dcp set 十二个可调键、持久化到 cordis.patch.yml 挂载块 config: 段(dsh-dcp-setup 管理)、ask_user_question 调参向导、五类触发(压力/溢出/轮数/模型切换/手动)、subagent 会话独立计数生效。触发词:dcp、压缩、compaction、上下文超限、摘要、thresholdRatio、roundInterval、onModelSwitch。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# dsh-dcp 使用指南(确定性上下文压缩)
|
|
@@ -80,7 +80,7 @@ dsh-dcp 自有键(除 `thresholdRatio` 外全部可用 `/dcp set` 调):
|
|
|
80
80
|
| 溢出 | 模型报 context 超限 | 继承官方恢复流程 |
|
|
81
81
|
| 轮数 | 每累计 `roundInterval` 条 assistant message | 任何一次压缩(含压力/手动)都重置时钟;`0` 关闭;需保持 `auto: true`(默认开) |
|
|
82
82
|
| 模型切换 | 会话实际路由的 provider/model 变化 | `onModelSwitch` 控制(默认 `notice` 提醒);`auto` 在下一个空闲点自动压缩;两道门:距上次压缩 <10 条消息、上下文 <`modelSwitchMinTokens` |
|
|
83
|
-
| 手动 | `/dcp compact`、`/compact` | 随时可用 |
|
|
83
|
+
| 手动 | `/dcp`(无参数)、`/dcp compact`、`/compact` | 随时可用 |
|
|
84
84
|
|
|
85
85
|
- **subagent 同样生效**:进程内子代理(含 continuable 与 one-shot)走同一套事件分发,
|
|
86
86
|
压力/溢出/轮数/模型切换对每个会话独立计数、独立触发。
|
|
@@ -89,8 +89,9 @@ dsh-dcp 自有键(除 `thresholdRatio` 外全部可用 `/dcp set` 调):
|
|
|
89
89
|
|
|
90
90
|
## 排障
|
|
91
91
|
|
|
92
|
-
1. `/dcp
|
|
92
|
+
1. `/dcp status` 看状态:当前配置、压缩次数、省下的 LLM 调用,以及
|
|
93
93
|
per-session 概览(含子代理;已销毁的会话自动消失,列表最多前 10 个,超出显示 `+N more`)。
|
|
94
|
+
手动压缩打裸 `/dcp`(或 `/dcp compact`);命令用法打 `/dcp help`。
|
|
94
95
|
2. 会话压不动 → 先确认 `auto` 是否为 `true`(自动触发总开关,默认开),再看
|
|
95
96
|
`thresholdRatio` 是否设得过高、`roundInterval` 是否为 `0`。
|
|
96
97
|
3. `npx dsh-dcp-setup --remove` 后出现 `WARN: a compaction-basic entry remains...` →
|