Skip to content

(fix) page large-block decompress output with offset/limit so one recovery can't flood or get silently trimmed - #118

Open
ranxianglei wants to merge 1 commit into
Tyan66666:mainfrom
ranxianglei:2026-09-06_decompress-pagination
Open

(fix) page large-block decompress output with offset/limit so one recovery can't flood or get silently trimmed#118
ranxianglei wants to merge 1 commit into
Tyan66666:mainfrom
ranxianglei:2026-09-06_decompress-pagination

Conversation

@ranxianglei

Copy link
Copy Markdown
Contributor

Fixes #112.

Problem
decompress (and /acp decompress) expands ALL shadowed seqs of a block into one uncapped tool result. For a large block (say 200K tokens) the recovered text either floods the model's context or — more usually — gets silently truncated by the host tool-result pruner (dsh-compaction-tool-result-pruner, tiers 8192/4096/1024): the tail of the recovered content is gone while the model believes it holds the whole block. That is precisely the failure mode decompress exists to undo.

Cause
handleDecompress (src/tools.ts) joins expandShadowedSeqs(session, block.blockId) into a single string; the tool schema only exposes blockId, so there is no way to page through.

Fix

  • sliceDecompressPage(expanded, offset, limit) + DEFAULT_DECOMPRESS_PAGE = 100 (src/region.ts): pure paging helper shared by the tool and the command. Clamps offset >= 0, limit >= 1; empty-text seqs still occupy slots so paging stays stable across calls.
  • decompress tool: optional integer offset / limit params. Results end with [messages X..Y of Z] plus an explicit continue hint (decompress({ blockId: "<id>", offset: N })) when more remains; an offset past the end returns guidance instead of an error.
  • /acp decompress <blockId> [offset] [limit]: same paging and footer (8-char prefix form); non-numeric args are rejected.
  • Default prompt copy (src/prompts.ts) + tool descriptions updated to mention paging; README.md / README.en.md tool table synced.

Small blocks behave as before (a <= 100 message block returns whole, plus the new [messages X..Y of Z] footer).

Verification

  • New regression tests:
    • tests/tools.test.ts "M3: decompress pages a large block by default and walks it with offset" — compresses 120 messages, asserts page 1 = [messages 1..100 of 120] + continue hint, walks to the final page via offset, and checks past-end guidance.
    • tests/tools.test.ts "M3: decompress honors an explicit limit and clamps a negative offset".
    • tests/commands.test.ts "M4: /acp decompress pages with [offset] [limit] args and rejects bad numbers".
  • npm run typecheck clean; npm test 211 pass / 0 fail (208 baseline + 3 new); npm run build clean (dist committed per AGENTS.md §4).

Built against main @ 6348af8 (v0.2.20).

@ranxianglei

Copy link
Copy Markdown
Contributor Author

我来协助看一下这个问题,请分析并回复处理结果。

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.

[bug][recall] decompress / /acp decompress 输出无上限、无分页 —— 大 block 恢复要么灌爆上下文,要么被宿主静默截断

2 participants