Skip to content

fix(slack): formatting consistency, table conversion, thread reply fix#2525

Closed
ghostmfr wants to merge 1 commit into
NousResearch:mainfrom
ghostmfr:fix/slack-gateway-formatting-threading
Closed

fix(slack): formatting consistency, table conversion, thread reply fix#2525
ghostmfr wants to merge 1 commit into
NousResearch:mainfrom
ghostmfr:fix/slack-gateway-formatting-threading

Conversation

@ghostmfr

Copy link
Copy Markdown
Contributor

Summary

This PR fixes three bugs in the Hermes Slack gateway.


Bug 1 — edit_message() skips format_message() (streaming sends raw markdown)

File: gateway/platforms/slack.py

edit_message() was calling chat_update with raw markdown content, bypassing the format_message() conversion that translates standard markdown to Slack mrkdwn. This meant streamed message edits would show **bold** instead of *bold*, ## Header instead of bold text, etc.

Fix: Added content = self.format_message(content) as the first line after the not-connected guard in edit_message().


Bug 2 — Markdown tables and horizontal rules leak through format_message()

File: gateway/platforms/slack.py

format_message() had no handling for markdown tables (| col | col |) or horizontal rules (---, ***, ___), so these were passed through as-is to Slack, where they render as raw text.

Fix: Added two new conversion steps in format_message() before placeholder restoration:

  1. Table conversion — consecutive lines matching ^\|.*\| are detected, separator rows (containing only -, :, |, space) are stripped, and data rows are formatted into a fenced code block (``````) with cells joined by two spaces.
  2. Horizontal rule stripping — lines consisting solely of ---, ***, or ___ (3+ chars) are removed.

Bug 3 — Wrong thread replies (interrupt/follow-up path)

File: gateway/run.py (~line 5285)

In the interrupt/follow-up path, when sending the first response before processing a queued message, adapter.send() was using getattr(event, "metadata", None) for thread metadata. The event object at that point may not carry correct thread context, causing replies to land in the wrong thread or at the channel level.

Fix: Replaced with {"thread_id": source.thread_id} if getattr(source, "thread_id", None) else None so the reply always targets the correct source thread.


Tests

All 1378 gateway tests pass:

1378 passed, 95 warnings in 12.79s

Bug 1: edit_message() now calls format_message() before chat_update so
streaming edits render proper Slack mrkdwn instead of raw markdown.

Bug 2: format_message() now converts markdown tables into fenced code
blocks (stripping separator rows) and strips horizontal rules (---, ***,
___) that previously leaked into Slack messages as raw syntax.

Bug 3: In the interrupt/follow-up path of run.py, the adapter.send()
call now uses source.thread_id for thread metadata instead of
event.metadata, ensuring follow-up replies land in the correct thread.
@teknium1

teknium1 commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Merged via PR #6809 as part of a consolidated Slack adapter improvement. Your contribution was superseded by #3715's comprehensive formatting fixes. Your authorship is preserved in git history. Thank you @ghostmfr for your work on this!

@teknium1 teknium1 closed this Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants