fix(matrix): stop tagging the user on every reply (#16932)

The mention_user_id injection from #38a6bada9 unconditionally attached an
@user:server mention pill + MSC3952 m.mentions.user_ids payload to every
outbound reply and every tool-progress status update. The stated intent
was push notifications in muted rooms, but shipped as always-on in every
room, DM or group, muted or not — so every reply pinged the user.

- gateway/platforms/base.py: stop injecting mention_user_id into send
  metadata on every reply; restore the original _thread_metadata passthrough.
- gateway/run.py: drop mention_user_id from status-thread metadata.
- gateway/platforms/matrix.py: drop the mention-pill append block in
  _send_text that consumed the metadata. Keep the reaction-based exec
  approval half of #38a6bada9 and the inbound/outbound m.mentions
  handling (unrelated to the per-reply ping).

Reported by Elkim [NOUS] on Discord.

Co-authored-by: teknium1 <teknium@users.noreply.github.com>
This commit is contained in:
Teknium
2026-04-28 02:00:37 -07:00
committed by GitHub
parent 447d800b81
commit 4e5ebf07ea
3 changed files with 2 additions and 26 deletions

View File

@@ -2469,15 +2469,11 @@ class BasePlatformAdapter(ABC):
# Send the text portion
if text_content:
logger.info("[%s] Sending response (%d chars) to %s", self.name, len(text_content), event.source.chat_id)
# Build send metadata: thread_id + mention target for platforms that need it
send_metadata = dict(_thread_metadata) if _thread_metadata else {}
if event.source.user_id:
send_metadata["mention_user_id"] = event.source.user_id
result = await self._send_with_retry(
chat_id=event.source.chat_id,
content=text_content,
reply_to=event.message_id,
metadata=send_metadata,
metadata=_thread_metadata,
)
_record_delivery(result)

View File

@@ -879,8 +879,6 @@ class MatrixAdapter(BasePlatformAdapter):
if not content:
return SendResult(success=True)
mention_user_id = (metadata or {}).get("mention_user_id")
formatted = self.format_message(content)
chunks = self.truncate_message(formatted, MAX_MESSAGE_LENGTH)
@@ -888,24 +886,6 @@ class MatrixAdapter(BasePlatformAdapter):
for i, chunk in enumerate(chunks):
msg_content = self._build_text_message_content(chunk)
# Append @mention pill to the last chunk for push notifications
# in muted rooms (mention-only mode).
if mention_user_id and i == len(chunks) - 1:
mention_html = (
f'<a href="https://matrix.to/#/{mention_user_id}">'
f"{mention_user_id}</a>"
)
msg_content["body"] = chunk + f" @{mention_user_id}"
base_html = msg_content.get("formatted_body", chunk)
msg_content["format"] = "org.matrix.custom.html"
msg_content["formatted_body"] = base_html + " " + mention_html
# m.mentions for MSC3952 push reliability.
existing_mentions = msg_content.get("m.mentions", {}).get("user_ids", [])
if mention_user_id not in existing_mentions:
msg_content["m.mentions"] = {
"user_ids": existing_mentions + [mention_user_id]
}
# Reply-to support.
if reply_to:
msg_content["m.relates_to"] = {"m.in_reply_to": {"event_id": reply_to}}

View File

@@ -10033,7 +10033,7 @@ class GatewayRunner:
# Bridge sync status_callback → async adapter.send for context pressure
_status_adapter = self.adapters.get(source.platform)
_status_chat_id = source.chat_id
_status_thread_metadata = {"thread_id": _progress_thread_id, "mention_user_id": source.user_id} if _progress_thread_id else {"mention_user_id": source.user_id}
_status_thread_metadata = {"thread_id": _progress_thread_id} if _progress_thread_id else None
def _status_callback_sync(event_type: str, message: str) -> None:
if not _status_adapter or not _run_still_current():