Skip to content

fix(discord): auto-convert markdown tables to bullet groups - #45781

Closed
yashiels wants to merge 3 commits into
NousResearch:mainfrom
yashiels:fix/discord-table-to-bullets
Closed

fix(discord): auto-convert markdown tables to bullet groups#45781
yashiels wants to merge 3 commits into
NousResearch:mainfrom
yashiels:fix/discord-table-to-bullets

Conversation

@yashiels

Copy link
Copy Markdown
Contributor

Summary

Discord does not render GFM pipe tables — raw pipe characters display as garbage text. This PR adds automatic table-to-bullet conversion in the Discord adapter's format_message, matching the pattern Telegram already uses.

Changes

1. Shared helpers (gateway/platforms/helpers.py)

  • Added TABLE_SEPARATOR_RE, is_table_row, split_markdown_table_row, _render_table_block, and convert_table_to_bullets
  • Same alignment logic as Telegram's proven renderer: non-row-label tables keep data_cells = cells and skip the duplicate-heading bullet

2. Discord adapter (plugins/platforms/discord/adapter.py)

  • format_message now calls convert_table_to_bullets() instead of returning content as-is

3. Telegram DRY (gateway/platforms/telegram.py)

  • Replaced local _TABLE_SEPARATOR_RE, _is_table_row, _split_markdown_table_row with imports from shared helpers
  • Telegram-specific MarkdownV2 rendering (_render_table_block_for_telegram, _wrap_markdown_tables) stays local

Before / After (Discord)

Before: Raw pipe characters render as unreadable garbage:

| Model | Speed | Cost |
|-------|-------|------|
| GPT-4 | Slow | $$$ |

After:

**GPT-4**
• Speed: Slow
• Cost: $$$

Tests

  • 18 new tests for shared helpers (tests/gateway/test_table_helpers.py)
  • 4 new tests for Discord formatting (tests/gateway/test_discord_format.py)
  • All existing Telegram format tests pass unchanged (34 total across all 3 files)

Edge Cases Handled

  • Tables inside fenced code blocks are left untouched
  • Plain text with pipe characters passes through unchanged
  • Horizontal rules (---) are not mistaken for table separators
  • Row-label columns (data rows with one more cell than header) detected correctly
  • Bare pipe tables (no outer |) supported
  • Multiple consecutive tables converted independently

Fixes #21168

@yashiels
yashiels force-pushed the fix/discord-table-to-bullets branch from 4e4e0f8 to 4efc491 Compare June 13, 2026 19:16
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/discord Discord bot adapter P2 Medium — degraded but workaround exists labels Jun 13, 2026
@yashiels
yashiels force-pushed the fix/discord-table-to-bullets branch from 4efc491 to bc44d5c Compare June 13, 2026 21:07
yashiels added 3 commits June 18, 2026 11:58
Move table-detection regex, row-splitting, and table-to-bullet
conversion into gateway/platforms/helpers.py so both Discord and
Telegram adapters can share them.

Co-authored-by: Yashiel Sookdeo <yashiel@skyner.co.za>
Discord does not render GFM pipe tables — raw pipe characters display
as garbage text. format_message now rewrites tables into bold-heading +
bullet groups using the shared helpers.

Fixes #21168

Co-authored-by: Yashiel Sookdeo <yashiel@skyner.co.za>
…pers.py

Replace local _TABLE_SEPARATOR_RE, _is_table_row, and
_split_markdown_table_row with imports from the shared module.
Telegram-specific rendering stays local.

Co-authored-by: Yashiel Sookdeo <yashiel@skyner.co.za>
@yashiels
yashiels force-pushed the fix/discord-table-to-bullets branch from bc44d5c to 44e343f Compare June 18, 2026 09:59
@yashiels

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main (2026-06-18).

Approach note: This PR converts GFM tables to bold-heading + bullet groups rather than code fences. In practice, bullet groups read much better in Discord (especially mobile) than monospace code blocks for tabular agent output. Happy to pivot to code-fence wrapping if maintainers prefer that approach — the shared helpers in helpers.py would still be useful either way.

Conflict resolution: kept upstream's rich_messages=True default in telegram.py; this PR only deduplicates table-detection primitives into the shared module.

@yashiels

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main — merge conflicts resolved, CI should be green.

No CODEOWNERS file in repo; tagging Discord/gateway maintainers for review:

@teknium1 @kshitijk4poor — would appreciate a look when you have a moment.

Summary: Converts markdown tables to bullet groups in Discord format_message() (Telegram-style). Shared helpers extracted to gateway/platforms/helpers.py. Fixes #21168.

Happy to pivot to code-fence wrapping if that's the preferred approach — bullets read better on Discord mobile in our testing.

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Merged via #53284. Your commits were cherry-picked with authorship preserved (rebase-merge) onto latest main. The original branch was 1086 commits behind, and Telegram had migrated from gateway/platforms/telegram.py to plugins/platforms/telegram/adapter.py since your base — resolved the conflict and also completed the DRY refactor you started (deleted the duplicated renderer+driver from Telegram that were verbatim copies of the shared helpers). Your 3 commits + 1 follow-up fix landed in commit 6326d5c.

Thanks for the contribution!

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/discord Discord bot adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Discord markdown tables render as garbage — need auto code-fence wrapping

3 participants