fix: coalesce multiple background process completion notifications by session_key - #70319
fix: coalesce multiple background process completion notifications by session_key#70319handnewb wants to merge 2 commits into
Conversation
… session_key When multiple background processes finish in the same gateway tick, each one injected a separate notification into the agent session, flooding the context and causing session lag. This change adds _coalesce_and_inject_watch_events() which groups standard completion events by session_key before injection. When N processes complete for the same session, a single batched message like '[IMPORTANT: N background processes finished]' is delivered instead of N individual messages. watch_match events are NOT coalesced — each pattern match is individually important and must reach the agent separately. Closes NousResearch#70300
…debug log, test type=None - Batched message now includes process session_ids (truncated to 5 + '...and N more') - Added logger.debug when coalescing events - New test: test_coalesced_message_truncates_ids_after_5 - New test: test_type_none_treated_as_completion - Updated existing test to verify IDs in coalesced message
|
I reproduced #70300 against current One important ownership detail: standard I opened #71898 with batching at the Sharing this here to connect the two approaches and avoid duplicated debugging; maintainers can choose whichever shape best fits the gateway ownership model. |
|
@yuzilongleif-collab — great catch on the architectural issue. You're absolutely right that standard completions flow through I've opened a new approach in #72675 that:
89 tests passing. Closing this in favor of the combined approach. Thanks for the thorough review! |
Coalesce multiple background process completions and watch events that share the same gateway route so the agent receives one synthetic turn instead of one turn per process (NousResearch#70300). Two-pronged approach, each at the correct ownership seam: 1. Standard completions: batched at _run_process_watcher() via _enqueue_process_completion_notification() with a short (100ms) window and threshold-based early flush (5+ entries = immediate). Single completions pass through with zero extra latency. 2. watch_match / watch_disabled events: coalesced at the post-turn drain via _coalesce_and_inject_watch_events(), grouped by type and session_key. Output format includes: - Per-process status with visual indicators (✅/❌) - Exit codes, elapsed time, reason - Aggregate summary (N succeeded, M failed) - Bounded output (10 detailed results, 800-char tails) Edge cases covered: - Flush during delivery schedules next batch - Duplicate primary tries next batch identity - Formatter failure resolves all waiters with False - Lazy init for tests using object.__new__ - None-safe batch key and type handling Closes NousResearch#70300 Supersedes NousResearch#70319 and NousResearch#71898 Co-authored-by: yuzilongleif-collab <235949691+yuzilongleif-collab@users.noreply.github.com>
Problem
When multiple background processes finish in the same gateway tick, each one injects a separate notification into the agent session via
_inject_watch_notification. This floods the context with redundant messages, causes session lag (Persisted transcript lagged), and leaves the agent processing notification-after-notification instead of responding to the user.Evidence from production (Discord gateway)
Then immediately:
6 processes → 6 injections → flooded session → unresponsive agent.
Fix
Added
GatewayRunner._coalesce_and_inject_watch_events()which groups standard completion events bysession_keybefore injection. When N processes complete for the same session in one drain tick, a single batched message is delivered:Key design decisions:
watch_matchevents pass through individually since each pattern match is independently importantChanges
gateway/run.py:_coalesce_and_inject_watch_events()with coalescing logic_format_gateway_process_notification()to handle standardcompletionevent type (previously returnedNone)tests/gateway/test_background_process_notifications.py:Testing
Closes #70300