Problem
Telegram Bot API 10.1 (released 2026-06-11, four days before this issue) introduced RichBlockTable — a structured block-tree JSON entity that renders as a native, styled table in the Telegram client (mobile + desktop + web), with full per-cell styling, is_bordered / is_striped, and a caption.
The new send method is sendRichMessage (plus streaming partial rich messages), and editMessageText now accepts rich_message.
The Hermes→Telegram gateway currently does NOT convert markdown pipe tables to this new format. When an agent emits a markdown table in a Telegram DM, the user sees it as plain text (or, per the system prompt, auto-rewritten to row-group bullets which is worse).
Real-world trigger
The agent needed to send a 6-column comparison of LLM inference service prices (DeepInfra / Together / Fireworks / OpenRouter / Anthropic / OpenAI / Google × MiniMax-M3, Qwen3-32B-FT, DeepSeek-V4-Pro, etc.). Three attempts:
- Markdown pipe table — rendered as plain text in user's client
- Monospace code block with
str.ljust()-aligned columns — looked like ASCII art, not a table
- Pre/code with MarkdownV2 entity — also rendered as text
Final workaround: generate a PNG via Pillow, send via MEDIA: directive. This works but the image is non-selectable, non-responsive, and a hack.
Proposed solution
In the Telegram gateway (gateway/platforms/telegram.py or wherever outbound message construction lives), detect markdown pipe tables in the agent's output, parse them, and emit a RichMessage block via the new sendRichMessage method.
Scope:
- New module:
gateway/rich_text/markdown_to_rich.py — converts standard markdown (bold, italic, lists, code, tables) to the RichMessage block tree.
- New method (or extend
send_message) in gateway/platforms/telegram.py that calls sendRichMessage when the converted payload contains a RichBlockTable or other rich blocks; falls back to plain sendMessage with parse_mode=MarkdownV2 for plain text without tables.
- Backwards compatible: existing
parse_mode=MarkdownV2 flow continues to work; rich pipeline is opt-in by content detection.
Acceptance criteria:
Environment
- Hermes version: latest (
hermes update)
- Telegram Bot API: 10.1+
- Tested with: Telegram Desktop 4.x, Telegram iOS 10.x, Telegram Android 10.x
- Python: 3.11
- Pillow already a dep (used for current PNG-table workaround)
Workaround currently in use
While this is being implemented, end-users in the Hermes community have a workaround skill that generates a PNG via Pillow and ships it as MEDIA:. This skill is functional but lossy (no copy/paste, no dark mode, no per-cell styling). It would be retired once native rich tables ship.
Why this matters
Multi-column data comparison degrades to either bullet lists (loses column alignment) or PNG hacks (loses interactivity). Bot API 10.1 closes this gap; the gateway just needs to expose it.
Reference
Problem
Telegram Bot API 10.1 (released 2026-06-11, four days before this issue) introduced RichBlockTable — a structured block-tree JSON entity that renders as a native, styled table in the Telegram client (mobile + desktop + web), with full per-cell styling,
is_bordered/is_striped, and a caption.The new send method is
sendRichMessage(plus streaming partial rich messages), andeditMessageTextnow acceptsrich_message.The Hermes→Telegram gateway currently does NOT convert markdown pipe tables to this new format. When an agent emits a markdown table in a Telegram DM, the user sees it as plain text (or, per the system prompt, auto-rewritten to row-group bullets which is worse).
Real-world trigger
The agent needed to send a 6-column comparison of LLM inference service prices (DeepInfra / Together / Fireworks / OpenRouter / Anthropic / OpenAI / Google × MiniMax-M3, Qwen3-32B-FT, DeepSeek-V4-Pro, etc.). Three attempts:
str.ljust()-aligned columns — looked like ASCII art, not a tableFinal workaround: generate a PNG via Pillow, send via
MEDIA:directive. This works but the image is non-selectable, non-responsive, and a hack.Proposed solution
In the Telegram gateway (
gateway/platforms/telegram.pyor wherever outbound message construction lives), detect markdown pipe tables in the agent's output, parse them, and emit a RichMessage block via the newsendRichMessagemethod.Scope:
gateway/rich_text/markdown_to_rich.py— converts standard markdown (bold, italic, lists, code, tables) to the RichMessage block tree.send_message) ingateway/platforms/telegram.pythat callssendRichMessagewhen the converted payload contains aRichBlockTableor other rich blocks; falls back to plainsendMessagewithparse_mode=MarkdownV2for plain text without tables.parse_mode=MarkdownV2flow continues to work; rich pipeline is opt-in by content detection.Acceptance criteria:
is_header: true, cells usealign: "right"for numeric columnssendRichMessageis not supported by the user's client versionEnvironment
hermes update)Workaround currently in use
While this is being implemented, end-users in the Hermes community have a workaround skill that generates a PNG via Pillow and ships it as
MEDIA:. This skill is functional but lossy (no copy/paste, no dark mode, no per-cell styling). It would be retired once native rich tables ship.Why this matters
Multi-column data comparison degrades to either bullet lists (loses column alignment) or PNG hacks (loses interactivity). Bot API 10.1 closes this gap; the gateway just needs to expose it.
Reference
sendRichMessage: search "sendRichMessage" on the same pagerich_messagefield on Message: https://core.telegram.org/bots/api#message