fix(compression): let explicit interrupts cancel safely (salvage #74449) - #76647
Merged
kshitijk4poor merged 2 commits intoAug 2, 2026
Merged
Conversation
Collaborator
Related: #74449 is the open predecessor. This current-head salvage preserves its explicit-stop compression repair while resolving current-main conflicts in the pre-LLM feasibility and TUI interrupt paths; review should choose the current salvage versus the now-dirty predecessor. |
kshitijk4poor
force-pushed
the
salvage/compression-interrupt
branch
from
August 2, 2026 07:12
11ea844 to
faa0cc9
Compare
Makes interrupt-protected context compression cancellable by an explicit user or lifecycle stop, without weakening protection against ordinary incoming messages, voice interjections, or active-turn redirects. Separates explicit hard cancellation from ordinary interrupt/redirect state with a dedicated threading.Event; introduces AuxiliaryExplicitCancellation as an attempt-local frozen-cause signal; isolates the synchronous provider callback in a bounded daemon worker during protected compression; atomically linearizes Codex timeout cleanup against explicit cancellation; propagates hard cancellation through child agents and explicit stop surfaces; serializes hard-cancel admission against compression commit admission with CompressionCommitFence; aborts before session rotation or late DB commit, restores in-place transcript mutations and compressor state, and releases the heartbeat and compression lease. Based on NousResearch#74449 by @suparious. Resolved merge conflicts in agent/context_compressor.py (feasibility check + try/except) and tui_gateway/methods_session.py.
_abandon_timed_out_gateway_turn landed on main (eb4772e) after this PR's base and still used the soft interrupt(). Every other inactivity- timeout surface in this change (cron, gateway executor poll, delegate children) treats a timeout as an explicit stop that may cancel a protected compression summary — widen the same fix to this sibling.
kshitijk4poor
force-pushed
the
salvage/compression-interrupt
branch
from
August 2, 2026 16:41
faa0cc9 to
513fc96
Compare
kshitijk4poor
enabled auto-merge (rebase)
August 2, 2026 16:42
12 tasks
18 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes interrupt-protected context compression cancellable by an explicit user or lifecycle stop (Ctrl+C, /stop, gateway shutdown), without weakening protection against ordinary incoming messages, voice interjections, or active-turn redirects.
The bug: context compression held the session compression lease while generating its handoff summary. When the user pressed Ctrl+C, interrupt protection kept the summary worker alive after the frontend's grace period. The CLI accepted another turn while that worker still held the lease, and the next persistence operation failed with
session storage could not be written.Based on #74449 by @suparious, cherry-picked with authorship preserved.
Rebase onto current main (2026-08-02)
Rebased onto latest main (was 51 commits behind, CONFLICTING). Repairs made during the rebase — the previous head carried stale-base revert hunks that this update removes:
message.reactRPC handler (7d92056), the kanban session deny-list (e41d202), and theinclude_row_ids/ queued-prompt-generation fixes (d508585) intui_gateway/methods_session.py— the intrinsic diff there is now only the intended 6-line hard-interrupt changeBedrockAuxiliaryClient.close()(main's_close_cached_clientshutdown path calls it)gateway/run.py_interrupt_and_clear_sessionin favor of main's process-reaper flow +request_hard_interruptChanges
agent/interrupt_compat.py(new):request_hard_interrupt()— feature-detectedhard_interrupt()with legacyinterrupt()fallback (getattr_static so MagicMock/RPC proxies don't fabricate support)agent/auxiliary_client.py:AuxiliaryExplicitCancellation(BaseException),_run_protected_sync_provider_call(daemon worker isolation for protected calls only),_AuxiliaryCancellationDecision(atomic cancel/timeout linearization)agent/context_compressor.py: try/except around_generate_summary,_last_cooldown_refresh_was_authoritativefor rollbackagent/conversation_compression.py:CompressionCommitFencecancel admission, full rollback path (transcript, compressor state, cooldown, lease)run_agent.py:hard_interrupt()method,_hard_interrupt_requestedEvent, per-agent fence registrationcli.py,gateway/run.py,acp_adapter/server.py,cron/scheduler.py,tools/delegate_tool.py,tui_gateway/: propagaterequest_hard_interruptthrough all stop surfaceshermes_state.py: raw cooldown row get/restore for exact rollback (the active getter filters expired rows and cannot serve as a lossless rollback source)gateway/run.py_abandon_timed_out_gateway_turn(landed on main after this PR's base, eb4772e) widened to the same hard-stop semantics as every other inactivity-timeout surface in this changeValidation
Closes #74449