feat(slack): render agent bodies as native markdown blocks - #654
Open
yzxcj797 wants to merge 1 commit into
Open
Conversation
Every agent reply left Slack through toSlackMrkdwn posted as text, so
structure was encoded as characters: bullets were literal dots that
lost their hang-indent on wrap, ordered lists passed through as text,
GFM tables became aligned code blocks that misalign on CJK width, and
single-asterisk bold only rendered at half-width boundaries -- a
Chinese-language reply could not reliably use bold at all.
Each outbound body now renders once into { text, blocks }: text stays
the mrkdwn fallback for notifications, mirrors and older clients, and a
single markdown block carries the raw Markdown -- where lists, tables,
code languages and CJK-flanked bold translate into native elements.
Bodies over 11,500 chars (Slack's budget applies to the translated
result, cumulatively) fall back to today's text-only path, keeping
Markdown-safe chunking off the critical path.
All six agent-body sites render through it: the ack presenter and the
turn reply, both approval-result paths (the card update resends the
block, because an update with no blocks clears them), and both delivery
pollers -- the channel poller's markdown block replaces its section-
block body while the task-list section survives alongside. The agent-
to-agent completion header is bolded ** for the block and kept in
mrkdwn * form for the fallback, since *x* is italic in Markdown.
Fixes yc-software#651
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the fix shape from #651 verbatim: every outbound agent body renders once into
{ text, blocks }—textstays the existingtoSlackMrkdwnfallback (notifications,mirrorSelfPostcache, older clients), and a singlemarkdownblock carries the raw Markdown, where lists, tables, fenced-code languages and CJK-flanked bold translate into native Slack elements instead of character-encoded approximations.Implementation
renderSlackBody(md)inmrkdwn.tsreturns both renderings;slackMarkdownBlockswraps the raw Markdown. The block is emitted only when the body fitsSLACK_MARKDOWN_BLOCK_BUDGET = 11,500— Slack's 12,000 budget applies to the translated result cumulatively, so over-budget bodies fall back to today's text-only path, keeping Markdown-safe chunking (fences, table rows, ordered-list continuity) off the critical path per the issue's note 4.turn-handler.ts— the ack presenter and the turn reply (postReplyalready acceptedblocks);approvals.ts— both result paths; the non-remote card update resends the block (an update with no blocks clears them, per note 5), andpostApprovalFollowupthreads it; the agent-to-agent completion header is bolded**for the block and stays*in the text fallback, since*x*is italic in Markdown (note 1);deliveries.ts— both pollers; the channel poller's markdown block replaces its section-block body while the task-listsectionblock survives alongside (per the "a section block sent alongside it survived" measurement), and the principal poller posts it directly.textfallback path is byte-identical to today, sotest/slack-mrkdwn.test.ts's existing expectations are unchanged.Testing
slack-delivery,slack-approval-cards,slack-ack-emoji) are 72/72.test/live-slackasserting•lines) still applies to thetextlayer, which is unchanged; the native-list layer only appears through the block, which the live suite would need block-structure assertions for — left to that suite's maintainers since it requires a live workspace.Fixes #651
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.