Skip to content

fix(agent): protect context compression from session interrupts - #24001

Closed
konsisumer wants to merge 1 commit into
NousResearch:mainfrom
konsisumer:fix/compression-survives-interrupt
Closed

fix(agent): protect context compression from session interrupts#24001
konsisumer wants to merge 1 commit into
NousResearch:mainfrom
konsisumer:fix/compression-survives-interrupt

Conversation

@konsisumer

Copy link
Copy Markdown
Contributor

Context compression should not abort when a new gateway message arrives mid-stream.

What changed and why

  • Add a thread-local protection flag (_AuxInterruptProtection) in agent/auxiliary_client.py that masks _CodexCompletionsAdapter._check_cancelled's is_interrupted() poll while it is active.
  • call_llm(task="compression", ...) now wraps the inner implementation with that protection, so a new Telegram message or watch-pattern notification arriving while the summary is streaming no longer raises InterruptedError and forces Hermes to insert a fallback context marker.
  • Timeouts and the existing close-on-timeout closer are unchanged: a genuinely hung Codex stream still cancels via the configured auxiliary.compression.timeout. The protection is scoped to the auxiliary call site only; other auxiliary tasks (vision, web_extract, etc.) continue to honor interrupts so users can still cancel long-running web extractions or vision lookups.
  • The pending gateway message stays queued by the platform adapter in _pending_messages and is served as soon as compression returns, so the user-facing UX is unchanged except that the next turn now sees a real summary instead of the fallback marker.

How to test

  • pytest tests/agent/test_auxiliary_client.py::TestCodexAuxiliaryCompressionInterruptProtection -q covers: baseline interrupt aborts the non-compression call, protection masks the interrupt during streaming, timeouts still fire under protection, the flag is thread-local and nests correctly, and call_llm enables protection only for task="compression".
  • pytest tests/agent/test_context_compressor.py tests/agent/test_compress_focus.py tests/agent/test_context_compressor_summary_continuity.py tests/agent/test_auxiliary_main_first.py -q to confirm no regressions in the compression flow.

What platforms tested on

  • macOS on darwin-arm64 (local)

Fixes #23975

@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint labels May 11, 2026
Compression is infrastructure that preserves conversation continuity. The
Codex auxiliary Responses adapter polled `tools.interrupt.is_interrupted()`
during streaming, so a new Telegram message or watch-pattern notification
arriving while a summary was running would raise InterruptedError and
force Hermes to insert a fallback context marker — silently dropping the
middle of the session from model context.

Add a thread-local protection flag (`_AuxInterruptProtection`) that masks
the interrupt check inside `_CodexCompletionsAdapter._check_cancelled`,
and enable it for `task="compression"` calls in `call_llm`.  Timeouts and
the explicit close-on-timeout closer are unchanged, so a hung Codex
stream still cancels via the configured `auxiliary.compression.timeout`.
The pending gateway message stays queued in `_pending_messages` and is
served as soon as compression returns, preserving the existing UX without
losing the summary.

Fixes NousResearch#23975
@konsisumer
konsisumer force-pushed the fix/compression-survives-interrupt branch from af4443c to ac26e04 Compare May 17, 2026 07:51
@konsisumer

Copy link
Copy Markdown
Contributor Author

Thanks for the additional reproductions. I re-ran the scoped regression checks on this branch: pytest tests/agent/test_auxiliary_client.py::TestCodexAuxiliaryCompressionInterruptProtection -q and pytest tests/agent/test_context_compressor.py tests/agent/test_compress_focus.py tests/agent/test_context_compressor_summary_continuity.py tests/agent/test_auxiliary_main_first.py -q, and they passed (6 passed, 101 passed).

The new Telegram follow-up repro and the Windows Desktop confirmation hit the same interrupt path this PR is targeting: compression is already in flight, a session interrupt lands, and Hermes falls back to the marker. This branch keeps compression runs alive for task="compression" while preserving timeout behavior and leaving other auxiliary tasks interruptible.

The Azure max_tokens 400 report and the duplicated compaction notice look like separate failure modes / UX issues, not regressions in the interrupt path itself, so I did not broaden this PR beyond the two files already in scope.

@teknium1

Copy link
Copy Markdown
Contributor

Merged via #49928 — your authorship is preserved as a co-author trailer on the merge. This fix incorporates the thread-local interrupt-protection approach from your PR. Thanks for the contribution! #49928

@teknium1 teknium1 closed this Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Context compression can be interrupted by gateway messages, causing fallback summary marker

3 participants