Markdown Formatting
Read this if: you need the exact formatting pipeline from model Markdown to channel-safe outbound content.
Skip this if: you only need the message/conversation architecture; start with Messages and Conversations.
Go deeper: Message flow control and delivery, Channels.
Tyrum formats assistant output by converting Markdown into a neutral intermediate representation (IR) before chunking and rendering. This keeps formatting deterministic across channels with different markup rules.
Formatting pipeline
What this page guarantees
- Consistency: one parse step, many channel renderers.
- Safe chunking: split before rendering so inline formatting and code fences stay valid.
- Channel fit: map the same IR to Slack/Telegram/Discord/etc. without re-parsing.
- Security: escape/encode channel markup correctly and avoid link/HTML injection.
IR pipeline
-
Parse Markdown → IR
- IR is plain text plus structured spans:
- styles: bold/italic/strike/inline-code/spoiler (where supported)
- links:
{start,end,href} - blocks: paragraphs, lists, blockquotes, code blocks/fences
- Parsing is deterministic and does not execute embedded HTML/JS.
- IR is plain text plus structured spans:
-
Chunk IR (format-first)
- Chunking happens on the IR text, not on channel markup.
- Rules:
- never split inside inline styles
- never split inside fenced code blocks; when forced, close + reopen the fence
- prefer chunk breaks at paragraph boundaries, then newlines, then whitespace
- Chunk sizes are clamped by each channel’s text limits.
-
Render per channel
- Each channel adapter renders from IR into the channel’s native format:
- Slack: mrkdwn tokens + safe link rendering
- Telegram: HTML parse mode with strict escaping
- Discord: Markdown with length/line caps
- WhatsApp/Signal/iMessage: conservative formatting subset
- Each channel adapter renders from IR into the channel’s native format:
Table policy
Markdown tables are normalized using a channel policy:
code: render as a fenced code block (portable default)bullets: convert rows into bullet points (mobile-friendly)off: pass through as plain text
Link policy
Links are rendered with channel-safe rules:
- preserve label vs href when the channel supports it
- when the channel cannot represent labeled links, render as
label (url) - normalize and validate URL schemes; disallowed schemes are rendered as plain text
Fallbacks
If parsing or rendering fails for a chunk:
- fall back to plain text for that chunk
- emit an event indicating a formatting fallback occurred
The system emits a durable episodic event (event_type=channel_formatting_fallback) so operators can inspect fallbacks in operator surfaces.
This keeps delivery robust under channel-specific formatting quirks without losing the underlying content.
Interaction with streaming
Block streaming uses the same IR chunker. This guarantees that streamed partial replies and final replies share identical chunk boundaries and formatting rules.