Skip to content

feat: support Telegram guest messages - #32802

Closed
vincelwt wants to merge 3 commits into
NousResearch:mainfrom
vincelwt:feat/telegram-guest-message
Closed

feat: support Telegram guest messages#32802
vincelwt wants to merge 3 commits into
NousResearch:mainfrom
vincelwt:feat/telegram-guest-message

Conversation

@vincelwt

@vincelwt vincelwt commented May 26, 2026

Copy link
Copy Markdown

Summary

  • Subscribe Telegram polling/webhooks to the official Bot API 10.0 guest_message update type.
  • Decode guest messages from either typed Update.guest_message or SDK-lagged Update.api_kwargs["guest_message"].
  • Route Guest Bot replies through official answerGuestQuery with Message.guest_query_id, instead of sendMessage into chats where the bot is not a member.
  • Preserve guest-query metadata through the gateway response path and keep normal/group/channel routing intact.

Official Telegram docs used:

  • Bot API 10.0 adds Update.guest_message, Message.guest_query_id, SentGuestMessage, and answerGuestQuery.
  • answerGuestQuery requires guest_query_id plus an InlineQueryResult result payload.

Test Plan

  • python -m pytest tests/gateway/test_telegram*.py -q
    • Result: 557 passed
  • python -m py_compile gateway/platforms/telegram.py gateway/platforms/base.py gateway/session.py tests/gateway/test_telegram_format.py
  • git diff --check

@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter labels May 26, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused guest-message implementation. The feature premise remains valid on current main, but this needs a current-architecture salvage and one delivery fix.

Problems

  • gateway/platforms/telegram.py:1924-1942 splits a response and then answers the guest query with only chunks[0]. Any later chunks are silently discarded while SendResult(success=True) is returned. The guest path needs an explicit, tested one-shot overflow policy.
  • The adapter target was moved by 5600105478ffde29d7566b45421b100eaa29c4ef from gateway/platforms/telegram.py to plugins/platforms/telegram/adapter.py. Current main still has four Update.ALL_TYPES registration sites there, including plugins/platforms/telegram/adapter.py:2009, so all update-registration and reply wiring needs to be ported to that surface.

Suggested changes

  • Port the feature to the bundled Telegram plugin and cover polling, reconnect, conflict-recovery, and webhook registrations.
  • Add a gateway-level test for complete final delivery and a response exceeding MAX_MESSAGE_LENGTH.

This is an automated hermes-sweeper review.

# Official Telegram Guest Bot replies go through
# answerGuestQuery, not sendMessage, because the bot is not a
# member of the chat that summoned it.
return await self._send_guest_query_answer(guest_query_id, chunks[0])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chunks was produced by truncate_message() immediately above, so this silently discards every chunk after the first while returning success. Please implement and test an explicit one-shot guest-reply overflow policy rather than dropping the remainder.

@vincelwt vincelwt closed this Jul 13, 2026
@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
milnerrad added a commit to milnerrad/hermes-agent that referenced this pull request Jul 30, 2026
Address blocking review comment. Moving the catch-all TypeHandler(Update)
from group=-1 to fallback group=1 ensures it does not compete with normal
text/command/media handlers in the default group (0).

While PTB's group-dispatch rules evaluate groups independently (so a group=-1
catch-all does not prevent default group-0 handlers from running unless a
handler raises ApplicationHandlerStop), this movement matches the placement in
sibling PR NousResearch#32802 and keeps registration clean.

Extracted adapter.py handler registration into _register_handlers() and added
accompanying regression tests in test_telegram_guest_mode.py to assert both
group-sorting and dispatch routing.
milnerrad added a commit to milnerrad/hermes-agent that referenced this pull request Jul 30, 2026
Address blocking review comment. Moving the catch-all TypeHandler(Update)
from group=-1 to fallback group=1 ensures it does not compete with normal
text/command/media handlers in the default group (0).

While PTB's group-dispatch rules evaluate groups independently (so a group=-1
catch-all does not prevent default group-0 handlers from running unless a
handler raises ApplicationHandlerStop), this movement matches the placement in
sibling PR NousResearch#32802 and keeps registration clean.

Extracted adapter.py handler registration into _register_handlers() and added
accompanying regression tests in test_telegram_guest_mode.py to assert both
group-sorting and dispatch routing.
milnerrad added a commit to milnerrad/hermes-agent that referenced this pull request Aug 2, 2026
Address blocking review comment. Moving the catch-all TypeHandler(Update)
from group=-1 to fallback group=1 ensures it does not compete with normal
text/command/media handlers in the default group (0).

While PTB's group-dispatch rules evaluate groups independently (so a group=-1
catch-all does not prevent default group-0 handlers from running unless a
handler raises ApplicationHandlerStop), this movement matches the placement in
sibling PR NousResearch#32802 and keeps registration clean.

Extracted adapter.py handler registration into _register_handlers() and added
accompanying regression tests in test_telegram_guest_mode.py to assert both
group-sorting and dispatch routing.
milnerrad added a commit to milnerrad/hermes-agent that referenced this pull request Aug 4, 2026
Address blocking review comment. Moving the catch-all TypeHandler(Update)
from group=-1 to fallback group=1 ensures it does not compete with normal
text/command/media handlers in the default group (0).

While PTB's group-dispatch rules evaluate groups independently (so a group=-1
catch-all does not prevent default group-0 handlers from running unless a
handler raises ApplicationHandlerStop), this movement matches the placement in
sibling PR NousResearch#32802 and keeps registration clean.

Extracted adapter.py handler registration into _register_handlers() and added
accompanying regression tests in test_telegram_guest_mode.py to assert both
group-sorting and dispatch routing.

(cherry picked from commit ae489fd)
milnerrad added a commit to milnerrad/hermes-agent that referenced this pull request Aug 8, 2026
Address blocking review comment. Moving the catch-all TypeHandler(Update)
from group=-1 to fallback group=1 ensures it does not compete with normal
text/command/media handlers in the default group (0).

While PTB's group-dispatch rules evaluate groups independently (so a group=-1
catch-all does not prevent default group-0 handlers from running unless a
handler raises ApplicationHandlerStop), this movement matches the placement in
sibling PR NousResearch#32802 and keeps registration clean.

Extracted adapter.py handler registration into _register_handlers() and added
accompanying regression tests in test_telegram_guest_mode.py to assert both
group-sorting and dispatch routing.

(cherry picked from commit ae489fd)
milnerrad added a commit to milnerrad/hermes-agent that referenced this pull request Aug 10, 2026
Address blocking review comment. Moving the catch-all TypeHandler(Update)
from group=-1 to fallback group=1 ensures it does not compete with normal
text/command/media handlers in the default group (0).

While PTB's group-dispatch rules evaluate groups independently (so a group=-1
catch-all does not prevent default group-0 handlers from running unless a
handler raises ApplicationHandlerStop), this movement matches the placement in
sibling PR NousResearch#32802 and keeps registration clean.

Extracted adapter.py handler registration into _register_handlers() and added
accompanying regression tests in test_telegram_guest_mode.py to assert both
group-sorting and dispatch routing.

(cherry picked from commit ae489fd)
milnerrad added a commit to milnerrad/hermes-agent that referenced this pull request Aug 17, 2026
Address blocking review comment. Moving the catch-all TypeHandler(Update)
from group=-1 to fallback group=1 ensures it does not compete with normal
text/command/media handlers in the default group (0).

While PTB's group-dispatch rules evaluate groups independently (so a group=-1
catch-all does not prevent default group-0 handlers from running unless a
handler raises ApplicationHandlerStop), this movement matches the placement in
sibling PR NousResearch#32802 and keeps registration clean.

Extracted adapter.py handler registration into _register_handlers() and added
accompanying regression tests in test_telegram_guest_mode.py to assert both
group-sorting and dispatch routing.

(cherry picked from commit ae489fd)
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 sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants