opencode-acp 1.14.4 → 1.14.5
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 +10 -23
- package/README.zh-CN.md +10 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +144 -899
- package/dist/index.js.map +1 -1
- package/dist/lib/commands/context.d.ts.map +1 -1
- package/dist/lib/commands/help.d.ts.map +1 -1
- package/dist/lib/commands/index.d.ts +0 -1
- package/dist/lib/commands/index.d.ts.map +1 -1
- package/dist/lib/compress/index.d.ts +1 -2
- package/dist/lib/compress/index.d.ts.map +1 -1
- package/dist/lib/compress/pipeline.d.ts.map +1 -1
- package/dist/lib/config-validation.d.ts.map +1 -1
- package/dist/lib/config.d.ts +0 -14
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/messages/inject/inject.d.ts.map +1 -1
- package/dist/lib/messages/prune.d.ts.map +1 -1
- package/dist/lib/messages/truncate-tools.d.ts +10 -0
- package/dist/lib/messages/truncate-tools.d.ts.map +1 -0
- package/dist/lib/prompts/extensions/nudge.d.ts +1 -2
- package/dist/lib/prompts/extensions/nudge.d.ts.map +1 -1
- package/dist/lib/prompts/system.d.ts +1 -1
- package/dist/lib/prompts/system.d.ts.map +1 -1
- package/dist/lib/state/persistence.d.ts.map +1 -1
- package/dist/lib/state/state.d.ts.map +1 -1
- package/dist/lib/state/types.d.ts +12 -1
- package/dist/lib/state/types.d.ts.map +1 -1
- package/dist/lib/state/utils.d.ts +0 -1
- package/dist/lib/state/utils.d.ts.map +1 -1
- package/dist/lib/ui/notification.d.ts +0 -2
- package/dist/lib/ui/notification.d.ts.map +1 -1
- package/dist/lib/ui/utils.d.ts +1 -3
- package/dist/lib/ui/utils.d.ts.map +1 -1
- package/package.json +2 -1
- package/dist/lib/commands/sweep.d.ts +0 -23
- package/dist/lib/commands/sweep.d.ts.map +0 -1
- package/dist/lib/compress/prune-tool.d.ts +0 -4
- package/dist/lib/compress/prune-tool.d.ts.map +0 -1
- package/dist/lib/gc/truncate.d.ts +0 -15
- package/dist/lib/gc/truncate.d.ts.map +0 -1
- package/dist/lib/strategies/deduplication.d.ts +0 -10
- package/dist/lib/strategies/deduplication.d.ts.map +0 -1
- package/dist/lib/strategies/index.d.ts +0 -3
- package/dist/lib/strategies/index.d.ts.map +0 -1
- package/dist/lib/strategies/purge-errors.d.ts +0 -13
- package/dist/lib/strategies/purge-errors.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -238,7 +238,6 @@ ACP provides an `/acp` slash command (also accepts `/dcp` for backward compatibi
|
|
|
238
238
|
| `/acp` | Shows available ACP commands |
|
|
239
239
|
| `/acp context` | Token usage breakdown by category (system, user, assistant, tools, etc.) and how much has been saved through pruning |
|
|
240
240
|
| `/acp stats` | Cumulative pruning statistics across all sessions |
|
|
241
|
-
| `/acp sweep [n]` | Prunes all tools since the last user message. Optional count: `/acp sweep 10` prunes the last 10 tools. Respects `commands.protectedTools` |
|
|
242
241
|
| `/acp manual [on\|off]` | Toggle manual mode. When on, the AI will not autonomously use context management tools |
|
|
243
242
|
| `/acp compress [focus]` | Trigger a single compress tool execution. Optional focus text directs what content to compress, following the active `compress.mode` |
|
|
244
243
|
| `/acp decompress <n>` | Restore a specific active compression by ID. Running without an argument shows available compression IDs, token sizes, and topics |
|
|
@@ -294,16 +293,13 @@ Each level overrides the previous, so project settings take priority over global
|
|
|
294
293
|
// Slash commands configuration
|
|
295
294
|
"commands": {
|
|
296
295
|
"enabled": true,
|
|
297
|
-
// Additional tools to protect from pruning via commands
|
|
296
|
+
// Additional tools to protect from pruning via commands
|
|
298
297
|
"protectedTools": [],
|
|
299
298
|
},
|
|
300
299
|
// Manual mode: disables autonomous context management,
|
|
301
300
|
// tools only run when explicitly triggered via /acp commands
|
|
302
301
|
"manualMode": {
|
|
303
302
|
"enabled": false,
|
|
304
|
-
// When true, automatic cleanup (deduplication, purgeErrors)
|
|
305
|
-
// still runs even in manual mode
|
|
306
|
-
"automaticStrategies": true,
|
|
307
303
|
},
|
|
308
304
|
// Protect from pruning for <turns> message turns past tool invocation
|
|
309
305
|
"turnProtection": {
|
|
@@ -374,23 +370,6 @@ Each level overrides the previous, so project settings take priority over global
|
|
|
374
370
|
// Warning: large copy-pasted prompts will never be compressed away
|
|
375
371
|
"protectUserMessages": false,
|
|
376
372
|
},
|
|
377
|
-
// Automatic pruning strategies
|
|
378
|
-
"strategies": {
|
|
379
|
-
// Remove duplicate tool calls (same tool with same arguments)
|
|
380
|
-
"deduplication": {
|
|
381
|
-
"enabled": true,
|
|
382
|
-
// Additional tools to protect from pruning
|
|
383
|
-
"protectedTools": [],
|
|
384
|
-
},
|
|
385
|
-
// Prune tool inputs for errored tools after X turns
|
|
386
|
-
"purgeErrors": {
|
|
387
|
-
"enabled": true,
|
|
388
|
-
// Number of turns before errored tool inputs are pruned
|
|
389
|
-
"turns": 4,
|
|
390
|
-
// Additional tools to protect from pruning
|
|
391
|
-
"protectedTools": [],
|
|
392
|
-
},
|
|
393
|
-
},
|
|
394
373
|
// Garbage collection — hardcoded 100% fallback only
|
|
395
374
|
"gc": {
|
|
396
375
|
"algorithm": "truncate",
|
|
@@ -454,7 +433,7 @@ To reset an override, delete the matching file from your overrides directory.
|
|
|
454
433
|
By default, these tools are always protected from pruning:
|
|
455
434
|
`task`, `skill`, `todowrite`, `todoread`, `compress`, `decompress`, `batch`, `plan_enter`, `plan_exit`, `write`, `edit`
|
|
456
435
|
|
|
457
|
-
The `protectedTools`
|
|
436
|
+
The `protectedTools` array in `commands` adds to this default list.
|
|
458
437
|
|
|
459
438
|
For the `compress` tool, `compress.protectedTools` ensures specific tool outputs are **hard-excluded** from compression ranges (v1.10.0+). When the model compresses a range that includes a protected tool message, that message survives intact in visible context — only the surrounding non-protected messages are compressed. The root default is `["skill", "compress"]` (the `compress` entry protects compress tool calls — which carry summaries — from being eaten by subsequent sequential compressions); an explicit array replaces the inherited policy. **`"compress"` is always force-protected regardless of user config** — its `summary` parameter is the sole record of compressed conversation and cannot be recovered if lost. Setting `[]` protects only `compress`; setting `["task"]` protects `task` and `compress`.
|
|
460
439
|
|
|
@@ -528,6 +507,14 @@ For the complete list with root cause analysis, see the [bug tracker](https://gi
|
|
|
528
507
|
|
|
529
508
|
## Changelog
|
|
530
509
|
|
|
510
|
+
### v1.14.5 — GC Module Removal + Property-Based Tests + Issue #176 Fix + Config Docs (PRs #222, #206, #221, #223, #224)
|
|
511
|
+
|
|
512
|
+
**Problem**: Five issues bundled. (1) **GC data-loss bugs** (PR #222): The `gc/truncate.ts` module had 4 confirmed bugs that could silently lose summaries — single-line truncation exceeded maxLength by 19 chars, barely-over-maxLength silently failed (longer than input), long-header output overrun, and off-by-one marker reservation. GC only triggered at 100% context (default), so it was rarely reached but catastrophic when it did. (2) **Dead code** (PR #206): Prune tool, sweep command, and strategies (~2309 lines) were never used — `prune` tool was replaced by `compress` tool, `sweep` was superseded by batch cleanup, strategies were vestigial. (3) **No property-based tests** (PR #221): All tests were targeted/unit tests — invariant violations across edge cases were undetectable. (4) **Missing config docs** (PR #223): No comprehensive config reference — users had to read source to discover parameters. (5) **Nudge permanently stops after compress** (PR #224, Issue #176): In autonomous sessions (single user message + many assistant/tool turns), `injectCompressNudges` had an unconditional early return when any compress was detected in the current turn. Since the entire session IS one turn, once compress happened, `currentTurnHasCompress` was always true → function always returned early → nudges never fired again → unbounded context growth.
|
|
513
|
+
|
|
514
|
+
**Fix**: (1) PR #222 — Removed `gc/truncate.ts` entirely. Added `lib/messages/truncate-tools.ts`: emergency tool output truncation at `majorGcThresholdPercent` that truncates largest tool outputs (keeps prefix+suffix, skips summaries/text/messages, protects last 3 messages, skips already-truncated outputs). Never touches model-written summaries. Removed aging warning from nudge extension. `config.gc` fields kept for backward compat. (2) PR #206 — Removed dead prune tool, sweep command, dedup/purge strategies. ~2309 lines deleted. (3) PR #221 — Added `tests/property-invariants.test.ts`: 10 property-based tests using fast-check covering range exclusion invariants, compressible group construction, protected ref computation, nudge decision properties, pipeline consistency, and idempotency. ~1,400 random inputs per run. (4) PR #223 — Added `CONFIGURATION.md` + `CONFIGURATION.zh-CN.md`: comprehensive parameter reference documenting all 60+ config parameters with type, default, status (ACTIVE/DEPRECATED/EXPERIMENTAL), and description. (5) PR #224 — Added `lastProcessedCompressMessageId` to `Nudges` state (transient, not persisted). In `injectCompressNudges`, the early-return block now tracks which compress message was already processed. If the same compress ID is seen again, the early return is skipped and normal nudge evaluation proceeds. First-time compress still processes (clears anchors, adjusts baseline) and returns early. Failed/repeated compress calls are handled correctly.
|
|
515
|
+
|
|
516
|
+
Files: `lib/gc/truncate.ts` (DELETED), `lib/messages/truncate-tools.ts` (NEW), `lib/hooks.ts`, `lib/prompts/extensions/nudge.ts`, `lib/compress/{prune-tool,status,decompress-logic,decompress,index}.ts` (DELETED), `lib/strategies/` (DELETED), `lib/commands/{sweep,stats,manual}.ts` (modified), `tests/property-invariants.test.ts` (NEW), `tests/property-bughunt.test.ts` (NEW), `CONFIGURATION.md` (NEW), `CONFIGURATION.zh-CN.md` (NEW), `lib/state/types.ts`, `lib/state/{state,utils}.ts`, `lib/messages/inject/inject.ts`. Tests: 937+ tests, 0 failures. E2E: 10 scenarios (added 09 + 10).
|
|
517
|
+
|
|
531
518
|
### v1.14.4 — Tier Detection + E2E Tests + Debug Notification + Nudge Loop Fix (PRs #215, #214, #217, #218)
|
|
532
519
|
|
|
533
520
|
**Problem**: Four issues accumulated since v1.14.3. (1) **Tier misclassification** (PR #215): `applyCompressionState` determined the compression tier from `consumedBlockIds` — any consumed block bumped the tier up. This misclassified T1 compressions that incidentally overlapped existing T1 blocks as T2 (6 of 18 T2-labeled blocks in a real session were misclassified). (2) **E2E test gaps** (PR #214): E2E tests disabled all protection (`preserveRecentMessages: 0`), CI ran only 4/6 scenarios, and `verify.ts` only checked `blockCount` — the protection mechanism fixed 3× in v1.14.x was completely untested in E2E. (3) **Debug notifications invisible** (PR #217): With `debug: true`, compression notifications went to toast only — users couldn't see them in the chat session for debugging. (4) **Nudge injection loop** (PR #218, issue #216): `applyAnchoredNudges` fired before `nothingToCompress` was computed, so the nudge text ("compress now") was injected even when there was nothing to compress — the model saw a nudge with an empty recommendation list, tried random compressions, failed, and looped. Additionally, `messageHasCompress` only recognized `status === "completed"`, so failed compressions never reset the halved nudge threshold, keeping the loop alive.
|
package/README.zh-CN.md
CHANGED
|
@@ -193,7 +193,6 @@ ACP 提供 `/acp` 斜杠命令(为向后兼容也接受 `/dcp`):
|
|
|
193
193
|
| `/acp` | 显示可用的 ACP 命令 |
|
|
194
194
|
| `/acp context` | 按类别(system、user、assistant、tools 等)显示 token 用量明细,以及通过剪枝节省的量 |
|
|
195
195
|
| `/acp stats` | 跨所有会话的累计剪枝统计 |
|
|
196
|
-
| `/acp sweep [n]` | 剪除自上次用户消息以来的所有工具。可选数量:`/acp sweep 10` 剪除最近 10 个工具。遵循 `commands.protectedTools` 设置 |
|
|
197
196
|
| `/acp manual [on\|off]` | 切换手动模式。开启后,AI 不会自动使用上下文管理工具 |
|
|
198
197
|
| `/acp compress [focus]` | 触发一次 `compress` 工具执行。可选的焦点文本指示要压缩的内容,遵循当前 `compress.mode` |
|
|
199
198
|
| `/acp decompress <n>` | 按 ID 恢复特定的活动压缩。不带参数运行时显示可用的压缩 ID、token 大小和主题 |
|
|
@@ -249,16 +248,13 @@ ACP 使用自己的配置文件,按以下顺序搜索:
|
|
|
249
248
|
// Slash commands configuration
|
|
250
249
|
"commands": {
|
|
251
250
|
"enabled": true,
|
|
252
|
-
// Additional tools to protect from pruning via commands
|
|
251
|
+
// Additional tools to protect from pruning via commands
|
|
253
252
|
"protectedTools": [],
|
|
254
253
|
},
|
|
255
254
|
// Manual mode: disables autonomous context management,
|
|
256
255
|
// tools only run when explicitly triggered via /acp commands
|
|
257
256
|
"manualMode": {
|
|
258
257
|
"enabled": false,
|
|
259
|
-
// When true, automatic cleanup (deduplication, purgeErrors)
|
|
260
|
-
// still runs even in manual mode
|
|
261
|
-
"automaticStrategies": true,
|
|
262
258
|
},
|
|
263
259
|
// Protect from pruning for <turns> message turns past tool invocation
|
|
264
260
|
"turnProtection": {
|
|
@@ -329,23 +325,6 @@ ACP 使用自己的配置文件,按以下顺序搜索:
|
|
|
329
325
|
// Warning: large copy-pasted prompts will never be compressed away
|
|
330
326
|
"protectUserMessages": false,
|
|
331
327
|
},
|
|
332
|
-
// Automatic pruning strategies
|
|
333
|
-
"strategies": {
|
|
334
|
-
// Remove duplicate tool calls (same tool with same arguments)
|
|
335
|
-
"deduplication": {
|
|
336
|
-
"enabled": true,
|
|
337
|
-
// Additional tools to protect from pruning
|
|
338
|
-
"protectedTools": [],
|
|
339
|
-
},
|
|
340
|
-
// Prune tool inputs for errored tools after X turns
|
|
341
|
-
"purgeErrors": {
|
|
342
|
-
"enabled": true,
|
|
343
|
-
// Number of turns before errored tool inputs are pruned
|
|
344
|
-
"turns": 4,
|
|
345
|
-
// Additional tools to protect from pruning
|
|
346
|
-
"protectedTools": [],
|
|
347
|
-
},
|
|
348
|
-
},
|
|
349
328
|
// 垃圾回收与批量清理
|
|
350
329
|
"gc": {
|
|
351
330
|
"algorithm": "truncate",
|
|
@@ -408,7 +387,7 @@ ACP 暴露六个可编辑的 prompt:
|
|
|
408
387
|
默认情况下,以下工具始终受保护不被剪枝:
|
|
409
388
|
`task`、`skill`、`todowrite`、`todoread`、`compress`、`decompress`、`batch`、`plan_enter`、`plan_exit`、`write`、`edit`
|
|
410
389
|
|
|
411
|
-
`commands`
|
|
390
|
+
`commands` 中的 `protectedTools` 数组会添加到此默认列表。
|
|
412
391
|
|
|
413
392
|
对于 `compress` 工具,`compress.protectedTools` 确保特定工具的输出被**硬排除**在压缩范围之外(v1.10.0+)。当模型压缩包含受保护工具消息的范围时,该消息完整保留在可见上下文中 — 只有周围的非受保护消息被压缩。根默认值为 `["skill", "compress"]`(`compress` 条目保护携带 summary 的 compress 工具调用,防止被后续顺序压缩吞噬);显式数组会替换继承的策略。**`"compress"` 无论用户如何配置都会被强制保护** — 其 `summary` 参数是已压缩对话的唯一记录,一旦丢失无法恢复。设置 `[]` 仅保护 `compress`;设置 `["task"]` 保护 `task` 和 `compress`。
|
|
414
393
|
|
|
@@ -482,6 +461,14 @@ ACP 在首次启动时自动将配置从 `dcp.jsonc` 迁移到 `acp.jsonc`,将
|
|
|
482
461
|
|
|
483
462
|
## 更新日志
|
|
484
463
|
|
|
464
|
+
### v1.14.5 — GC 模块移除 + 属性测试 + Issue #176 修复 + 配置文档(PRs #222, #206, #221, #223, #224)
|
|
465
|
+
|
|
466
|
+
**问题**:打包修复 5 个问题。(1) **GC 数据丢失 Bug**(PR #222):`gc/truncate.ts` 有 4 个已确认的 bug,可能静默丢失摘要——单行截断超过 maxLength 19 字符、刚好超过 maxLength 时静默失败(输出比输入更长)、长 header 输出溢出、标记预留 off-by-one。GC 默认只在 100% 上下文时触发,所以很少触发但触发时是灾难性的。(2) **死代码**(PR #206):prune 工具、sweep 命令和策略(约 2309 行)从未被使用。(3) **无属性测试**(PR #221):所有测试都是针对性/单元测试——不变量违反在边界情况下无法检测。(4) **缺少配置文档**(PR #223):没有完整的配置参考——用户必须读源码才能发现参数。(5) **压缩后 nudge 永久停止**(PR #224,Issue #176):在自治会话(单条用户消息 + 大量助手/工具消息)中,`injectCompressNudges` 在检测到当前 turn 有压缩时无条件 early return。由于整个会话就是一个 turn,一旦发生压缩,`currentTurnHasCompress` 永远为 true → 函数永远 early return → nudge 不再触发 → 上下文无限增长。
|
|
467
|
+
|
|
468
|
+
**修复**:(1) PR #222——完全移除 `gc/truncate.ts`。新增 `lib/messages/truncate-tools.ts`:在 `majorGcThresholdPercent` 时紧急截断最大的工具输出(保留前后缀,跳过摘要/文本/消息,保护最后 3 条消息,跳过已截断的输出)。从不触碰模型写的摘要。从 nudge 扩展中移除老化警告。`config.gc` 字段保留以兼容旧配置。(2) PR #206——移除死掉的 prune 工具、sweep 命令、去重/清除策略。约 2309 行删除。(3) PR #221——新增 `tests/property-invariants.test.ts`:10 个基于 fast-check 的属性测试,覆盖范围排除不变量、可压缩分组构造、保护 ref 计算、nudge 决策属性、管线一致性和幂等性。每次运行约 1,400 个随机输入。(4) PR #223——新增 `CONFIGURATION.md` + `CONFIGURATION.zh-CN.md`:完整参数参考文档,记录所有 60+ 配置参数的类型、默认值、状态(活跃/废弃/实验性)和描述。(5) PR #224——在 `Nudges` 状态中新增 `lastProcessedCompressMessageId`(瞬态,不持久化)。在 `injectCompressNudges` 中,early-return 块现在跟踪已处理的 compress 消息 ID。如果再次看到同一个 compress ID,跳过 early return,进入正常 nudge 评估。首次 compress 仍然处理(清除锚点、调整基线)并 early return。
|
|
469
|
+
|
|
470
|
+
文件:`lib/gc/truncate.ts`(删除)、`lib/messages/truncate-tools.ts`(新增)、`lib/hooks.ts`、`lib/prompts/extensions/nudge.ts`、`lib/compress/{prune-tool,status,decompress-logic,decompress,index}.ts`(删除)、`lib/strategies/`(删除)、`tests/property-invariants.test.ts`(新增)、`tests/property-bughunt.test.ts`(新增)、`CONFIGURATION.md`(新增)、`CONFIGURATION.zh-CN.md`(新增)、`lib/state/types.ts`、`lib/state/{state,utils}.ts`、`lib/messages/inject/inject.ts`。测试:937+ 通过,0 失败。E2E:10 个场景(新增 09 + 10)。
|
|
471
|
+
|
|
485
472
|
### v1.14.4 — Tier 检测 + E2E 测试 + Debug 通知 + Nudge 循环修复(PRs #215, #214, #217, #218)
|
|
486
473
|
|
|
487
474
|
**问题**:自 v1.14.3 以来积累的 4 个问题。(1) **Tier 误分类**(PR #215):`applyCompressionState` 从 `consumedBlockIds` 判断压缩层级——只要消费了任何已有 block 就会提升层级。这导致那些恰好覆盖了已有 T1 block 的 T1 压缩被错误分类为 T2(在一个真实 session 中,18 个标记为 T2 的 block 里有 6 个被误分类)。(2) **E2E 测试缺口**(PR #214):E2E 测试禁用了所有保护(`preserveRecentMessages: 0`),CI 只运行 4/6 个场景,`verify.ts` 只检查 `blockCount`——v1.14.x 修了 3 次的保护机制在 E2E 里完全没有覆盖。(3) **Debug 通知不可见**(PR #217):开启 `debug: true` 时,压缩通知只发到 toast——用户无法在 chat session 里看到用于调试的通知。(4) **Nudge 注入循环**(PR #218,issue #216):`applyAnchoredNudges` 在 `nothingToCompress` 计算之前就触发,导致即使没有可压缩内容,nudge 文本("compress now")也被注入——模型看到 nudge 但推荐列表为空,尝试随机压缩、失败、循环。此外 `messageHasCompress` 只识别 `status === "completed"`,失败的压缩不会重置被减半的 nudge 阈值,循环持续。
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AA4BjD,QAAA,MAAM,MAAM,EAAE,MAoHK,CAAA;AAEnB,eAAe,MAAM,CAAA"}
|