Skip to content

fix(telegram): convert Markdown tables to bullet lists - #11226

Closed
mauruk wants to merge 1 commit into
NousResearch:mainfrom
mauruk:fix/telegram-markdown-tables
Closed

mauruk wants to merge 1 commit into
NousResearch:mainfrom
mauruk:fix/telegram-markdown-tables

Conversation

@mauruk

@mauruk mauruk commented Apr 16, 2026

Copy link
Copy Markdown

Summary

  • Telegram does not render Markdown tables — pipes and dashes show up raw, making structured output illegible.
  • _convert_table() rewrites table blocks to **header:** value bullets before MarkdownV2 escaping.
  • Plain text and inline pipes outside tables are untouched.

Problem

When the agent produces tables (comparisons, specs, schedules) for Telegram DMs/topics, users see this:

| Feature | Hook | Provider |
|---------|------|----------|
| Latency | ~500ms | ~0ms |
| Shutdown | hard kill | graceful |

…rendered literally. Zero visual structure.

Fix

In TelegramAdapter.format_text() (the hook before MarkdownV2 escaping), walk the text line-by-line. When a block of |…| rows is detected, optionally followed by a separator |---|…|:

  1. Parse the header row (cells between pipes).
  2. Skip the separator.
  3. For each data row, emit:
    • A blank line
    • For each (header, cell): • **header:** cell (one line each)

Everything else passes through unchanged.

Test plan

  • Tables with 2–6 columns render as readable bullets
  • Tables with alignment hints (:---, ---:, :---:) handled (separator-row regex is permissive)
  • Text with inline pipes outside tables (a | b in prose) not rewritten
  • Mixed content (prose + multiple tables) preserves order
  • Empty cells skipped cleanly
  • Running in production on a private Hetzner instance since early April 2026 — zero table-related complaints since.

Note

Patch has been carried locally in production for ~10 days. Opening upstream so it doesn't need to be rebased on every release.

🤖 Generated with Claude Code

Telegram's MarkdownV2 parser does not render tables — they are
shown raw, with visible pipes and dashes. When the agent uses
tables for structured data (comparisons, schedules, specs),
the Telegram output is illegible.

_convert_table() walks the outgoing text before MarkdownV2
escaping, detects table blocks (lines starting and ending
with `|`, followed by a separator row `|---|---|`), and
rewrites each row as a bulleted list in `**header:** value`
format.  Plain text outside tables is untouched.

Tested on:
- tables with 2-6 columns
- tables with/without alignment hints (`:---`, `---:`)
- text with inline pipes outside tables (no false-positive)
- mixed content (multiple tables + prose in one message)
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter labels Apr 25, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

Related to #14160 (feature request) and competing with #14431 (similar approach: row-group bullet formatting). Please coordinate.

@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the contribution and for running this in production — the approach is solid and the problem was real.

This is an automated hermes-sweeper review.

The underlying bug is already fixed on main. PR #11794 (commit 036dacf65, merged April 17 2026 — one day after this PR was opened) added _wrap_markdown_tables() to gateway/platforms/telegram.py and wires it into format_message() at the same pre-escaping step this PR targets. Telegram now renders pipe tables as monospace fenced code blocks rather than raw escaped text.

  • Implementation: gateway/platforms/telegram.py, _wrap_markdown_tables() (~line 147) + call at ~line 2062
  • Merged commit: 036dacf6592dac36a57a3d26187039fb3b1a37a0

The rendering approach differs (code fences vs bullet lists), and if bullet-group formatting is preferred over code-fence wrapping, the right path forward is PR #14431 which explicitly proposes that upgrade and closes issue #14160. Please feel free to coordinate there.

@teknium1 teknium1 closed this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

3 participants