Skip to content

fix(compression): keep lite from truncating the latest tool results - #15037

Merged
diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.51from
QuangBlue:fix/lite-current-turn
Sep 29, 2026
Merged

diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.51from
QuangBlue:fix/lite-current-turn

Conversation

@QuangBlue

Copy link
Copy Markdown
Contributor

Problem

The default compression combo ("Standard Savings": session-dedup → lite) runs for every key with compression enabled. lite.compressToolResults cut every role:"tool" string to 2000 chars (…[truncated]), including the results of the tool calls the model had just made.

The model never saw past the cut, so it read the file again. The re-read was cut again, or deduped by session-dedup into a [dedup:ref] pointing at the cut copy, and OpenAI-format agents (Cursor IDE, Kilo/OpenCode) looped on the same read. A Cursor IDE session on our deployment re-read the same two files 15+ times; every result was 2007–2015 chars ending in …[truncated], including the newest.

Anthropic-format tool_result blocks are not affected, since compressToolResults only handles string role:"tool" messages.

Fix

Skip tool messages after the last assistant message, which are the results of the latest tool calls. This is the same current-turn rule session-dedup already applies. Older turns are still truncated. A body with no assistant message keeps the previous behaviour.

Tests

tests/unit/compression/lite-current-turn.test.ts:

  • the newest tool result stays whole;
  • earlier-turn results are still truncated;
  • a re-read stays whole through the stacked session-dedup + lite pipeline.

Reproduced and verified against a real model through a local router with an OpenAI-format agent that uses a Kilo-style read tool, and with Cursor IDE's own system prompt and tool set replayed. Before the fix, 3/3 runs looped 12 reads without an answer, and 0/3 answered with the Cursor IDE shape. After the fix, 3/3 answered correctly in 1–2 reads.

The compression suites show the same failures as the base tip (previewRouteFuzzy fuzzyDedup CCR marker, #7849 heap test). Neither is touched by this change.

⚠️ base-red inherited: #15032

The default "Standard Savings" compression combo runs session-dedup then lite,
and lite cut every role:"tool" message to 2000 chars, including the results
of the tool calls the model just made. The model never saw past the cut, so it
re-read the file; the re-read was cut again or deduped against the cut copy,
and OpenAI-format agents (Cursor IDE, Kilo/OpenCode) looped on the same read.

Skip tool messages after the last assistant message, matching the current-turn
exemption session-dedup already has. Older turns are still truncated.
@diegosouzapw
diegosouzapw merged commit 2c60f35 into diegosouzapw:release/v3.8.51 Sep 29, 2026
9 of 16 checks passed
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.

2 participants