Files
openclaw/src/agents/cli-runner
Abdel Gomez-Perez 5c4a733912 fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars (#83117)
* fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars

`buildCliSessionHistoryPrompt` was prefix-slicing the rendered history,
dropping the most recent assistant turns from the reseed prompt. After
#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is
exposed to this on session_expired when the rendered transcript exceeds
12288 chars. The truncation marker landed mid-word in real reproductions.

Fix:
- Tail-slice (keep the recent suffix, drop the older prefix)
- Pin the compaction summary as a prefix when present, only cap the
  post-summary transcript (loadCliSessionReseedMessages deliberately
  places the summary first)
- When the summary alone exceeds maxHistoryChars, head-slice the summary
  itself to honor the cap; drop the post-summary tail in that case
- Move the truncation marker to the lead since what follows is the
  recent tail, not what was dropped

Closes #83157

* fix(cli-runner): retain recent tail with oversize summaries

* fix(cli-runner): cap summary block plus marker against maxHistoryChars

ClawSweeper P2 on #83117 flagged that when `summaryRendered.length` is
less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n`
separator) meets or exceeds it, the `remainingBudget <= 0` arm of
`buildCliSessionHistoryPrompt` appends the truncation marker after the
already-full summary block. A 199-char rendered summary under a 200-char
cap produced a 257-char history block — defeating the cap that prevents
reseeding fresh CLI sessions with unexpectedly huge prompts.

Fix the budget edge by truncating the summary in this branch as well so
`summary + separator + marker` stays within `maxHistoryChars`. The tail
still drops (the summary alone consumes the budget) and the marker still
leads its own line so the prompt announces what was discarded. Mirrors
the existing oversize-summary branch's pattern of head-slicing the
summary against an explicit budget that reserves marker + separator.

Add a focused regression in `session-history.test.ts` covering exactly
the gap the finding called out: `summaryRendered.length < maxHistoryChars`
with a non-empty post-summary tail. Asserts the rendered history block
stays within `maxHistoryChars` and the truncation marker is present.

* fix(cli-runner): keep tail for near-cap summaries

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-05-24 00:07:11 +01:00
..