fix(gateway): plain text while busy interrupts by default again#40590
Merged
Conversation
Port from anomalyco/opencode#30749. When compression.enabled is false, NO automatic compaction trigger may fire. The proactive token-threshold paths (preflight + post-response should_compress gate) already honoured the setting, but the three provider-overflow recovery paths in the agent loop — long-context-tier 429, 413 payload-too-large, and context-overflow — called _compress_context() unconditionally, silently compressing and rotating the session against the user's explicit choice. Add a single guard at the top of the overflow-recovery dispatch: when compression is disabled and the error is one of those three overflow classes, surface a terminal error (compaction_disabled: True) telling the user to /compress manually, /new, switch to a larger-context model, or reduce attachments. Manual /compress (force=True) is unaffected — it never enters this loop. Tests: new TestOverflowWithCompactionDisabled (413 + 400 overflow don't compress when disabled; control case still compresses when enabled). Existing overflow-recovery tests updated to enable compaction explicitly (they verify the recovery fires); fixture defaults flipped to True to match production (compression.enabled defaults to True).
busy_input_mode (default 'interrupt') was advertised as the busy-behavior knob, but a second knob added in 7abd627 — busy_text_mode, defaulting to 'queue' — short-circuited every plain TEXT message before busy_input_mode was consulted. Result: plain follow-ups silently queued instead of interrupting, even with busy_input_mode left at its 'interrupt' default (regression #38390, silent-queue #31588). Collapse to one source of truth: busy_input_mode drives text handling. busy_text_mode is kept only as a legacy explicit override for back-compat (existing queue setups keep working); when unset it follows busy_input_mode. All default fallbacks flipped queue->interrupt. The debounce mechanism is preserved and now keyed off the resolved mode. Fixes #38390, #31588.
Contributor
🔎 Lint report:
|
This was referenced Jun 6, 2026
changman
pushed a commit
to changman/hermes-agent
that referenced
this pull request
Jun 10, 2026
…Research#40590) * fix: respect disabled auto-compaction on context overflow Port from anomalyco/opencode#30749. When compression.enabled is false, NO automatic compaction trigger may fire. The proactive token-threshold paths (preflight + post-response should_compress gate) already honoured the setting, but the three provider-overflow recovery paths in the agent loop — long-context-tier 429, 413 payload-too-large, and context-overflow — called _compress_context() unconditionally, silently compressing and rotating the session against the user's explicit choice. Add a single guard at the top of the overflow-recovery dispatch: when compression is disabled and the error is one of those three overflow classes, surface a terminal error (compaction_disabled: True) telling the user to /compress manually, /new, switch to a larger-context model, or reduce attachments. Manual /compress (force=True) is unaffected — it never enters this loop. Tests: new TestOverflowWithCompactionDisabled (413 + 400 overflow don't compress when disabled; control case still compresses when enabled). Existing overflow-recovery tests updated to enable compaction explicitly (they verify the recovery fires); fixture defaults flipped to True to match production (compression.enabled defaults to True). * fix(gateway): plain text while busy interrupts by default again busy_input_mode (default 'interrupt') was advertised as the busy-behavior knob, but a second knob added in 7abd627 — busy_text_mode, defaulting to 'queue' — short-circuited every plain TEXT message before busy_input_mode was consulted. Result: plain follow-ups silently queued instead of interrupting, even with busy_input_mode left at its 'interrupt' default (regression NousResearch#38390, silent-queue NousResearch#31588). Collapse to one source of truth: busy_input_mode drives text handling. busy_text_mode is kept only as a legacy explicit override for back-compat (existing queue setups keep working); when unset it follows busy_input_mode. All default fallbacks flipped queue->interrupt. The debounce mechanism is preserved and now keyed off the resolved mode. Fixes NousResearch#38390, NousResearch#31588.
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
Plain text messages sent while the agent is busy now interrupt by default again — the advertised
busy_input_mode: interruptdefault is no longer silently overridden.Root cause: A second knob,
busy_text_mode(added in 7abd627, defaultqueue), short-circuited every plain TEXT message in_handle_active_session_busy_messagebeforebusy_input_modewas ever consulted. So even users on the defaultinterruptmode saw plain follow-ups silently queued instead of interrupting. Two contradicting knobs with opposite defaults — the newer one quietly won.Changes
gateway/run.py:busy_input_modeis now the single source of truth._load_busy_text_mode()follows it; the legacybusy_text_modeknob is honored only when explicitly set (env or config) so existing queue setups keep working. Busy-gate fallback default flippedqueue→interrupt.gateway/platforms/base.py: adapter init default + debounce-candidate gate flippedqueue→interrupt. Debounce mechanism preserved, now keyed off the resolved mode.busy_input_mode; legacy override still wins)./stopand/neware unaffected — they always went through the slash-command bypass, not this gate.Validation
busy_input_modebusy_text_mode(resolved)busy_input_mode: queuebusy_text_mode: queuebusy_input_mode: steer55 targeted gateway tests pass; E2E resolution verified with real imports + isolated config.
Fixes #38390, #31588.
Infographic