fix(matrix): correct platform hint over-claims, add regression tests + docs

Follow-up to the salvaged #52552 and #53083 commits:

- Rework the Matrix PLATFORM_HINTS entry around what the adapter actually
  emits: headings, numbered lists, blockquotes, strikethrough-free markdown
  all render (the adapter converts them to sanctioned HTML). Keep the
  genuinely valuable guidance: no Markdown tables (Element X / Beeper /
  mobile clients don't render HTML tables — cells collapse into one line),
  no spoilers/checkboxes/~~strikethrough~~ (not converted by
  python-markdown), prefer descriptive link text.
- Regression test: hint must steer models away from tables.
- Fix test_long_response_split_preserves_thread_context to derive its
  payload size from the adapter's configurable limit instead of assuming
  the old hardcoded 4000.
- Document matrix.max_message_length in the Matrix docs page.
- Contributor mapping for RKelln.
This commit is contained in:
Teknium 2026-07-20 10:43:46 -07:00
parent 35e0f56fbf
commit 086a56a028
5 changed files with 24 additions and 21 deletions

View file

@ -805,26 +805,19 @@ PLATFORM_HINTS = {
),
"matrix": (
"You are in a Matrix room communicating with your user. "
"The adapter converts your Markdown to HTML for rich display.\n\n"
"CRITICAL FORMATTING RULES (Matrix renders Markdown inconsistently):\n\n"
"Supported and safe: **bold**, *italic*, `inline code`, ``` code blocks, "
"- bullet lists, [links](url), > blockquote, labeled **Label:** value pairs, "
"and key: value pairs.\n\n"
"Do NOT use (they render incorrectly or not at all):\n"
"- Tables — become one continuous line; use labeled **Label:** value pairs\n"
"- Numbered lists — collapse to bullets; use - bullets\n"
"- Horizontal rules (---) — invisible\n"
"- ||spoiler|| tags — no visual effect\n"
"- ~strikethrough~ — no visual effect\n"
"- Headings (# ## ###) — no visual effect\n"
"- Checkboxes (- [ ] / - [x]) — render as plain ASCII\n\n"
"LINEBREAKS ARE CRITICAL: A single newline does NOT create a new line — "
"adjacent lines merge together. Use TWO trailing spaces at the end of a "
"line for a soft linebreak. Use a blank line between paragraphs. "
"Without two trailing spaces or a blank line, everything runs together.\n\n"
"LINKS: Always use [descriptive link text](url) — never show bare URLs. "
"When referencing something with an associated URL (event names, venues, "
"people, sources), make the name a clickable link.\n\n"
"The adapter converts your Markdown to HTML for rich display — bold, "
"italic, inline code, fenced code blocks, headings, bullet and "
"numbered lists, blockquotes, and links all render.\n\n"
"Do NOT use Markdown tables: many popular Matrix clients (Element X, "
"Beeper, most mobile apps) do not render HTML tables, so the cells "
"collapse into one continuous run of text. Present tabular data as "
"labeled '**Label:** value' lines or bullet lists instead.\n\n"
"Avoid ||spoiler|| tags, ~~strikethrough~~, and checkboxes "
"(- [ ] / - [x]) — they are not converted and appear as literal "
"characters.\n\n"
"LINKS: prefer [descriptive link text](url) over bare URLs. When "
"referencing something with an associated URL (events, sources, "
"people), make the name a clickable link.\n\n"
"You can send media files natively: include MEDIA:/absolute/path/to/file "
"in your response. Images (.jpg, .png, .webp) are sent as inline photos, "
"audio (.ogg, .mp3) as voice/audio messages, video (.mp4) inline, "

View file

@ -0,0 +1 @@
RKelln

View file

@ -1169,6 +1169,11 @@ class TestPromptBuilderConstants:
assert "Matrix" in hint
assert "MEDIA:" in hint
assert "Markdown" in hint
# Regression (#52552): the hint must steer models away from Markdown
# tables — popular Matrix clients don't render HTML tables and the
# cells collapse into one continuous line.
assert "table" in hint.lower()
assert "Do NOT use Markdown tables" in hint
def test_platform_hints_feishu(self):
hint = PLATFORM_HINTS["feishu"]

View file

@ -1033,7 +1033,10 @@ class TestMatrixRenderingPayloads:
@pytest.mark.asyncio
async def test_long_response_split_preserves_thread_context(self):
long_text = "Intro\n```python\n" + ("print('hello')\n" * 500) + "```\nDone"
# Build a payload guaranteed to exceed the adapter's outbound chunk
# size (configurable since #53026) so send() must split it.
repeats = (self.adapter.max_message_length // 15) + 200
long_text = "Intro\n```python\n" + ("print('hello')\n" * repeats) + "```\nDone"
result = await self.adapter.send(
"!room:example.org",

View file

@ -97,6 +97,7 @@ matrix:
session_scope: room # auto|room|thread; room is recommended for project rooms
auto_thread: true # Auto-create threads for responses (default: true)
dm_mention_threads: false # Create thread when @mentioned in DM (default: false)
max_message_length: 16000 # Outbound chunk size in chars (default: 16000, max: 65535)
```
Or via environment variables: