Skip to content

fix(compress): 'nothing to compress' is terminal — one-shot continue msg, not re-nudge - #194

Open
ranxianglei wants to merge 1 commit into
masterfrom
2026-08-22_nothing-to-compress-loop-fix
Open

fix(compress): 'nothing to compress' is terminal — one-shot continue msg, not re-nudge#194
ranxianglei wants to merge 1 commit into
masterfrom
2026-08-22_nothing-to-compress-loop-fix

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

问题

Session 01a02715 死循环:compress 调用被内核以 "Nothing to do"(range 已压缩 / 低于最小阈值)拒绝后,扩展的 retry-nudge 每次 LLM 调用都重推。封顶计数器只在"模型再调 compress 且失败"时才 +1,而模型改调 acp_status(不是 compress)→ 计数停在 1 → nudge 永远重推 → 203 次 acp_status 调用

根因

retry-nudge 混淆了两种失败:

  • 参数错(bad args)→ 该重试
  • 无可压(terminal)→ 该停下继续原任务

nudge 对两种情况一律说 "retry compress NOW" + "run acp_status",对"无可压"是错的,直接导致死循环。

修复(仅扩展;内核无 retry-nudge,不受影响)

  • isNothingToCompressText():字符串匹配内核的 terminal 报错("Nothing to do" / "too small" / "nothing to compress")
  • noteCompressOutcomes 返回 continueFor(terminal)vs retryFor(可重试);nothingToCompress 不消耗重试预算(后续真参数错仍有完整 3 次)
  • compressContinueMessage():一次性"继续原任务,别再调 compress/acp_status"消息,由 continueShownTurns 跟踪,每 turn 只注入一次——不再每次 LLM 调用重推

验证

  • ✅ typecheck 通过
  • ✅ 412 测试全过(409 原有 + 3 新增:分类 / 计数器 / 集成一次性不重推)
  • ✅ build 成功

改动

src/compress-tool.ts         |  9 ++++++
src/index.ts                 | 54 ++++++++++++++++++++++---------
src/runtime.ts               | 27 +++++++++++++---
tests/compress-retry.test.ts | 75 +++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 145 insertions(+), 20 deletions(-)

…msg, not re-nudge

Session 01a02715 post-mortem: a compress call rejected with 'Nothing to do'
(ranges already compressed / below min) triggered the retry nudge, which
re-injected on EVERY LLM call. The cap only advances on a NEW compress
failure, and the model switched to acp_status (not compress) — so the counter
stayed at 1 and the nudge re-pushed forever → 203 acp_status calls.

Root cause: the retry nudge conflated two failure types:
  - parameter error (bad args) → should retry
  - nothing-to-compress (terminal) → should stop and continue the task

Fix (extension only; the kernel has no retry nudge):
  - isNothingToCompressText(): string-match the kernel's terminal error
  - noteCompressOutcomes returns continueFor (terminal) vs retryFor (retryable);
    nothing-to-compress does NOT consume the retry budget
  - compressContinueMessage(): one-shot 'continue your task, stop calling
    compress/acp_status' message, tracked by continueShownTurns so it is
    injected exactly once per turn — not re-injected on every LLM call

+3 tests (classification, counter, integration one-shot-not-reinjected).
412 tests pass, typecheck + build clean.
ranxianglei pushed a commit that referenced this pull request Sep 6, 2026
…es now single-sourced from kernel (#309)

- Remove adapter-level SUMMARY FIDELITY RULES from src/system-prompt.ts —
  kernel #205 (v0.0.55) merged the rules into howToCompressRules /
  tier2DistillRules, delivered via ${prompts.howToCompressRules}.
- Pin acp-kernel to exact 0.0.55 (picks up #194 first-sight mass bypass,
  #198 min-pressure-benefit gate max(5000, limit×1%)).
- Verified with npm ci clean tree: 477 pass / 0 fail / 3 skipped.
ranxianglei pushed a commit that referenced this pull request Sep 6, 2026
…rules, adapt nudge tests

- Pin acp-kernel to exact 0.0.55 (from 0.0.50): picks up #194 first-sight
  mass bypass, #198 min-pressure-benefit gate max(5000, limit×1%), and the
  write-side summary-fidelity prompt rules (kernel #205) now merged into
  howToCompressRules / tier2DistillRules.
- Remove the adapter-level SUMMARY FIDELITY RULES section from
  src/system-prompt.ts: kernel 0.0.55 delivers the rules via
  ${prompts.howToCompressRules} — single source of truth, no gap (this
  commit swaps the source atomically).
- Adapt 3 tests to post-#194/#198 kernel semantics (verified NOT kernel
  bugs — instrumented reasons confirm intended behavior):
  * e2e 2w/2w: bulk 3K→8K chars/msg keeps every merged range effective
    (≥ minCompressRange) and T1 pending ≈24K above the 5K benefit floor —
    the original intent (config limit flows into the decision) is preserved;
    under #198 the old 3024-token pending was correctly suppressed.
  * sent-view idle/stale-anchor controls: bulk 18K→1.8K chars/msg drops
    usage to ~5% (< 45% first-sight floor), so the controls stay idle for
    the reason they isolate (the usage floor), not because #194 masks them.
- Verified: npm ci clean tree, 565 pass / 0 fail / 3 skipped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant