Skip to content

fix(session): prevent infinite loop in auto-compaction when assistant ended its turn#15532

Open
Lee-SiHyeon wants to merge 1 commit intoanomalyco:devfrom
Lee-SiHyeon:fix/compaction-infinite-loop
Open

fix(session): prevent infinite loop in auto-compaction when assistant ended its turn#15532
Lee-SiHyeon wants to merge 1 commit intoanomalyco:devfrom
Lee-SiHyeon:fix/compaction-infinite-loop

Conversation

@Lee-SiHyeon
Copy link

@Lee-SiHyeon Lee-SiHyeon commented Mar 1, 2026

Issue for this PR

Closes #15533

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

When auto-compaction triggers, SessionCompaction.process() unconditionally injects a synthetic "Continue if you have next steps..." user message. This works correctly when the assistant was mid-execution (tool calls in progress), but causes an infinite loop when the assistant had naturally ended its turn (e.g., asked a question or finished responding with finish === "stop"):

assistant responds → context overflow → auto-compaction → synthetic "Continue..." →
agent responds → overflow → compaction → synthetic "Continue..." → …

The fix checks the last non-summary assistant message's finish reason before injecting the synthetic continue:

  • finish === "tool-calls" or "unknown" → assistant was mid-execution → inject continue (existing behavior preserved)
  • finish === "stop" or other → assistant naturally ended its turn → skip inject, let session wait for real user input

This is the opposite case from #12970 (which fixed continue NOT being injected when it should be). Our fix only gates the injection — when wasUsingTools is true, the existing behavior is 100% unchanged.

Related PRs reviewed for overlap:

How did you verify your code works?

  1. Reproduced the infinite loop with a long conversation + oh-my-opencode plugin (Sisyphus agent) using Claude Sonnet 4
  2. After the fix, auto-compaction completes without injecting synthetic continue when finish === "stop", and the session correctly waits for user input
  3. Verified that when finish === "tool-calls", the synthetic continue is still injected (existing behavior preserved)

Screenshots / recordings

N/A — not a UI change

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

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 Mar 1, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

The following comment was made by an LLM, it may be inaccurate:

Based on my search, I found several potentially related PRs:

Potential Duplicates/Related Issues:

  1. PR feat(session): add custom compaction thresholds along with prevention of continuous compaction #10123 - feat(session): add custom compaction thresholds along with prevention of continuous compaction

    • Related to compaction behavior and preventing continuous compaction cycles, which is closely aligned with this PR's goal
  2. PR fix: auto-resume agent loop after context compaction #12970 - fix: auto-resume agent loop after context compaction

    • Addresses agent loop behavior after compaction, which relates to the synthetic continue message injection issue
  3. PR fix: compaction bugs #13946 and #13980 #14245 - fix: compaction bugs #13946 and #13980

    • Fixes existing compaction bugs, which may be related to or overlapping with this infinite loop issue

These PRs all touch on session compaction behavior and preventing unintended loops. You may want to review them to ensure there's no overlap or if they provide additional context for this fix.

@github-actions github-actions bot removed needs:issue needs:compliance This means the issue will auto-close after 2 hours. labels Mar 1, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

… ended its turn

When auto-compaction triggers after the assistant has naturally ended its turn
(finish reason is 'stop' or similar, not 'tool-calls'), the synthetic
'Continue...' user message should NOT be injected. Previously, this message was
always injected during auto-compaction regardless of the assistant's state,
causing an infinite loop:

  compaction → synthetic continue → agent response → overflow → compaction → …

This is especially problematic when the assistant asked a question and was
waiting for user input — the synthetic continue overrides the pending question,
causing the agent to respond to itself indefinitely.

The fix checks the last non-summary assistant message's finish reason before
injecting the synthetic continue. Only when the assistant was in the middle of
tool execution (finish === 'tool-calls' or 'unknown') is the continue message
injected. If the assistant had ended its turn naturally (finish === 'stop'),
the compaction completes without a synthetic continue, allowing the session
loop to exit and wait for actual user input.

Fixes infinite loop observed with oh-my-opencode plugin (Sisyphus/Ultraworker)
where auto-compaction + synthetic continue created unbounded agent loops.
@Lee-SiHyeon Lee-SiHyeon force-pushed the fix/compaction-infinite-loop branch from c3cdf1e to f613443 Compare March 1, 2026 10:02
@github-actions github-actions bot mentioned this pull request Mar 1, 2026
6 tasks
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.

Auto-compaction infinite loop when assistant ended its turn (finish !== tool-calls)

1 participant