Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1569,7 +1569,14 @@ def _rich_text_from_ansi(text: str) -> _RichText:
def _strip_markdown_syntax(text: str) -> str:
"""Best-effort markdown marker removal for plain-text display."""
plain = _rich_text_from_ansi(text or "").plain
plain = re.sub(r"^\s{0,3}(?:[-*_]\s*){3,}$", "", plain, flags=re.MULTILINE)
# Avoid stripping cron-style expressions like "* * * * *" as if they were
# Markdown horizontal rules. CommonMark treats three or more "*" as an HR,
# but in Hermes output it's common to display cron schedules verbatim.
#
# Keep the behavior for "-" / "_" HR markers, and only strip "*" HR lines
# when there are exactly 3 asterisks (with optional whitespace).
plain = re.sub(r"^\s{0,3}(?:[-_]\s*){3,}$", "", plain, flags=re.MULTILINE)
plain = re.sub(r"^\s{0,3}(?:\*\s*){3}\s*$", "", plain, flags=re.MULTILINE)
plain = re.sub(r"^\s{0,3}#{1,6}\s+", "", plain, flags=re.MULTILINE)
# Preserve blockquotes, lists, and checkboxes because they carry structure.
plain = re.sub(r"(```+|~~~+)", "", plain)
Expand All @@ -1580,7 +1587,9 @@ def _strip_markdown_syntax(text: str) -> str:
plain = re.sub(r"(?<!\w)___([^_]+)___(?!\w)", r"\1", plain)
plain = re.sub(r"\*\*([^*]+)\*\*", r"\1", plain)
plain = re.sub(r"(?<!\w)__([^_]+)__(?!\w)", r"\1", plain)
plain = re.sub(r"\*([^*]+)\*", r"\1", plain)
# Only strip `*emphasis*` markers when the inner text is non-whitespace.
# This avoids corrupting cron expressions like "* * * * *".
plain = re.sub(r"\*([^\s*][^*]*?[^\s*])\*", r"\1", plain)
plain = re.sub(r"(?<!\w)_([^_]+)_(?!\w)", r"\1", plain)
plain = re.sub(r"~~([^~]+)~~", r"\1", plain)
plain = re.sub(r"\n{3,}", "\n\n", plain)
Expand Down
12 changes: 12 additions & 0 deletions tests/cli/test_cli_markdown_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,18 @@ def test_strip_mode_preserves_table_structure_while_cleaning_cell_markdown():
)


def test_strip_mode_preserves_cron_asterisks_in_plain_text():
renderable = _render_final_assistant_content("* * * * *", mode="strip")

output = _render_to_text(renderable)
assert "* * * * *" in output

# Still treat the canonical 3-asterisk Markdown horizontal rule as decoration.
renderable = _render_final_assistant_content("* * *", mode="strip")
output = _render_to_text(renderable)
assert "* * *" not in output


def test_final_assistant_content_can_leave_markdown_raw():
renderable = _render_final_assistant_content("***Bold italic***", mode="raw")

Expand Down