Skip to content

fix(gateway): route watch-pattern notifications to originating session#10446

Closed
kshitijk4poor wants to merge 2 commits into
mainfrom
salvage/watch-notification-routing
Closed

fix(gateway): route watch-pattern notifications to originating session#10446
kshitijk4poor wants to merge 2 commits into
mainfrom
salvage/watch-notification-routing

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

Salvage of #9537 by @etcircle — fixes watch-pattern notifications being delivered to whichever Discord/Telegram thread happens to be active when the queue is drained, instead of routing back to the thread that started the background process.

Root cause

_inject_watch_notification(synth_text, event) in gateway/run.py passed the current foreground event (whatever thread the user just messaged from) instead of the process's own routing metadata. So if thread A started a background process and thread B later triggered the agent, thread A's watch notification appeared in thread B.

What the original PR (#9537) fixes

  1. process_registry.py — Watch event dicts now carry session_key + routing fields (platform, chat_id, thread_id, etc.)
  2. gateway/run.py — New _build_process_event_source(evt) resolves the correct SessionSource via 3-tier fallback: session store → session_key parse → event dict fields
  3. _inject_watch_notification() takes the queue event dict instead of the foreground event
  4. _run_process_watcher completion path also uses _build_process_event_source

Follow-up fixes (our commit)

Fix Description
Watch-only routing metadata watcher_platform/chat_id/thread_id are now populated for watch-pattern-only processes (previously only set when notify_on_complete was also enabled). Without this, watch events had empty routing fields and relied solely on session_key parsing fallback.
_parse_session_key() helper Extracted duplicated session key parsing logic (agent:main:{platform}:{chat_type}:{chat_id}) into a shared helper used by both _notify_active_sessions_shutdown and _build_process_event_source.
Negative cross-thread test Test proving the old bug (foreground event routing) doesn't happen.
Edge-case tests Tests for _build_process_event_source returning None on: empty event, invalid platform, short session key.
_parse_session_key tests Unit tests for the new helper: valid key, extra parts, too short, wrong prefix.

Test results

  • 53 passed (PR-specific test files), 0 new failures
  • Pre-existing flaky: test_run_progress_topics.py (4 failures, noted by contributor as baseline-drifty)

Based on #9537 by @etcircle. Closes #9532.

etcircle and others added 2 commits April 15, 2026 22:47
- Populate watcher_* routing fields for watch-only processes (not just
  notify_on_complete), so watch-pattern events carry direct metadata
  instead of relying solely on session_key parsing fallback
- Extract _parse_session_key() helper to dedupe session key parsing
  at two call sites in gateway/run.py
- Add negative test proving cross-thread leakage doesn't happen
- Add edge-case tests for _build_process_event_source returning None
  (empty evt, invalid platform, short session_key)
- Add unit tests for _parse_session_key helper
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #10460. Your salvage of #9537 was cherry-picked onto current main with both contributors' authorship preserved in git log. We added a small follow-up fix for a stale parts reference and missing thread_id in _parse_session_key(). Thanks @kshitijk4poor and @etcircle!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: background process watch notifications can leak into the wrong threaded session

3 participants