feat(matrix): add thread session isolation (#8241)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
peetzweg/
2026-02-10 01:16:40 +01:00
committed by GitHub
parent a97db0c372
commit 49c60e9065

View File

@@ -12,6 +12,7 @@ import {
} from "openclaw/plugin-sdk";
import type { CoreConfig, MatrixRoomConfig, ReplyToMode } from "../../types.js";
import type { MatrixRawEvent, RoomMessageEventContent } from "./types.js";
import { fetchEventSummary } from "../actions/summary.js";
import {
formatPollAsText,
isPollStartType,
@@ -431,7 +432,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
isThreadRoot: false, // @vector-im/matrix-bot-sdk doesn't have this info readily available
});
const route = core.channel.routing.resolveAgentRoute({
const baseRoute = core.channel.routing.resolveAgentRoute({
cfg,
channel: "matrix",
peer: {
@@ -439,8 +440,57 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
id: isDirectMessage ? senderId : roomId,
},
});
const route = {
...baseRoute,
sessionKey: threadRootId
? `${baseRoute.sessionKey}:thread:${threadRootId}`
: baseRoute.sessionKey,
};
let threadStarterBody: string | undefined;
let threadLabel: string | undefined;
let parentSessionKey: string | undefined;
if (threadRootId) {
const existingSession = core.channel.session.readSessionUpdatedAt({
storePath: core.channel.session.resolveStorePath(cfg.session?.store, {
agentId: baseRoute.agentId,
}),
sessionKey: route.sessionKey,
});
if (existingSession === undefined) {
try {
const rootEvent = await fetchEventSummary(client, roomId, threadRootId);
if (rootEvent?.body) {
const rootSenderName = rootEvent.sender
? await getMemberDisplayName(roomId, rootEvent.sender)
: undefined;
threadStarterBody = core.channel.reply.formatAgentEnvelope({
channel: "Matrix",
from: rootSenderName ?? rootEvent.sender ?? "Unknown",
timestamp: rootEvent.timestamp,
envelope: core.channel.reply.resolveEnvelopeFormatOptions(cfg),
body: rootEvent.body,
});
threadLabel = `Matrix thread in ${roomName ?? roomId}`;
parentSessionKey = baseRoute.sessionKey;
}
} catch (err) {
logVerboseMessage(
`matrix: failed to fetch thread root ${threadRootId}: ${String(err)}`,
);
}
}
}
const envelopeFrom = isDirectMessage ? senderName : (roomName ?? roomId);
const textWithId = `${bodyText}\n[matrix event id: ${messageId} room: ${roomId}]`;
const textWithId = threadRootId
? `${bodyText}\n[matrix event id: ${messageId} room: ${roomId} thread: ${threadRootId}]`
: `${bodyText}\n[matrix event id: ${messageId} room: ${roomId}]`;
const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
agentId: route.agentId,
});
@@ -467,7 +517,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
To: `room:${roomId}`,
SessionKey: route.sessionKey,
AccountId: route.accountId,
ChatType: isDirectMessage ? "direct" : "channel",
ChatType: threadRootId ? "thread" : isDirectMessage ? "direct" : "channel",
ConversationLabel: envelopeFrom,
SenderName: senderName,
SenderId: senderId,
@@ -490,6 +540,9 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
CommandSource: "text" as const,
OriginatingChannel: "matrix" as const,
OriginatingTo: `room:${roomId}`,
ThreadStarterBody: threadStarterBody,
ThreadLabel: threadLabel,
ParentSessionKey: parentSessionKey,
});
await core.channel.session.recordInboundSession({