* fix(matrix): bound raw transport response reads to prevent OOM
* test(matrix): add real node:http server proof for bound transport
Two new integration-style tests drive performMatrixRequest against a real
node:http server (no stubRuntimeFetch mock) using real undici + SSRF
dispatcher and ssrfPolicy.allowPrivateNetwork:
- over-cap: server declares Content-Length > MATRIX_SDK_RESPONSE_MAX_BYTES
with maxBytes omitted → rejects MatrixMediaSizeLimitError (68 ms wall)
- under-cap: server returns small payload with maxBytes omitted → Buffer
returned correctly (12 ms wall)
Addresses ClawSweeper feedback: previous proof showed only Vitest mock
output; these tests exercise the real Matrix runtime fetch path end-to-end.
* test(matrix): satisfy lint for transport proof
* fix(matrix): preserve encrypted media download limits
* test(matrix): add streaming OOM guard proof via real node:http server without Content-Length
Drive readResponseWithLimit directly by omitting Content-Length so that
enforceDeclaredResponseSize is a no-op and the streaming byte cap is the
sole enforcement path. A 20 MiB chunked server response with a 16 MiB
cap confirms the stream is canceled before full buffering (chunksWritten
< TOTAL_CHUNKS). A second case verifies under-cap payloads pass through.
* test(matrix): fix lint errors in real HTTP server proof (curly)
* test(matrix): add under-cap proof to real HTTP server test
Wrap JSON.parse(text) in MatrixAuthedHttpClient.requestJson with try/catch to prevent a malformed Matrix homeserver response from throwing an unhandled SyntaxError.
On parse failure, throw an Error with statusCode attached (matching the buildHttpError convention) so callers can handle it like any other Matrix API error.
Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
Wrap the matrix outbound sanitizeText hook with sanitizeAssistantVisibleText so assistant internal tool-trace scaffolding is stripped before delivery, matching the sibling channel fixes under #90684 (Telegram #95774, Google Chat #95084, IRC #97214).
truncateReplyBody used a raw value.slice(0, MAX_REPLY_BODY_LENGTH - 3)
to shorten long reply bodies. When the cut index fell between the two
UTF-16 code units of a surrogate pair (e.g. an emoji), the slice left a
lone high surrogate before the ellipsis, which renders as a broken glyph
in the reply context shown to the agent.
Replace the raw slice with sliceUtf16Safe from the plugin SDK so the
truncation never cuts inside a surrogate pair. A normal (non-astral)
body is unaffected.
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Matrix thread-starter previews truncated long bodies by raw UTF-16
slice, which could cut an astral character (e.g. emoji) and leave a lone
surrogate, rendering mojibake in the agent's thread context.
Reuse the existing sliceUtf16Safe helper so the cut backs up to a valid
surrogate boundary, preserving the 500-code-unit limit and '...' suffix.
Adds a regression test that fails against the raw-slice implementation.
Salvages the original fix from #96407 (auto-closed by the active-PR
queue cap). Preserves @ly-wang19's authorship; rebased clean onto main
by @Bartok9.
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
The non-raw JSON read in performMatrixRequest fell back to the bound
reader's default media idle-timeout message ('Matrix media download
stalled: ...'), which is misleading for a JSON control-plane read. Pass
a JSON-specific onIdleTimeout so a stalled JSON stream now rejects with
'Matrix JSON response stalled: no data received for {ms}ms', letting the
timeout diagnostic distinguish a stalled JSON read from a stalled
raw/media read. Update the regression assertion accordingly.
fake-indexeddb@6.2.5 retains finished transactions in raw.transactions
array indefinitely. For Matrix E2EE crypto stores, this causes unbounded
heap growth and eventual OOM crashes.
Add a transaction pruner that patches IDBDatabase.prototype.transaction
to automatically remove finished transactions for Matrix crypto databases
(::matrix-sdk-crypto and ::matrix-sdk-crypto-meta suffixes).
Fixes#90455
Validates Matrix CLI numeric option ranges before invoking setup or verification side effects.
`--initial-sync-limit` must now be non-negative, and `--timeout-ms` must now be positive.
Original PR by @rohitjavvadi.
Verification:
- `node scripts/run-vitest.mjs extensions/matrix/src/cli.test.ts --maxWorkers=1`
- autoreview clean
- Crabbox AWS `cbx_5c32f138ab3a` / `swift-lobster`, run `run_6e133b8b82e7`: `check:changed` passed
- exact PR head CI green: `d75f118299029b0516311646276cd2d6582379c5`
Move Matrix sync cache state into plugin SQLite storage, with startup and doctor migrations for readable legacy bot-storage.json files.\n\nVerification: focused Matrix and QA tests passed locally; focused touched-file oxlint and git diff --check passed; autoreview clean. CI failures are current main/unrelated: lint/type/madge/gateway-watch issues outside the Matrix diff.
## Summary
- Document scoped configured mention-pattern policy on the Groups page, including allow/deny mode semantics, supported conversation IDs, account-level precedence, and native-mention behavior.
- Add config UI help for `mentionPatterns.mode`, `allowIn`, and `denyIn` on Discord, Matrix, Slack, Telegram, and WhatsApp.
- Regenerate channel config/docs/plugin SDK metadata baselines for the new hint copy.
Refs #70864.
## Verification
- git diff --check
- pnpm format:docs:check
- pnpm docs:check-mdx
- pnpm docs:check-links
- pnpm config:channels:check
- pnpm config:docs:check
- pnpm plugin-sdk:api:check
- node scripts/run-vitest.mjs src/config/schema.hints.test.ts
- .agents/skills/autoreview/scripts/autoreview --mode local
## Real behavior proof
Behavior addressed: Documentation and config UI metadata for scoped configured mention-pattern policy.
Real environment tested: Local OpenClaw checkout on macOS.
Exact steps or command run after this patch: The verification commands listed above.
Evidence after fix: Docs formatting, MDX, link audit, generated config/channel/API baselines, and config hint tests passed; autoreview reported no accepted/actionable findings.
Observed result after fix: The Groups page now explains how to scope `messages.groupChat.mentionPatterns` with `channels.<channel>.mentionPatterns`, and config metadata exposes field help for the supported channels.
What was not tested: Live Discord, Matrix, Slack, Telegram, or WhatsApp inbound messages; this PR is documentation/config metadata only and follows the already-landed runtime behavior from #70864.
Provider-scoped configured regex mention patterns for Discord, Matrix, Slack, Telegram, and WhatsApp.
Native platform mentions keep their existing behavior, and unsupported channels do not opt into the new regex policy path. The new policy supports per-channel allow/deny routing through mentionPatterns.mode with allowIn and denyIn so group auto-reply regexes can be limited without broad global blast radius.
Refs #70864.
Supersedes #87200.
Thanks @patrick-slimelab.