fix(tools): regex-fallback Matrix formatted_body when markdown lib missing - #32492
Closed
briandevans wants to merge 1 commit into
Closed
fix(tools): regex-fallback Matrix formatted_body when markdown lib missing#32492briandevans wants to merge 1 commit into
briandevans wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR improves Matrix message rendering by always generating formatted_body HTML from markdown, using the optional markdown library when available and a shared regex-based fallback when it isn’t (notably in the default Docker image scenario mentioned in issue #32486).
Changes:
- Update
_send_matrixto produceformatted_bodyHTML viamarkdownor a fallback converter. - Apply Element X heading compatibility conversion for both rendering paths.
- Add tests covering both the
markdown-installed path and the fallback path.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tools/send_message_tool.py | Always populate Matrix formatted_body using markdown rendering or a fallback converter. |
| tests/tools/test_send_message_tool.py | Add regression tests for formatted_body generation with and without the markdown dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1601
to
+1602
| # Hide the markdown library to force the ImportError branch. | ||
| with patch.dict(sys.modules, {"markdown": None}): |
Comment on lines
+1392
to
+1393
| from gateway.platforms.matrix import MatrixAdapter | ||
| html = MatrixAdapter._markdown_to_html_fallback(message) |
briandevans
force-pushed
the
fix/matrix-send-markdown-fallback-32486
branch
from
May 28, 2026 10:12
38fe6e4 to
0eacb6d
Compare
…ssing The `_send_matrix()` cron-delivery path in tools/send_message_tool.py imports the optional `markdown` library and silently degrades to plain text when it isn't installed. The official Docker image installs `[all]` + `[messaging]` only, neither of which pulls `Markdown` — so out-of-the-box cron deliveries render in Element as raw `##`, `**`, `|...|` despite PR NousResearch#5271. `MatrixAdapter._markdown_to_html_fallback()` already exists in gateway/platforms/matrix.py as a comprehensive regex converter for exactly this case (fenced code, inline code, headers, bold, italic, strikethrough, links, blockquotes, lists, hr). It's a staticmethod that depends only on `re` and `html.escape`, safe to import without mautrix installed. Mirror `MatrixAdapter._markdown_to_html()`'s precedence in `_send_matrix()`: prefer the markdown library when available, fall back to the regex converter otherwise. Element X heading→bold post-processing applies to both branches. Fixes NousResearch#32486
briandevans
force-pushed
the
fix/matrix-send-markdown-fallback-32486
branch
from
May 29, 2026 23:10
0eacb6d to
3a8b0d4
Compare
Contributor
Author
|
Closing to focus the queue on security/file-safety work where civilian merges are landing. Happy to reopen if maintainers want this picked up. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
_send_matrix()intools/send_message_tool.py(the cron /send_message-tool path to Matrix) imports the optionalmarkdownlibrary and silently degrades to plain text when it isn't installed. The official Docker image installs[all]+[messaging]only, neither of which pullsMarkdown— so out-of-the-box cron deliveries render in Element as raw##,**,|...|despite PR #5271.MatrixAdapter._markdown_to_html_fallback()already exists ingateway/platforms/matrix.pyas a comprehensive regex converter (fenced code, inline code, headers, bold, italic, strikethrough, links, blockquotes, lists, hr) — it's a@staticmethodthat depends only onreandhtml.escape, safe to import withoutmautrixinstalled.Mirror
MatrixAdapter._markdown_to_html()'s precedence in_send_matrix():markdownlibrary when available, regex fallback otherwise. The Element X heading→bold post-processing already runs after both branches.Related Issue
Fixes #32486
Type of Change
Changes Made
tools/send_message_tool.py— whenimport markdownfails inside_send_matrix(), fall back toMatrixAdapter._markdown_to_html_fallback()instead of silently droppingformatted_body. The Element X<h*>→<strong>post-processing is hoisted out of the success-only branch so it applies to both paths.tests/tools/test_send_message_tool.py— newTestSendMatrixFormattedBodyclass with two cases: (1) markdown lib path produces<strong>Heading</strong>+<li>bullet</li>informatted_body; (2) lib-missing path (patch.dict(sys.modules, {"markdown": None})) still produces<strong>Heading</strong>+<li>bullet</li>, with no raw## Headingsurviving intoformatted_body.How to Test
Reproduction (without this PR): in a venv that lacks
markdown, call_send_matrix(token, extra, room_id, "## H\n\n- a\n- b")and observe the capturedaiohttpPUT payload —formatted_bodyandformatare absent; Element renders raw markdown.Focused tests:
Regression sweep:
123 tests in
test_send_message_tool.pypass; 29 markdown tests intest_matrix.pypass.Checklist
Code
fix(scope):,feat(scope):, etc.)Documentation & Housekeeping
docs/, docstrings) — N/A (inline docstring updated to describe the fallback)cli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
Before (no markdown lib in venv):
After (no markdown lib in venv):
Related / Positioning
The reporter listed three options in #32486 — (1) ship
markdownin the Docker image, (2) makemarkdowna hard dependency, (3) align the cron-path fallback with the interactive path's regex_markdown_to_html_fallback. This PR is option (3): smallest blast-radius change (nopyproject.toml/Dockerfile/uv.lockchurn, no transitive-dep movement) and removes the asymmetry between the two Matrix HTML emitters at the same time. Options (1) and (2) remain viable as follow-ups if the maintainers prefer a dep-level fix; this PR doesn't block either.PR #20259 (DanAsBjorn) proposes routing all Matrix text sends through the adapter — a wider scope that has been idle 21 days. If it lands,
_send_matrixis removed wholesale and this fallback goes with it; the two PRs don't conflict.