feat(matrix): thread-isolated sessions and per-chat-type threadReplies (#57995)

Merged via squash.

Prepared head SHA: 9ed96dd063
Co-authored-by: teconomix <6959299+teconomix@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
Teconomix
2026-03-31 04:45:32 +02:00
committed by GitHub
parent d859746862
commit 697dddbeb6
20 changed files with 564 additions and 67 deletions

View File

@@ -143,6 +143,7 @@ This is a practical baseline config with DM pairing, room allowlist, and E2EE en
dm: {
policy: "pairing",
threadReplies: "off",
},
groupPolicy: "allowlist",
@@ -501,9 +502,10 @@ The repair flow does not delete old rooms automatically. It only picks the healt
Matrix supports native Matrix threads for both automatic replies and message-tool sends.
- `threadReplies: "off"` keeps replies top-level.
- `threadReplies: "off"` keeps replies top-level and keeps inbound threaded messages on the parent session.
- `threadReplies: "inbound"` replies inside a thread only when the inbound message was already in that thread.
- `threadReplies: "always"` keeps room replies in a thread rooted at the triggering message.
- `threadReplies: "always"` keeps room replies in a thread rooted at the triggering message and routes that conversation through the matching thread-scoped session from the first triggering message.
- `dm.threadReplies` overrides the top-level setting for DMs only. For example, you can keep room threads isolated while keeping DMs flat.
- Inbound threaded messages include the thread root message as extra agent context.
- Message-tool sends now auto-inherit the current Matrix thread when the target is the same room, or the same DM user target, unless an explicit `threadId` is provided.
- Runtime thread bindings are supported for Matrix. `/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, and thread-bound `/acp spawn` now work in Matrix rooms and DMs.
@@ -595,6 +597,7 @@ Current behavior:
dm: {
policy: "allowlist",
allowFrom: ["@admin:example.org"],
threadReplies: "off",
},
groupPolicy: "allowlist",
groupAllowFrom: ["@admin:example.org"],
@@ -642,6 +645,7 @@ See [Pairing](/channels/pairing) for the shared DM pairing flow and storage layo
dm: {
policy: "allowlist",
allowFrom: ["@ops:example.org"],
threadReplies: "off",
},
},
},
@@ -757,8 +761,9 @@ Live directory lookup uses the logged-in Matrix account:
- `mediaMaxMb`: media size cap in MB for Matrix media handling. It applies to outbound sends and inbound media processing.
- `autoJoin`: invite auto-join policy (`always`, `allowlist`, `off`). Default: `off`.
- `autoJoinAllowlist`: rooms/aliases allowed when `autoJoin` is `allowlist`. Alias entries are resolved to room IDs during invite handling; OpenClaw does not trust alias state claimed by the invited room.
- `dm`: DM policy block (`enabled`, `policy`, `allowFrom`).
- `dm`: DM policy block (`enabled`, `policy`, `allowFrom`, `threadReplies`).
- `dm.allowFrom` entries should be full Matrix user IDs unless you already resolved them through live directory lookup.
- `dm.threadReplies`: DM-only thread policy override (`off`, `inbound`, `always`). It overrides the top-level `threadReplies` setting for both reply placement and session isolation in DMs.
- `accounts`: named per-account overrides. Top-level `channels.matrix` values act as defaults for these entries.
- `groups`: per-room policy map. Prefer room IDs or aliases; unresolved room names are ignored at runtime. Session/group identity uses the stable room ID after resolution, while human-readable labels still come from room names.
- `rooms`: legacy alias for `groups`.