feat: convert markdown to Slack formatting instead of stripping it

Converts: ## Header → *Header* (bold), **bold** → *bold*,
*italic* → _italic_, ~~strike~~ → ~strike~, [text](url) → <url|text>.
Removes LaTeX and HTML. System prompt updated to use simple markdown
since it gets auto-converted per platform.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jon Saad-Falcon
2026-03-28 15:06:57 -07:00
co-authored by Claude Opus 4.6
parent d3c7c59c8d
commit 590e8b90a3
2 changed files with 40 additions and 16 deletions
+3 -4
View File
@@ -141,10 +141,9 @@ abbreviations, related terms.
- Research answers: cite as [source] title -- author. End with Sources.
- Casual answers: no citations needed.
- Concise unless detail is asked for.
- Format for text messages: use plain text, short paragraphs, and \
simple bullet points (- item). Never use markdown headers (##), bold \
(**), italic (*), code blocks, LaTeX ($), or tables. These don't \
render in SMS/iMessage. Use line breaks and dashes for structure.
- Use simple markdown: **bold** for emphasis, bullet lists with -, \
short paragraphs. Avoid LaTeX, complex tables, and deeply nested \
formatting. Keep it readable in both web and messaging apps.
- If nothing found, say so honestly and suggest alternatives."""
+37 -12
View File
@@ -1428,17 +1428,42 @@ def create_agent_manager_router(
_msg_queue: _q.Queue = _q.Queue()
_processing = _thr.Event()
def _strip_markdown(text: str) -> str:
"""Strip markdown for clean Slack messages."""
# Remove headers
text = _re.sub(r"^#{1,6}\s+", "", text, flags=_re.MULTILINE)
# Remove bold/italic markers
text = _re.sub(r"\*\*(.+?)\*\*", r"\1", text)
text = _re.sub(r"\*(.+?)\*", r"\1", text)
# Remove code blocks
text = _re.sub(r"```[\s\S]*?```", "", text)
text = _re.sub(r"`(.+?)`", r"\1", text)
# Clean up extra whitespace
def _to_slack_fmt(text: str) -> str:
"""Convert markdown to Slack formatting."""
# Headers → bold
text = _re.sub(
r"^#{1,6}\s+(.+)$",
r"*\1*",
text,
flags=_re.MULTILINE,
)
# Bold: **text** → *text*
text = _re.sub(
r"\*\*(.+?)\*\*", r"*\1*", text,
)
# Italic: _text_ stays, *text* → _text_
# (only single * not already bold)
text = _re.sub(
r"(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)",
r"_\1_",
text,
)
# Strikethrough: ~~text~~ → ~text~
text = _re.sub(
r"~~(.+?)~~", r"~\1~", text,
)
# Links: [text](url) → <url|text>
text = _re.sub(
r"\[(.+?)\]\((.+?)\)",
r"<\2|\1>",
text,
)
# Remove LaTeX
text = _re.sub(r"\$\$.+?\$\$", "", text)
text = _re.sub(r"\$(.+?)\$", r"\1", text)
# Remove HTML tags
text = _re.sub(r"<[^>|]+>", "", text)
# Clean up whitespace
text = _re.sub(r"\n{3,}", "\n\n", text)
return text.strip()
@@ -1460,7 +1485,7 @@ def create_agent_manager_router(
reply = (
"Agent not available."
)
say_fn(_strip_markdown(reply))
say_fn(_to_slack_fmt(reply))
_processing.clear()
@bolt_app.event("message")