Skip to content

fix(telegram): honor message.quote for partial-quote reply context - #22632

Closed
briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/telegram-partial-quote-22619
Closed

briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/telegram-partial-quote-22619

Conversation

@briandevans

Copy link
Copy Markdown
Contributor

Summary

When a Telegram user replies using Telegram's native partial-quote feature (selecting a substring of a prior message), _build_message_event was injecting the entire replied-to message into reply_to_text. Now it prefers message.quote.text (the user-selected substring) and falls back to the full replied-to message only when no native quote is present.

The bug

gateway/platforms/telegram.py::_build_message_event extracted reply context as:

if message.reply_to_message:
    reply_to_id = str(message.reply_to_message.message_id)
    reply_to_text = message.reply_to_message.text or message.reply_to_message.caption or None

message.reply_to_message.text is always the full prior message body. If Hermes sent a multi-section message and the user replied to one quoted bullet with "mark this one as done", the agent saw:

[Replying to: "<entire previous Hermes message — every bullet>"]

mark this one as done

python-telegram-bot >=21 exposes Message.quote: Optional[TextQuote] which carries TextQuote.text for the user-selected substring (PTB docs: "For replies that quote part of the original message, the quoted part of the message."). The repo pins python-telegram-bot[webhooks]>=22.6,<23 (pyproject.toml:58) so quote is reliably available — the production code just wasn't reading it.

The fix

Read getattr(message, "quote", None) and prefer quote.text when truthy. Fall back to reply_to_message.text or reply_to_message.caption for replies without a native quote (older PTB, or replies that don't select a substring) and for replied-to media messages where only the caption is set.

getattr + is not None checks keep the path safe if quote is ever absent or empty.

Test plan

  • Focused regression: tests/gateway/test_telegram_reply_quote.py — 4 tests covering the partial-quote path, no-quote fallback, caption fallback, and an empty-string quote.text defensive case
  • Adjacent suite: tests/gateway/test_dm_topics.py, test_telegram_reply_mode.py, test_reply_to_injection.py (70 tests passed)
  • Regression guard: with the fix reverted, test_native_partial_quote_used_as_reply_to_text fails with AssertionError: 'Briefing:\\n- Item A:...' == 'Item B: rotate keys' — proves the test exercises the new code path

Run focused tests:

uv run --with pytest --with pytest-xdist --with pytest-asyncio python3 -m pytest \
  tests/gateway/test_telegram_reply_quote.py -v

Related

Sibling code paths that may need the same fix: none in this adapter — _build_message_event is the single inbound extraction site for Telegram updates. Other adapters (Discord, Slack, Matrix, etc.) have their own reply-context paths and would need a per-platform check before extending.

When a Telegram user replies using the native quote feature to select
only part of a prior message, _build_message_event was injecting the
ENTIRE replied-to message into reply_to_text via
message.reply_to_message.text/caption. python-telegram-bot exposes
the user-selected substring as message.quote (TextQuote.text); we now
prefer that and fall back to the full replied-to text only when no
native quote is present.

The agent-visible "[Replying to: \"...\"]" prefix can otherwise expand
the user's narrow quote into the full prior message, causing the agent
to act on unrelated actionable-looking text the user did not select
(e.g. multi-item briefings where the user quotes one bullet but the
prefix injects every bullet). Falls back cleanly when message.quote
is absent (PTB <21 or replies that don't quote a substring).

Fixes NousResearch#22619

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 9, 2026 15:14

Copilot AI 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.

Pull request overview

This PR fixes Telegram reply-context extraction so that when a user replies with Telegram’s native partial-quote feature, the gateway prefers the user-selected substring (message.quote.text) for reply_to_text instead of injecting the entire replied-to message body.

Changes:

  • Update TelegramAdapter._build_message_event to prefer message.quote.text when present/truthy, with a fallback to reply_to_message.text or reply_to_message.caption.
  • Add a focused regression test suite covering partial-quote, no-quote fallback, caption fallback, and empty-quote defensive behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
gateway/platforms/telegram.py Prefer Telegram native partial quote text for reply_to_text, falling back to full replied-to message text/caption.
tests/gateway/test_telegram_reply_quote.py Adds regression coverage for partial-quote handling and fallbacks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@teknium1

teknium1 commented May 9, 2026

Copy link
Copy Markdown
Collaborator

Merged via salvage PR #22676. Your commit was cherry-picked onto current main with your authorship preserved in git log (rebase-merge). Thanks for the contribution!

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]: Telegram native partial quotes are expanded to the full replied-to message

3 participants