Fix broken markdown rendering in AI Slack responses#163
Fix broken markdown rendering in AI Slack responses#163bajman wants to merge 1 commit intodev-chat:masterfrom
Conversation
LLM responses containing standard markdown (### headers, **bold**, * bullet lists) were rendering as raw text in Slack because Slack uses its own mrkdwn format. The existing markdownToSlackMrkdwn() converter was incomplete and not applied to all code paths. Resolves this by adopting Slack's new markdown block type, which natively translates standard markdown server-side. Applied across all four AI text paths: /ai/text, /ai/prompt-with-history, @moonbeam, and redeployMoonbeam. Removes the manual converter and getChunks utility. Also upgrades @slack/web-api v6 → v7.15.0 with associated breaking change fixes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| token: muzzleToken, | ||
| channel, | ||
| ts, | ||
| as_user: true, |
There was a problem hiding this comment.
Pretty sure we need this. Bots can't delete messages, only bots acting as the user who has the entitlement to do this, can. Since I am the owner/admin, I have this entitlement + I gave her permission to act on my behalf.
|
|
||
| public getAllUsers(): Promise<WebAPICallResult> { | ||
| return this.web.users.list(); | ||
| return this.web.users.list({}); |
There was a problem hiding this comment.
Unnecessary param, remove.
| public sendMessage(channel: string, text: string, blocks?: Block[] | KnownBlock[]): Promise<WebAPICallResult> { | ||
| const token: string | undefined = process.env.MUZZLE_BOT_USER_TOKEN; | ||
| const postRequest: ChatPostMessageArguments = { | ||
| const postRequest = { |
There was a problem hiding this comment.
Add the type back. We want type safety and as ChatMessageArguments is not that.
| "@types/jest-when": "^2.7.0", | ||
| "@types/lolex": "^3.1.1", | ||
| "@types/node": "^12.12.56", | ||
| "@types/node": "^18.0.0", |
There was a problem hiding this comment.
Nit: Realistically, this should be bumped to 20 since that is the version of node we end up deploying based on what is present in the docker image.
| if (blocks) { | ||
| postRequest.blocks = blocks; | ||
| } | ||
| ...(blocks && { blocks }), |
There was a problem hiding this comment.
Syntax is weird, change to blocks: blocks ?? undefined
| postRequest.blocks = blocks; | ||
| } | ||
| ...(blocks && { blocks }), | ||
| } as ChatPostMessageArguments; |
There was a problem hiding this comment.
Don't do this as type coercion. Make the type right from the get.
Summary
### headers,**bold**,* bullet lists) were rendering as raw text in Slack because Slack uses its ownmrkdwnformatmarkdownToSlackMrkdwn()converter was incomplete (missing bullet lists, regex collisions) and not applied to all code paths (Gemini path had zero conversion)markdownblock type (released March 6, 2026), which natively translates standard markdown server-side — designed specifically for LLM output/ai/text,/ai/prompt-with-history,@moonbeam, andredeployMoonbeammarkdownToSlackMrkdwn()converter andgetChunksutility (net -520 lines)@slack/web-apiv6 → v7.15.0 with associated breaking change fixes (users.listargs,as_userdeprecation,files.upload→filesUploadV2)Test plan
/promptslash command renders headers, bold, italic, and bullet lists correctly in Slack/ai/textslash command renders formatted AI responses correctly@moonbeammention responses render with proper formatting#muzzlefeedbackrenders quote correctlynpx jestinpackages/backend— all tests related to changed files pass🤖 Generated with Claude Code