@openclaw/matrix 2026.7.1 → 2026.7.2-beta.2
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/dist/{account-selection-5e4mHR1m.js → account-selection-Bz00QTmQ.js} +4 -3
- package/dist/api.js +8 -8
- package/dist/{approval-handler.runtime-DI5x9r8I.js → approval-handler.runtime-BQZdg_dJ.js} +27 -17
- package/dist/{approval-ids-ZgqbspmS.js → approval-ids-De4IhOSN.js} +1 -1
- package/dist/{approval-reaction-auth-D9LijQhr.js → approval-reaction-auth-BLJKPLku.js} +2 -2
- package/dist/approval-reactions-D-BxBK_L.js +202 -0
- package/dist/auth-presence.js +1 -1
- package/dist/{channel-jUTBsjHU.js → channel-B1woOUgk.js} +103 -143
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-DO1Nv9ed.js → channel.runtime-BvJm9z0w.js} +7 -7
- package/dist/{cli-CEfWwCKx.js → cli-CLWOkMvw.js} +15 -12
- package/dist/{cli-metadata-CfiEO-CE.js → cli-metadata-9Naf7in0.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{client-FRuyCNju.js → client-BUai6s29.js} +2 -2
- package/dist/{client-tgnlQJk4.js → client-CPuYbNL8.js} +4 -4
- package/dist/{client-bootstrap-DjFJ7e0N.js → client-bootstrap-CNVF73sF.js} +1 -1
- package/dist/{config-schema-DtnhNYd-.js → config-schema-BTSatSY3.js} +27 -63
- package/dist/contract-api.js +2 -2
- package/dist/{create-client-CNakT7zF.js → create-client-85ttAWDP.js} +3 -3
- package/dist/{credentials-Ds9V1mn2.js → credentials-CncWUieb.js} +1 -1
- package/dist/{credentials-read-BlkvsNFg.js → credentials-read-CwNJrmwu.js} +2 -2
- package/dist/{credentials-write.runtime-CTqqxcut.js → credentials-write.runtime-BDtpqvj0.js} +1 -1
- package/dist/{crypto-runtime-B74cTS6A.js → crypto-runtime-DoEB5RpM.js} +74 -44
- package/dist/{deps-CdjHvnmh.js → deps-DDbghaZH.js} +23 -90
- package/dist/{directory-live-Ufd4qSpX.js → directory-live-0TyS9xep.js} +3 -3
- package/dist/doctor-BGTs609f.js +64 -0
- package/dist/{doctor-contract-BAja_fmb.js → doctor-contract-D2qTLe-C.js} +72 -6
- package/dist/doctor-contract-api.js +323 -45
- package/dist/{draft-stream-D4EH25gv.js → draft-stream-GOdPZMBm.js} +1 -1
- package/dist/{encryption-guidance-D8walY04.js → encryption-guidance-BFfgq7c7.js} +1 -1
- package/dist/{env-auth-DIzOApj0.js → env-auth-CQsYbz-p.js} +1 -1
- package/dist/{env-vars-KzaYveuy.js → env-vars-B0NxQnPk.js} +3 -1
- package/dist/{exec-approval-resolver-f9j6staN.js → exec-approval-resolver-BCgqRtZS.js} +2 -1
- package/dist/{file-sync-store-DVm0ACml.js → file-sync-store-CUE9WwD2.js} +2 -3
- package/dist/helper-api.js +4 -4
- package/dist/{http-client-nSmFiVgk.js → http-client-Jw5_bwQo.js} +18 -34
- package/dist/{idb-persistence-BHm97th-.js → idb-persistence-BiHEEzD7.js} +1 -1
- package/dist/inbound-dedupe-CaBLblef.js +48 -0
- package/dist/index.js +1 -1
- package/dist/{media-text-p-LP21qs.js → media-text-DPCtdFjk.js} +1 -1
- package/dist/{messages-DRKkiEY-.js → messages-DCRbGLMh.js} +3 -3
- package/dist/{monitor-CsGOGdwu.js → monitor-C5EOF9et.js} +90 -427
- package/dist/plugin-entry.handlers.runtime.js +1 -1
- package/dist/probe.runtime-BBvciVfo.js +3 -0
- package/dist/{profile-update-Ucc8RrJL.js → profile-update-DompcDyu.js} +2 -2
- package/dist/{reaction-events-DentrVii.js → reaction-events-QUgxkQKQ.js} +60 -10
- package/dist/record-shared-CvzjvHRn.js +2 -0
- package/dist/{recovery-key-store-DSeLFvNx.js → recovery-key-store-B2RglalK.js} +1 -1
- package/dist/{resolve-targets-DcV_KfgX.js → resolve-targets-Cx1VVArA.js} +1 -1
- package/dist/{resolver.runtime-Hr6bO5zl.js → resolver.runtime-PPrv3ZHu.js} +1 -1
- package/dist/room-info-B6vKD5DF.js +86 -0
- package/dist/{runtime-api-CsBoesCU.js → runtime-api-D1xI_cvh.js} +3 -3
- package/dist/runtime-api.js +6 -6
- package/dist/{sdk-AZYVl34z.js → sdk-1TXuSiXZ.js} +10 -15
- package/dist/{secret-contract-DTgQyQxc.js → secret-contract-OZoQf0kI.js} +7 -48
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-D92v6Yy0.js → send-yre1krm8.js} +9 -3
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/{setup-bootstrap-Da564w5f.js → setup-bootstrap-DXVRCd4G.js} +2 -2
- package/dist/{setup-core-BGgbrdaJ.js → setup-core-CYQRY2oG.js} +9 -7
- package/dist/setup-plugin-api.js +3 -3
- package/dist/{setup-surface-iJ6pd-t5.js → setup-surface-BjvRQzK6.js} +7 -7
- package/dist/{shared-DkFfq7mH.js → shared-BfW4lxGu.js} +13 -8
- package/dist/{startup-verification-BKMAXvcV.js → startup-verification-DSiyDKM5.js} +2 -3
- package/dist/storage-DD-EnNJE.js +718 -0
- package/dist/{storage-paths-BWo_ZEMC.js → storage-paths-B4_I9iqO.js} +1 -12
- package/dist/{thread-bindings-BX5nmWpw.js → thread-bindings-U5ZroBeZ.js} +3 -4
- package/dist/{tool-actions.runtime-C1d5fxE_.js → tool-actions.runtime-BlfTr9b0.js} +246 -53
- package/dist/{verification-BGCMiO1p.js → verification-CGnI9k1O.js} +2 -2
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +136 -125
- package/package.json +4 -4
- package/dist/approval-reactions-BdUaUXVw.js +0 -113
- package/dist/crypto-state-store-Jy3qwhdy.js +0 -352
- package/dist/doctor-DfaOqFtr.js +0 -167
- package/dist/legacy-crypto-inspector-vzXSkm18.js +0 -42
- package/dist/legacy-crypto-restore-CIBfOmLn.js +0 -93
- package/dist/matrix-migration.runtime-BMCyrANT.js +0 -524
- package/dist/migration-snapshot-backup-YcCrSjbE.js +0 -69
- package/dist/migration-snapshot.runtime-VGD4QfeS.js +0 -2
- package/dist/probe.runtime-2MZLc6ng.js +0 -3
- package/dist/runtime-heavy-api.js +0 -3
- package/dist/storage-CQdyKcGg.js +0 -430
|
@@ -1,40 +1,36 @@
|
|
|
1
1
|
import { a as resolveMatrixAccountConfig, i as resolveMatrixAccountAllowlistConfig } from "./account-config-BZWN9tGS.js";
|
|
2
2
|
import { t as getMatrixRuntime } from "./runtime-6S3DNFNv.js";
|
|
3
|
-
import { m as resolveConfiguredMatrixBotUserIds } from "./setup-core-
|
|
4
|
-
import { a as buildAllowlistResolutionSummary, c as createTypingCallbacks, d as logInboundDrop, f as logTypingFailure, h as toLocationContext, i as addAllowlistUserEntriesFromConfigEntry, l as formatLocationText, m as summarizeMapping, n as resolveMatrixStoredSessionMeta, o as canonicalizeAllowlistWithResolvedIds, p as patchAllowlistUsersInConfigEntries, r as resolveMatrixRoomConfig, s as createReplyPrefixOptions, u as getAgentScopedMediaLocalRoots } from "./channel-
|
|
5
|
-
import { a as normalizeMatrixUserId, i as normalizeMatrixAllowList, o as resolveMatrixAllowListMatch } from "./config-schema-
|
|
3
|
+
import { m as resolveConfiguredMatrixBotUserIds } from "./setup-core-CYQRY2oG.js";
|
|
4
|
+
import { a as buildAllowlistResolutionSummary, c as createTypingCallbacks, d as logInboundDrop, f as logTypingFailure, h as toLocationContext, i as addAllowlistUserEntriesFromConfigEntry, l as formatLocationText, m as summarizeMapping, n as resolveMatrixStoredSessionMeta, o as canonicalizeAllowlistWithResolvedIds, p as patchAllowlistUsersInConfigEntries, r as resolveMatrixRoomConfig, s as createReplyPrefixOptions, u as getAgentScopedMediaLocalRoots } from "./channel-B1woOUgk.js";
|
|
5
|
+
import { a as normalizeMatrixUserId, i as normalizeMatrixAllowList, o as resolveMatrixAllowListMatch } from "./config-schema-BTSatSY3.js";
|
|
6
6
|
import { t as isMatrixQualifiedUserId } from "./target-ids-B-5aQxwn.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { t as
|
|
12
|
-
import { n as LogService } from "./logger-D0GCSDQq.js";
|
|
13
|
-
import { a as resolveMatrixMessageAttachment, c as fetchMatrixPollSnapshot, i as isLikelyBareFilename, n as formatMatrixMediaUnavailableText, o as resolveMatrixMessageBody, r as formatMatrixMessageText, t as formatMatrixMediaTooLargeText } from "./media-text-p-LP21qs.js";
|
|
7
|
+
import { t as formatMatrixErrorMessage } from "./errors-C47hvAF8.js";
|
|
8
|
+
import { D as parsePollStartContent, S as formatPollAsText, T as isPollStartType, _ as readJoinedMatrixMembers, a as sendMessageMatrix, f as promoteMatrixDirectRoomCandidate, g as isStrictDirectMembership, h as hasDirectMatrixMemberFlag, t as chunkMatrixText, v as MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY, w as isPollEventType } from "./send-yre1krm8.js";
|
|
9
|
+
import { t as createMatrixThreadBindingManager } from "./thread-bindings-U5ZroBeZ.js";
|
|
10
|
+
import { i as createMatrixInboundEventDeduper } from "./inbound-dedupe-CaBLblef.js";
|
|
11
|
+
import { a as resolveMatrixMessageAttachment, c as fetchMatrixPollSnapshot, i as isLikelyBareFilename, n as formatMatrixMediaUnavailableText, o as resolveMatrixMessageBody, r as formatMatrixMessageText, t as formatMatrixMediaTooLargeText } from "./media-text-DPCtdFjk.js";
|
|
14
12
|
import { n as setActiveMatrixClient } from "./active-client-DXvz2gCo.js";
|
|
15
13
|
import { t as isBunRuntime } from "./runtime-BefyhPWv.js";
|
|
16
|
-
import { d as backfillMatrixAuthDeviceIdAfterStartup, f as resolveMatrixAuth, i as resolveSharedMatrixClient, l as isMatrixStartupAbortError, n as releaseSharedClientInstance, p as resolveMatrixAuthContext, u as throwIfMatrixStartupAborted } from "./shared-
|
|
17
|
-
import "./client-
|
|
18
|
-
import { i as isMatrixMediaSizeLimitError, r as MatrixMediaSizeLimitError } from "./http-client-
|
|
19
|
-
import { d as resolveDefaultGroupPolicy,
|
|
20
|
-
import { t as resolveMatrixTargets } from "./resolve-targets-
|
|
21
|
-
import { t as formatMatrixEncryptedEventDisabledWarning } from "./encryption-guidance-
|
|
14
|
+
import { d as backfillMatrixAuthDeviceIdAfterStartup, f as resolveMatrixAuth, i as resolveSharedMatrixClient, l as isMatrixStartupAbortError, n as releaseSharedClientInstance, p as resolveMatrixAuthContext, u as throwIfMatrixStartupAborted } from "./shared-BfW4lxGu.js";
|
|
15
|
+
import "./client-CPuYbNL8.js";
|
|
16
|
+
import { i as isMatrixMediaSizeLimitError, r as MatrixMediaSizeLimitError } from "./http-client-Jw5_bwQo.js";
|
|
17
|
+
import { d as resolveAllowlistProviderRuntimeGroupPolicy, f as resolveDefaultGroupPolicy, g as warnMissingProviderGroupPolicyFallbackOnce, h as resolveThreadBindingMaxAgeMsForChannel, m as resolveThreadBindingIdleTimeoutMsForChannel, t as GROUP_POLICY_BLOCKED_LABEL } from "./runtime-api-D1xI_cvh.js";
|
|
18
|
+
import { t as resolveMatrixTargets } from "./resolve-targets-Cx1VVArA.js";
|
|
19
|
+
import { t as formatMatrixEncryptedEventDisabledWarning } from "./encryption-guidance-BFfgq7c7.js";
|
|
22
20
|
import { n as isMatrixReadySyncState, r as isMatrixTerminalSyncState, t as isMatrixDisconnectedSyncState } from "./sync-state-CWbp0QSY.js";
|
|
23
21
|
import { a as EventType, i as resolveMatrixThreadRouting, n as resolveMatrixReplyToEventId, o as RelationType, r as resolveMatrixThreadRootId, t as resolveMatrixInboundRoute } from "./route-DY6at4qJ.js";
|
|
22
|
+
import { t as createMatrixRoomInfoResolver } from "./room-info-B6vKD5DF.js";
|
|
24
23
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
25
|
-
import { buildChannelProgressDraftLineForEntry, createChannelProgressDraftGate, createPreviewMessageReceipt, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, formatChannelProgressDraftLine, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, normalizeChannelProgressDraftLineIdentity, resolveChannelProgressDraftMaxLines, waitUntilAbort } from "openclaw/plugin-sdk/channel-outbound";
|
|
24
|
+
import { buildChannelProgressDraftLineForEntry, createChannelProgressDraftGate, createPreviewMessageReceipt, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, formatChannelProgressDraftLine, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, normalizeChannelProgressDraftLineIdentity, resolveChannelProgressDraftMaxLines, resolveChannelStreamingBlockEnabled, waitUntilAbort } from "openclaw/plugin-sdk/channel-outbound";
|
|
26
25
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringifiedEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
27
|
-
import path from "node:path";
|
|
28
|
-
import { createHash } from "node:crypto";
|
|
29
26
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
30
27
|
import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
31
28
|
import { buildChannelInboundEventContext, hasFinalInboundReplyDispatch, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
|
|
32
29
|
import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
|
33
30
|
import { isFutureDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
|
34
|
-
import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
|
|
35
|
-
import fs from "node:fs/promises";
|
|
36
31
|
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
37
32
|
import { format } from "node:util";
|
|
33
|
+
import { escapeRegExp, sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
38
34
|
import { buildTtsSupplementMediaPayload, getReplyPayloadTtsSupplement } from "openclaw/plugin-sdk/reply-payload";
|
|
39
35
|
import { resolveAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
40
36
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
@@ -44,7 +40,7 @@ import { evaluateSupplementalContextVisibility, resolveChannelContextVisibilityM
|
|
|
44
40
|
import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
|
|
45
41
|
import { buildInboundHistoryFromEntries } from "openclaw/plugin-sdk/reply-history";
|
|
46
42
|
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
|
47
|
-
import {
|
|
43
|
+
import { decodeHtmlEntities } from "openclaw/plugin-sdk/html-entity-runtime";
|
|
48
44
|
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
49
45
|
import { createConnectedChannelStatusPatch, createTransportActivityStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
50
46
|
//#region extensions/matrix/src/matrix/monitor/auto-join.ts
|
|
@@ -471,7 +467,7 @@ const DM_CACHE_TTL_MS = 3e4;
|
|
|
471
467
|
const RECENT_INVITE_TTL_MS = 3e4;
|
|
472
468
|
const MAX_TRACKED_DM_ROOMS = 1024;
|
|
473
469
|
const MAX_TRACKED_DM_MEMBER_FLAGS = 2048;
|
|
474
|
-
function rememberBounded
|
|
470
|
+
function rememberBounded(map, key, value, maxSize = MAX_TRACKED_DM_ROOMS) {
|
|
475
471
|
map.set(key, value);
|
|
476
472
|
if (map.size > maxSize) {
|
|
477
473
|
const oldest = map.keys().next().value;
|
|
@@ -509,7 +505,7 @@ function createDirectRoomTracker(client, opts = {}) {
|
|
|
509
505
|
try {
|
|
510
506
|
const normalized = await readJoinedMatrixMembers(client, roomId);
|
|
511
507
|
if (!normalized) throw new Error("membership unavailable");
|
|
512
|
-
rememberBounded
|
|
508
|
+
rememberBounded(joinedMembersCache, roomId, {
|
|
513
509
|
members: normalized,
|
|
514
510
|
ts: now
|
|
515
511
|
});
|
|
@@ -527,7 +523,7 @@ function createDirectRoomTracker(client, opts = {}) {
|
|
|
527
523
|
const now = Date.now();
|
|
528
524
|
if (cached && now - cached.ts < DM_CACHE_TTL_MS) return cached.isDirect;
|
|
529
525
|
const isDirect = await hasDirectMatrixMemberFlag(client, roomId, normalizedUserId);
|
|
530
|
-
rememberBounded
|
|
526
|
+
rememberBounded(directMemberFlagCache, cacheKey, {
|
|
531
527
|
isDirect,
|
|
532
528
|
ts: now
|
|
533
529
|
}, MAX_TRACKED_DM_MEMBER_FLAGS);
|
|
@@ -584,7 +580,7 @@ function createDirectRoomTracker(client, opts = {}) {
|
|
|
584
580
|
const rememberLocallyPromotedDirectRoom = (roomId, remoteUserId) => {
|
|
585
581
|
const normalizedRemoteUserId = remoteUserId.trim();
|
|
586
582
|
if (!normalizedRemoteUserId) return;
|
|
587
|
-
rememberBounded
|
|
583
|
+
rememberBounded(locallyPromotedDirectRooms, roomId, { remoteUserId: normalizedRemoteUserId });
|
|
588
584
|
};
|
|
589
585
|
return {
|
|
590
586
|
invalidateRoom: (roomId) => {
|
|
@@ -596,7 +592,7 @@ function createDirectRoomTracker(client, opts = {}) {
|
|
|
596
592
|
rememberInvite: (roomId, remoteUserId) => {
|
|
597
593
|
const normalizedRemoteUserId = remoteUserId.trim();
|
|
598
594
|
if (!normalizedRemoteUserId) return;
|
|
599
|
-
rememberBounded
|
|
595
|
+
rememberBounded(recentInviteCandidates, roomId, {
|
|
600
596
|
remoteUserId: normalizedRemoteUserId,
|
|
601
597
|
ts: Date.now()
|
|
602
598
|
});
|
|
@@ -821,7 +817,7 @@ const matrixVerificationConstants = {
|
|
|
821
817
|
const MAX_TRACKED_VERIFICATION_EVENTS = 1024;
|
|
822
818
|
const SAS_NOTICE_RETRY_DELAY_MS = 750;
|
|
823
819
|
const VERIFICATION_EVENT_STARTUP_GRACE_MS = 3e4;
|
|
824
|
-
const loadMatrixDirectRoomDeps = createLazyRuntimeModule(() => Promise.all([import("./send-
|
|
820
|
+
const loadMatrixDirectRoomDeps = createLazyRuntimeModule(() => Promise.all([import("./send-yre1krm8.js").then((n) => n.d), import("./send-yre1krm8.js").then((n) => n.m)]).then(([directManagementModule, directRoomModule]) => ({
|
|
825
821
|
inspectMatrixDirectRooms: directManagementModule.inspectMatrixDirectRooms,
|
|
826
822
|
isStrictDirectRoom: directRoomModule.isStrictDirectRoom
|
|
827
823
|
})));
|
|
@@ -1429,6 +1425,7 @@ function parseGeoUri(value) {
|
|
|
1429
1425
|
if (!trimmed) return null;
|
|
1430
1426
|
if (!normalizeLowercaseStringOrEmpty(trimmed).startsWith("geo:")) return null;
|
|
1431
1427
|
const [coordsPart, ...paramParts] = trimmed.slice(4).split(";");
|
|
1428
|
+
if (!coordsPart) return null;
|
|
1432
1429
|
const coords = coordsPart.split(",");
|
|
1433
1430
|
if (coords.length < 2) return null;
|
|
1434
1431
|
const latitude = parseStrictFiniteNumber(coords[0] ?? "");
|
|
@@ -1525,30 +1522,15 @@ async function downloadMatrixMedia(params) {
|
|
|
1525
1522
|
}
|
|
1526
1523
|
//#endregion
|
|
1527
1524
|
//#region extensions/matrix/src/matrix/monitor/mentions.ts
|
|
1528
|
-
const
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
nbsp: " ",
|
|
1534
|
-
quot: "\""
|
|
1535
|
-
};
|
|
1536
|
-
const MAX_UNICODE_SCALAR_VALUE = 1114111;
|
|
1537
|
-
function decodeNumericHtmlEntity(match, rawValue, radix) {
|
|
1538
|
-
const codePoint = Number.parseInt(rawValue, radix);
|
|
1539
|
-
if (!Number.isSafeInteger(codePoint) || codePoint < 0 || codePoint > MAX_UNICODE_SCALAR_VALUE || codePoint >= 55296 && codePoint <= 57343) return match;
|
|
1540
|
-
return String.fromCodePoint(codePoint);
|
|
1541
|
-
}
|
|
1542
|
-
function decodeHtmlEntities(value) {
|
|
1543
|
-
return value.replace(/&(#x?[0-9a-f]+|\w+);/gi, (match, entity) => {
|
|
1544
|
-
const normalized = normalizeLowercaseStringOrEmpty(entity);
|
|
1545
|
-
if (normalized.startsWith("#x")) return decodeNumericHtmlEntity(match, normalized.slice(2), 16);
|
|
1546
|
-
if (normalized.startsWith("#")) return decodeNumericHtmlEntity(match, normalized.slice(1), 10);
|
|
1547
|
-
return HTML_ENTITY_REPLACEMENTS[normalized] ?? match;
|
|
1525
|
+
const MATRIX_HTML_ENTITY_RE = /&(?:#x?[0-9a-f]+|amp|apos|gt|lt|nbsp|quot);/gi;
|
|
1526
|
+
function decodeVisibleHtmlEntities(value) {
|
|
1527
|
+
return value.replace(MATRIX_HTML_ENTITY_RE, (entity) => {
|
|
1528
|
+
const decoded = decodeHtmlEntities(entity.startsWith("&#") ? entity : entity.toLowerCase());
|
|
1529
|
+
return decoded === "\xA0" ? " " : decoded;
|
|
1548
1530
|
});
|
|
1549
1531
|
}
|
|
1550
1532
|
function normalizeVisibleMentionText(value) {
|
|
1551
|
-
return normalizeLowercaseStringOrEmpty(
|
|
1533
|
+
return normalizeLowercaseStringOrEmpty(decodeVisibleHtmlEntities(value.replace(/<[^>]+>/g, " ").replace(/[\u200b-\u200f\u202a-\u202e\u2060-\u206f]/g, "")).replace(/\s+/g, " "));
|
|
1552
1534
|
}
|
|
1553
1535
|
function extractVisibleMentionText(value) {
|
|
1554
1536
|
return normalizeVisibleMentionText(value ?? "");
|
|
@@ -2099,14 +2081,6 @@ function createRoomHistoryTrackerInternal(maxQueueSize = DEFAULT_MAX_QUEUE_SIZE,
|
|
|
2099
2081
|
discarded: true
|
|
2100
2082
|
};
|
|
2101
2083
|
},
|
|
2102
|
-
getPendingHistory(agentId, roomId, limit, threadRootId) {
|
|
2103
|
-
const queue = findScopedQueue(roomId, threadRootId);
|
|
2104
|
-
if (!queue) return [];
|
|
2105
|
-
return computePendingHistory(queue, agentId, roomId, limit, void 0, void 0, threadRootId);
|
|
2106
|
-
},
|
|
2107
|
-
recordTrigger(roomId, entry, threadRootId) {
|
|
2108
|
-
return appendToQueue(getScopedQueue(roomId, threadRootId), entry);
|
|
2109
|
-
},
|
|
2110
2084
|
prepareTrigger(agentId, roomId, limit, entry, threadRootId) {
|
|
2111
2085
|
return prepareTriggerInternal(agentId, roomId, limit, entry, threadRootId);
|
|
2112
2086
|
},
|
|
@@ -2230,11 +2204,11 @@ function createMatrixThreadContextResolver(params) {
|
|
|
2230
2204
|
const ALLOW_FROM_STORE_CACHE_TTL_MS = 3e4;
|
|
2231
2205
|
const PAIRING_REPLY_COOLDOWN_MS = 5 * 6e4;
|
|
2232
2206
|
const MATRIX_TOOL_PROGRESS_MAX_CHARS = 300;
|
|
2233
|
-
const loadMatrixSendModule = createLazyRuntimeModule(() => import("./send-
|
|
2207
|
+
const loadMatrixSendModule = createLazyRuntimeModule(() => import("./send-yre1krm8.js").then((n) => n.l));
|
|
2234
2208
|
const loadAcpBindingRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/acp-binding-runtime"));
|
|
2235
2209
|
const loadSessionBindingRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/session-binding-runtime"));
|
|
2236
|
-
const loadMatrixReactionEvents = createLazyRuntimeModule(() => import("./reaction-events-
|
|
2237
|
-
const loadMatrixDraftStream = createLazyRuntimeModule(() => import("./draft-stream-
|
|
2210
|
+
const loadMatrixReactionEvents = createLazyRuntimeModule(() => import("./reaction-events-QUgxkQKQ.js"));
|
|
2211
|
+
const loadMatrixDraftStream = createLazyRuntimeModule(() => import("./draft-stream-GOdPZMBm.js"));
|
|
2238
2212
|
async function matrixTextWouldActivateMentions(client, text) {
|
|
2239
2213
|
const { resolveMatrixMentionsForBody } = await loadMatrixSendModule();
|
|
2240
2214
|
const mentions = await resolveMatrixMentionsForBody({
|
|
@@ -2245,12 +2219,6 @@ async function matrixTextWouldActivateMentions(client, text) {
|
|
|
2245
2219
|
}
|
|
2246
2220
|
const MAX_TRACKED_PAIRING_REPLY_SENDERS = 512;
|
|
2247
2221
|
const MAX_TRACKED_SHARED_DM_CONTEXT_NOTICES = 512;
|
|
2248
|
-
var MatrixRetryableInboundError = class extends Error {
|
|
2249
|
-
constructor(message, options) {
|
|
2250
|
-
super(message, options);
|
|
2251
|
-
this.name = "MatrixRetryableInboundError";
|
|
2252
|
-
}
|
|
2253
|
-
};
|
|
2254
2222
|
async function redactMatrixDraftEvent(client, roomId, draftEventId) {
|
|
2255
2223
|
await client.redactEvent(roomId, draftEventId).catch(() => {});
|
|
2256
2224
|
}
|
|
@@ -2357,7 +2325,7 @@ function resolveMatrixAllowBotsMode(value) {
|
|
|
2357
2325
|
return "off";
|
|
2358
2326
|
}
|
|
2359
2327
|
function formatMatrixToolProgressMarkdownCode(text) {
|
|
2360
|
-
return `\`${(text.length <= MATRIX_TOOL_PROGRESS_MAX_CHARS ? text : `${text
|
|
2328
|
+
return `\`${(text.length <= MATRIX_TOOL_PROGRESS_MAX_CHARS ? text : `${truncateUtf16Safe(text, MATRIX_TOOL_PROGRESS_MAX_CHARS - 1).trimEnd()}...`).replaceAll("`", "'")}\``;
|
|
2361
2329
|
}
|
|
2362
2330
|
function createMatrixRoomMessageHandler(params) {
|
|
2363
2331
|
const { client, core, cfg, accountId, accountConfig, runtime, logger, logVerboseMessage, allowFromResolvedEntries = [], groupAllowFromResolvedEntries = [], roomsConfig, accountAllowBots, configuredBotUserIds = /* @__PURE__ */ new Set(), groupPolicy, replyToMode, threadReplies, dmThreadReplies, dmSessionScope, streaming, previewToolProgressEnabled, blockStreamingEnabled, dmEnabled, dmPolicy, textLimit, mediaMaxBytes, historyLimit, startupMs, startupGraceMs, dropPreStartupMessages, inboundDeduper, directTracker, getRoomInfo, getMemberDisplayName, needsRoomAliasesForConfig, resolveLiveUserAllowlist = resolveMatrixMonitorLiveUserAllowlist } = params;
|
|
@@ -2445,7 +2413,7 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
2445
2413
|
};
|
|
2446
2414
|
return async (roomId, event) => {
|
|
2447
2415
|
const eventId = typeof event.event_id === "string" ? event.event_id.trim() : "";
|
|
2448
|
-
let
|
|
2416
|
+
let inboundReplayClaim;
|
|
2449
2417
|
let draftStreamRef;
|
|
2450
2418
|
let draftConsumed = false;
|
|
2451
2419
|
try {
|
|
@@ -2463,12 +2431,9 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
2463
2431
|
const eventTs = event.origin_server_ts;
|
|
2464
2432
|
const eventAge = event.unsigned?.age;
|
|
2465
2433
|
const commitInboundEventIfClaimed = async () => {
|
|
2466
|
-
if (!
|
|
2467
|
-
await
|
|
2468
|
-
|
|
2469
|
-
eventId
|
|
2470
|
-
});
|
|
2471
|
-
claimedInboundEvent = false;
|
|
2434
|
+
if (!inboundReplayClaim) return;
|
|
2435
|
+
await inboundReplayClaim.commit();
|
|
2436
|
+
inboundReplayClaim = void 0;
|
|
2472
2437
|
};
|
|
2473
2438
|
const readIngressPrefix = async () => {
|
|
2474
2439
|
const selfUserId = await client.getUserId();
|
|
@@ -2493,11 +2458,12 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
2493
2458
|
if (relates && "rel_type" in relates && relates.rel_type === RelationType.Replace) return;
|
|
2494
2459
|
if (hasBundledMatrixReplacementRelation(event)) return;
|
|
2495
2460
|
if (eventId && inboundDeduper) {
|
|
2496
|
-
|
|
2461
|
+
const claim = await inboundDeduper.claim({
|
|
2497
2462
|
roomId,
|
|
2498
2463
|
eventId
|
|
2499
2464
|
});
|
|
2500
|
-
if (
|
|
2465
|
+
if (claim.kind === "claimed") inboundReplayClaim = claim.handle;
|
|
2466
|
+
else if (claim.kind !== "invalid") {
|
|
2501
2467
|
logVerboseMessage(`matrix: skip duplicate inbound event room=${roomId} id=${eventId}`);
|
|
2502
2468
|
return;
|
|
2503
2469
|
}
|
|
@@ -3184,7 +3150,7 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3184
3150
|
}
|
|
3185
3151
|
});
|
|
3186
3152
|
if (quoteHidden) logVerboseMessage(`matrix: drop reply context (mode=${contextVisibilityMode})`);
|
|
3187
|
-
const preview = bodyText
|
|
3153
|
+
const preview = truncateUtf16Safe(bodyText, 200).replace(/\n/g, "\\n");
|
|
3188
3154
|
logVerboseMessage(`matrix inbound: room=${roomId} from=${senderId} preview="${preview}"`);
|
|
3189
3155
|
const replyTarget = ctxPayload.To;
|
|
3190
3156
|
if (!replyTarget) {
|
|
@@ -3220,7 +3186,6 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3220
3186
|
const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, _route.agentId);
|
|
3221
3187
|
let finalReplyDeliveryFailed = false;
|
|
3222
3188
|
let nonFinalReplyDeliveryFailed = false;
|
|
3223
|
-
let retryableReplyDeliveryFailed = false;
|
|
3224
3189
|
const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
|
|
3225
3190
|
cfg,
|
|
3226
3191
|
agentId: _route.agentId,
|
|
@@ -3281,16 +3246,20 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3281
3246
|
let currentDraftReplyToId = draftReplyToId;
|
|
3282
3247
|
let previewToolProgressSuppressed = false;
|
|
3283
3248
|
let previewToolProgressLines = [];
|
|
3249
|
+
let latestPlan;
|
|
3250
|
+
let latestPlanExplanation;
|
|
3284
3251
|
const progressConfigEntry = params.accountConfig ?? cfg.channels?.matrix;
|
|
3285
3252
|
const progressSeed = `${_route.accountId}:${roomId}`;
|
|
3286
3253
|
const renderProgressDraft = () => {
|
|
3287
|
-
if (!draftStream
|
|
3254
|
+
if (!draftStream) return;
|
|
3288
3255
|
const previewText = formatChannelProgressDraftText({
|
|
3289
3256
|
entry: progressConfigEntry,
|
|
3290
3257
|
lines: previewToolProgressLines,
|
|
3291
3258
|
seed: progressSeed,
|
|
3292
3259
|
formatLine: formatMatrixToolProgressMarkdownCode,
|
|
3293
|
-
bullet: "-"
|
|
3260
|
+
bullet: "-",
|
|
3261
|
+
narration: latestPlanExplanation,
|
|
3262
|
+
plan: latestPlan
|
|
3294
3263
|
});
|
|
3295
3264
|
if (!previewText) return;
|
|
3296
3265
|
draftStream.update(previewText);
|
|
@@ -3311,7 +3280,9 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3311
3280
|
lines: previewToolProgressLines,
|
|
3312
3281
|
seed: progressSeed,
|
|
3313
3282
|
formatLine: formatMatrixToolProgressMarkdownCode,
|
|
3314
|
-
bullet: "-"
|
|
3283
|
+
bullet: "-",
|
|
3284
|
+
narration: latestPlanExplanation,
|
|
3285
|
+
plan: latestPlan
|
|
3315
3286
|
}));
|
|
3316
3287
|
return;
|
|
3317
3288
|
}
|
|
@@ -3320,14 +3291,30 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3320
3291
|
const progressActive = await progressDraftGate.noteWork();
|
|
3321
3292
|
if ((alreadyStarted || progressActive) && progressDraftGate.hasStarted) renderProgressDraft();
|
|
3322
3293
|
};
|
|
3294
|
+
const pushPlanProgress = async (steps, explanation) => {
|
|
3295
|
+
latestPlan = steps?.length ? steps.map((entry) => ({ ...entry })) : void 0;
|
|
3296
|
+
latestPlanExplanation = explanation?.replace(/\s+/g, " ").trim() || void 0;
|
|
3297
|
+
if (!draftStream || previewToolProgressSuppressed) return;
|
|
3298
|
+
if (!progressDraftStreaming) {
|
|
3299
|
+
renderProgressDraft();
|
|
3300
|
+
return;
|
|
3301
|
+
}
|
|
3302
|
+
const alreadyStarted = progressDraftGate.hasStarted;
|
|
3303
|
+
await progressDraftGate.startNow();
|
|
3304
|
+
if (alreadyStarted && progressDraftGate.hasStarted) renderProgressDraft();
|
|
3305
|
+
};
|
|
3323
3306
|
const suppressPreviewToolProgressForAnswerText = (text) => {
|
|
3324
3307
|
if (!text?.trim()) return;
|
|
3325
3308
|
previewToolProgressSuppressed = true;
|
|
3326
3309
|
previewToolProgressLines = [];
|
|
3310
|
+
latestPlan = void 0;
|
|
3311
|
+
latestPlanExplanation = void 0;
|
|
3327
3312
|
};
|
|
3328
3313
|
const resetPreviewToolProgress = () => {
|
|
3329
3314
|
previewToolProgressSuppressed = false;
|
|
3330
3315
|
previewToolProgressLines = [];
|
|
3316
|
+
latestPlan = void 0;
|
|
3317
|
+
latestPlanExplanation = void 0;
|
|
3331
3318
|
};
|
|
3332
3319
|
const buildPreviewToolProgressReplyOptions = () => {
|
|
3333
3320
|
if (!shouldSuppressDefaultToolProgressMessages) return {};
|
|
@@ -3363,13 +3350,7 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3363
3350
|
},
|
|
3364
3351
|
onPlanUpdate: async (payload) => {
|
|
3365
3352
|
if (payload.phase !== "update") return;
|
|
3366
|
-
await
|
|
3367
|
-
event: "plan",
|
|
3368
|
-
phase: payload.phase,
|
|
3369
|
-
title: payload.title,
|
|
3370
|
-
explanation: payload.explanation,
|
|
3371
|
-
steps: payload.steps
|
|
3372
|
-
}));
|
|
3353
|
+
await pushPlanProgress(payload.planSteps, payload.explanation);
|
|
3373
3354
|
},
|
|
3374
3355
|
onApprovalEvent: async (payload) => {
|
|
3375
3356
|
if (payload.phase !== "requested") return;
|
|
@@ -3445,6 +3426,19 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3445
3426
|
currentDraftBlockOffset = 0;
|
|
3446
3427
|
latestDraftFullText = "";
|
|
3447
3428
|
};
|
|
3429
|
+
const resetDraftDeliveryState = async () => {
|
|
3430
|
+
await draftStream?.discardPending();
|
|
3431
|
+
draftStream?.reset();
|
|
3432
|
+
draftConsumed = false;
|
|
3433
|
+
currentDraftMessageGeneration = 0;
|
|
3434
|
+
currentDraftBlockOffset = 0;
|
|
3435
|
+
latestDraftFullText = "";
|
|
3436
|
+
pendingDraftBoundaries.length = 0;
|
|
3437
|
+
latestQueuedDraftBoundaryOffsets.clear();
|
|
3438
|
+
currentDraftReplyToId = draftReplyToId;
|
|
3439
|
+
progressDraftGate.reset();
|
|
3440
|
+
resetPreviewToolProgress();
|
|
3441
|
+
};
|
|
3448
3442
|
const { dispatcher, replyOptions, markDispatchIdle, markRunComplete } = core.channel.reply.createReplyDispatcherWithTyping({
|
|
3449
3443
|
...prefixOptions,
|
|
3450
3444
|
humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, _route.agentId),
|
|
@@ -3625,7 +3619,6 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3625
3619
|
});
|
|
3626
3620
|
},
|
|
3627
3621
|
onError: (err, info) => {
|
|
3628
|
-
if (err instanceof MatrixRetryableInboundError) retryableReplyDeliveryFailed = true;
|
|
3629
3622
|
if (info.kind === "final") finalReplyDeliveryFailed = true;
|
|
3630
3623
|
else nonFinalReplyDeliveryFailed = true;
|
|
3631
3624
|
if (info.kind === "block") advanceDraftBlockBoundary({ fallbackToLatestEnd: true });
|
|
@@ -3746,6 +3739,7 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3746
3739
|
resetDraftBlockOffsets();
|
|
3747
3740
|
resetPreviewToolProgress();
|
|
3748
3741
|
} : void 0,
|
|
3742
|
+
onQueuedFollowupAdmitted: draftStream ? resetDraftDeliveryState : void 0,
|
|
3749
3743
|
...buildPreviewToolProgressReplyOptions(),
|
|
3750
3744
|
onModelSelected
|
|
3751
3745
|
}
|
|
@@ -3767,19 +3761,11 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3767
3761
|
const { dispatchResult } = turnResult;
|
|
3768
3762
|
const { queuedFinal, counts } = dispatchResult;
|
|
3769
3763
|
if (finalReplyDeliveryFailed) {
|
|
3770
|
-
if (retryableReplyDeliveryFailed) {
|
|
3771
|
-
logVerboseMessage(`matrix: final reply delivery failed room=${roomId} id=${messageId}; leaving event uncommitted`);
|
|
3772
|
-
return;
|
|
3773
|
-
}
|
|
3774
3764
|
logVerboseMessage(`matrix: final reply delivery failed room=${roomId} id=${messageId}; keeping replay committed`);
|
|
3775
3765
|
await commitInboundEventIfClaimed();
|
|
3776
3766
|
return;
|
|
3777
3767
|
}
|
|
3778
3768
|
if (!queuedFinal && nonFinalReplyDeliveryFailed) {
|
|
3779
|
-
if (retryableReplyDeliveryFailed) {
|
|
3780
|
-
logVerboseMessage(`matrix: non-final reply delivery failed room=${roomId} id=${messageId}; leaving event uncommitted`);
|
|
3781
|
-
return;
|
|
3782
|
-
}
|
|
3783
3769
|
logVerboseMessage(`matrix: non-final reply delivery failed room=${roomId} id=${messageId}; keeping replay committed`);
|
|
3784
3770
|
await commitInboundEventIfClaimed();
|
|
3785
3771
|
return;
|
|
@@ -3802,225 +3788,8 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3802
3788
|
const draftEventId = await draftStreamRef.stop().catch(() => void 0);
|
|
3803
3789
|
if (draftEventId && !draftConsumed) await redactMatrixDraftEvent(client, roomId, draftEventId);
|
|
3804
3790
|
}
|
|
3805
|
-
|
|
3806
|
-
roomId,
|
|
3807
|
-
eventId
|
|
3808
|
-
});
|
|
3809
|
-
}
|
|
3810
|
-
};
|
|
3811
|
-
}
|
|
3812
|
-
//#endregion
|
|
3813
|
-
//#region extensions/matrix/src/matrix/monitor/inbound-dedupe.ts
|
|
3814
|
-
const INBOUND_DEDUPE_FILENAME = "inbound-dedupe.json";
|
|
3815
|
-
const INBOUND_DEDUPE_NAMESPACE = "inbound-dedupe";
|
|
3816
|
-
const INBOUND_DEDUPE_MIGRATIONS_NAMESPACE = "inbound-dedupe-migrations";
|
|
3817
|
-
const STORE_VERSION = 1;
|
|
3818
|
-
const DEFAULT_MAX_ENTRIES = 2e4;
|
|
3819
|
-
const DEFAULT_TTL_MS = 720 * 60 * 60 * 1e3;
|
|
3820
|
-
function normalizeEventPart(value) {
|
|
3821
|
-
return value.trim();
|
|
3822
|
-
}
|
|
3823
|
-
function buildEventKey(params) {
|
|
3824
|
-
const accountId = normalizeEventPart(params.auth.accountId) || "default";
|
|
3825
|
-
const roomId = normalizeEventPart(params.roomId);
|
|
3826
|
-
const eventId = normalizeEventPart(params.eventId);
|
|
3827
|
-
if (!roomId || !eventId) return "";
|
|
3828
|
-
return `${accountId}:${createHash("sha256").update(accountId).update("\0").update(roomId).update("\0").update(eventId).digest("hex")}`;
|
|
3829
|
-
}
|
|
3830
|
-
function resolveInboundDedupeStatePath(params) {
|
|
3831
|
-
return resolveMatrixStateFilePath({
|
|
3832
|
-
auth: params.auth,
|
|
3833
|
-
env: params.env,
|
|
3834
|
-
stateDir: params.stateDir,
|
|
3835
|
-
filename: INBOUND_DEDUPE_FILENAME
|
|
3836
|
-
});
|
|
3837
|
-
}
|
|
3838
|
-
function normalizeTimestamp(raw) {
|
|
3839
|
-
if (typeof raw !== "number" || !Number.isFinite(raw)) return null;
|
|
3840
|
-
return Math.max(0, Math.floor(raw));
|
|
3841
|
-
}
|
|
3842
|
-
function pruneSeenEvents(params) {
|
|
3843
|
-
const { seen, ttlMs, maxEntries, nowMs } = params;
|
|
3844
|
-
if (ttlMs > 0) {
|
|
3845
|
-
const cutoff = nowMs - ttlMs;
|
|
3846
|
-
for (const [key, ts] of seen) if (ts < cutoff) seen.delete(key);
|
|
3847
|
-
}
|
|
3848
|
-
const max = Math.max(0, Math.floor(maxEntries));
|
|
3849
|
-
if (max <= 0) {
|
|
3850
|
-
seen.clear();
|
|
3851
|
-
return;
|
|
3852
|
-
}
|
|
3853
|
-
while (seen.size > max) {
|
|
3854
|
-
const oldestKey = [...seen.entries()].toSorted((a, b) => a[1] - b[1] || a[0].localeCompare(b[0]))[0]?.[0];
|
|
3855
|
-
if (typeof oldestKey !== "string") break;
|
|
3856
|
-
seen.delete(oldestKey);
|
|
3857
|
-
}
|
|
3858
|
-
}
|
|
3859
|
-
function openMatrixInboundDedupeStoreOptions(params) {
|
|
3860
|
-
return {
|
|
3861
|
-
namespace: INBOUND_DEDUPE_NAMESPACE,
|
|
3862
|
-
maxEntries: DEFAULT_MAX_ENTRIES,
|
|
3863
|
-
env: resolveMatrixSqliteStateEnv(params)
|
|
3864
|
-
};
|
|
3865
|
-
}
|
|
3866
|
-
function createInboundDedupeStore(params) {
|
|
3867
|
-
return getMatrixRuntime().state.openKeyedStore(openMatrixInboundDedupeStoreOptions(params));
|
|
3868
|
-
}
|
|
3869
|
-
function createInboundDedupeMigrationStore(params) {
|
|
3870
|
-
return getMatrixRuntime().state.openKeyedStore({
|
|
3871
|
-
namespace: INBOUND_DEDUPE_MIGRATIONS_NAMESPACE,
|
|
3872
|
-
maxEntries: 1e3,
|
|
3873
|
-
env: resolveMatrixSqliteStateEnv(params)
|
|
3874
|
-
});
|
|
3875
|
-
}
|
|
3876
|
-
function buildLegacyImportKey(params) {
|
|
3877
|
-
const accountId = normalizeEventPart(params.auth.accountId) || "default";
|
|
3878
|
-
return `${accountId}:${createHash("sha256").update(accountId).update("\0").update(params.storagePath).digest("hex")}`;
|
|
3879
|
-
}
|
|
3880
|
-
async function loadLegacyEntries(storagePath) {
|
|
3881
|
-
const { value } = await readJsonFileWithFallback(storagePath, null);
|
|
3882
|
-
if (value?.version !== STORE_VERSION || !Array.isArray(value.entries)) return [];
|
|
3883
|
-
const entries = [];
|
|
3884
|
-
for (const entry of value.entries) {
|
|
3885
|
-
if (!entry || typeof entry.key !== "string") continue;
|
|
3886
|
-
const separatorIndex = entry.key.indexOf("|");
|
|
3887
|
-
if (separatorIndex <= 0) continue;
|
|
3888
|
-
const roomId = entry.key.slice(0, separatorIndex).trim();
|
|
3889
|
-
const eventId = entry.key.slice(separatorIndex + 1).trim();
|
|
3890
|
-
const ts = normalizeTimestamp(entry.ts);
|
|
3891
|
-
if (!roomId || !eventId || ts === null) continue;
|
|
3892
|
-
entries.push({
|
|
3893
|
-
roomId,
|
|
3894
|
-
eventId,
|
|
3895
|
-
ts
|
|
3896
|
-
});
|
|
3897
|
-
}
|
|
3898
|
-
return entries;
|
|
3899
|
-
}
|
|
3900
|
-
async function createMatrixInboundEventDeduper(params) {
|
|
3901
|
-
const nowMs = params.nowMs ?? (() => Date.now());
|
|
3902
|
-
const ttlMs = typeof params.ttlMs === "number" && Number.isFinite(params.ttlMs) ? Math.max(0, Math.floor(params.ttlMs)) : DEFAULT_TTL_MS;
|
|
3903
|
-
const maxEntries = typeof params.maxEntries === "number" && Number.isFinite(params.maxEntries) ? Math.max(0, Math.floor(params.maxEntries)) : DEFAULT_MAX_ENTRIES;
|
|
3904
|
-
const storagePath = params.storagePath ?? resolveInboundDedupeStatePath({
|
|
3905
|
-
auth: params.auth,
|
|
3906
|
-
env: params.env,
|
|
3907
|
-
stateDir: params.stateDir
|
|
3908
|
-
});
|
|
3909
|
-
const stateDir = params.stateDir ?? path.dirname(storagePath);
|
|
3910
|
-
const store = createInboundDedupeStore({
|
|
3911
|
-
env: params.env,
|
|
3912
|
-
stateDir
|
|
3913
|
-
});
|
|
3914
|
-
const migrationStore = createInboundDedupeMigrationStore({
|
|
3915
|
-
env: params.env,
|
|
3916
|
-
stateDir
|
|
3917
|
-
});
|
|
3918
|
-
const seen = /* @__PURE__ */ new Map();
|
|
3919
|
-
const pending = /* @__PURE__ */ new Set();
|
|
3920
|
-
try {
|
|
3921
|
-
for (const entry of await store.entries()) {
|
|
3922
|
-
const value = entry.value;
|
|
3923
|
-
const roomId = typeof value?.roomId === "string" ? value.roomId.trim() : "";
|
|
3924
|
-
const eventId = typeof value?.eventId === "string" ? value.eventId.trim() : "";
|
|
3925
|
-
const ts = normalizeTimestamp(value?.ts);
|
|
3926
|
-
const expectedKey = buildEventKey({
|
|
3927
|
-
auth: params.auth,
|
|
3928
|
-
roomId,
|
|
3929
|
-
eventId
|
|
3930
|
-
});
|
|
3931
|
-
if (expectedKey && expectedKey === entry.key && ts !== null) seen.set(entry.key, ts);
|
|
3932
|
-
}
|
|
3933
|
-
const legacyImportKey = buildLegacyImportKey({
|
|
3934
|
-
auth: params.auth,
|
|
3935
|
-
storagePath
|
|
3936
|
-
});
|
|
3937
|
-
if (!await migrationStore.lookup(legacyImportKey)) {
|
|
3938
|
-
const legacyEntries = await loadLegacyEntries(storagePath);
|
|
3939
|
-
let migratedLegacyEntries = 0;
|
|
3940
|
-
for (const entry of legacyEntries) {
|
|
3941
|
-
const key = buildEventKey({
|
|
3942
|
-
auth: params.auth,
|
|
3943
|
-
roomId: entry.roomId,
|
|
3944
|
-
eventId: entry.eventId
|
|
3945
|
-
});
|
|
3946
|
-
if (!key) continue;
|
|
3947
|
-
if (seen.has(key)) {
|
|
3948
|
-
migratedLegacyEntries += 1;
|
|
3949
|
-
continue;
|
|
3950
|
-
}
|
|
3951
|
-
seen.set(key, entry.ts);
|
|
3952
|
-
await store.register(key, entry, ttlMs > 0 ? { ttlMs } : void 0).then(() => {
|
|
3953
|
-
migratedLegacyEntries += 1;
|
|
3954
|
-
}).catch(() => {});
|
|
3955
|
-
}
|
|
3956
|
-
if (legacyEntries.length > 0 && migratedLegacyEntries === legacyEntries.length) {
|
|
3957
|
-
await migrationStore.register(legacyImportKey, { importedAt: nowMs() });
|
|
3958
|
-
await fs.rm(storagePath, { force: true }).catch(() => {});
|
|
3959
|
-
}
|
|
3791
|
+
inboundReplayClaim?.release();
|
|
3960
3792
|
}
|
|
3961
|
-
pruneSeenEvents({
|
|
3962
|
-
seen,
|
|
3963
|
-
ttlMs,
|
|
3964
|
-
maxEntries,
|
|
3965
|
-
nowMs: nowMs()
|
|
3966
|
-
});
|
|
3967
|
-
} catch (err) {
|
|
3968
|
-
LogService.warn("MatrixInboundDedupe", "Failed loading Matrix inbound dedupe store:", err);
|
|
3969
|
-
}
|
|
3970
|
-
return {
|
|
3971
|
-
claimEvent: ({ roomId, eventId }) => {
|
|
3972
|
-
const key = buildEventKey({
|
|
3973
|
-
auth: params.auth,
|
|
3974
|
-
roomId,
|
|
3975
|
-
eventId
|
|
3976
|
-
});
|
|
3977
|
-
if (!key) return true;
|
|
3978
|
-
pruneSeenEvents({
|
|
3979
|
-
seen,
|
|
3980
|
-
ttlMs,
|
|
3981
|
-
maxEntries,
|
|
3982
|
-
nowMs: nowMs()
|
|
3983
|
-
});
|
|
3984
|
-
if (seen.has(key) || pending.has(key)) return false;
|
|
3985
|
-
pending.add(key);
|
|
3986
|
-
return true;
|
|
3987
|
-
},
|
|
3988
|
-
commitEvent: async ({ roomId, eventId }) => {
|
|
3989
|
-
const key = buildEventKey({
|
|
3990
|
-
auth: params.auth,
|
|
3991
|
-
roomId,
|
|
3992
|
-
eventId
|
|
3993
|
-
});
|
|
3994
|
-
if (!key) return;
|
|
3995
|
-
pending.delete(key);
|
|
3996
|
-
const ts = nowMs();
|
|
3997
|
-
seen.delete(key);
|
|
3998
|
-
seen.set(key, ts);
|
|
3999
|
-
pruneSeenEvents({
|
|
4000
|
-
seen,
|
|
4001
|
-
ttlMs,
|
|
4002
|
-
maxEntries,
|
|
4003
|
-
nowMs: nowMs()
|
|
4004
|
-
});
|
|
4005
|
-
await store.register(key, {
|
|
4006
|
-
roomId: normalizeEventPart(roomId),
|
|
4007
|
-
eventId: normalizeEventPart(eventId),
|
|
4008
|
-
ts
|
|
4009
|
-
}, ttlMs > 0 ? { ttlMs } : void 0).catch((err) => {
|
|
4010
|
-
LogService.warn("MatrixInboundDedupe", "Failed persisting Matrix inbound dedupe entry:", err);
|
|
4011
|
-
});
|
|
4012
|
-
},
|
|
4013
|
-
releaseEvent: ({ roomId, eventId }) => {
|
|
4014
|
-
const key = buildEventKey({
|
|
4015
|
-
auth: params.auth,
|
|
4016
|
-
roomId,
|
|
4017
|
-
eventId
|
|
4018
|
-
});
|
|
4019
|
-
if (!key) return;
|
|
4020
|
-
pending.delete(key);
|
|
4021
|
-
},
|
|
4022
|
-
flush: async () => {},
|
|
4023
|
-
stop: async () => {}
|
|
4024
3793
|
};
|
|
4025
3794
|
}
|
|
4026
3795
|
//#endregion
|
|
@@ -4036,101 +3805,16 @@ function shouldPromoteRecentInviteRoom(params) {
|
|
|
4036
3805
|
}).matchSource === void 0;
|
|
4037
3806
|
}
|
|
4038
3807
|
//#endregion
|
|
4039
|
-
//#region extensions/matrix/src/matrix/monitor/room-info.ts
|
|
4040
|
-
const MAX_TRACKED_ROOM_INFO = 1024;
|
|
4041
|
-
const MAX_TRACKED_MEMBER_DISPLAY_NAMES = 4096;
|
|
4042
|
-
function rememberBounded(map, key, value, maxEntries) {
|
|
4043
|
-
map.set(key, value);
|
|
4044
|
-
if (map.size > maxEntries) {
|
|
4045
|
-
const oldest = map.keys().next().value;
|
|
4046
|
-
if (typeof oldest === "string") map.delete(oldest);
|
|
4047
|
-
}
|
|
4048
|
-
}
|
|
4049
|
-
function createMatrixRoomInfoResolver(client) {
|
|
4050
|
-
const roomNameCache = /* @__PURE__ */ new Map();
|
|
4051
|
-
const roomAliasCache = /* @__PURE__ */ new Map();
|
|
4052
|
-
const memberDisplayNameCache = /* @__PURE__ */ new Map();
|
|
4053
|
-
const getRoomName = async (roomId) => {
|
|
4054
|
-
if (roomNameCache.has(roomId)) return roomNameCache.get(roomId) ?? { nameResolved: false };
|
|
4055
|
-
let name;
|
|
4056
|
-
let nameResolved = false;
|
|
4057
|
-
try {
|
|
4058
|
-
const nameState = await client.getRoomStateEvent(roomId, "m.room.name", "");
|
|
4059
|
-
nameResolved = true;
|
|
4060
|
-
if (nameState && typeof nameState.name === "string") name = nameState.name;
|
|
4061
|
-
} catch (err) {
|
|
4062
|
-
if (isMatrixNotFoundError(err)) nameResolved = true;
|
|
4063
|
-
}
|
|
4064
|
-
const info = {
|
|
4065
|
-
name,
|
|
4066
|
-
nameResolved
|
|
4067
|
-
};
|
|
4068
|
-
if (nameResolved) rememberBounded(roomNameCache, roomId, info, MAX_TRACKED_ROOM_INFO);
|
|
4069
|
-
return info;
|
|
4070
|
-
};
|
|
4071
|
-
const getRoomAliases = async (roomId) => {
|
|
4072
|
-
const cached = roomAliasCache.get(roomId);
|
|
4073
|
-
if (cached) return cached;
|
|
4074
|
-
let canonicalAlias;
|
|
4075
|
-
let altAliases = [];
|
|
4076
|
-
let aliasesResolved = false;
|
|
4077
|
-
try {
|
|
4078
|
-
const aliasState = await client.getRoomStateEvent(roomId, "m.room.canonical_alias", "");
|
|
4079
|
-
aliasesResolved = true;
|
|
4080
|
-
if (aliasState && typeof aliasState.alias === "string") canonicalAlias = aliasState.alias;
|
|
4081
|
-
const rawAliases = aliasState?.alt_aliases;
|
|
4082
|
-
if (Array.isArray(rawAliases)) altAliases = rawAliases.filter((entry) => typeof entry === "string");
|
|
4083
|
-
} catch (err) {
|
|
4084
|
-
if (isMatrixNotFoundError(err)) aliasesResolved = true;
|
|
4085
|
-
}
|
|
4086
|
-
const info = {
|
|
4087
|
-
canonicalAlias,
|
|
4088
|
-
altAliases,
|
|
4089
|
-
aliasesResolved
|
|
4090
|
-
};
|
|
4091
|
-
if (aliasesResolved) rememberBounded(roomAliasCache, roomId, info, MAX_TRACKED_ROOM_INFO);
|
|
4092
|
-
return info;
|
|
4093
|
-
};
|
|
4094
|
-
const getRoomInfo = async (roomId, opts = {}) => {
|
|
4095
|
-
const { name, nameResolved } = await getRoomName(roomId);
|
|
4096
|
-
if (!opts.includeAliases) return {
|
|
4097
|
-
name,
|
|
4098
|
-
altAliases: [],
|
|
4099
|
-
nameResolved,
|
|
4100
|
-
aliasesResolved: false
|
|
4101
|
-
};
|
|
4102
|
-
return {
|
|
4103
|
-
name,
|
|
4104
|
-
nameResolved,
|
|
4105
|
-
...await getRoomAliases(roomId)
|
|
4106
|
-
};
|
|
4107
|
-
};
|
|
4108
|
-
const getMemberDisplayName = async (roomId, userId) => {
|
|
4109
|
-
const cacheKey = `${roomId}:${userId}`;
|
|
4110
|
-
if (memberDisplayNameCache.has(cacheKey)) return memberDisplayNameCache.get(cacheKey) ?? userId;
|
|
4111
|
-
const memberState = await client.getRoomStateEvent(roomId, "m.room.member", userId).catch(() => null);
|
|
4112
|
-
const displayName = memberState && typeof memberState.displayname === "string" ? memberState.displayname : userId;
|
|
4113
|
-
rememberBounded(memberDisplayNameCache, cacheKey, displayName, MAX_TRACKED_MEMBER_DISPLAY_NAMES);
|
|
4114
|
-
return displayName;
|
|
4115
|
-
};
|
|
4116
|
-
return {
|
|
4117
|
-
getRoomInfo,
|
|
4118
|
-
getMemberDisplayName
|
|
4119
|
-
};
|
|
4120
|
-
}
|
|
4121
|
-
//#endregion
|
|
4122
3808
|
//#region extensions/matrix/src/matrix/monitor/startup.ts
|
|
4123
3809
|
const loadMatrixStartupMaintenanceDeps = createLazyRuntimeModule(() => Promise.all([
|
|
4124
|
-
import("./setup-core-
|
|
3810
|
+
import("./setup-core-CYQRY2oG.js").then((n) => n.s),
|
|
4125
3811
|
import("./device-health-D4LBxuPq.js"),
|
|
4126
|
-
import("./setup-core-
|
|
4127
|
-
import("./
|
|
4128
|
-
|
|
4129
|
-
]).then(([configUpdateModule, deviceHealthModule, profileModule, legacyCryptoRestoreModule, startupVerificationModule]) => ({
|
|
3812
|
+
import("./setup-core-CYQRY2oG.js").then((n) => n.a),
|
|
3813
|
+
import("./startup-verification-DSiyDKM5.js")
|
|
3814
|
+
]).then(([configUpdateModule, deviceHealthModule, profileModule, startupVerificationModule]) => ({
|
|
4130
3815
|
updateMatrixAccountConfig: configUpdateModule.updateMatrixAccountConfig,
|
|
4131
3816
|
summarizeMatrixDeviceHealth: deviceHealthModule.summarizeMatrixDeviceHealth,
|
|
4132
3817
|
syncMatrixOwnProfile: profileModule.syncMatrixOwnProfile,
|
|
4133
|
-
maybeRestoreLegacyMatrixBackup: legacyCryptoRestoreModule.maybeRestoreLegacyMatrixBackup,
|
|
4134
3818
|
ensureMatrixStartupVerification: startupVerificationModule.ensureMatrixStartupVerification
|
|
4135
3819
|
})));
|
|
4136
3820
|
async function runMatrixStartupMaintenance(params, deps) {
|
|
@@ -4187,25 +3871,6 @@ async function runMatrixStartupMaintenance(params, deps) {
|
|
|
4187
3871
|
if (isMatrixStartupAbortError(err)) throw err;
|
|
4188
3872
|
params.logger.debug?.("Failed to resolve matrix verification status (non-fatal)", { error: String(err) });
|
|
4189
3873
|
}
|
|
4190
|
-
try {
|
|
4191
|
-
throwIfMatrixStartupAborted(params.abortSignal);
|
|
4192
|
-
const legacyCryptoRestore = await runtimeDeps.maybeRestoreLegacyMatrixBackup({
|
|
4193
|
-
client: params.client,
|
|
4194
|
-
auth: params.auth,
|
|
4195
|
-
env: params.env
|
|
4196
|
-
});
|
|
4197
|
-
throwIfMatrixStartupAborted(params.abortSignal);
|
|
4198
|
-
if (legacyCryptoRestore.kind === "restored") {
|
|
4199
|
-
params.logger.info(`matrix: restored ${legacyCryptoRestore.imported}/${legacyCryptoRestore.total} room key(s) from legacy encrypted-state backup`);
|
|
4200
|
-
if (legacyCryptoRestore.localOnlyKeys > 0) params.logger.warn(`matrix: ${legacyCryptoRestore.localOnlyKeys} legacy local-only room key(s) were never backed up and could not be restored automatically`);
|
|
4201
|
-
} else if (legacyCryptoRestore.kind === "failed") {
|
|
4202
|
-
params.logger.warn(`matrix: failed restoring room keys from legacy encrypted-state backup: ${legacyCryptoRestore.error}`);
|
|
4203
|
-
if (legacyCryptoRestore.localOnlyKeys > 0) params.logger.warn(`matrix: ${legacyCryptoRestore.localOnlyKeys} legacy local-only room key(s) were never backed up and may remain unavailable until manually recovered`);
|
|
4204
|
-
}
|
|
4205
|
-
} catch (err) {
|
|
4206
|
-
if (isMatrixStartupAbortError(err)) throw err;
|
|
4207
|
-
params.logger.warn("matrix: failed restoring legacy encrypted-state backup", { error: String(err) });
|
|
4208
|
-
}
|
|
4209
3874
|
}
|
|
4210
3875
|
//#endregion
|
|
4211
3876
|
//#region extensions/matrix/src/matrix/monitor/status.ts
|
|
@@ -4478,7 +4143,6 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4478
4143
|
let cleanedUp = false;
|
|
4479
4144
|
let client = null;
|
|
4480
4145
|
let threadBindingManager = null;
|
|
4481
|
-
let inboundDeduper = null;
|
|
4482
4146
|
const monitorTaskRunner = createMatrixMonitorTaskRunner({
|
|
4483
4147
|
logger,
|
|
4484
4148
|
logVerboseMessage
|
|
@@ -4492,7 +4156,6 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4492
4156
|
if (client && mode === "persist") await client.drainPendingDecryptions("matrix monitor shutdown");
|
|
4493
4157
|
if (mode === "persist") await monitorTaskRunner.waitForIdle();
|
|
4494
4158
|
threadBindingManager?.stop();
|
|
4495
|
-
await inboundDeduper?.stop();
|
|
4496
4159
|
if (client) await releaseSharedClientInstance(client, mode);
|
|
4497
4160
|
} finally {
|
|
4498
4161
|
client?.off("sync.state", onSyncState);
|
|
@@ -4540,7 +4203,7 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4540
4203
|
const mediaMaxBytes = Math.max(1, mediaMaxMb) * 1024 * 1024;
|
|
4541
4204
|
const streaming = resolveMatrixStreamingMode(accountConfig.streaming);
|
|
4542
4205
|
const previewToolProgressEnabled = resolveMatrixPreviewToolProgressEnabled(accountConfig.streaming);
|
|
4543
|
-
const blockStreamingEnabled = accountConfig
|
|
4206
|
+
const blockStreamingEnabled = resolveChannelStreamingBlockEnabled(accountConfig) === true;
|
|
4544
4207
|
const startupMs = Date.now();
|
|
4545
4208
|
const startupGraceMs = 0;
|
|
4546
4209
|
const warnedEncryptedRooms = /* @__PURE__ */ new Set();
|
|
@@ -4564,7 +4227,7 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4564
4227
|
accountId: auth.accountId
|
|
4565
4228
|
});
|
|
4566
4229
|
setActiveMatrixClient(client, auth.accountId);
|
|
4567
|
-
inboundDeduper =
|
|
4230
|
+
const inboundDeduper = createMatrixInboundEventDeduper({
|
|
4568
4231
|
auth,
|
|
4569
4232
|
env: process.env
|
|
4570
4233
|
});
|