fix(telegram): preserve pipe tables on rich-message and standalone send paths - #45327
fix(telegram): preserve pipe tables on rich-message and standalone send paths#45327liuhao1024 wants to merge 1 commit into
Conversation
…nd paths When rich messages are enabled, Telegram renders pipe tables natively via sendRichMessage — the shared format_message() rewriter was destroying the pipe syntax before the rich path could see it. The standalone send_message tool path had the same issue: it always called format_message() with table rewriting enabled, flattening tables into bullet groups. Add a rewrite_tables keyword parameter to format_message() (default True for backward compatibility). The rich-message path and the standalone send_message path now pass rewrite_tables=False when rich messages are enabled in config. Fixes NousResearch#45323
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Clean, well-scoped fix/feature with comprehensive tests. No issues found.
- Logic is correct and focused
- Tests cover the new behavior
- No security concerns
- Good error handling
Reviewed by Hermes Agent
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the focused report and tests. The rich gateway defect described by #45323 is already addressed on current main: TelegramAdapter.send() sends raw content through sendRichMessage before the legacy formatter (plugins/platforms/telegram/adapter.py:3587-3610), and _rich_message_payload() explicitly forbids format_message() because MarkdownV2 escapes table pipes (plugins/platforms/telegram/adapter.py:1506-1521).
Problems
- The standalone change does not produce native tables. It still sends with
ParseMode.MARKDOWN_V2after formatting (tools/send_message_tool.py:1136-1144); disabling only the bullet rewrite leaves MarkdownV2, which the current adapter documents as unable to preserve rich table syntax. - The gateway target moved from
gateway/platforms/telegram.pytoplugins/platforms/telegram/adapter.pyin5600105478ffde29d7566b45421b100eaa29c4ef, so the gateway portion needs re-scoping rather than a direct port.
Suggested changes
- Retire the superseded gateway formatter change.
- If standalone rich delivery is intended, implement and test an explicit
sendRichMessagepath with capability-safe fallback rather than passing raw tables to MarkdownV2.
Automated hermes-sweeper review.
| pass | ||
| try: | ||
| from gateway.platforms.telegram import TelegramAdapter | ||
| _adapter = TelegramAdapter.__new__(TelegramAdapter) |
There was a problem hiding this comment.
This still sends the result through ParseMode.MARKDOWN_V2 immediately below, so rewrite_tables=False cannot yield a native Telegram table: the formatter escapes table pipes and this path never invokes sendRichMessage. Please use an explicit rich endpoint with fallback if native standalone table rendering is the intended behavior.
What does this PR do?
Adds a
rewrite_tableskeyword parameter toTelegramAdapter.format_message()to control whether GFM pipe tables are rewritten into bullet groups. When rich messages are enabled (platforms.telegram.extra.rich_messages: true), tables are preserved for native Telegram rendering instead of being flattened.Related Issue
Fixes #45323
Type of Change
Changes Made
gateway/platforms/telegram.py: Addedrewrite_tables: bool = Trueparameter toformat_message(). When False, skips_wrap_markdown_tables()so pipe table syntax survives MarkdownV2 escaping for Telegram's native table renderer.tools/send_message_tool.py: Standalone_send_telegramnow readsplatforms.telegram.extra.rich_messagesfrom config and passesrewrite_tables=Falsewhen rich messages are enabled.tests/gateway/test_telegram_format.py: 5 new tests covering rewrite_tables=True (default), rewrite_tables=False (rich path), backward compatibility, no-bullet-groups, and code-block isolation.How to Test
hermes config set platforms.telegram.extra.rich_messages truepytest tests/gateway/test_telegram_format.py -xvs— all 106 tests should passChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/ACode Intelligence
gateway/platforms/telegram.py::format_message(callers: 20+ across telegram.py and send_message_tool.py)_wrap_markdown_tables()(table rewriting),_should_attempt_rich()(rich message routing),_rich_message_payload()(raw markdown path)