From d3c8a155cbfd265fd50d0fe126dfd368ea0ba5f6 Mon Sep 17 00:00:00 2001 From: liuhao1024 Date: Thu, 2 Jul 2026 21:48:53 +0800 Subject: [PATCH] fix(slack): keep blank-line-separated ordered items in one rich_text_list When a Markdown ordered list has blank lines between items (common in LLM-authored content), the list run loop breaks on each blank line. Slack numbers each rich_text_list independently, so N items produce N lists each starting at 1. Skip blank lines inside the list run as soft separators instead of breaking, so ordered items stay in one rich_text_list and Slack renders the correct numbering. Fixes #57076 --- plugins/platforms/slack/block_kit.py | 4 ++++ tests/gateway/test_slack_block_kit.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/plugins/platforms/slack/block_kit.py b/plugins/platforms/slack/block_kit.py index 01b048f93..ac1055200 100644 --- a/plugins/platforms/slack/block_kit.py +++ b/plugins/platforms/slack/block_kit.py @@ -451,6 +451,10 @@ def render_blocks( indent, ordered, txt = items[-1] items[-1] = (indent, ordered, txt + " " + lines[i].strip()) i += 1 + elif not lines[i].strip(): + # blank line — soft separator within a list run; + # skip so that ordered items stay in one rich_text_list. + i += 1 else: break blocks.append(_list_block(items)) diff --git a/tests/gateway/test_slack_block_kit.py b/tests/gateway/test_slack_block_kit.py index 6dc0d74c7..6d1bfad4c 100644 --- a/tests/gateway/test_slack_block_kit.py +++ b/tests/gateway/test_slack_block_kit.py @@ -90,6 +90,22 @@ class TestInlineFormatting: ] assert styled, "expected a bold-styled text element in the list item" + def test_blank_line_separated_ordered_items_stay_in_one_list(self): + """Regression: blank lines between ordered items must not reset numbering. + + Slack numbers each rich_text_list independently. If blank lines break + the list run, N items produce N separate lists each starting at 1. + See: https://github.com/NousResearch/hermes-agent/issues/57076 + """ + md = "1. alpha\n\n1. beta\n\n1. gamma" + blocks = render_blocks(md) + rich = [b for b in blocks if b["type"] == "rich_text"][0] + lists = [e for e in rich["elements"] if e["type"] == "rich_text_list"] + # Must be ONE list with 3 items, not 3 separate single-item lists + assert len(lists) == 1 + items = lists[0]["elements"] + assert len(items) == 3 + class TestTables: def test_pipe_table_renders_native_table_block(self):