mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-09 13:21:42 +00:00
_handle_active_session_busy_message (the busy_session_handler most platform adapters register) demotes busy_input_mode='interrupt' to queue semantics for two reasons: active subagents (#30170) and, as of this week, context compression in flight (#56391) — interrupting while compression holds the state.db lock races a new turn against the pre-rotation parent session, and if that new turn also grows past the compression threshold it starts its own uncancellable compression on the same stale parent, forking orphaned compression siblings. _handle_message has its own, independent inline "PRIORITY" busy-path (reached directly with a live running agent — see the `if _quick_key in self._running_agents:` guard, exercised end-to-end by the existing tests/gateway/test_running_agent_session_toggles.py harness). Its own comment says it mirrors _handle_active_session_busy_message's subagent- demotion rationale verbatim, and it does demote for active subagents, but it never checked _session_has_compression_in_flight, so a plain-text follow-up landing on this path while compression is mid-flight still called running_agent.interrupt() unconditionally. Fix: add the same _session_has_compression_in_flight(session_key) check before the PRIORITY interrupt call, demoting to queue exactly like the sibling path. Tests: tests/gateway/test_priority_path_compression_demotion_56391.py drives _handle_message end-to-end (reusing the test_running_agent_ session_toggles.py harness pattern) with a live running agent and a mocked compression lock. Mutation-verified: reverting the fix makes the demotion test fail (interrupt() gets called) against the pre-fix code; a control test pins the unchanged default-interrupt behavior when no compression lock is held. |
||
|---|---|---|
| .. | ||
| assets | ||
| builtin_hooks | ||
| platforms | ||
| relay | ||
| __init__.py | ||
| authz_mixin.py | ||
| cgroup_cleanup.py | ||
| channel_directory.py | ||
| code_skew.py | ||
| config.py | ||
| cwd_placeholder.py | ||
| dead_targets.py | ||
| delivery.py | ||
| display_config.py | ||
| drain_control.py | ||
| hooks.py | ||
| kanban_watchers.py | ||
| memory_monitor.py | ||
| message_timestamps.py | ||
| mirror.py | ||
| pairing.py | ||
| platform_registry.py | ||
| response_filters.py | ||
| restart.py | ||
| restart_loop_guard.py | ||
| rich_sent_store.py | ||
| run.py | ||
| runtime_footer.py | ||
| scale_to_zero.py | ||
| session.py | ||
| session_context.py | ||
| shutdown_forensics.py | ||
| slash_access.py | ||
| slash_commands.py | ||
| status.py | ||
| status_phrases.py | ||
| sticker_cache.py | ||
| stream_consumer.py | ||
| stream_dispatch.py | ||
| stream_events.py | ||
| whatsapp_identity.py | ||