Compaction summary nesting grows unboundedly with each compaction
Bug description
Every time a session is compacted, the merge_compact_summaries function in compact.rs adds another layer of nested "- Previously compacted context:" bullets to the compaction summary. After 31 compactions (which is not unusual over a long session), the summary becomes 31 levels deep, ballooning from a healthy ~500 bytes to ~16KB, and causes the API to reject the request due to context overflow.
Root cause
The bug is in merge_compact_summaries (compact.rs:282–313) in combination with extract_summary_highlights (compact.rs:519–539).
When merging a new summary into an existing one, merge_compact_summaries calls extract_summary_highlights(existing_summary) to pull out the highlights from the previous compaction so it can re-wrap them under a new "- Previously compacted context:" bullet. The intent is to preserve the old highlights as historical context.
The problem: extract_summary_highlights iterates over all lines in the formatted summary and returns everything before the - Key timeline: section — including the "- Previously compacted context:" wrapper bullets themselves from the previous compaction. These wrapper bullets already contain the nested highlights from even older compactions. When those extracted lines are then placed under a new "- Previously compacted context:" wrapper in merge_compact_summaries, the old wrapper becomes a child of the new one.
After compaction N, the summary looks like:
<summary>
Conversation summary:
- Previously compacted context: ← layer N
- Previously compacted context: ← layer N-1 (extracted from previous highlights)
- Previously compacted context: ← layer N-2
...
- Key timeline:
...
Each compaction adds exactly one new layer. The content within the deepest layer doubles in size as highlights accumulate (since each merge also adds new highlights), so the growth is roughly quadratic in the number of compactions.
Reproduction
Run a session through ~31+ context compactions. Observe that the compaction entry in the session file has 31+ nested "- Previously compacted context:" bullets, and the summary grows from ~500 bytes to ~16KB.
Fix
In extract_summary_highlights, skip lines that begin with "- Previously compacted context:" (or whatever the wrapper string is). Only return the actual content lines beneath the wrapper. This ensures that when merge_compact_summaries wraps the old highlights under a new bullet, it doesn't also carry over the old wrapper's bullet marker.
Alternatively, in merge_compact_summaries, strip the wrapper bullet prefix from the extracted lines before re-wrapping them.
Disclaimer: This was written with the assistance of an LLM (Claw-Code/MiniMax-M2.7)
Compaction summary nesting grows unboundedly with each compaction
Bug description
Every time a session is compacted, the
merge_compact_summariesfunction incompact.rsadds another layer of nested"- Previously compacted context:"bullets to the compaction summary. After 31 compactions (which is not unusual over a long session), the summary becomes 31 levels deep, ballooning from a healthy ~500 bytes to ~16KB, and causes the API to reject the request due to context overflow.Root cause
The bug is in
merge_compact_summaries(compact.rs:282–313) in combination withextract_summary_highlights(compact.rs:519–539).When merging a new summary into an existing one,
merge_compact_summariescallsextract_summary_highlights(existing_summary)to pull out the highlights from the previous compaction so it can re-wrap them under a new"- Previously compacted context:"bullet. The intent is to preserve the old highlights as historical context.The problem:
extract_summary_highlightsiterates over all lines in the formatted summary and returns everything before the- Key timeline:section — including the"- Previously compacted context:"wrapper bullets themselves from the previous compaction. These wrapper bullets already contain the nested highlights from even older compactions. When those extracted lines are then placed under a new"- Previously compacted context:"wrapper inmerge_compact_summaries, the old wrapper becomes a child of the new one.After compaction N, the summary looks like:
Each compaction adds exactly one new layer. The content within the deepest layer doubles in size as highlights accumulate (since each merge also adds new highlights), so the growth is roughly quadratic in the number of compactions.
Reproduction
Run a session through ~31+ context compactions. Observe that the compaction entry in the session file has 31+ nested
"- Previously compacted context:"bullets, and the summary grows from ~500 bytes to ~16KB.Fix
In
extract_summary_highlights, skip lines that begin with"- Previously compacted context:"(or whatever the wrapper string is). Only return the actual content lines beneath the wrapper. This ensures that whenmerge_compact_summarieswraps the old highlights under a new bullet, it doesn't also carry over the old wrapper's bullet marker.Alternatively, in
merge_compact_summaries, strip the wrapper bullet prefix from the extracted lines before re-wrapping them.Disclaimer: This was written with the assistance of an LLM (Claw-Code/MiniMax-M2.7)