Skip to content

fix(matrix): emit spec-compliant mentions#59323

Merged
gumadeiras merged 14 commits into
mainfrom
codex/matrix-mentions-56950
Apr 2, 2026
Merged

fix(matrix): emit spec-compliant mentions#59323
gumadeiras merged 14 commits into
mainfrom
codex/matrix-mentions-56950

Conversation

@gumadeiras

Copy link
Copy Markdown
Member

Summary

  • emit spec-compliant Matrix m.mentions metadata and matrix.to anchors for outbound text, media captions, polls, and edits
  • route action-driven Matrix edits through the shared edit helper so mention diffing and formatting stay consistent
  • simplify Matrix send formatting so mention extraction and HTML rendering share one plugin-owned path

Change Type

  • Bug fix
  • New feature
  • Breaking change
  • Docs update
  • Refactor / internal improvement

Scope

  • Plugins / extensions
  • Core runtime / channels
  • CLI
  • Docs
  • Infra / CI

Linked Issue / PR

Closes #56950

Root Cause / Regression History

Outbound Matrix sends never populated content["m.mentions"] and rendered mentions as plain text HTML, so Element/spec-compliant clients had no structured mention metadata to notify on. Action-driven edits also bypassed the shared Matrix edit helper, and poll fallback text never ran through mention extraction.

Regression Test Plan

  • added mention coverage in extensions/matrix/src/matrix/format.test.ts
  • added send/edit/poll mention coverage in extensions/matrix/src/matrix/send.test.ts
  • added action-edit routing coverage in extensions/matrix/src/matrix/actions/messages.test.ts

User-visible / Behavior Changes

Matrix mentions now notify reliably across text sends, media captions, edits, poll fallback text, and action-driven edits when the content resolves to @room, a full MXID, or a unique bare localpart in the room.

Security Impact

None.

Repro + Verification

  1. Before: send @alice:example.org or @room from OpenClaw Matrix paths; payloads lacked m.mentions, so clients like Element would not treat them as spec-compliant mentions.
  2. After: covered Matrix send paths emit m.mentions and matrix.to anchors; edit paths also send correct mention deltas.
  3. Verified locally with:
    • pnpm test -- extensions/matrix/src/matrix/format.test.ts
    • pnpm test -- extensions/matrix/src/matrix/send.test.ts
    • pnpm test -- extensions/matrix/src/matrix/actions/messages.test.ts
    • pnpm build
    • pnpm check

Human Verification

Not run.

Compatibility / Migration

No migration needed.

Risks and Mitigations

Risk is limited to Matrix-plugin outbound formatting. Coverage now spans qualified mentions, unique bare-localpart resolution, ambiguity fallback, @room, poll fallback text, and action/edit routing.

Copilot AI review requested due to automatic review settings April 2, 2026 01:24
@openclaw-barnacle openclaw-barnacle Bot added channel: matrix Channel integration: matrix size: L maintainer Maintainer-authored PR labels Apr 2, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2544b757f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts Outdated
@gumadeiras gumadeiras self-assigned this Apr 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Emits Matrix-spec-compliant mention metadata (m.mentions) and HTML mention anchors (matrix.to) across outbound Matrix send/edit flows so Matrix clients can reliably notify/highlight mentions.

Changes:

  • Add mention extraction + HTML rendering that produces m.mentions and matrix.to anchors from Markdown.
  • Route all outbound content types (text, media captions, polls’ fallback text, edits, action-driven edits) through the shared formatting/mention pipeline.
  • Add/expand tests covering mention extraction, ambiguity handling, edit mention diffs, and poll mention metadata.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
extensions/matrix/src/matrix/send/media.ts Removes direct formatting call so media captions are enriched via the shared formatting path.
extensions/matrix/src/matrix/send/formatting.ts Introduces async formatting enrichment that attaches m.mentions and formatted_body consistently; adds mention diff helpers for edits.
extensions/matrix/src/matrix/send.ts Applies enrichment to send/edit/poll flows; computes mention deltas for edit events.
extensions/matrix/src/matrix/send.test.ts Adds integration-style tests asserting m.mentions + matrix.to anchors across send/edit/poll/media caption scenarios.
extensions/matrix/src/matrix/format.ts Implements Markdown-based mention detection, bare-localpart resolution via joined members, and HTML token mutation for mention links.
extensions/matrix/src/matrix/format.test.ts Adds unit tests for mention rendering/metadata, ambiguity behavior, and code-span exclusion.
extensions/matrix/src/matrix/actions/messages.ts Routes action-driven edits through the shared edit helper to keep mention behavior consistent.
extensions/matrix/src/matrix/actions/messages.test.ts Adds coverage ensuring action edits preserve mention behavior via the shared helper.
CHANGELOG.md Documents the Matrix mention compliance fix.

Comment thread extensions/matrix/src/matrix/format.ts Outdated
Comment thread extensions/matrix/src/matrix/format.ts Outdated
@greptile-apps

greptile-apps Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds spec-compliant m.mentions metadata to all outbound Matrix message paths (text, media captions, edits, polls, action-driven edits) and renders qualified user mentions as matrix.to anchor links in the HTML body. It also refactors buildTextContent into a pure builder and introduces the new async enrichMatrixFormattedContent to own all formatting and mention-extraction in one place.

The implementation is well-structured, correctly handles qualified MXIDs, bare localpart resolution, ambiguity fallback, @room, self-mention suppression, code-span exclusion, and edit mention diffing per the Matrix spec.

Confidence Score: 5/5

  • Safe to merge — all remaining findings are P2 style/migration notes with no impact on correctness.
  • All changed paths are covered by dedicated tests (format, send, poll, edit, action routing). No P0/P1 issues found. The two flagged items are a minor efficiency suggestion and an expected transient migration behaviour that has no good alternative.
  • No files require special attention.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/matrix/src/matrix/format.ts
Line: 291

Comment:
**`getUserId()` called unconditionally on every send**

`getUserId()` is awaited on every call to `resolveMarkdownMentionState`, even for messages that contain no mentions at all. While the underlying Matrix JS SDK call is synchronous/cached (just reads stored credentials), it still adds an unnecessary async microtask for every outbound message that has no `@` references.

Consider guarding this call similarly to how `getJoinedRoomMembers` is already guarded — only fetch `selfUserId` when at least one user-mention candidate exists in the parsed tokens:

```ts
const hasMentionCandidates = tokens.some((t) =>
  t.children?.some((c) => c.type === "text" && collectMentionCandidates(c.content).length > 0)
);
const selfUserId = hasMentionCandidates
  ? await params.client.getUserId().catch(() => null)
  : null;
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/matrix/src/matrix/send.ts
Line: 449-453

Comment:
**Edit of pre-`m.mentions` message over-notifies existing mentions**

When a user edits a message that was sent before this PR (i.e., the original event has no `m.mentions` field), `extractMatrixMentions(previousContent)` returns `{}`. `diffMatrixMentions` then treats every mention in the new content as "new", so all mentioned users receive a notification again — even if they were already mentioned in the original text.

This is an inherent migration concern: there is no way to reconstruct the prior mention set from old events. It's worth documenting this behaviour (e.g. with a code comment) so future maintainers understand why seemingly-duplicate notifications can occur immediately after the rollout.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(matrix): emit spec-compliant mention..." | Re-trigger Greptile

Comment thread extensions/matrix/src/matrix/format.ts Outdated
Comment thread extensions/matrix/src/matrix/send.ts Outdated
@gumadeiras gumadeiras force-pushed the codex/matrix-mentions-56950 branch 2 times, most recently from 88b4ca7 to d2715f3 Compare April 2, 2026 02:00

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2715f3adf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts Outdated
@gumadeiras gumadeiras force-pushed the codex/matrix-mentions-56950 branch from 1e028ea to 63d39eb Compare April 2, 2026 02:11
chatgpt-codex-connector[bot]

This comment was marked as resolved.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 581b4ae34d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93d6d2d14d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85d863f90d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 357805af07

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 33b0de8d48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts Outdated
@gumadeiras gumadeiras force-pushed the codex/matrix-mentions-56950 branch from 8c00219 to 24d4ebf Compare April 2, 2026 05:23

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 24d4ebfd8d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/format.ts
@gumadeiras gumadeiras force-pushed the codex/matrix-mentions-56950 branch 2 times, most recently from f5c4c3e to 9fee0dc Compare April 2, 2026 05:58
@gumadeiras gumadeiras force-pushed the codex/matrix-mentions-56950 branch from 9fee0dc to 4b641e3 Compare April 2, 2026 05:59
@gumadeiras gumadeiras merged commit be52594 into main Apr 2, 2026
9 checks passed
@gumadeiras gumadeiras deleted the codex/matrix-mentions-56950 branch April 2, 2026 06:00
@gumadeiras

Copy link
Copy Markdown
Member Author

Merged via squash.

Thanks @gumadeiras!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b641e35a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/send.ts
ngutman pushed a commit that referenced this pull request Apr 3, 2026
Merged via squash.

Prepared head SHA: 4b641e3
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
steipete pushed a commit to duncanita/openclaw that referenced this pull request Apr 4, 2026
Merged via squash.

Prepared head SHA: 4b641e3
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
Merged via squash.

Prepared head SHA: 4b641e3
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
Merged via squash.

Prepared head SHA: 4b641e3
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Merged via squash.

Prepared head SHA: 4b641e3
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
Merged via squash.

Prepared head SHA: 4b641e3
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: matrix Channel integration: matrix maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Matrix plugin does not send m.mentions field when @mentioning users

2 participants