Skip to content

fix(session): stop looping auto-compaction when it cannot restore context headroom - #48828

Closed
whitesm2000 wants to merge 1 commit into
anomalyco:devfrom
whitesm2000:fix/compaction-loop-guard
Closed

whitesm2000 wants to merge 1 commit into
anomalyco:devfrom
whitesm2000:fix/compaction-loop-guard

Conversation

@whitesm2000

Copy link
Copy Markdown

Fix: stop looping auto-compaction when it cannot restore context headroom

Fixes 48827

Problem

When a session's irreducible context (system prompt + retained recent tail) exceeds the model's usable window (context - min(limit.output, OUTPUT_TOKEN_MAX)), auto-compaction can never bring the session back under the overflow threshold. The session loop then compacts after every step forever: compaction → synthetic "Continue if you have next steps…" → overflowing step → compaction → …

Concretely observed with cerebras/qwen-3.8-27b (context 65,536 → usable 33,536) on a session whose post-compaction floor was ~43k tokens: an unattended compaction↔build ping-pong running 20+ cycles per minute, each cycle issuing a full-context API call, until it tripped the provider's TPM rate limit. The user sees a spinner and no error; meanwhile the auto-continue keeps the agent executing tool calls autonomously on every cycle.

Fix

New no-progress guard, judged by outcome rather than count:

  • SessionCompaction.failedAutoCompactions(msgs, over) — pure helper: walks the session history and counts the trailing run of automatic compactions whose first finished non-summary successor step still overflows the model's usable window. A real user turn, a manual compaction, or a successful compaction resets the run.

  • SessionCompaction.failedStreak({ sessionID, model }) — service method that applies the helper to the full (unfiltered, chronological) session history using the same isOverflow inputs as the trigger (cfg + outputTokenMax aware).

  • Both auto-compaction trigger sites in session/prompt.ts (the start-of-iteration isOverflow check and the processor's "compact" outcome) now consult the streak before creating another compaction. When it reaches MAX_FAILED_AUTO_COMPACTIONS (2), the loop stops and publishes a ContextOverflowError:

    Session still exceeds the model's usable context window after 2 automatic compactions. Start a new session or switch to a model with a larger context window.

Judging by the first successor step is what avoids false positives: legitimate flows that overflow again only after pulling in a new large tool result have a healthy first post-compaction step, so they compact normally. Because the streak is computed from persisted history (not loop-local state), the guard still trips promptly even if the session loop was restarted in between (app relaunch).

Validation

  • Unit tests: 9 new cases for failedAutoCompactions (consecutive failures, synthetic-continue messages don't reset, real user turns reset, manual compactions ignored, summary steps skipped as successors, no-successor edge, later-overflow-doesn't-mark-good-compaction) plus a DB-backed failedStreak test building a real ping-pong history. Full package suite: 3590 pass / 0 fail, tsgo --noEmit clean.
  • Repro scenario: the guard turns the observed infinite loop in the issue into 2 bounded compaction cycles followed by a clear, actionable error.

…text headroom

When a session's irreducible context (system prompt plus retained tail)
exceeds the model's usable window, every step finishes over the overflow
threshold and the loop auto-compacts after every single step forever,
burning provider quota (and tripping rate limits) without making progress.

Add a no-progress guard: count consecutive automatic compactions whose
first finished successor step still overflows the model's usable window.
Once that streak reaches MAX_FAILED_AUTO_COMPACTIONS (2), stop the loop
and surface a ContextOverflowError telling the user to start a new
session or switch to a larger-context model, instead of compacting again.

A compaction is judged by its first finished non-summary successor step,
so legitimate flows that overflow again only after pulling in new large
tool results still get compacted normally. Real user turns and manual
compactions reset the streak.
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Sep 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Sep 13, 2026
@github-actions github-actions Bot closed this Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant