fix: exempt the Matrix quote block from the mention strip only on real replies

The reply-pill fix split the body on a leading "> " so the strip would not
rewrite the "> <@bot:srv>" pill. That keyed the exemption on the body shape,
not on the relation: a hand-typed blockquote in a plain (non-reply) message
that mentions the bot inside the quote reached the agent with the raw
"@hermes:example.org" text, which main used to strip. Split around the quote
only when m.relates_to carries m.in_reply_to; otherwise strip the whole body.

Review finding: quote-block exemption keyed on body.startswith('> ') instead of m.in_reply_to.
This commit is contained in:
teknium1
2026-09-14 21:33:45 -07:00
committed by Teknium
parent ccc811dd24
commit 060e2a4286
2 changed files with 23 additions and 3 deletions
+7 -3
View File
@@ -2025,9 +2025,13 @@ class MatrixAdapter(BasePlatformAdapter):
# Strip the mention from the reply text only: the quote block carries the
# ``> <@bot:srv> ...`` reply pill, which _extract_reply_context parses later
# for reply_to_author_id. A whole-body replace rewrote the pill to ``> <>``
# and silently dropped the replied-to author (#111233).
quote_block, reply_text = _split_reply_fallback(body)
body = quote_block + self._strip_mention(reply_text)
# and silently dropped the replied-to author (#111233). Only a real reply carries a
# pill; a hand-typed blockquote in a plain message is stripped whole as before.
if relates_to.get("m.in_reply_to"):
quote_block, reply_text = _split_reply_fallback(body)
body = quote_block + self._strip_mention(reply_text)
else:
body = self._strip_mention(body)
# Real thread roots are preserved above; synthetic roots (this event) follow policy: DM
# @mention threads / DM auto-thread, or room auto-thread unless session_scope pins the room.
if not thread_id:
@@ -290,3 +290,19 @@ async def test_reply_with_explicit_mention_still_strips_it_from_reply_text(monke
assert msg.reply_to_author_id == "@carol:example.org"
assert msg.reply_to_text == "original question"
assert msg.text == "because reasons"
@pytest.mark.asyncio
async def test_plain_blockquote_without_reply_is_stripped_whole(monkeypatch):
"""The quote exemption keys on m.in_reply_to, not on a leading ``> ``: a hand-typed
blockquote mentioning the bot in a non-reply message must not reach the agent raw."""
adapter = _make_adapter(require_mention=True, monkeypatch=monkeypatch)
adapter._startup_ts = time.time() - 10
event = _make_event("> @hermes:example.org please summarise\n\nthanks", event_id="$evt_quote")
await adapter._on_room_message(event)
msg = adapter.handle_message.await_args.args[0]
assert msg.reply_to_message_id is None
assert "@hermes:example.org" not in msg.text
assert "thanks" in msg.text