Skip to content

fix(telegram): preserve DM topic routing for synthetic background process events#26945

Closed
Ardem2025 wants to merge 1 commit into
NousResearch:mainfrom
Ardem2025:fix/dm-topic-routing-synthetic-events
Closed

fix(telegram): preserve DM topic routing for synthetic background process events#26945
Ardem2025 wants to merge 1 commit into
NousResearch:mainfrom
Ardem2025:fix/dm-topic-routing-synthetic-events

Conversation

@Ardem2025

Copy link
Copy Markdown

Summary

Fixes #9532 — background process completion notifications leak into the root DM chat instead of the correct DM topic thread.

Problem

When a background process completes (notify_on_complete=true), the gateway injects a synthetic MessageEvent without a message_id. For Telegram DM topics, _thread_kwargs_for_send() requires a reply anchor (reply_to_message_id) to route messages into the correct topic lane. Without it, the method returned {} — dropping all thread routing and sending the response to the root chat.

Fix

In _thread_kwargs_for_send(): when telegram_dm_topic_reply_fallback is set but no reply anchor is available, fall back to sending with message_thread_id instead of returning empty kwargs. This ensures the message is routed to the correct DM topic thread.

Testing

  • Updated existing test test_send_dm_topic_fallback_without_anchor_uses_message_thread_id to verify the new behavior
  • All 34 tests in test_telegram_thread_fallback.py pass

Reproduction

  1. Start a background process with notify_on_complete=true in a Telegram DM topic session
  2. Wait for the process to complete
  3. Before fix: completion notification goes to root DM chat
  4. After fix: completion notification stays in the correct DM topic thread

…cess events

When a background process completes, the gateway injects a synthetic
MessageEvent without a message_id. For Telegram DM topics, the
_thread_kwargs_for_send() method previously returned {} when no reply
anchor was available, causing the response to be sent to the root chat
instead of the topic thread.

Now falls back to sending with message_thread_id even without a reply
anchor. This prevents cross-thread bleed for background process
completion notifications and watch pattern events in DM topics.

Fixes NousResearch#9532
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter labels May 16, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #24222 (competing fix for background process thread routing). Both address notification routing to wrong Telegram topic, but different approaches — #24222 carries full routing context on completion queue events, while this PR fixes _thread_kwargs_for_send() fallback.

@cardtest15-coder

This comment was marked as spam.

@Ardem2025

Copy link
Copy Markdown
Author

Thanks for the pointer! I looked at #24222 — the two PRs are complementary rather than competing:

  • fix(gateway): preserve thread routing for process completions #24222 ensures the full routing context (thread_id, chat_id, etc.) is carried on completion queue events so _build_process_event_source() resolves correctly.
  • This PR fixes the downstream issue: even when source.thread_id is correctly resolved, _thread_kwargs_for_send() still returned {} for DM topics without a reply anchor (synthetic events never have a message_id). This caused the Telegram send to drop thread routing entirely.

Both fixes are needed for the full path to work: #24222 ensures the source has the right thread_id, and this PR ensures that thread_id actually gets passed to the Telegram Bot API even without a reply anchor.

@Qwinty

Qwinty commented May 18, 2026

Copy link
Copy Markdown
Contributor

I hit the same no-anchor symptom in the resumed final-response path and opened #27937 as a narrow alternative/follow-up.

One important difference: #27937 does not fall back to message_thread_id alone for Hermes-created Telegram DM topic lanes. The current tests and comments treat that as a known partial route that can render outside the visible lane. Instead, it carries direct_messages_topic_id into the base adapter metadata and uses that only when the reply anchor is unavailable.

@Ardem2025

Copy link
Copy Markdown
Author

Hey @Qwinty, thanks for chiming in and for #27937!

Good point about the bare message_thread_id fallback — you're right that without a reply anchor Telegram can render it outside the visible lane in some edge cases. The direct_messages_topic_id approach in your PR is a cleaner long-term solution for that.

This PR was intentionally minimal: fix the immediate symptom (notifications going to the general stream instead of the topic at all) while #24222 and now #27937 address the deeper routing context. Happy to coordinate — if #27937 lands first, this fallback becomes redundant for that path and can be dropped or scoped down.

Let me know if there's anything useful I can do on my end!

@Qwinty

Qwinty commented May 18, 2026

Copy link
Copy Markdown
Contributor

Thanks! That makes sense — I’ll keep #27937 focused on the no-reply-anchor DM-topic path and mention that if it lands first, the bare message_thread_id fallback here can be dropped or scoped down. No extra action needed from your side right now; happy to sync if maintainers prefer one combined direction.

@teknium1

Copy link
Copy Markdown
Contributor

Closing in favor of #27212 (same issue #9532, better approach).

The _thread_kwargs_for_send docstring on current main explicitly says:

Hermes-created private-chat topic lanes are marked with telegram_dm_topic_reply_fallback and must send the private topic thread id together with a reply anchor. Live testing showed that either parameter alone can render outside the visible lane.

Your fix falls back to message_thread_id alone — exactly the known-bad route that docstring warns against. #27212 (@fabiosiqueira) captures the triggering message id at process-spawn time and threads it through the synthetic event, supplying a real reply anchor. That respects the docstring invariant.

Also see #27937 (@Qwinty) which solves the resumed-send variant via direct_messages_topic_id fallback — different but complementary mechanism.

Thanks for the diagnosis on #9532; #27212 takes it to a working fix.

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter type/bug Something isn't working

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

6 participants