@openclaw/matrix 2026.2.9 → 2026.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/matrix",
3
- "version": "2026.2.9",
3
+ "version": "2026.2.12",
4
4
  "description": "OpenClaw Matrix channel plugin",
5
5
  "type": "module",
6
6
  "dependencies": {
7
7
  "@matrix-org/matrix-sdk-crypto-nodejs": "^0.4.0",
8
8
  "@vector-im/matrix-bot-sdk": "0.8.0-element.3",
9
- "markdown-it": "14.1.0",
9
+ "markdown-it": "14.1.1",
10
10
  "music-metadata": "^11.12.0",
11
11
  "zod": "^4.3.6"
12
12
  },
@@ -12,6 +12,7 @@ import {
12
12
  } from "openclaw/plugin-sdk";
13
13
  import type { CoreConfig, MatrixRoomConfig, ReplyToMode } from "../../types.js";
14
14
  import type { MatrixRawEvent, RoomMessageEventContent } from "./types.js";
15
+ import { fetchEventSummary } from "../actions/summary.js";
15
16
  import {
16
17
  formatPollAsText,
17
18
  isPollStartType,
@@ -431,7 +432,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
431
432
  isThreadRoot: false, // @vector-im/matrix-bot-sdk doesn't have this info readily available
432
433
  });
433
434
 
434
- const route = core.channel.routing.resolveAgentRoute({
435
+ const baseRoute = core.channel.routing.resolveAgentRoute({
435
436
  cfg,
436
437
  channel: "matrix",
437
438
  peer: {
@@ -439,8 +440,57 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
439
440
  id: isDirectMessage ? senderId : roomId,
440
441
  },
441
442
  });
443
+
444
+ const route = {
445
+ ...baseRoute,
446
+ sessionKey: threadRootId
447
+ ? `${baseRoute.sessionKey}:thread:${threadRootId}`
448
+ : baseRoute.sessionKey,
449
+ };
450
+
451
+ let threadStarterBody: string | undefined;
452
+ let threadLabel: string | undefined;
453
+ let parentSessionKey: string | undefined;
454
+
455
+ if (threadRootId) {
456
+ const existingSession = core.channel.session.readSessionUpdatedAt({
457
+ storePath: core.channel.session.resolveStorePath(cfg.session?.store, {
458
+ agentId: baseRoute.agentId,
459
+ }),
460
+ sessionKey: route.sessionKey,
461
+ });
462
+
463
+ if (existingSession === undefined) {
464
+ try {
465
+ const rootEvent = await fetchEventSummary(client, roomId, threadRootId);
466
+ if (rootEvent?.body) {
467
+ const rootSenderName = rootEvent.sender
468
+ ? await getMemberDisplayName(roomId, rootEvent.sender)
469
+ : undefined;
470
+
471
+ threadStarterBody = core.channel.reply.formatAgentEnvelope({
472
+ channel: "Matrix",
473
+ from: rootSenderName ?? rootEvent.sender ?? "Unknown",
474
+ timestamp: rootEvent.timestamp,
475
+ envelope: core.channel.reply.resolveEnvelopeFormatOptions(cfg),
476
+ body: rootEvent.body,
477
+ });
478
+
479
+ threadLabel = `Matrix thread in ${roomName ?? roomId}`;
480
+ parentSessionKey = baseRoute.sessionKey;
481
+ }
482
+ } catch (err) {
483
+ logVerboseMessage(
484
+ `matrix: failed to fetch thread root ${threadRootId}: ${String(err)}`,
485
+ );
486
+ }
487
+ }
488
+ }
489
+
442
490
  const envelopeFrom = isDirectMessage ? senderName : (roomName ?? roomId);
443
- const textWithId = `${bodyText}\n[matrix event id: ${messageId} room: ${roomId}]`;
491
+ const textWithId = threadRootId
492
+ ? `${bodyText}\n[matrix event id: ${messageId} room: ${roomId} thread: ${threadRootId}]`
493
+ : `${bodyText}\n[matrix event id: ${messageId} room: ${roomId}]`;
444
494
  const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
445
495
  agentId: route.agentId,
446
496
  });
@@ -461,13 +511,14 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
461
511
  const groupSystemPrompt = roomConfig?.systemPrompt?.trim() || undefined;
462
512
  const ctxPayload = core.channel.reply.finalizeInboundContext({
463
513
  Body: body,
514
+ BodyForAgent: bodyText,
464
515
  RawBody: bodyText,
465
516
  CommandBody: bodyText,
466
517
  From: isDirectMessage ? `matrix:${senderId}` : `matrix:channel:${roomId}`,
467
518
  To: `room:${roomId}`,
468
519
  SessionKey: route.sessionKey,
469
520
  AccountId: route.accountId,
470
- ChatType: isDirectMessage ? "direct" : "channel",
521
+ ChatType: threadRootId ? "thread" : isDirectMessage ? "direct" : "channel",
471
522
  ConversationLabel: envelopeFrom,
472
523
  SenderName: senderName,
473
524
  SenderId: senderId,
@@ -490,6 +541,9 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
490
541
  CommandSource: "text" as const,
491
542
  OriginatingChannel: "matrix" as const,
492
543
  OriginatingTo: `room:${roomId}`,
544
+ ThreadStarterBody: threadStarterBody,
545
+ ThreadLabel: threadLabel,
546
+ ParentSessionKey: parentSessionKey,
493
547
  });
494
548
 
495
549
  await core.channel.session.recordInboundSession({
@@ -30,11 +30,13 @@ async function fetchMatrixMediaBuffer(params: {
30
30
  // Use the client's download method which handles auth
31
31
  try {
32
32
  const result = await params.client.downloadContent(params.mxcUrl);
33
- const buffer = result.data;
33
+ const raw = result.data ?? result;
34
+ const buffer = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
35
+
34
36
  if (buffer.byteLength > params.maxBytes) {
35
37
  throw new Error("Matrix media exceeds configured size limit");
36
38
  }
37
- return { buffer: Buffer.from(buffer) };
39
+ return { buffer, headerType: result.contentType };
38
40
  } catch (err) {
39
41
  throw new Error(`Matrix media download failed: ${String(err)}`, { cause: err });
40
42
  }