← Back to PRs

#13431: feat(whatsapp): add built-in Markdown to WhatsApp format transform

by asklee-klawd open 2026-02-10 14:14 View on GitHub →
channel: whatsapp-web stale
## Summary Adds automatic conversion of standard Markdown to WhatsApp-compatible formatting for outbound messages. Enabled by default. ## Problem LLMs output standard Markdown (`**bold**`, `~~strike~~`, `# headers`, etc.) but WhatsApp uses its own formatting syntax (`*bold*`, `~strike~`, no headers). Currently users need to patch source files or train agents to output WhatsApp-specific syntax. Fixes #12129 ## Solution Built-in transform that runs automatically on outbound WhatsApp messages: ### Transforms - `**bold**` or `__bold__` → `*bold*` - `~~strikethrough~~` → `~strikethrough~` - `# Headers` → `*Headers*` (bold) - `[text](url)` → `text (url)` - `![alt](url)` → `alt (url)` - `---` horizontal rules → removed - Preserves code blocks and inline code (WhatsApp supports them natively) ### Config Options ```json { "channels": { "whatsapp": { "formatting": { "markdownTransform": true // default } } } } ``` Also supports per-account override: ```json { "channels": { "whatsapp": { "accounts": { "myaccount": { "formatting": { "markdownTransform": false } } } } } } ``` ### Implementation Applied after `convertMarkdownTables()` and before chunking in both delivery paths: 1. **Auto-reply** (`deliverWebReply`) — main path for agent responses 2. **Outbound** (`sendMessageWhatsApp`) — message tool and explicit sends Transform ordering follows the issue recommendation: runs after table conversion to avoid `convertMarkdownTables()` re-introducing `**` markers. ## Testing - 27 unit tests covering all transforms and edge cases - Build passes - Tested manually with WhatsApp channel ## Files Changed - `src/markdown/whatsapp.ts` — new transform function - `src/markdown/whatsapp.test.ts` — unit tests - `src/config/types.whatsapp.ts` — config types - `src/config/zod-schema.providers-whatsapp.ts` — Zod schema - `src/web/auto-reply/deliver-reply.ts` — integrate transform - `src/web/auto-reply/monitor/process-message.ts` — pass config - `src/web/outbound.ts` — integrate transform <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds a WhatsApp-specific Markdown normalization pass that converts common Markdown constructs (bold/strike/headers/links/images/hr) into WhatsApp-friendly formatting. The transform is wired into both outbound send paths: auto-reply delivery (`src/web/auto-reply/deliver-reply.ts`) and explicit outbound sends (`src/web/outbound.ts`), and it’s controlled via new `channels.whatsapp.formatting.markdownTransform` config (with per-account override) defined in the WhatsApp config types and Zod provider schema. Main integration is: convert markdown tables → (optionally) transform markdown to WhatsApp format → chunk and send. <h3>Confidence Score: 3/5</h3> - This PR is close to mergeable, but there are a couple correctness issues in the new markdown transform that can corrupt output or violate type expectations. - The new transform is integrated in the right places and is feature-scoped, but (1) placeholder restoration is not robust (non-global replace + user-collidable placeholders) and (2) the exported transform function can return null/undefined despite being typed as returning string; both can break downstream message handling. - src/markdown/whatsapp.ts (placeholder restore + input/output type contract); src/markdown/whatsapp.test.ts (null/undefined behavior expectations) <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs