You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Remainder of #209, split per its Metadata (the full port came to about 2k changed lines; the split threshold is 1.5k). #209's first PR ports part (a): self-mention decoding, content-based is_mention, and bot author ids / email / is_system. This issue is part (b): inbound mrkdwn normalization, channel.post thread ids, and Socket Mode retries.
Starting point: branch wip/4.41-sl4-full (commit c0788056) holds the full #209 port, with full validation green on its base: 6710 passed, strict fidelity 733/733, pyrefly 0 errors. Part (b) is that branch's diff minus what the #209 part-(a) PR merged. Rebase or cherry-pick the (b) pieces listed below once that PR has landed, re-run the validation, and send the result through astra review. Nothing on that branch has been reviewed yet.
Upstream changes
e71bfead fix(slack): preserve first line of incoming code blocks (#843), chat@4.39.0
44423bdc fix(slack): convert special mentions to readable text (#960), chat@4.41.1
c3118279 fix(slack): preserve channel id and normalize frequently hallucinated link format (#756), chat@4.37.0
92530dd3 fix(slack): return replyable thread ID from channel posts (#720), chat@4.35.0
0b63791b fix(slack): process Socket Mode retry envelopes instead of dropping them (#667), chat@4.33.0 (Slack half)
Scope (all already on wip/4.41-sl4-full)
adapters/slack/format.py: port convertSpecialMentions and convertMrkdwnWithCodeFences and their helpers (findAngleTokenEnd, findInlineCodeEnd, isOnBlockquoteLine, escapeLeadingBlockMarker), plus the #name (C…) rewrite and the inverted-link swap. The scanners are linear: a failed <…> scan is memoized, the newline search is bounded, and the blockquote check matches in place.
SlackFormatConverter.to_ast becomes parse_markdown(slack_mrkdwn_to_markdown(text)). This fixes the missing unescape, so < now renders as <. Drop the Python-only regex extract_plain_text override; upstream markdown.ts has none.
post_channel_message: return slack:{channel}:{ts} when raw["ts"] is a str.
Socket Mode: stop dropping retry envelopes. Log "Processing socket mode retry" at info with retry_attempt, retry_reason and type, then route the event.
Tests:
tests/test_slack_format_primitives.py: every it that e71bfead (10), 44423bdc (7, including the it.each) and c3118279 (3) added, plus an adversarial 50k-character case.
tests/test_slack_format.py: the 6 e71bfead markdown.test.ts cases.
tests/test_slack_socket_mode.py: "processes retries like first deliveries (dedupe drops true duplicates)", replacing test_retry_attempt_is_skipped_but_acked.
Slack parse tests: "converts special mentions to readable text", "preserves special mention tokens in an inbound inline code span" and "preserves special mention tokens in an inbound code block".
Post-channel tests: "posts to channel without thread context", plus a Python case with no string ts.
docs/UPSTREAM_SYNC.md and the CHANGELOG Breaking/consumer-visible bullets for: special mentions and #general (C123), the kept first code line, message.text as plain text of formatted (list markers, #, > and backticks dropped), channel.post() ids, and processed socket retries.
Known gaps found while porting (not Slack-specific; record them or file separately)
The shared parse_markdown has no multi-backtick code spans and keeps a paragraph's leading space. Two markdown.test.ts assertions were adapted ("keeps a quoted fence inside the blockquote", "keeps trailing text after a code block as a paragraph").
The shared parse_markdown is quadratic on some inputs: 50k characters of `x or *a take 25–37 s. This predates the port, but every inbound Slack message goes through to_ast.
Notes
Consumer impact: high. The shape of message.text changes. A live Slack-loop check is pending.
Summary
Remainder of #209, split per its Metadata (the full port came to about 2k changed lines; the split threshold is 1.5k). #209's first PR ports part (a): self-mention decoding, content-based
is_mention, and bot author ids /email/is_system. This issue is part (b): inbound mrkdwn normalization,channel.postthread ids, and Socket Mode retries.Starting point: branch
wip/4.41-sl4-full(commitc0788056) holds the full #209 port, with full validation green on its base: 6710 passed, strict fidelity 733/733, pyrefly 0 errors. Part (b) is that branch's diff minus what the #209 part-(a) PR merged. Rebase or cherry-pick the (b) pieces listed below once that PR has landed, re-run the validation, and send the result through astra review. Nothing on that branch has been reviewed yet.Upstream changes
e71bfeadfix(slack): preserve first line of incoming code blocks (#843), chat@4.39.044423bdcfix(slack): convert special mentions to readable text (#960), chat@4.41.1c3118279fix(slack): preserve channel id and normalize frequently hallucinated link format (#756), chat@4.37.092530dd3fix(slack): return replyable thread ID from channel posts (#720), chat@4.35.00b63791bfix(slack): process Socket Mode retry envelopes instead of dropping them (#667), chat@4.33.0 (Slack half)Scope (all already on
wip/4.41-sl4-full)adapters/slack/format.py: portconvertSpecialMentionsandconvertMrkdwnWithCodeFencesand their helpers (findAngleTokenEnd,findInlineCodeEnd,isOnBlockquoteLine,escapeLeadingBlockMarker), plus the#name (C…)rewrite and the inverted-link swap. The scanners are linear: a failed<…>scan is memoized, the newline search is bounded, and the blockquote check matches in place.SlackFormatConverter.to_astbecomesparse_markdown(slack_mrkdwn_to_markdown(text)). This fixes the missing unescape, so<now renders as<. Drop the Python-only regexextract_plain_textoverride; upstreammarkdown.tshas none.formatted = to_ast(text), thentext = ast_to_plain_text(formatted)(upstreamtoPlainText(formatted)). [4.41/SL5] Slack inbound: pasted tables and alert attachments in message content #210 later swapsformattedfor the assembled content.post_channel_message: returnslack:{channel}:{ts}whenraw["ts"]is astr."Processing socket mode retry"at info withretry_attempt,retry_reasonandtype, then route the event.tests/test_slack_format_primitives.py: everyitthat e71bfead (10), 44423bdc (7, including theit.each) and c3118279 (3) added, plus an adversarial 50k-character case.tests/test_slack_format.py: the 6 e71bfeadmarkdown.test.tscases.tests/test_slack_socket_mode.py: "processes retries like first deliveries (dedupe drops true duplicates)", replacingtest_retry_attempt_is_skipped_but_acked.ts.docs/UPSTREAM_SYNC.mdand the CHANGELOG Breaking/consumer-visible bullets for: special mentions and#general (C123), the kept first code line,message.textas plain text offormatted(list markers,#,>and backticks dropped),channel.post()ids, and processed socket retries.Known gaps found while porting (not Slack-specific; record them or file separately)
parse_markdownhas no multi-backtick code spans and keeps a paragraph's leading space. Twomarkdown.test.tsassertions were adapted ("keeps a quoted fence inside the blockquote", "keeps trailing text after a code block as a paragraph").parse_markdownis quadratic on some inputs: 50k characters of`xor*atake 25–37 s. This predates the port, but every inbound Slack message goes throughto_ast.Notes
message.textchanges. A live Slack-loop check is pending.