@openclaw/matrix 2026.7.2-beta.7 → 2026.8.1-beta.3
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-kqquRzCf.js → account-selection-CWuhuFn1.js} +7 -8
- package/dist/{accounts-DfngqebB.js → accounts-BCzyubQt.js} +3 -3
- package/dist/api.js +8 -11
- package/dist/{approval-handler.runtime-DSeaIsGa.js → approval-handler.runtime-CSvueU9P.js} +7 -6
- package/dist/{approval-ids-BdJGPAJT.js → approval-ids-CEcf-EiM.js} +1 -1
- package/dist/{approval-reaction-auth-BjOpELxu.js → approval-reaction-auth-CziKXatm.js} +2 -2
- package/dist/{approval-reactions-D-BxBK_L.js → approval-reactions-tXh9KYrW.js} +2 -8
- package/dist/auth-presence.js +2 -2
- package/dist/{channel-vj788dNZ.js → channel-CzQw5OZN.js} +376 -148
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CLoF2S9T.js → channel.runtime-I9pBRQb3.js} +79 -55
- package/dist/{config-schema-Djxw3C6b.js → channel.setup-aNaa3Uyn.js} +51 -10
- package/dist/{cli-DMqfDE-q.js → cli-iR6QJ5U0.js} +16 -16
- package/dist/{cli-metadata-C7D53SND.js → cli-metadata-BmUYWjuM.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-BBQdBG7t.js +799 -0
- package/dist/{client-6eRENr7k.js → client-D8XghqmX.js} +4 -4
- package/dist/{client-bootstrap-XsIkHNt0.js → client-bootstrap-Co3RlItb.js} +25 -61
- package/dist/client-support-DLj4vDeu.js +93 -0
- package/dist/config-update-Bor_Pjsv.js +150 -0
- package/dist/contract-api.js +2 -2
- package/dist/{credentials-W2EmwRhu.js → credentials-BdAaWuiR.js} +2 -1
- package/dist/credentials-read-B37cQknZ.js +51 -0
- package/dist/credentials-state-B3cuUFwZ.js +27 -0
- package/dist/{credentials-write.runtime-Be9zNSUw.js → credentials-write.runtime-nAV2-5uR.js} +1 -1
- package/dist/{crypto-runtime-D9_6J5tZ.js → crypto-runtime-Bnz3zEcS.js} +55 -32
- package/dist/direct-room-RinHjtqX.js +71 -0
- package/dist/{directory-live-C8dVBiCc.js → directory-live-DLQzel12.js} +2 -3
- package/dist/{doctor-CM8ijNpW.js → doctor-EWf9CDso.js} +2 -2
- package/dist/{doctor-contract-BMSJkkAE.js → doctor-contract-DEt4O4Zt.js} +2 -3
- package/dist/doctor-contract-api.js +209 -91
- package/dist/{draft-stream-CtvOXq0Z.js → draft-stream-DQ7QNC-l.js} +20 -23
- package/dist/{encryption-guidance-CbEFe38F.js → encryption-guidance-DmLY8NiO.js} +1 -1
- package/dist/{env-auth-CQsYbz-p.js → env-auth-MVS-Vv41.js} +4 -3
- package/dist/{env-vars-B0NxQnPk.js → env-vars-dGqak9dN.js} +1 -1
- package/dist/{errors-C47hvAF8.js → errors-DKVS3_DO.js} +2 -5
- package/dist/{file-sync-store-DiiFsayX.js → file-sync-store-DjskBX2o.js} +24 -3
- package/dist/helper-api.js +2 -2
- package/dist/{idb-persistence-B6x7dMsF.js → idb-persistence-BM0P27Zg.js} +3 -2
- package/dist/{inbound-dedupe-CaBLblef.js → inbound-dedupe-RvSLqdsz.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{logger-D0GCSDQq.js → logger-B_71hN6W.js} +1 -1
- package/dist/{logging-DV-p52N0.js → logging-DRjvUOIh.js} +1 -1
- package/dist/{media-text-BTwzADS_.js → media-text-Dh-DpTc3.js} +4 -1
- package/dist/{messages-DxQJkhxs.js → messages-DEqg7HVy.js} +31 -11
- package/dist/{monitor-VyWlSLwo.js → monitor-FNrfkuWL.js} +413 -405
- package/dist/plugin-entry.handlers.runtime.js +3 -3
- package/dist/probe.runtime-NIJZYqc2.js +2 -0
- package/dist/profile-D-Wubo0A.js +108 -0
- package/dist/{profile-update-CffmyW_4.js → profile-update-BQlE5s2J.js} +3 -2
- package/dist/{reaction-events-B00WSi98.js → reaction-events-BKOLlnCo.js} +10 -7
- package/dist/{recovery-key-store-BNnHvXdk.js → recovery-key-store-CognuDys.js} +5 -4
- package/dist/{resolve-targets-nm2L48sh.js → resolve-targets-e7AI0P75.js} +2 -2
- package/dist/{resolver.runtime-DS6uPaEe.js → resolver.runtime-V8u0pHEb.js} +1 -1
- package/dist/{room-info-CAFZ3Z9J.js → room-info-BXQA7y10.js} +12 -3
- package/dist/runtime-api.js +7 -4
- package/dist/{sdk-bUytQHx7.js → sdk-NxK3vzMa.js} +242 -119
- package/dist/{secret-contract-M3hRmGO-.js → secret-contract-CufozuyJ.js} +1 -1
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-BldGYG8g.js → send-ClHgDZLT.js} +1477 -1210
- package/dist/session-binding-contract-api.js +2 -3
- package/dist/{setup-bootstrap-Deleiibz.js → setup-bootstrap-BGPjbA5N.js} +4 -4
- package/dist/{setup-core-BVfBv2ai.js → setup-core-DigrLebY.js} +17 -266
- package/dist/setup-plugin-api.js +1 -44
- package/dist/{setup-surface-BBq3WeqX.js → setup-surface-Dtn8sAWs.js} +15 -16
- package/dist/{startup-verification-wm3_i88s.js → startup-verification-Cs08ca8u.js} +3 -3
- package/dist/{storage-BvAkgzvT.js → storage-BsGuHngK.js} +3 -3
- package/dist/subagent-hooks-CMoZaARG.js +48 -0
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{target-ids-B-5aQxwn.js → target-ids-Nwx7cMVE.js} +11 -1
- package/dist/{thread-binding-api-DRbBZlhS.js → thread-binding-api-CzkeLZCU.js} +1 -1
- package/dist/thread-binding-api.js +1 -1
- package/dist/{thread-bindings-DGbl3vDW.js → thread-bindings-BYEGfw3h.js} +17 -10
- package/dist/thread-bindings-runtime.js +1 -1
- package/dist/{thread-bindings-shared-CKnY4LSd.js → thread-bindings-shared-oNPiyMWY.js} +1 -6
- package/dist/{tool-actions.runtime-uu9blSqO.js → tool-actions.runtime-ck6IJyP0.js} +36 -19
- package/dist/{verification-DYMQ1QpI.js → verification-CabtBTtB.js} +2 -2
- package/openclaw.plugin.json +61 -1
- package/package.json +4 -4
- package/dist/active-client-DXvz2gCo.js +0 -20
- package/dist/client-Dbso3-0V.js +0 -30
- package/dist/create-client-BmSU-q-D.js +0 -61
- package/dist/credentials-read-DVmFCm7X.js +0 -77
- package/dist/exec-approval-resolver-BCgqRtZS.js +0 -16
- package/dist/preflight-audio.runtime-BZxxQsxY.js +0 -11
- package/dist/probe.runtime-BuieqmS3.js +0 -3
- package/dist/record-shared-CWWx6fvI.js +0 -2
- package/dist/route-DY6at4qJ.js +0 -161
- package/dist/shared-CUMWxcMz.js +0 -673
- package/dist/subagent-hooks-dkPAF6Et.js +0 -143
- package/dist/sync-state-CWbp0QSY.js +0 -12
- package/dist/{runtime-api-D1xI_cvh.js → runtime-api-BGO16Fu8.js} +3 -3
|
@@ -1,51 +1,49 @@
|
|
|
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 { n as resolveConfiguredMatrixBotUserIds } from "./accounts-
|
|
4
|
-
import { a as
|
|
5
|
-
import { a as normalizeMatrixUserId, i as normalizeMatrixAllowList, o as resolveMatrixAllowListMatch } from "./
|
|
6
|
-
import { t as isMatrixQualifiedUserId } from "./target-ids-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { t as createMatrixThreadBindingManager } from "./thread-bindings-
|
|
10
|
-
import { i as
|
|
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-BTwzADS_.js";
|
|
12
|
-
import { n as setActiveMatrixClient } from "./active-client-DXvz2gCo.js";
|
|
3
|
+
import { n as resolveConfiguredMatrixBotUserIds } from "./accounts-BCzyubQt.js";
|
|
4
|
+
import { _ as logInboundDrop, a as resolveMatrixThreadRootId, b as summarizeMapping, c as RelationType, d as buildAllowlistResolutionSummary, f as canonicalizeAllowlistWithResolvedIds, g as getAgentScopedMediaLocalRoots, h as formatLocationText, i as resolveMatrixReplyToEventId, l as resolveMatrixRoomConfig, m as createTypingCallbacks, n as resolveMatrixStoredSessionMeta, o as resolveMatrixThreadRouting, p as createReplyPrefixOptions, r as resolveMatrixInboundRoute, s as EventType, u as addAllowlistUserEntriesFromConfigEntry, v as logTypingFailure, x as toLocationContext, y as patchAllowlistUsersInConfigEntries } from "./channel-CzQw5OZN.js";
|
|
5
|
+
import { a as normalizeMatrixUserId, i as normalizeMatrixAllowList, o as resolveMatrixAllowListMatch } from "./channel.setup-aNaa3Uyn.js";
|
|
6
|
+
import { n as isMatrixRoomId, t as isMatrixQualifiedUserId } from "./target-ids-Nwx7cMVE.js";
|
|
7
|
+
import { C as promoteMatrixDirectRoomCandidate, T as MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY, _ as parsePollStartContent, c as chunkMatrixText, f as formatPollAsText, h as isPollStartType, m as isPollEventType, r as sendMessageMatrix } from "./send-ClHgDZLT.js";
|
|
8
|
+
import { i as isStrictDirectMembership, n as hasDirectMatrixMemberFlag, o as readJoinedMatrixMembers } from "./direct-room-RinHjtqX.js";
|
|
9
|
+
import { t as createMatrixThreadBindingManager } from "./thread-bindings-BYEGfw3h.js";
|
|
10
|
+
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-Dh-DpTc3.js";
|
|
13
11
|
import { t as isBunRuntime } from "./runtime-BefyhPWv.js";
|
|
14
|
-
import {
|
|
15
|
-
import "./client-Dbso3-0V.js";
|
|
12
|
+
import { a as throwIfMatrixStartupAborted, c as resolveMatrixAuth, i as isMatrixStartupAbortError, l as resolveMatrixAuthContext, n as acquireSharedMatrixClient, s as backfillMatrixAuthDeviceIdAfterStartup } from "./client-BBQdBG7t.js";
|
|
16
13
|
import { i as isMatrixMediaSizeLimitError, r as MatrixMediaSizeLimitError } from "./http-client-CycYxU9-.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-
|
|
18
|
-
import { t as resolveMatrixTargets } from "./resolve-targets-
|
|
19
|
-
import { t as formatMatrixEncryptedEventDisabledWarning } from "./encryption-guidance-
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
14
|
+
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-BGO16Fu8.js";
|
|
15
|
+
import { t as resolveMatrixTargets } from "./resolve-targets-e7AI0P75.js";
|
|
16
|
+
import { t as formatMatrixEncryptedEventDisabledWarning } from "./encryption-guidance-DmLY8NiO.js";
|
|
17
|
+
import { createMatrixInboundEventDeduper } from "./inbound-dedupe-RvSLqdsz.js";
|
|
18
|
+
import { a as isMatrixAccessTokenInvalidatedError, d as isMatrixDisconnectedSyncState, f as isMatrixReadySyncState, p as isMatrixTerminalSyncState } from "./client-support-DLj4vDeu.js";
|
|
19
|
+
import { n as setBoundedMap, t as createMatrixRoomInfoResolver } from "./room-info-BXQA7y10.js";
|
|
23
20
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
24
|
-
import { buildChannelProgressDraftLineForEntry,
|
|
21
|
+
import { buildChannelProgressDraftLineForEntry, createChannelProgressDraftCompositor, createMessageReceiptFromOutboundResults, createPreviewMessageReceipt, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, formatChannelProgressDraftLine, formatChannelProgressDraftText, listMessageReceiptPlatformIds, resolveChannelStreamingBlockEnabled, waitUntilAbort } from "openclaw/plugin-sdk/channel-outbound";
|
|
25
22
|
import { normalizeLowercaseStringOrEmpty, normalizeNullableString, normalizeOptionalString, normalizeStringifiedEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
26
23
|
import { stripReasoningTagsFromText } from "openclaw/plugin-sdk/text-chunking";
|
|
27
24
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
25
|
+
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
26
|
+
import { isFutureDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
|
28
27
|
import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
29
|
-
import {
|
|
28
|
+
import { createChannelInboundEnvelopeBuilder, createChannelPartialDeliveryError, hasFinalInboundReplyDispatch, isChannelPartialDeliveryError, resolveInboundMentionDecision, resolveInboundReplyDispatchCounts, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
|
|
30
29
|
import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
31
|
-
import { isFutureDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
|
32
|
-
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
|
|
33
30
|
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
34
31
|
import { format } from "node:util";
|
|
35
|
-
import {
|
|
32
|
+
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
|
36
33
|
import { escapeRegExp, sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
37
34
|
import { buildTtsSupplementMediaPayload, getReplyPayloadTtsSupplement } from "openclaw/plugin-sdk/reply-payload";
|
|
38
35
|
import { resolveAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
39
36
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
40
37
|
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
41
38
|
import { createChannelIngressResolver, defineStableChannelIngressIdentity } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
39
|
+
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
|
|
42
40
|
import { evaluateSupplementalContextVisibility, resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
|
|
43
41
|
import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
|
|
44
|
-
import {
|
|
42
|
+
import { createChannelPreflightAudio, formatAudioTranscriptForAgent } from "openclaw/plugin-sdk/media-understanding-runtime";
|
|
45
43
|
import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
|
|
46
44
|
import { buildInboundHistoryFromEntries } from "openclaw/plugin-sdk/reply-history";
|
|
47
45
|
import { decodeHtmlEntities } from "openclaw/plugin-sdk/html-entity-runtime";
|
|
48
|
-
import {
|
|
46
|
+
import { channelBlockedPatch, channelReadyPatch, channelStoppedPatch, createTransportActivityStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
49
47
|
//#region extensions/matrix/src/matrix/monitor/auto-join.ts
|
|
50
48
|
function registerMatrixAutoJoin(params) {
|
|
51
49
|
const { client, accountConfig, runtime } = params;
|
|
@@ -60,7 +58,7 @@ function registerMatrixAutoJoin(params) {
|
|
|
60
58
|
const allowedRoomIds = new Set(rawAllowlist.filter((entry) => entry.startsWith("!")));
|
|
61
59
|
const allowedAliases = rawAllowlist.filter((entry) => entry.startsWith("#"));
|
|
62
60
|
const resolvedAliasRoomIds = /* @__PURE__ */ new Map();
|
|
63
|
-
if (autoJoin === "off") return;
|
|
61
|
+
if (autoJoin === "off") return () => {};
|
|
64
62
|
if (autoJoin === "always") logVerbose("matrix: auto-join enabled for all invites");
|
|
65
63
|
else logVerbose("matrix: auto-join enabled for allowlist invites");
|
|
66
64
|
const resolveAllowedAliasRoomId = async (alias) => {
|
|
@@ -79,13 +77,8 @@ function registerMatrixAutoJoin(params) {
|
|
|
79
77
|
}
|
|
80
78
|
}))).filter((roomId) => Boolean(roomId));
|
|
81
79
|
};
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
runtime.error?.(`matrix: auto-join invite handler failed for room ${roomId}: ${String(err)}`);
|
|
85
|
-
});
|
|
86
|
-
};
|
|
87
|
-
client.on("room.invite", (roomId, _inviteEvent) => {
|
|
88
|
-
runInviteTask(roomId, async () => {
|
|
80
|
+
const onInvite = (roomId, _inviteEvent) => {
|
|
81
|
+
params.runDetachedTask(`auto-join invite handler room=${roomId}`, async () => {
|
|
89
82
|
if (autoJoin === "allowlist") {
|
|
90
83
|
const allowedAliasRoomIds = await resolveAllowedAliasRoomIds();
|
|
91
84
|
if (!(autoJoinAllowlist.has("*") || allowedRoomIds.has(roomId) || allowedAliasRoomIds.some((resolvedRoomId) => resolvedRoomId === roomId))) {
|
|
@@ -100,7 +93,11 @@ function registerMatrixAutoJoin(params) {
|
|
|
100
93
|
runtime.error?.(`matrix: failed to join room ${roomId}: ${String(err)}`);
|
|
101
94
|
}
|
|
102
95
|
});
|
|
103
|
-
}
|
|
96
|
+
};
|
|
97
|
+
client.on("room.invite", onInvite);
|
|
98
|
+
return () => {
|
|
99
|
+
client.off("room.invite", onInvite);
|
|
100
|
+
};
|
|
104
101
|
}
|
|
105
102
|
//#endregion
|
|
106
103
|
//#region extensions/matrix/src/matrix/monitor/config.ts
|
|
@@ -155,7 +152,7 @@ function isMatrixDangerousNameMatchingEnabled(params) {
|
|
|
155
152
|
function addUniqueMatrixAllowlistEntry(params) {
|
|
156
153
|
const trimmed = params.entry.trim();
|
|
157
154
|
if (!trimmed) return;
|
|
158
|
-
const key = trimmed
|
|
155
|
+
const key = normalizeMatrixUserId(trimmed);
|
|
159
156
|
if (params.seen.has(key)) return;
|
|
160
157
|
params.seen.add(key);
|
|
161
158
|
params.entries.push(trimmed);
|
|
@@ -188,7 +185,8 @@ function resolveStableMatrixMonitorUserAllowlist(params) {
|
|
|
188
185
|
const resolution = resolveStableMatrixMonitorUserEntries(allowList);
|
|
189
186
|
const canonicalized = canonicalizeAllowlistWithResolvedIds({
|
|
190
187
|
existing: allowList,
|
|
191
|
-
resolvedMap: resolution.resolvedMap
|
|
188
|
+
resolvedMap: resolution.resolvedMap,
|
|
189
|
+
entryKey: normalizeMatrixUserId
|
|
192
190
|
});
|
|
193
191
|
logStableMatrixAllowlistUnresolved({
|
|
194
192
|
label: params.label,
|
|
@@ -265,7 +263,8 @@ async function resolveMatrixMonitorUserAllowlist(params) {
|
|
|
265
263
|
});
|
|
266
264
|
const canonicalized = canonicalizeAllowlistWithResolvedIds({
|
|
267
265
|
existing: allowList,
|
|
268
|
-
resolvedMap: resolution.resolvedMap
|
|
266
|
+
resolvedMap: resolution.resolvedMap,
|
|
267
|
+
entryKey: normalizeMatrixUserId
|
|
269
268
|
});
|
|
270
269
|
summarizeMapping(params.label, resolution.mapping, resolution.unresolved, params.runtime);
|
|
271
270
|
if (resolution.unresolved.length > 0) params.runtime.log?.(`${params.label} entries must be full Matrix IDs (example: @user:server). Unresolved entries will not match any sender.`);
|
|
@@ -334,7 +333,8 @@ async function resolveMatrixMonitorLiveUserAllowlist(params) {
|
|
|
334
333
|
entries: pending,
|
|
335
334
|
runtime: params.runtime,
|
|
336
335
|
resolveTargets: params.resolveTargets ?? resolveMatrixTargets
|
|
337
|
-
})).resolvedMap
|
|
336
|
+
})).resolvedMap,
|
|
337
|
+
entryKey: normalizeMatrixUserId
|
|
338
338
|
});
|
|
339
339
|
const resolvedEntries = params.failClosedOnUnresolved ? filterFailClosedMatrixAllowlistEntries(canonicalized) : filterResolvedMatrixAllowlistEntries(canonicalized);
|
|
340
340
|
for (const entry of resolvedEntries) addUniqueMatrixAllowlistEntry({
|
|
@@ -365,7 +365,7 @@ async function resolveMatrixMonitorRoomsConfig(params) {
|
|
|
365
365
|
unresolved.push(entry);
|
|
366
366
|
continue;
|
|
367
367
|
}
|
|
368
|
-
if (
|
|
368
|
+
if (isMatrixRoomId(cleaned)) {
|
|
369
369
|
if (!nextRooms[cleaned]) nextRooms[cleaned] = roomConfig;
|
|
370
370
|
if (cleaned !== input) mapping.push(`${input}→${cleaned}`);
|
|
371
371
|
continue;
|
|
@@ -396,7 +396,7 @@ async function resolveMatrixMonitorRoomsConfig(params) {
|
|
|
396
396
|
} else unresolved.push(source.input);
|
|
397
397
|
});
|
|
398
398
|
summarizeMapping("matrix rooms", mapping, unresolved, params.runtime);
|
|
399
|
-
if (unresolved.length > 0) params.runtime.log?.("matrix rooms must be room IDs or aliases (example: !room:server or #alias:server). Unresolved entries are ignored.");
|
|
399
|
+
if (unresolved.length > 0) params.runtime.log?.("matrix rooms must be room IDs or aliases (example: !room:server, the suffixless !room form on room version 12+, or #alias:server). Unresolved entries are ignored.");
|
|
400
400
|
const roomUsers = /* @__PURE__ */ new Set();
|
|
401
401
|
for (const roomConfig of Object.values(nextRooms)) addAllowlistUserEntriesFromConfigEntry(roomUsers, roomConfig);
|
|
402
402
|
if (roomUsers.size === 0) return nextRooms;
|
|
@@ -410,7 +410,8 @@ async function resolveMatrixMonitorRoomsConfig(params) {
|
|
|
410
410
|
return patchAllowlistUsersInConfigEntries({
|
|
411
411
|
entries: nextRooms,
|
|
412
412
|
resolvedMap: resolution.resolvedMap,
|
|
413
|
-
strategy: "canonicalize"
|
|
413
|
+
strategy: "canonicalize",
|
|
414
|
+
entryKey: normalizeMatrixUserId
|
|
414
415
|
});
|
|
415
416
|
}
|
|
416
417
|
const resolution = await resolveMatrixMonitorUserEntries({
|
|
@@ -425,7 +426,8 @@ async function resolveMatrixMonitorRoomsConfig(params) {
|
|
|
425
426
|
return patchAllowlistUsersInConfigEntries({
|
|
426
427
|
entries: nextRooms,
|
|
427
428
|
resolvedMap: resolution.resolvedMap,
|
|
428
|
-
strategy: "canonicalize"
|
|
429
|
+
strategy: "canonicalize",
|
|
430
|
+
entryKey: normalizeMatrixUserId
|
|
429
431
|
});
|
|
430
432
|
}
|
|
431
433
|
async function resolveMatrixMonitorConfig(params) {
|
|
@@ -719,34 +721,38 @@ async function resolveMatrixMonitorAccessState(params) {
|
|
|
719
721
|
});
|
|
720
722
|
const accountId = params.accountId ?? "default";
|
|
721
723
|
const eventKind = params.eventKind ?? "message";
|
|
724
|
+
const ingress = createChannelIngressResolver({
|
|
725
|
+
channelId: "matrix",
|
|
726
|
+
accountId,
|
|
727
|
+
identity: matrixIngressIdentity,
|
|
728
|
+
readStoreAllowFrom: async () => params.storeAllowFrom
|
|
729
|
+
});
|
|
730
|
+
const resolveMessageIngress = async (contextBinding, conversation) => await ingress.message({
|
|
731
|
+
subject: { stableId: params.senderId },
|
|
732
|
+
conversation: conversation ?? {
|
|
733
|
+
kind: params.isRoom ? "channel" : "direct",
|
|
734
|
+
id: params.conversationId ?? (params.isRoom ? "matrix-room" : "matrix-dm")
|
|
735
|
+
},
|
|
736
|
+
...contextBinding ? { contextBinding } : {},
|
|
737
|
+
event: {
|
|
738
|
+
kind: eventKind,
|
|
739
|
+
authMode: "inbound",
|
|
740
|
+
mayPair: params.isRoom ? false : eventKind === "message"
|
|
741
|
+
},
|
|
742
|
+
dmPolicy,
|
|
743
|
+
groupPolicy: params.isRoom ? groupIngress.groupPolicy : "disabled",
|
|
744
|
+
policy: { groupAllowFromFallbackToAllowFrom: false },
|
|
745
|
+
allowFrom: params.allowFrom,
|
|
746
|
+
...params.isRoom ? { groupAllowFrom: groupIngress.groupAllowFrom } : {}
|
|
747
|
+
});
|
|
722
748
|
return {
|
|
723
749
|
effectiveGroupAllowFrom,
|
|
724
750
|
effectiveRoomUsers,
|
|
725
|
-
messageIngress: await
|
|
726
|
-
channelId: "matrix",
|
|
727
|
-
accountId,
|
|
728
|
-
identity: matrixIngressIdentity,
|
|
729
|
-
readStoreAllowFrom: async () => params.storeAllowFrom
|
|
730
|
-
}).message({
|
|
731
|
-
subject: { stableId: params.senderId },
|
|
732
|
-
conversation: {
|
|
733
|
-
kind: params.isRoom ? "group" : "direct",
|
|
734
|
-
id: params.isRoom ? "matrix-room" : "matrix-dm"
|
|
735
|
-
},
|
|
736
|
-
event: {
|
|
737
|
-
kind: eventKind,
|
|
738
|
-
authMode: "inbound",
|
|
739
|
-
mayPair: params.isRoom ? false : eventKind === "message"
|
|
740
|
-
},
|
|
741
|
-
dmPolicy,
|
|
742
|
-
groupPolicy: params.isRoom ? groupIngress.groupPolicy : "disabled",
|
|
743
|
-
policy: { groupAllowFromFallbackToAllowFrom: false },
|
|
744
|
-
allowFrom: params.allowFrom,
|
|
745
|
-
...params.isRoom ? { groupAllowFrom: groupIngress.groupAllowFrom } : {}
|
|
746
|
-
}),
|
|
751
|
+
messageIngress: await resolveMessageIngress(),
|
|
747
752
|
accountId,
|
|
748
753
|
senderId: params.senderId,
|
|
749
|
-
isRoom: params.isRoom
|
|
754
|
+
isRoom: params.isRoom,
|
|
755
|
+
resolveMessageIngress
|
|
750
756
|
};
|
|
751
757
|
}
|
|
752
758
|
async function resolveMatrixMonitorCommandAccess(state, params) {
|
|
@@ -813,7 +819,7 @@ const matrixVerificationConstants = {
|
|
|
813
819
|
const MAX_TRACKED_VERIFICATION_EVENTS = 1024;
|
|
814
820
|
const SAS_NOTICE_RETRY_DELAY_MS = 750;
|
|
815
821
|
const VERIFICATION_EVENT_STARTUP_GRACE_MS = 3e4;
|
|
816
|
-
const loadMatrixDirectRoomDeps = createLazyRuntimeModule(() => Promise.all([import("./send-
|
|
822
|
+
const loadMatrixDirectRoomDeps = createLazyRuntimeModule(() => Promise.all([import("./send-ClHgDZLT.js").then((n) => n.S), import("./direct-room-RinHjtqX.js").then((n) => n.t)]).then(([directManagementModule, directRoomModule]) => ({
|
|
817
823
|
inspectMatrixDirectRooms: directManagementModule.inspectMatrixDirectRooms,
|
|
818
824
|
isStrictDirectRoom: directRoomModule.isStrictDirectRoom
|
|
819
825
|
})));
|
|
@@ -1253,7 +1259,7 @@ async function resolveMatrixSelfUserId(client, logVerboseMessage) {
|
|
|
1253
1259
|
}
|
|
1254
1260
|
}
|
|
1255
1261
|
function registerMatrixMonitorEvents(params) {
|
|
1256
|
-
const { cfg, client, auth, allowFrom, dmEnabled, dmPolicy, readStoreAllowFrom, directTracker, logVerboseMessage, warnedEncryptedRooms, warnedCryptoMissingRooms, logger, startupGraceMs, getHealthySyncSinceMs, formatNativeDependencyHint, onRoomMessage, runDetachedTask, sasNoticeRetryDelayMs } = params;
|
|
1262
|
+
const { cfg, client, auth, allowFrom, dmEnabled, dmPolicy, readStoreAllowFrom, directTracker, invalidateMemberDisplayName, logVerboseMessage, warnedEncryptedRooms, warnedCryptoMissingRooms, logger, startupGraceMs, getHealthySyncSinceMs, formatNativeDependencyHint, onRoomMessage, runDetachedTask, sasNoticeRetryDelayMs } = params;
|
|
1257
1263
|
const postHealthySyncDecryptFailureTracker = createMatrixPostHealthySyncDecryptFailureTracker({
|
|
1258
1264
|
getHealthySyncSinceMs,
|
|
1259
1265
|
startupGraceMs
|
|
@@ -1274,18 +1280,18 @@ function registerMatrixMonitorEvents(params) {
|
|
|
1274
1280
|
logVerboseMessage(`matrix: ${label} failed (${String(error)})`);
|
|
1275
1281
|
});
|
|
1276
1282
|
};
|
|
1277
|
-
|
|
1283
|
+
const onRoomMessageEvent = (roomId, event) => {
|
|
1278
1284
|
if (routeVerificationEvent(roomId, event)) return;
|
|
1279
1285
|
runMonitorTask(`room message handler room=${roomId} id=${event.event_id ?? "unknown"}`, async () => {
|
|
1280
1286
|
await onRoomMessage(roomId, event);
|
|
1281
1287
|
});
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1288
|
+
};
|
|
1289
|
+
const onEncryptedEvent = (roomId, event) => {
|
|
1284
1290
|
const eventId = event?.event_id ?? "unknown";
|
|
1285
1291
|
const eventType = event?.type ?? "unknown";
|
|
1286
1292
|
logVerboseMessage(`matrix: encrypted event room=${roomId} type=${eventType} id=${eventId}`);
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1293
|
+
};
|
|
1294
|
+
const onDecryptedEvent = (roomId, event) => {
|
|
1289
1295
|
const eventId = event?.event_id ?? "unknown";
|
|
1290
1296
|
const eventType = event?.type ?? "unknown";
|
|
1291
1297
|
logVerboseMessage(`matrix: decrypted event room=${roomId} type=${eventType} id=${eventId}`);
|
|
@@ -1294,8 +1300,8 @@ function registerMatrixMonitorEvents(params) {
|
|
|
1294
1300
|
runMonitorTask(`decrypted room message handler room=${roomId} id=${event.event_id ?? "unknown"}`, async () => {
|
|
1295
1301
|
await onRoomMessage(roomId, event);
|
|
1296
1302
|
});
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1303
|
+
};
|
|
1304
|
+
const onFailedDecryption = (roomId, event, error) => {
|
|
1299
1305
|
runMonitorTask(`failed decryption handler room=${roomId} id=${event.event_id ?? "unknown"}`, async () => {
|
|
1300
1306
|
const failureState = postHealthySyncDecryptFailureTracker.recordFailure(roomId, event, error);
|
|
1301
1307
|
const selfUserId = await resolveMatrixSelfUserId(client, logVerboseMessage);
|
|
@@ -1329,13 +1335,13 @@ function registerMatrixMonitorEvents(params) {
|
|
|
1329
1335
|
});
|
|
1330
1336
|
logVerboseMessage(`matrix: failed decrypt room=${roomId} id=${event.event_id ?? "unknown"} freshAfterHealthySync=${String(failureState.freshAfterHealthySync)} error=${error.message}`);
|
|
1331
1337
|
});
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1338
|
+
};
|
|
1339
|
+
const onVerificationSummary = (summary) => {
|
|
1334
1340
|
runMonitorTask("verification summary handler", async () => {
|
|
1335
1341
|
await routeVerificationSummary(summary);
|
|
1336
1342
|
});
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1343
|
+
};
|
|
1344
|
+
const onInvite = (roomId, event) => {
|
|
1339
1345
|
directTracker?.invalidateRoom(roomId);
|
|
1340
1346
|
const eventId = event?.event_id ?? "unknown";
|
|
1341
1347
|
const sender = event?.sender ?? "unknown";
|
|
@@ -1345,13 +1351,13 @@ function registerMatrixMonitorEvents(params) {
|
|
|
1345
1351
|
const rememberedSender = normalizeOptionalString(event?.sender);
|
|
1346
1352
|
if (rememberedSender && !senderIsInvitee) directTracker?.rememberInvite?.(roomId, rememberedSender);
|
|
1347
1353
|
logVerboseMessage(`matrix: invite room=${roomId} sender=${sender} direct=${String(isDirect)} id=${eventId}`);
|
|
1348
|
-
}
|
|
1349
|
-
|
|
1354
|
+
};
|
|
1355
|
+
const onJoin = (roomId, event) => {
|
|
1350
1356
|
directTracker?.invalidateRoom(roomId);
|
|
1351
1357
|
const eventId = event?.event_id ?? "unknown";
|
|
1352
1358
|
logVerboseMessage(`matrix: join room=${roomId} id=${eventId}`);
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1359
|
+
};
|
|
1360
|
+
const onRoomEvent = (roomId, event) => {
|
|
1355
1361
|
const eventType = event?.type ?? "unknown";
|
|
1356
1362
|
if (eventType === EventType.RoomMessageEncrypted) {
|
|
1357
1363
|
logVerboseMessage(`matrix: encrypted raw event room=${roomId} id=${event?.event_id ?? "unknown"}`);
|
|
@@ -1375,6 +1381,7 @@ function registerMatrixMonitorEvents(params) {
|
|
|
1375
1381
|
directTracker?.invalidateRoom(roomId);
|
|
1376
1382
|
const membership = (event?.content)?.membership;
|
|
1377
1383
|
const stateKey = event.state_key ?? "";
|
|
1384
|
+
if (stateKey) invalidateMemberDisplayName?.(roomId, stateKey);
|
|
1378
1385
|
logVerboseMessage(`matrix: member event room=${roomId} stateKey=${stateKey} membership=${membership ?? "unknown"}`);
|
|
1379
1386
|
}
|
|
1380
1387
|
if (eventType === EventType.Reaction) {
|
|
@@ -1384,7 +1391,25 @@ function registerMatrixMonitorEvents(params) {
|
|
|
1384
1391
|
return;
|
|
1385
1392
|
}
|
|
1386
1393
|
routeVerificationEvent(roomId, event);
|
|
1387
|
-
}
|
|
1394
|
+
};
|
|
1395
|
+
client.on("room.message", onRoomMessageEvent);
|
|
1396
|
+
client.on("room.encrypted_event", onEncryptedEvent);
|
|
1397
|
+
client.on("room.decrypted_event", onDecryptedEvent);
|
|
1398
|
+
client.on("room.failed_decryption", onFailedDecryption);
|
|
1399
|
+
client.on("verification.summary", onVerificationSummary);
|
|
1400
|
+
client.on("room.invite", onInvite);
|
|
1401
|
+
client.on("room.join", onJoin);
|
|
1402
|
+
client.on("room.event", onRoomEvent);
|
|
1403
|
+
return () => {
|
|
1404
|
+
client.off("room.message", onRoomMessageEvent);
|
|
1405
|
+
client.off("room.encrypted_event", onEncryptedEvent);
|
|
1406
|
+
client.off("room.decrypted_event", onDecryptedEvent);
|
|
1407
|
+
client.off("room.failed_decryption", onFailedDecryption);
|
|
1408
|
+
client.off("verification.summary", onVerificationSummary);
|
|
1409
|
+
client.off("room.invite", onInvite);
|
|
1410
|
+
client.off("room.join", onJoin);
|
|
1411
|
+
client.off("room.event", onRoomEvent);
|
|
1412
|
+
};
|
|
1388
1413
|
}
|
|
1389
1414
|
//#endregion
|
|
1390
1415
|
//#region extensions/matrix/src/matrix/monitor/ack-config.ts
|
|
@@ -1404,42 +1429,18 @@ function resolveMatrixAckReactionConfig(params) {
|
|
|
1404
1429
|
}
|
|
1405
1430
|
//#endregion
|
|
1406
1431
|
//#region extensions/matrix/src/matrix/monitor/preflight-audio.ts
|
|
1407
|
-
const MATRIX_DEFAULT_ECHO_TRANSCRIPT_FORMAT = "📝 \"{transcript}\"";
|
|
1408
|
-
const loadMatrixPreflightAudioRuntime = createLazyRuntimeModule(() => import("./preflight-audio.runtime-BZxxQsxY.js"));
|
|
1409
|
-
function formatMatrixAudioTranscript(transcript) {
|
|
1410
|
-
return `[Audio transcript (machine-generated, untrusted)]: ${JSON.stringify(transcript)}`;
|
|
1411
|
-
}
|
|
1412
|
-
function formatMatrixAudioTranscriptEcho(transcript, format) {
|
|
1413
|
-
return format.replace("{transcript}", () => transcript);
|
|
1414
|
-
}
|
|
1415
|
-
function suppressMatrixPreflightAudioEcho(cfg) {
|
|
1416
|
-
const audio = cfg.tools?.media?.audio;
|
|
1417
|
-
if (!audio?.echoTranscript) return cfg;
|
|
1418
|
-
return {
|
|
1419
|
-
...cfg,
|
|
1420
|
-
tools: {
|
|
1421
|
-
...cfg.tools,
|
|
1422
|
-
media: {
|
|
1423
|
-
...cfg.tools?.media,
|
|
1424
|
-
audio: {
|
|
1425
|
-
...audio,
|
|
1426
|
-
echoTranscript: false
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
};
|
|
1431
|
-
}
|
|
1432
1432
|
function isMatrixAudioContent(params) {
|
|
1433
1433
|
if (params.msgtype === "m.audio") return true;
|
|
1434
1434
|
if (params.msgtype === "m.file" && typeof params.mimetype === "string") return params.mimetype.toLowerCase().startsWith("audio/");
|
|
1435
1435
|
return false;
|
|
1436
1436
|
}
|
|
1437
|
+
const matrixPreflightAudio = createChannelPreflightAudio({
|
|
1438
|
+
channel: "matrix",
|
|
1439
|
+
isAudio: isMatrixAudioContent
|
|
1440
|
+
});
|
|
1437
1441
|
async function resolveMatrixPreflightAudioTranscript(params) {
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
const { transcribeFirstAudio } = await loadMatrixPreflightAudioRuntime();
|
|
1441
|
-
if (params.abortSignal?.aborted) return;
|
|
1442
|
-
const transcript = await transcribeFirstAudio({
|
|
1442
|
+
return await matrixPreflightAudio.resolve({
|
|
1443
|
+
request: {
|
|
1443
1444
|
ctx: {
|
|
1444
1445
|
media: [{
|
|
1445
1446
|
path: params.mediaPath,
|
|
@@ -1454,34 +1455,13 @@ async function resolveMatrixPreflightAudioTranscript(params) {
|
|
|
1454
1455
|
ChatType: params.chatType,
|
|
1455
1456
|
SessionKey: params.sessionKey
|
|
1456
1457
|
},
|
|
1457
|
-
cfg:
|
|
1458
|
-
}
|
|
1459
|
-
|
|
1460
|
-
}
|
|
1461
|
-
logVerbose(`matrix: audio preflight transcription failed: ${String(err)}`);
|
|
1462
|
-
return;
|
|
1463
|
-
}
|
|
1458
|
+
cfg: params.cfg
|
|
1459
|
+
},
|
|
1460
|
+
abortSignal: params.abortSignal
|
|
1461
|
+
});
|
|
1464
1462
|
}
|
|
1465
1463
|
async function sendMatrixPreflightAudioTranscriptEcho(params) {
|
|
1466
|
-
|
|
1467
|
-
if (!audio?.echoTranscript) return;
|
|
1468
|
-
const text = formatMatrixAudioTranscriptEcho(params.transcript, audio.echoFormat ?? MATRIX_DEFAULT_ECHO_TRANSCRIPT_FORMAT);
|
|
1469
|
-
try {
|
|
1470
|
-
const { sendDurableMessageBatch } = await loadMatrixPreflightAudioRuntime();
|
|
1471
|
-
const send = await sendDurableMessageBatch({
|
|
1472
|
-
cfg: params.cfg,
|
|
1473
|
-
channel: "matrix",
|
|
1474
|
-
to: params.originatingTo,
|
|
1475
|
-
accountId: params.accountId,
|
|
1476
|
-
threadId: params.messageThreadId,
|
|
1477
|
-
payloads: [{ text }],
|
|
1478
|
-
bestEffort: true,
|
|
1479
|
-
durability: "best_effort"
|
|
1480
|
-
});
|
|
1481
|
-
if (send.status === "failed") throw send.error;
|
|
1482
|
-
} catch (err) {
|
|
1483
|
-
logVerbose(`matrix: audio transcript echo failed: ${String(err)}`);
|
|
1484
|
-
}
|
|
1464
|
+
await matrixPreflightAudio.send(params);
|
|
1485
1465
|
}
|
|
1486
1466
|
//#endregion
|
|
1487
1467
|
//#region extensions/matrix/src/matrix/monitor/handler-helpers.ts
|
|
@@ -1597,11 +1577,11 @@ async function redactMatrixDraftEvent(client, roomId, draftEventId) {
|
|
|
1597
1577
|
function buildMatrixFinalizedPreviewContent() {
|
|
1598
1578
|
return { [MATRIX_OPENCLAW_FINALIZED_PREVIEW_KEY]: true };
|
|
1599
1579
|
}
|
|
1600
|
-
const loadMatrixSendModule = createLazyRuntimeModule(() => import("./send-
|
|
1580
|
+
const loadMatrixSendModule = createLazyRuntimeModule(() => import("./send-ClHgDZLT.js").then((n) => n.s));
|
|
1601
1581
|
const loadAcpBindingRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/acp-binding-runtime"));
|
|
1602
1582
|
const loadSessionBindingRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/session-binding-runtime"));
|
|
1603
|
-
const loadMatrixReactionEvents = createLazyRuntimeModule(() => import("./reaction-events-
|
|
1604
|
-
const loadMatrixDraftStream = createLazyRuntimeModule(() => import("./draft-stream-
|
|
1583
|
+
const loadMatrixReactionEvents = createLazyRuntimeModule(() => import("./reaction-events-BKOLlnCo.js"));
|
|
1584
|
+
const loadMatrixDraftStream = createLazyRuntimeModule(() => import("./draft-stream-DQ7QNC-l.js"));
|
|
1605
1585
|
async function matrixTextWouldActivateMentions(client, text) {
|
|
1606
1586
|
const { resolveMatrixMentionsForBody } = await loadMatrixSendModule();
|
|
1607
1587
|
const mentions = await resolveMatrixMentionsForBody({
|
|
@@ -1747,7 +1727,7 @@ function createMatrixThreadContextResolver(params) {
|
|
|
1747
1727
|
//#endregion
|
|
1748
1728
|
//#region extensions/matrix/src/matrix/monitor/handler-context.ts
|
|
1749
1729
|
async function resolveMatrixInboundContext(config) {
|
|
1750
|
-
const { client, core, cfg, accountId, runtime, logVerboseMessage, roomId, event, eventTs, route: _route, isDirectMessage, isRoom, effectiveRoomUsers, groupPolicy, effectiveGroupAllowFrom, contextVisibilityMode, resolveThreadContext, resolveReplyContext, threadRootId, thread, getRoomInfo, senderId, senderName, bodyText, commandBodyText, roomConfig, messageId, inboundHistory, wasMentioned, effectiveWasMentioned, shouldBypassMention, canDetectMention, shouldRequireMention, commandAuthorized, locationPayload, media, preflightAudioTranscript, historyLimit, hasExplicitSessionBinding, dmSessionScope, sharedDmContextNoticeRooms, resolveStorePath: resolveStorePathImpl, createChannelInboundEnvelopeBuilder: createChannelInboundEnvelopeBuilderImpl, finalizeInboundContext } = config;
|
|
1730
|
+
const { client, core, cfg, accountId, resolveMessageIngress, runtime, logVerboseMessage, roomId, event, eventTs, route: _route, isDirectMessage, isRoom, effectiveRoomUsers, groupPolicy, effectiveGroupAllowFrom, contextVisibilityMode, resolveThreadContext, resolveReplyContext, threadRootId, thread, getRoomInfo, senderId, senderName, bodyText, commandBodyText, roomConfig, messageId, inboundHistory, wasMentioned, effectiveWasMentioned, shouldBypassMention, canDetectMention, shouldRequireMention, commandAuthorized, locationPayload, media, preflightAudioTranscript, historyLimit, hasExplicitSessionBinding, dmSessionScope, sharedDmContextNoticeRooms, resolveStorePath: resolveStorePathImpl, createChannelInboundEnvelopeBuilder: createChannelInboundEnvelopeBuilderImpl, finalizeInboundContext } = config;
|
|
1751
1731
|
const replyToEventId = resolveMatrixReplyToEventId(event.content);
|
|
1752
1732
|
const threadTarget = thread.threadId;
|
|
1753
1733
|
const isRoomContextSenderAllowed = (contextSenderId) => {
|
|
@@ -1822,7 +1802,18 @@ async function resolveMatrixInboundContext(config) {
|
|
|
1822
1802
|
kind: "quote",
|
|
1823
1803
|
senderAllowed: replySenderAllowed
|
|
1824
1804
|
}).include);
|
|
1825
|
-
const
|
|
1805
|
+
const channelIngress = await resolveMessageIngress({
|
|
1806
|
+
agentId: _route.agentId,
|
|
1807
|
+
sessionKey: _route.sessionKey,
|
|
1808
|
+
messageId,
|
|
1809
|
+
inboundEventKind: "user_request"
|
|
1810
|
+
}, {
|
|
1811
|
+
kind: isDirectMessage ? "direct" : "channel",
|
|
1812
|
+
id: roomId,
|
|
1813
|
+
threadId: threadTarget
|
|
1814
|
+
});
|
|
1815
|
+
const ctxPayload = core.channel.inbound.buildContext({
|
|
1816
|
+
channelIngress,
|
|
1826
1817
|
channel: "matrix",
|
|
1827
1818
|
contextVisibility: contextVisibilityMode,
|
|
1828
1819
|
finalize: finalizeInboundContext,
|
|
@@ -1891,7 +1882,6 @@ async function resolveMatrixInboundContext(config) {
|
|
|
1891
1882
|
extra: {
|
|
1892
1883
|
GroupSubject: isRoom ? roomName ?? roomId : void 0,
|
|
1893
1884
|
GroupId: isRoom ? roomId : void 0,
|
|
1894
|
-
GroupChannel: isRoom ? roomId : void 0,
|
|
1895
1885
|
...locationPayload?.context,
|
|
1896
1886
|
CommandSource: "text",
|
|
1897
1887
|
NativeDirectUserId: isDirectMessage ? senderId : void 0
|
|
@@ -1937,7 +1927,7 @@ async function resolveMatrixInboundContext(config) {
|
|
|
1937
1927
|
//#region extensions/matrix/src/matrix/monitor/handler-draft-controller.ts
|
|
1938
1928
|
async function createMatrixDraftController(params) {
|
|
1939
1929
|
const { streaming, previewToolProgressEnabled, replyToMode, messageId, threadTarget, accountConfig, cfg, accountId, roomId, client, logVerboseMessage } = params;
|
|
1940
|
-
let
|
|
1930
|
+
let draftDisposition = "active";
|
|
1941
1931
|
const draftStreamingEnabled = streaming !== "off";
|
|
1942
1932
|
const quietDraftStreaming = streaming === "quiet" || streaming === "progress";
|
|
1943
1933
|
const progressDraftStreaming = streaming === "progress";
|
|
@@ -1961,77 +1951,40 @@ async function createMatrixDraftController(params) {
|
|
|
1961
1951
|
const pendingDraftBoundaries = [];
|
|
1962
1952
|
const latestQueuedDraftBoundaryOffsets = /* @__PURE__ */ new Map();
|
|
1963
1953
|
let currentDraftReplyToId = draftReplyToId;
|
|
1964
|
-
let
|
|
1965
|
-
let
|
|
1966
|
-
let
|
|
1967
|
-
let latestPlanExplanation;
|
|
1954
|
+
let previewPlan;
|
|
1955
|
+
let previewPlanExplanation;
|
|
1956
|
+
let previewPlanSuppressed = false;
|
|
1968
1957
|
const progressConfigEntry = accountConfig ?? cfg.channels?.matrix;
|
|
1969
1958
|
const progressSeed = `${accountId}:${roomId}`;
|
|
1970
|
-
const
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
draftStream
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
const nextLines = mergeChannelProgressDraftLine(previewToolProgressLines, progressLine, { maxLines: resolveChannelProgressDraftMaxLines(progressConfigEntry) });
|
|
1993
|
-
if (nextLines === previewToolProgressLines) return;
|
|
1994
|
-
previewToolProgressLines = nextLines;
|
|
1995
|
-
draftStream.update(formatChannelProgressDraftText({
|
|
1996
|
-
entry: progressConfigEntry,
|
|
1997
|
-
lines: previewToolProgressLines,
|
|
1998
|
-
seed: progressSeed,
|
|
1999
|
-
formatLine: formatMatrixToolProgressMarkdownCode,
|
|
2000
|
-
bullet: "-",
|
|
2001
|
-
narration: latestPlanExplanation,
|
|
2002
|
-
plan: latestPlan
|
|
2003
|
-
}));
|
|
2004
|
-
return;
|
|
2005
|
-
}
|
|
2006
|
-
if (shouldStreamPreviewToolProgress && !previewToolProgressSuppressed && normalized) previewToolProgressLines = mergeChannelProgressDraftLine(previewToolProgressLines, progressLine, { maxLines: resolveChannelProgressDraftMaxLines(progressConfigEntry) });
|
|
2007
|
-
const alreadyStarted = progressDraftGate.hasStarted;
|
|
2008
|
-
const progressActive = await progressDraftGate.noteWork();
|
|
2009
|
-
if ((alreadyStarted || progressActive) && progressDraftGate.hasStarted) renderProgressDraft();
|
|
2010
|
-
};
|
|
2011
|
-
const pushPlanProgress = async (steps, explanation) => {
|
|
2012
|
-
latestPlan = steps?.length ? steps.map((entry) => ({ ...entry })) : void 0;
|
|
2013
|
-
latestPlanExplanation = explanation?.replace(/\s+/g, " ").trim() || void 0;
|
|
2014
|
-
if (!draftStream || previewToolProgressSuppressed) return;
|
|
2015
|
-
if (!progressDraftStreaming) {
|
|
2016
|
-
renderProgressDraft();
|
|
2017
|
-
return;
|
|
1959
|
+
const renderPreviewPlan = () => formatChannelProgressDraftText({
|
|
1960
|
+
entry: progressConfigEntry,
|
|
1961
|
+
lines: [...progressDraft.getSnapshot().lines],
|
|
1962
|
+
seed: progressSeed,
|
|
1963
|
+
formatLine: formatMatrixToolProgressMarkdownCode,
|
|
1964
|
+
bullet: "-",
|
|
1965
|
+
narration: previewPlanExplanation,
|
|
1966
|
+
plan: previewPlan
|
|
1967
|
+
});
|
|
1968
|
+
const progressDraft = createChannelProgressDraftCompositor({
|
|
1969
|
+
entry: progressConfigEntry,
|
|
1970
|
+
mode: streaming === "quiet" ? "partial" : streaming,
|
|
1971
|
+
active: Boolean(draftStream),
|
|
1972
|
+
seed: progressSeed,
|
|
1973
|
+
formatLine: formatMatrixToolProgressMarkdownCode,
|
|
1974
|
+
buildProgressEventLine: (input, options) => input.event === "approval" ? formatChannelProgressDraftLine(input, options) : buildChannelProgressDraftLineForEntry(progressConfigEntry, input, options),
|
|
1975
|
+
update: async (text, options) => {
|
|
1976
|
+
const previewText = !progressDraftStreaming && (previewPlan || previewPlanExplanation) ? renderPreviewPlan() : text.replace(/^• /gmu, "- ");
|
|
1977
|
+
if (!draftStream) return false;
|
|
1978
|
+
draftStream.update(previewText);
|
|
1979
|
+
if (options?.flush) await draftStream.flush();
|
|
1980
|
+
return Boolean(draftStream.eventId());
|
|
2018
1981
|
}
|
|
2019
|
-
|
|
2020
|
-
await progressDraftGate.startNow();
|
|
2021
|
-
if (alreadyStarted && progressDraftGate.hasStarted) renderProgressDraft();
|
|
2022
|
-
};
|
|
2023
|
-
const suppressPreviewToolProgressForAnswerText = (text) => {
|
|
2024
|
-
if (!text?.trim()) return;
|
|
2025
|
-
previewToolProgressSuppressed = true;
|
|
2026
|
-
previewToolProgressLines = [];
|
|
2027
|
-
latestPlan = void 0;
|
|
2028
|
-
latestPlanExplanation = void 0;
|
|
2029
|
-
};
|
|
1982
|
+
});
|
|
2030
1983
|
const resetPreviewToolProgress = () => {
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
1984
|
+
previewPlan = void 0;
|
|
1985
|
+
previewPlanExplanation = void 0;
|
|
1986
|
+
previewPlanSuppressed = false;
|
|
1987
|
+
progressDraft.reset();
|
|
2035
1988
|
};
|
|
2036
1989
|
const buildPreviewToolProgressReplyOptions = () => {
|
|
2037
1990
|
if (!shouldSuppressDefaultToolProgressMessages) return {};
|
|
@@ -2040,73 +1993,29 @@ async function createMatrixDraftController(params) {
|
|
|
2040
1993
|
return {
|
|
2041
1994
|
...options,
|
|
2042
1995
|
onToolStart: async (payload) => {
|
|
2043
|
-
|
|
2044
|
-
await pushPreviewToolProgress(buildChannelProgressDraftLineForEntry(progressConfigEntry, {
|
|
2045
|
-
event: "tool",
|
|
2046
|
-
itemId: payload.itemId,
|
|
2047
|
-
toolCallId: payload.toolCallId,
|
|
2048
|
-
name: toolName,
|
|
2049
|
-
phase: payload.phase,
|
|
2050
|
-
args: payload.args
|
|
2051
|
-
}, payload.detailMode ? { detailMode: payload.detailMode } : void 0), { toolName });
|
|
1996
|
+
return await progressDraft.pushToolEvent(payload);
|
|
2052
1997
|
},
|
|
2053
1998
|
onItemEvent: async (payload) => {
|
|
2054
|
-
await
|
|
2055
|
-
event: "item",
|
|
2056
|
-
itemId: payload.itemId,
|
|
2057
|
-
toolCallId: payload.toolCallId,
|
|
2058
|
-
itemKind: payload.kind,
|
|
2059
|
-
title: payload.title,
|
|
2060
|
-
name: payload.name,
|
|
2061
|
-
phase: payload.phase,
|
|
2062
|
-
status: payload.status,
|
|
2063
|
-
summary: payload.summary,
|
|
2064
|
-
progressText: payload.progressText,
|
|
2065
|
-
meta: payload.meta
|
|
2066
|
-
}));
|
|
1999
|
+
return await progressDraft.pushItemEvent(payload);
|
|
2067
2000
|
},
|
|
2068
2001
|
onPlanUpdate: async (payload) => {
|
|
2069
|
-
if (payload.phase !== "update") return;
|
|
2070
|
-
await pushPlanProgress(payload.steps, payload.explanation);
|
|
2002
|
+
if (payload.phase !== "update") return false;
|
|
2003
|
+
if (progressDraftStreaming) return await progressDraft.pushPlanProgress(payload.steps, { explanation: payload.explanation });
|
|
2004
|
+
if (!draftStream || previewPlanSuppressed) return false;
|
|
2005
|
+
previewPlan = payload.steps?.length ? payload.steps.map((step) => ({ ...step })) : void 0;
|
|
2006
|
+
previewPlanExplanation = payload.explanation?.replace(/\s+/g, " ").trim() || void 0;
|
|
2007
|
+
const text = renderPreviewPlan();
|
|
2008
|
+
if (text) draftStream.update(text);
|
|
2009
|
+
return false;
|
|
2071
2010
|
},
|
|
2072
2011
|
onApprovalEvent: async (payload) => {
|
|
2073
|
-
|
|
2074
|
-
await pushPreviewToolProgress(formatChannelProgressDraftLine({
|
|
2075
|
-
event: "approval",
|
|
2076
|
-
phase: payload.phase,
|
|
2077
|
-
title: payload.title,
|
|
2078
|
-
command: payload.command,
|
|
2079
|
-
reason: payload.reason,
|
|
2080
|
-
message: payload.message
|
|
2081
|
-
}));
|
|
2012
|
+
return await progressDraft.pushApprovalEvent(payload);
|
|
2082
2013
|
},
|
|
2083
2014
|
onCommandOutput: async (payload) => {
|
|
2084
|
-
|
|
2085
|
-
await pushPreviewToolProgress(buildChannelProgressDraftLineForEntry(progressConfigEntry, {
|
|
2086
|
-
event: "command-output",
|
|
2087
|
-
itemId: payload.itemId,
|
|
2088
|
-
toolCallId: payload.toolCallId,
|
|
2089
|
-
phase: payload.phase,
|
|
2090
|
-
title: payload.title,
|
|
2091
|
-
name: payload.name,
|
|
2092
|
-
status: payload.status,
|
|
2093
|
-
exitCode: payload.exitCode
|
|
2094
|
-
}));
|
|
2015
|
+
return await progressDraft.pushCommandOutputEvent(payload);
|
|
2095
2016
|
},
|
|
2096
2017
|
onPatchSummary: async (payload) => {
|
|
2097
|
-
|
|
2098
|
-
await pushPreviewToolProgress(buildChannelProgressDraftLineForEntry(progressConfigEntry, {
|
|
2099
|
-
event: "patch",
|
|
2100
|
-
itemId: payload.itemId,
|
|
2101
|
-
toolCallId: payload.toolCallId,
|
|
2102
|
-
phase: payload.phase,
|
|
2103
|
-
title: payload.title,
|
|
2104
|
-
name: payload.name,
|
|
2105
|
-
added: payload.added,
|
|
2106
|
-
modified: payload.modified,
|
|
2107
|
-
deleted: payload.deleted,
|
|
2108
|
-
summary: payload.summary
|
|
2109
|
-
}));
|
|
2018
|
+
return await progressDraft.pushPatchEvent(payload);
|
|
2110
2019
|
}
|
|
2111
2020
|
};
|
|
2112
2021
|
};
|
|
@@ -2146,19 +2055,19 @@ async function createMatrixDraftController(params) {
|
|
|
2146
2055
|
const resetDraftDeliveryState = async () => {
|
|
2147
2056
|
await draftStream?.discardPending();
|
|
2148
2057
|
draftStream?.reset();
|
|
2149
|
-
|
|
2058
|
+
draftDisposition = "active";
|
|
2150
2059
|
currentDraftMessageGeneration = 0;
|
|
2151
2060
|
currentDraftBlockOffset = 0;
|
|
2152
2061
|
latestDraftFullText = "";
|
|
2153
2062
|
pendingDraftBoundaries.length = 0;
|
|
2154
2063
|
latestQueuedDraftBoundaryOffsets.clear();
|
|
2155
2064
|
currentDraftReplyToId = draftReplyToId;
|
|
2156
|
-
|
|
2065
|
+
progressDraft.beginNewTurn({ force: true });
|
|
2157
2066
|
resetPreviewToolProgress();
|
|
2158
2067
|
};
|
|
2159
2068
|
return {
|
|
2160
2069
|
draftStream,
|
|
2161
|
-
|
|
2070
|
+
cancelProgressDraft: () => progressDraft.cancel(),
|
|
2162
2071
|
buildPreviewToolProgressReplyOptions,
|
|
2163
2072
|
queueDraftBlockBoundary,
|
|
2164
2073
|
advanceDraftBlockBoundary,
|
|
@@ -2166,12 +2075,15 @@ async function createMatrixDraftController(params) {
|
|
|
2166
2075
|
resetPreviewToolProgress,
|
|
2167
2076
|
resetDraftDeliveryState,
|
|
2168
2077
|
updateDraftFromLatestFullText,
|
|
2169
|
-
|
|
2078
|
+
draftDisposition: () => draftDisposition,
|
|
2079
|
+
beginDraftGeneration: () => {
|
|
2080
|
+
draftDisposition = "active";
|
|
2081
|
+
},
|
|
2170
2082
|
markDraftConsumed: () => {
|
|
2171
|
-
|
|
2083
|
+
draftDisposition = "consumed";
|
|
2172
2084
|
},
|
|
2173
|
-
|
|
2174
|
-
|
|
2085
|
+
markDraftRetained: () => {
|
|
2086
|
+
draftDisposition = "retained";
|
|
2175
2087
|
},
|
|
2176
2088
|
currentReplyToId: () => currentDraftReplyToId,
|
|
2177
2089
|
setCurrentReplyToId: (replyToId) => {
|
|
@@ -2181,10 +2093,16 @@ async function createMatrixDraftController(params) {
|
|
|
2181
2093
|
currentDraftReplyToId = replyToMode === "all" ? draftReplyToId : void 0;
|
|
2182
2094
|
},
|
|
2183
2095
|
onPartialReply: (text) => {
|
|
2184
|
-
if (progressDraftStreaming) return;
|
|
2096
|
+
if (progressDraftStreaming) return false;
|
|
2185
2097
|
latestDraftFullText = text;
|
|
2186
|
-
|
|
2098
|
+
if (text.trim()) {
|
|
2099
|
+
previewPlanSuppressed = true;
|
|
2100
|
+
previewPlan = void 0;
|
|
2101
|
+
previewPlanExplanation = void 0;
|
|
2102
|
+
progressDraft.suppress();
|
|
2103
|
+
}
|
|
2187
2104
|
updateDraftFromLatestFullText();
|
|
2105
|
+
return false;
|
|
2188
2106
|
}
|
|
2189
2107
|
};
|
|
2190
2108
|
}
|
|
@@ -2528,6 +2446,7 @@ async function resolveMatrixIngressAccess(config) {
|
|
|
2528
2446
|
roomUsers,
|
|
2529
2447
|
senderId,
|
|
2530
2448
|
isRoom,
|
|
2449
|
+
conversationId: roomId,
|
|
2531
2450
|
accountId,
|
|
2532
2451
|
eventKind: isReactionEvent ? "reaction" : "message"
|
|
2533
2452
|
});
|
|
@@ -2702,6 +2621,11 @@ function resolveMatrixUserLocalpart(userId) {
|
|
|
2702
2621
|
if (colonIndex <= 1) return null;
|
|
2703
2622
|
return trimmed.slice(1, colonIndex).trim() || null;
|
|
2704
2623
|
}
|
|
2624
|
+
function hasVisibleNativeMatrixUserMention(text, userId) {
|
|
2625
|
+
const localpart = resolveMatrixUserLocalpart(userId);
|
|
2626
|
+
if (!text || !localpart) return false;
|
|
2627
|
+
return new RegExp(String.raw`(?:^|\p{White_Space})(?:${escapeRegExp(userId)}(?=$|\p{White_Space}|:\p{White_Space}|[,!?;](?=$|\p{White_Space}))|${escapeRegExp(`@${localpart}`)}(?=$|\p{White_Space}|:\p{White_Space}))`, "u").test(text);
|
|
2628
|
+
}
|
|
2705
2629
|
function resolveMatrixMentionPrefixCandidates(params) {
|
|
2706
2630
|
const candidates = [];
|
|
2707
2631
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -2803,7 +2727,7 @@ function resolveMentions(params) {
|
|
|
2803
2727
|
displayName: params.displayName,
|
|
2804
2728
|
mentionRegexes: params.mentionRegexes
|
|
2805
2729
|
}) : false;
|
|
2806
|
-
const metadataBackedUserMention = Boolean(params.userId && mentionedUsers.has(params.userId) && (mentionedInFormattedBody || textMentioned));
|
|
2730
|
+
const metadataBackedUserMention = Boolean(params.userId && mentionedUsers.has(params.userId) && (mentionedInFormattedBody || textMentioned || hasVisibleNativeMatrixUserMention(params.text, params.userId)));
|
|
2807
2731
|
const metadataBackedRoomMention = Boolean(mentions?.room) && visibleRoomMention;
|
|
2808
2732
|
const explicitMention = mentionedInFormattedBody || metadataBackedUserMention || metadataBackedRoomMention;
|
|
2809
2733
|
return {
|
|
@@ -2817,6 +2741,7 @@ async function resolveMatrixIngressContent(config) {
|
|
|
2817
2741
|
const { handler, params: paramsLocal, access, roomId, event, eventType, isPollEvent, eventTs, senderId, roomHistoryTracker, commitInboundEventIfClaimed } = config;
|
|
2818
2742
|
const { client, core, cfg, accountId, accountConfig, logger, logVerboseMessage, historyLimit, mediaMaxBytes, dmSessionScope, getMemberDisplayName } = handler;
|
|
2819
2743
|
const { content: accessContent, messageId, audioPreflightMode, isDirectMessage, isRoom, locationPayload, reservedHistorySlot, threadRootId, thread, historyThreadId, discardReservedHistorySlot, markReservedHistorySlotConsumed, commitInboundEventIfClaimedAndDiscardReserved, roomConfig, allowBotsMode, isConfiguredBotSender, selfUserId, botLoopProtection, roomMatchMeta, getSenderName, accessState, effectiveGroupAllowFrom, effectiveRoomUsers } = access;
|
|
2744
|
+
const { messageIngress, resolveMessageIngress } = accessState;
|
|
2820
2745
|
let content = accessContent;
|
|
2821
2746
|
let pollSnapshotPromise = null;
|
|
2822
2747
|
const getPollSnapshot = async () => {
|
|
@@ -2898,7 +2823,7 @@ async function resolveMatrixIngressContent(config) {
|
|
|
2898
2823
|
} catch (err) {
|
|
2899
2824
|
preflightMediaDownloadFailed = true;
|
|
2900
2825
|
if (isMatrixMediaSizeLimitError(err)) preflightMediaSizeLimitExceeded = true;
|
|
2901
|
-
const errorText =
|
|
2826
|
+
const errorText = formatErrorMessage(err);
|
|
2902
2827
|
logVerboseMessage(`matrix: media download failed room=${roomId} id=${event.event_id ?? "unknown"} type=${content.msgtype} error=${errorText}`);
|
|
2903
2828
|
logger.warn("matrix media download failed", {
|
|
2904
2829
|
roomId,
|
|
@@ -2984,7 +2909,7 @@ async function resolveMatrixIngressContent(config) {
|
|
|
2984
2909
|
const { effectiveWasMentioned, shouldBypassMention } = mentionDecision;
|
|
2985
2910
|
const canDetectMention = agentMentionRegexes.length > 0 || hasExplicitMention;
|
|
2986
2911
|
if (mentionDecision.shouldSkip) {
|
|
2987
|
-
const pendingHistoryBody = preflightAudioTranscript ?
|
|
2912
|
+
const pendingHistoryBody = preflightAudioTranscript ? formatAudioTranscriptForAgent(preflightAudioTranscript) : pendingHistoryText || pendingHistoryPollText;
|
|
2988
2913
|
if (historyLimit > 0 && pendingHistoryBody) {
|
|
2989
2914
|
const pendingEntry = {
|
|
2990
2915
|
sender: senderId,
|
|
@@ -3046,7 +2971,7 @@ async function resolveMatrixIngressContent(config) {
|
|
|
3046
2971
|
} catch (err) {
|
|
3047
2972
|
mediaDownloadFailed = true;
|
|
3048
2973
|
if (isMatrixMediaSizeLimitError(err)) mediaSizeLimitExceeded = true;
|
|
3049
|
-
const errorText =
|
|
2974
|
+
const errorText = formatErrorMessage(err);
|
|
3050
2975
|
logVerboseMessage(`matrix: media download failed room=${roomId} id=${event.event_id ?? "unknown"} type=${content.msgtype} error=${errorText}`);
|
|
3051
2976
|
logger.warn("matrix media download failed", {
|
|
3052
2977
|
roomId,
|
|
@@ -3067,7 +2992,7 @@ async function resolveMatrixIngressContent(config) {
|
|
|
3067
2992
|
});
|
|
3068
2993
|
if (preflightMedia && bodyText && bodyText !== preflightMedia.placeholder && isLikelyBareFilename(bodyText)) bodyText = preflightMedia.placeholder;
|
|
3069
2994
|
if (preflightAudioTranscript) {
|
|
3070
|
-
const transcriptBody =
|
|
2995
|
+
const transcriptBody = formatAudioTranscriptForAgent(preflightAudioTranscript);
|
|
3071
2996
|
bodyText = !bodyText || bodyText === media?.placeholder ? transcriptBody : `${bodyText}\n${transcriptBody}`;
|
|
3072
2997
|
}
|
|
3073
2998
|
if (!bodyText) {
|
|
@@ -3109,6 +3034,8 @@ async function resolveMatrixIngressContent(config) {
|
|
|
3109
3034
|
}, historyThreadId) : void 0;
|
|
3110
3035
|
if (reservedHistorySlot && preparedTrigger) markReservedHistorySlotConsumed();
|
|
3111
3036
|
return {
|
|
3037
|
+
messageIngress,
|
|
3038
|
+
resolveMessageIngress,
|
|
3112
3039
|
route: _route,
|
|
3113
3040
|
hasExplicitSessionBinding,
|
|
3114
3041
|
roomConfig,
|
|
@@ -3346,12 +3273,12 @@ async function deliverMatrixReplies(params) {
|
|
|
3346
3273
|
const { chunks } = chunkMatrixText(rawText, {
|
|
3347
3274
|
cfg: params.cfg,
|
|
3348
3275
|
accountId: params.accountId,
|
|
3349
|
-
tableMode
|
|
3276
|
+
tableMode,
|
|
3277
|
+
preserveWhitespace: true
|
|
3350
3278
|
});
|
|
3351
3279
|
for (const chunk of chunks) {
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
await sendMessageMatrix(params.roomId, trimmed, {
|
|
3280
|
+
if (!chunk.trim()) continue;
|
|
3281
|
+
await sendMessageMatrix(params.roomId, chunk, {
|
|
3355
3282
|
client: params.client,
|
|
3356
3283
|
cfg: params.cfg,
|
|
3357
3284
|
replyToId: replyToIdForReply,
|
|
@@ -3392,19 +3319,21 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3392
3319
|
const hasRepliedRef = { value: false };
|
|
3393
3320
|
let finalReplyDeliveryFailed = false;
|
|
3394
3321
|
let nonFinalReplyDeliveryFailed = false;
|
|
3322
|
+
const beginNextBlockDraft = () => {
|
|
3323
|
+
draftController.beginDraftGeneration();
|
|
3324
|
+
draftController.advanceDraftBlockBoundary({ fallbackToLatestEnd: true });
|
|
3325
|
+
draftStream?.reset();
|
|
3326
|
+
draftController.resetReplyToIdForNextBlock();
|
|
3327
|
+
draftController.updateDraftFromLatestFullText();
|
|
3328
|
+
};
|
|
3395
3329
|
const { deliver: deliverReply, onError: onReplyError, ...turnDispatcherOptions } = {
|
|
3396
3330
|
...prefixOptions,
|
|
3397
3331
|
humanDelay,
|
|
3398
3332
|
deliver: async (payload, info) => {
|
|
3399
3333
|
const completeDelivery = async (result) => {
|
|
3400
3334
|
if (info.kind === "block") {
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
draftStream?.reset();
|
|
3404
|
-
draftController.resetReplyToIdForNextBlock();
|
|
3405
|
-
draftController.updateDraftFromLatestFullText();
|
|
3406
|
-
const { sendTypingMatrix } = await loadMatrixSendModule();
|
|
3407
|
-
await sendTypingMatrix(roomId, true, void 0, client).catch(() => {});
|
|
3335
|
+
beginNextBlockDraft();
|
|
3336
|
+
await typingCallbacks.onReplyStart();
|
|
3408
3337
|
}
|
|
3409
3338
|
return result;
|
|
3410
3339
|
};
|
|
@@ -3422,9 +3351,25 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3422
3351
|
content
|
|
3423
3352
|
};
|
|
3424
3353
|
};
|
|
3425
|
-
const
|
|
3426
|
-
const
|
|
3427
|
-
|
|
3354
|
+
const settleDraftReplacement = async (params) => {
|
|
3355
|
+
const draftDelivery = createDraftDeliveryResult(params.draftEventId, params.draftContent);
|
|
3356
|
+
let replacement;
|
|
3357
|
+
try {
|
|
3358
|
+
replacement = await params.deliver();
|
|
3359
|
+
} catch (error) {
|
|
3360
|
+
draftController.markDraftRetained();
|
|
3361
|
+
throw toMatrixPartialDeliveryError(error, [draftDelivery]);
|
|
3362
|
+
}
|
|
3363
|
+
if (!replacement.visibleReplySent) {
|
|
3364
|
+
draftController.markDraftRetained();
|
|
3365
|
+
return draftDelivery;
|
|
3366
|
+
}
|
|
3367
|
+
if (!await redactMatrixDraftEvent(client, roomId, params.draftEventId)) {
|
|
3368
|
+
draftController.markDraftRetained();
|
|
3369
|
+
return mergeMatrixReplyDeliveryResults([draftDelivery, replacement]);
|
|
3370
|
+
}
|
|
3371
|
+
draftController.markDraftConsumed();
|
|
3372
|
+
return replacement;
|
|
3428
3373
|
};
|
|
3429
3374
|
if (draftStream && info.kind !== "tool" && !payload.isCompactionNotice) {
|
|
3430
3375
|
const hasMedia = Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0;
|
|
@@ -3433,7 +3378,7 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3433
3378
|
...payload,
|
|
3434
3379
|
text: ttsSupplement.spokenText
|
|
3435
3380
|
} : payload;
|
|
3436
|
-
if (draftController.
|
|
3381
|
+
if (draftController.draftDisposition() !== "active") {
|
|
3437
3382
|
await draftStream.discardPending();
|
|
3438
3383
|
return await completeDelivery(await deliverMatrixReplies({
|
|
3439
3384
|
cfg,
|
|
@@ -3511,11 +3456,10 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3511
3456
|
}
|
|
3512
3457
|
}),
|
|
3513
3458
|
deliverNormally: async () => {
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
deliveredFallback = await deliverMatrixReplies({
|
|
3459
|
+
fallbackResult = await settleDraftReplacement({
|
|
3460
|
+
draftEventId,
|
|
3461
|
+
draftContent: draftStream.content() ?? preparedFinalPreviewContent,
|
|
3462
|
+
deliver: async () => await deliverMatrixReplies({
|
|
3519
3463
|
cfg,
|
|
3520
3464
|
replies: [fallbackPayload],
|
|
3521
3465
|
roomId,
|
|
@@ -3529,15 +3473,12 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3529
3473
|
accountId,
|
|
3530
3474
|
mediaLocalRoots,
|
|
3531
3475
|
tableMode
|
|
3532
|
-
})
|
|
3533
|
-
}
|
|
3534
|
-
throw toMatrixPartialDeliveryError(error, [survivingDraft]);
|
|
3535
|
-
}
|
|
3536
|
-
fallbackResult = mergeMatrixReplyDeliveryResults([survivingDraft, deliveredFallback]);
|
|
3476
|
+
})
|
|
3477
|
+
});
|
|
3537
3478
|
return fallbackResult.visibleReplySent;
|
|
3538
3479
|
}
|
|
3539
3480
|
});
|
|
3540
|
-
draftController.markDraftConsumed();
|
|
3481
|
+
if (previewResult.kind === "preview-finalized") draftController.markDraftConsumed();
|
|
3541
3482
|
return await completeDelivery(previewResult.kind === "preview-finalized" && previewResult.liveState?.receipt ? createDraftDeliveryResult(draftEventId, finalizedDraftContent ?? preparedFinalPreviewContent) : fallbackResult ?? mergeMatrixReplyDeliveryResults([]));
|
|
3542
3483
|
} else if (draftEventId && hasMedia && !payloadReplyMismatch) {
|
|
3543
3484
|
let textEditOk = !mustDeliverFinalNormally;
|
|
@@ -3575,44 +3516,15 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3575
3516
|
}
|
|
3576
3517
|
const reusesDraftAsFinalText = Boolean(payloadText?.trim()) && textEditOk;
|
|
3577
3518
|
const draftContent = draftStream.content();
|
|
3578
|
-
const draftRedacted = reusesDraftAsFinalText ? false : await redactMatrixDraftEvent(client, roomId, draftEventId);
|
|
3579
3519
|
const mediaPayload = ttsSupplement && reusesDraftAsFinalText ? buildTtsSupplementMediaPayload(payload) : {
|
|
3580
3520
|
...payload,
|
|
3581
3521
|
text: reusesDraftAsFinalText ? void 0 : payload.text ?? (ttsSupplement?.visibleTextAlreadyDelivered === true ? void 0 : ttsSupplement?.spokenText)
|
|
3582
3522
|
};
|
|
3583
3523
|
const providerDraftContent = finalizedDraftContent ?? preparedPayloadContent;
|
|
3584
|
-
const previewDelivery = reusesDraftAsFinalText && providerDraftContent ? createDraftDeliveryResult(draftEventId, providerDraftContent) :
|
|
3585
|
-
|
|
3586
|
-
try {
|
|
3587
|
-
mediaDelivery = await deliverMatrixReplies({
|
|
3588
|
-
cfg,
|
|
3589
|
-
replies: [mediaPayload],
|
|
3590
|
-
roomId,
|
|
3591
|
-
client,
|
|
3592
|
-
runtime,
|
|
3593
|
-
textLimit,
|
|
3594
|
-
replyToMode,
|
|
3595
|
-
hasRepliedRef,
|
|
3596
|
-
threadId: threadTarget,
|
|
3597
|
-
replyToId: threadTarget ?? replyToEventId ?? void 0,
|
|
3598
|
-
accountId,
|
|
3599
|
-
mediaLocalRoots,
|
|
3600
|
-
tableMode
|
|
3601
|
-
});
|
|
3602
|
-
} catch (error) {
|
|
3603
|
-
throw toMatrixPartialDeliveryError(error, [previewDelivery]);
|
|
3604
|
-
}
|
|
3605
|
-
draftController.markDraftConsumed();
|
|
3606
|
-
return await completeDelivery(mergeMatrixReplyDeliveryResults([previewDelivery, mediaDelivery]));
|
|
3607
|
-
}
|
|
3608
|
-
const shouldRedactDraft = Boolean(draftEventId) && (payload.isError || payloadReplyMismatch || mustDeliverFinalNormally || draftFinalTextNeedsNormalMentionDelivery);
|
|
3609
|
-
const draftRedacted = shouldRedactDraft && draftEventId ? await redactMatrixDraftEvent(client, roomId, draftEventId) : false;
|
|
3610
|
-
const survivingDraft = shouldRedactDraft && draftEventId ? createSurvivingDraftDelivery(draftEventId, draftRedacted) : mergeMatrixReplyDeliveryResults([]);
|
|
3611
|
-
let deliveredFallback;
|
|
3612
|
-
try {
|
|
3613
|
-
deliveredFallback = await deliverMatrixReplies({
|
|
3524
|
+
const previewDelivery = reusesDraftAsFinalText && providerDraftContent ? createDraftDeliveryResult(draftEventId, providerDraftContent) : draftContent ? createDraftDeliveryResult(draftEventId, draftContent) : mergeMatrixReplyDeliveryResults([]);
|
|
3525
|
+
const deliverMedia = async () => await deliverMatrixReplies({
|
|
3614
3526
|
cfg,
|
|
3615
|
-
replies: [
|
|
3527
|
+
replies: [mediaPayload],
|
|
3616
3528
|
roomId,
|
|
3617
3529
|
client,
|
|
3618
3530
|
runtime,
|
|
@@ -3625,11 +3537,46 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3625
3537
|
mediaLocalRoots,
|
|
3626
3538
|
tableMode
|
|
3627
3539
|
});
|
|
3628
|
-
|
|
3629
|
-
|
|
3540
|
+
if (reusesDraftAsFinalText) {
|
|
3541
|
+
draftController.markDraftConsumed();
|
|
3542
|
+
let mediaDelivery;
|
|
3543
|
+
try {
|
|
3544
|
+
mediaDelivery = await deliverMedia();
|
|
3545
|
+
} catch (error) {
|
|
3546
|
+
throw toMatrixPartialDeliveryError(error, [previewDelivery]);
|
|
3547
|
+
}
|
|
3548
|
+
return await completeDelivery(mergeMatrixReplyDeliveryResults([previewDelivery, mediaDelivery]));
|
|
3549
|
+
}
|
|
3550
|
+
if (draftContent) return await completeDelivery(await settleDraftReplacement({
|
|
3551
|
+
draftEventId,
|
|
3552
|
+
draftContent,
|
|
3553
|
+
deliver: deliverMedia
|
|
3554
|
+
}));
|
|
3555
|
+
return await completeDelivery(await deliverMedia());
|
|
3630
3556
|
}
|
|
3631
|
-
|
|
3632
|
-
|
|
3557
|
+
const shouldRedactDraft = Boolean(draftEventId) && (payload.isError || payloadReplyMismatch || mustDeliverFinalNormally || draftFinalTextNeedsNormalMentionDelivery);
|
|
3558
|
+
const deliverFallback = async () => await deliverMatrixReplies({
|
|
3559
|
+
cfg,
|
|
3560
|
+
replies: [fallbackPayload],
|
|
3561
|
+
roomId,
|
|
3562
|
+
client,
|
|
3563
|
+
runtime,
|
|
3564
|
+
textLimit,
|
|
3565
|
+
replyToMode,
|
|
3566
|
+
hasRepliedRef,
|
|
3567
|
+
threadId: threadTarget,
|
|
3568
|
+
replyToId: threadTarget ?? replyToEventId ?? void 0,
|
|
3569
|
+
accountId,
|
|
3570
|
+
mediaLocalRoots,
|
|
3571
|
+
tableMode
|
|
3572
|
+
});
|
|
3573
|
+
const draftContent = draftStream.content();
|
|
3574
|
+
if (shouldRedactDraft && draftEventId && draftContent) return await completeDelivery(await settleDraftReplacement({
|
|
3575
|
+
draftEventId,
|
|
3576
|
+
draftContent,
|
|
3577
|
+
deliver: deliverFallback
|
|
3578
|
+
}));
|
|
3579
|
+
return await completeDelivery(await deliverFallback());
|
|
3633
3580
|
}
|
|
3634
3581
|
return await completeDelivery(await deliverMatrixReplies({
|
|
3635
3582
|
cfg,
|
|
@@ -3650,7 +3597,7 @@ function createMatrixReplyDispatcher(config) {
|
|
|
3650
3597
|
onError: (err, info) => {
|
|
3651
3598
|
if (info.kind === "final") finalReplyDeliveryFailed = true;
|
|
3652
3599
|
else nonFinalReplyDeliveryFailed = true;
|
|
3653
|
-
if (info.kind === "block")
|
|
3600
|
+
if (info.kind === "block") beginNextBlockDraft();
|
|
3654
3601
|
runtime.error?.(`matrix ${info.kind} reply failed: ${String(err)}`);
|
|
3655
3602
|
},
|
|
3656
3603
|
onReplyStart: typingCallbacks.onReplyStart,
|
|
@@ -3902,8 +3849,9 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
3902
3849
|
})();
|
|
3903
3850
|
if (!resolvedIngressResult) return;
|
|
3904
3851
|
if ("deferredPrefix" in resolvedIngressResult) return;
|
|
3905
|
-
const { route: _route, hasExplicitSessionBinding, roomConfig, isDirectMessage, isRoom, shouldRequireMention, wasMentioned, effectiveWasMentioned, shouldBypassMention, canDetectMention, commandAuthorized, inboundHistory, senderName, bodyText, commandBodyText, media, preflightAudioTranscript, locationPayload, messageId, triggerSnapshot, threadRootId, thread, botLoopProtection, effectiveGroupAllowFrom, effectiveRoomUsers } = resolvedIngressResult;
|
|
3852
|
+
const { route: _route, hasExplicitSessionBinding, roomConfig, isDirectMessage, isRoom, shouldRequireMention, wasMentioned, effectiveWasMentioned, shouldBypassMention, canDetectMention, commandAuthorized, inboundHistory, senderName, bodyText, commandBodyText, media, preflightAudioTranscript, locationPayload, messageId, triggerSnapshot, threadRootId, thread, botLoopProtection, effectiveGroupAllowFrom, effectiveRoomUsers, resolveMessageIngress } = resolvedIngressResult;
|
|
3906
3853
|
const inboundContext = await resolveMatrixInboundContext({
|
|
3854
|
+
resolveMessageIngress,
|
|
3907
3855
|
client,
|
|
3908
3856
|
core,
|
|
3909
3857
|
cfg,
|
|
@@ -4102,19 +4050,21 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
4102
4050
|
},
|
|
4103
4051
|
dispatcherOptions: {
|
|
4104
4052
|
...turnDispatcherOptions,
|
|
4105
|
-
onSettled: () => draftController.
|
|
4053
|
+
onSettled: () => draftController.cancelProgressDraft()
|
|
4106
4054
|
},
|
|
4107
4055
|
replyOptions: {
|
|
4108
4056
|
skillFilter: roomConfig?.skills,
|
|
4109
4057
|
disableBlockStreaming: !blockStreamingEnabled,
|
|
4110
4058
|
onPartialReply: draftStream ? (payload) => draftController.onPartialReply(payload.text ?? "") : void 0,
|
|
4111
4059
|
onBlockReplyQueued: draftStream ? (payload, context) => {
|
|
4112
|
-
if (payload.isCompactionNotice === true) return;
|
|
4060
|
+
if (payload.isCompactionNotice === true) return false;
|
|
4113
4061
|
draftController.queueDraftBlockBoundary(payload, context);
|
|
4062
|
+
return false;
|
|
4114
4063
|
} : void 0,
|
|
4115
4064
|
onAssistantMessageStart: draftStream ? () => {
|
|
4116
4065
|
draftController.resetDraftBlockOffsets();
|
|
4117
4066
|
draftController.resetPreviewToolProgress();
|
|
4067
|
+
return false;
|
|
4118
4068
|
} : void 0,
|
|
4119
4069
|
onQueuedFollowupAdmitted: draftStream ? draftController.resetDraftDeliveryState : void 0,
|
|
4120
4070
|
...draftController.buildPreviewToolProgressReplyOptions(),
|
|
@@ -4128,7 +4078,7 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
4128
4078
|
return;
|
|
4129
4079
|
}
|
|
4130
4080
|
const { dispatchResult } = turnResult;
|
|
4131
|
-
const { queuedFinal
|
|
4081
|
+
const { queuedFinal } = dispatchResult;
|
|
4132
4082
|
if (replyDispatcher.finalReplyDeliveryFailed()) {
|
|
4133
4083
|
logVerboseMessage(`matrix: final reply delivery failed room=${roomId} id=${messageId}; keeping replay committed`);
|
|
4134
4084
|
await commitInboundEventIfClaimed();
|
|
@@ -4140,23 +4090,22 @@ function createMatrixRoomMessageHandler(params) {
|
|
|
4140
4090
|
return;
|
|
4141
4091
|
}
|
|
4142
4092
|
if (isRoom && triggerSnapshot) roomHistoryTracker.consumeHistory(_route.agentId, roomId, triggerSnapshot, messageId, threadRootId ? thread.threadId : void 0);
|
|
4143
|
-
if (!hasFinalInboundReplyDispatch({
|
|
4144
|
-
queuedFinal,
|
|
4145
|
-
counts
|
|
4146
|
-
})) {
|
|
4093
|
+
if (!hasFinalInboundReplyDispatch(dispatchResult)) {
|
|
4147
4094
|
await commitInboundEventIfClaimed();
|
|
4148
4095
|
return;
|
|
4149
4096
|
}
|
|
4150
|
-
const finalCount =
|
|
4097
|
+
const finalCount = resolveInboundReplyDispatchCounts(dispatchResult).final;
|
|
4151
4098
|
logVerboseMessage(`matrix: delivered ${finalCount} reply${finalCount === 1 ? "" : "ies"} to ${replyTarget}`);
|
|
4152
4099
|
await commitInboundEventIfClaimed();
|
|
4153
4100
|
} catch (err) {
|
|
4101
|
+
const draftController = draftControllerRef;
|
|
4102
|
+
if (draftController?.draftStream?.eventId() && draftController.draftDisposition() === "active") draftController.markDraftRetained();
|
|
4154
4103
|
runtime.error?.(`matrix handler failed: ${String(err)}`);
|
|
4155
4104
|
} finally {
|
|
4156
4105
|
const draftStream = draftControllerRef?.draftStream;
|
|
4157
4106
|
if (draftStream) {
|
|
4158
4107
|
const draftEventId = await draftStream.stop().catch(() => void 0);
|
|
4159
|
-
if (draftEventId && draftControllerRef?.
|
|
4108
|
+
if (draftEventId && draftControllerRef?.draftDisposition() === "active") await redactMatrixDraftEvent(client, roomId, draftEventId);
|
|
4160
4109
|
}
|
|
4161
4110
|
inboundReplayClaim?.release();
|
|
4162
4111
|
}
|
|
@@ -4177,10 +4126,10 @@ function shouldPromoteRecentInviteRoom(params) {
|
|
|
4177
4126
|
//#endregion
|
|
4178
4127
|
//#region extensions/matrix/src/matrix/monitor/startup.ts
|
|
4179
4128
|
const loadMatrixStartupMaintenanceDeps = createLazyRuntimeModule(() => Promise.all([
|
|
4180
|
-
import("./
|
|
4129
|
+
import("./config-update-Bor_Pjsv.js").then((n) => n.t),
|
|
4181
4130
|
import("./device-health-B4-YXtJR.js").then((n) => n.t),
|
|
4182
|
-
import("./
|
|
4183
|
-
import("./startup-verification-
|
|
4131
|
+
import("./profile-D-Wubo0A.js").then((n) => n.n),
|
|
4132
|
+
import("./startup-verification-Cs08ca8u.js")
|
|
4184
4133
|
]).then(([configUpdateModule, deviceHealthModule, profileModule, startupVerificationModule]) => ({
|
|
4185
4134
|
updateMatrixAccountConfig: configUpdateModule.updateMatrixAccountConfig,
|
|
4186
4135
|
summarizeMatrixDeviceHealth: deviceHealthModule.summarizeMatrixDeviceHealth,
|
|
@@ -4251,7 +4200,7 @@ function cloneLastDisconnect(value) {
|
|
|
4251
4200
|
function formatSyncError(error) {
|
|
4252
4201
|
if (!error) return null;
|
|
4253
4202
|
if (error instanceof Error) return error.message || error.name || "unknown";
|
|
4254
|
-
return
|
|
4203
|
+
return formatErrorMessage(error);
|
|
4255
4204
|
}
|
|
4256
4205
|
function createMatrixMonitorStatusController(params) {
|
|
4257
4206
|
const status = {
|
|
@@ -4261,7 +4210,8 @@ function createMatrixMonitorStatusController(params) {
|
|
|
4261
4210
|
lastConnectedAt: null,
|
|
4262
4211
|
lastDisconnect: null,
|
|
4263
4212
|
lastError: null,
|
|
4264
|
-
healthState: "starting"
|
|
4213
|
+
healthState: "starting",
|
|
4214
|
+
lifecycle: "starting"
|
|
4265
4215
|
};
|
|
4266
4216
|
const emit = () => {
|
|
4267
4217
|
params.statusSink?.({
|
|
@@ -4270,16 +4220,25 @@ function createMatrixMonitorStatusController(params) {
|
|
|
4270
4220
|
});
|
|
4271
4221
|
};
|
|
4272
4222
|
const noteConnected = (at = Date.now(), options) => {
|
|
4273
|
-
|
|
4274
|
-
|
|
4223
|
+
const lastConnectedAt = status.connected === true ? status.lastConnectedAt ?? at : at;
|
|
4224
|
+
Object.assign(status, channelReadyPatch({
|
|
4225
|
+
lastConnectedAt,
|
|
4226
|
+
lastEventAt: at,
|
|
4227
|
+
lastDisconnect: null,
|
|
4228
|
+
healthState: "healthy"
|
|
4229
|
+
}));
|
|
4275
4230
|
if (options?.transportActivity) Object.assign(status, createTransportActivityStatusPatch(at));
|
|
4276
|
-
status.lastError = null;
|
|
4277
|
-
status.lastDisconnect = null;
|
|
4278
|
-
status.healthState = "healthy";
|
|
4279
4231
|
emit();
|
|
4280
4232
|
};
|
|
4281
4233
|
const noteDisconnected = (paramsLocal) => {
|
|
4282
4234
|
const at = paramsLocal.at ?? Date.now();
|
|
4235
|
+
const tokenInvalidated = isMatrixAccessTokenInvalidatedError(paramsLocal.error);
|
|
4236
|
+
if (status.lifecycle === "blocked" && status.terminalDisconnect === true && !tokenInvalidated) {
|
|
4237
|
+
status.connected = false;
|
|
4238
|
+
status.lastEventAt = at;
|
|
4239
|
+
emit();
|
|
4240
|
+
return;
|
|
4241
|
+
}
|
|
4283
4242
|
const error = formatSyncError(paramsLocal.error);
|
|
4284
4243
|
status.connected = false;
|
|
4285
4244
|
status.lastEventAt = at;
|
|
@@ -4287,8 +4246,13 @@ function createMatrixMonitorStatusController(params) {
|
|
|
4287
4246
|
at,
|
|
4288
4247
|
...error ? { error } : {}
|
|
4289
4248
|
};
|
|
4290
|
-
status.lastError = error;
|
|
4291
4249
|
status.healthState = paramsLocal.state.toLowerCase();
|
|
4250
|
+
if (tokenInvalidated) Object.assign(status, channelBlockedPatch(error ?? "Matrix access token invalidated"));
|
|
4251
|
+
else {
|
|
4252
|
+
status.lastError = error;
|
|
4253
|
+
status.lifecycle = "recovering";
|
|
4254
|
+
status.terminalDisconnect = void 0;
|
|
4255
|
+
}
|
|
4292
4256
|
emit();
|
|
4293
4257
|
};
|
|
4294
4258
|
emit();
|
|
@@ -4318,9 +4282,14 @@ function createMatrixMonitorStatusController(params) {
|
|
|
4318
4282
|
});
|
|
4319
4283
|
},
|
|
4320
4284
|
markStopped(at = Date.now()) {
|
|
4321
|
-
status.
|
|
4322
|
-
|
|
4323
|
-
|
|
4285
|
+
if (status.lifecycle !== "blocked" && status.healthState !== "error") Object.assign(status, channelStoppedPatch({
|
|
4286
|
+
lastEventAt: at,
|
|
4287
|
+
healthState: "stopped"
|
|
4288
|
+
}));
|
|
4289
|
+
else {
|
|
4290
|
+
status.connected = false;
|
|
4291
|
+
status.lastEventAt = at;
|
|
4292
|
+
}
|
|
4324
4293
|
emit();
|
|
4325
4294
|
}
|
|
4326
4295
|
};
|
|
@@ -4385,7 +4354,9 @@ function createMatrixMonitorSyncLifecycle(params) {
|
|
|
4385
4354
|
//#region extensions/matrix/src/matrix/monitor/task-runner.ts
|
|
4386
4355
|
function createMatrixMonitorTaskRunner(params) {
|
|
4387
4356
|
const inFlight = /* @__PURE__ */ new Set();
|
|
4357
|
+
let closed = false;
|
|
4388
4358
|
const runDetachedTask = (label, task) => {
|
|
4359
|
+
if (closed) return Promise.resolve();
|
|
4389
4360
|
const trackedTask = Promise.resolve().then(task).catch((error) => {
|
|
4390
4361
|
const message = String(error);
|
|
4391
4362
|
params.logVerboseMessage(`matrix: ${label} failed (${message})`);
|
|
@@ -4403,6 +4374,7 @@ function createMatrixMonitorTaskRunner(params) {
|
|
|
4403
4374
|
while (inFlight.size > 0) await Promise.allSettled(Array.from(inFlight));
|
|
4404
4375
|
};
|
|
4405
4376
|
return {
|
|
4377
|
+
close: () => closed = true,
|
|
4406
4378
|
runDetachedTask,
|
|
4407
4379
|
waitForIdle
|
|
4408
4380
|
};
|
|
@@ -4504,28 +4476,30 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4504
4476
|
statusSink: opts.setStatus
|
|
4505
4477
|
});
|
|
4506
4478
|
let cleanedUp = false;
|
|
4479
|
+
let cleanupPromise = null;
|
|
4507
4480
|
let client = null;
|
|
4481
|
+
let clientLease = null;
|
|
4482
|
+
let monitorLifecycleSignal = opts.abortSignal;
|
|
4508
4483
|
let threadBindingManager = null;
|
|
4509
4484
|
const monitorTaskRunner = createMatrixMonitorTaskRunner({
|
|
4510
4485
|
logger,
|
|
4511
4486
|
logVerboseMessage
|
|
4512
4487
|
});
|
|
4488
|
+
let disposeAutoJoin = () => {};
|
|
4489
|
+
let disposeMonitorEvents = () => {};
|
|
4513
4490
|
let syncLifecycle = null;
|
|
4514
|
-
|
|
4515
|
-
|
|
4491
|
+
let monitorSetupClosed = false;
|
|
4492
|
+
const cleanup = (mode = "persist") => {
|
|
4493
|
+
if (cleanupPromise) return cleanupPromise;
|
|
4516
4494
|
cleanedUp = true;
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
}
|
|
4524
|
-
|
|
4525
|
-
syncLifecycle?.dispose();
|
|
4526
|
-
statusController.markStopped();
|
|
4527
|
-
setActiveMatrixClient(null, auth.accountId);
|
|
4528
|
-
}
|
|
4495
|
+
cleanupPromise = (async () => {
|
|
4496
|
+
try {
|
|
4497
|
+
await clientLease?.release({ mode });
|
|
4498
|
+
} finally {
|
|
4499
|
+
statusController.markStopped();
|
|
4500
|
+
}
|
|
4501
|
+
})();
|
|
4502
|
+
return cleanupPromise;
|
|
4529
4503
|
};
|
|
4530
4504
|
const defaultGroupPolicy = resolveDefaultGroupPolicy(cfg);
|
|
4531
4505
|
const { groupPolicy: groupPolicyRaw, providerMissingFallbackApplied } = resolveAllowlistProviderRuntimeGroupPolicy({
|
|
@@ -4582,14 +4556,32 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4582
4556
|
const onSyncState = (state) => {
|
|
4583
4557
|
noteSyncHealthState(state);
|
|
4584
4558
|
};
|
|
4559
|
+
const monitorRetirement = {
|
|
4560
|
+
closeTaskAdmission: () => {
|
|
4561
|
+
monitorSetupClosed = true;
|
|
4562
|
+
monitorTaskRunner.close();
|
|
4563
|
+
},
|
|
4564
|
+
detachListeners: () => {
|
|
4565
|
+
disposeAutoJoin();
|
|
4566
|
+
disposeMonitorEvents();
|
|
4567
|
+
client?.off("sync.state", onSyncState);
|
|
4568
|
+
syncLifecycle?.dispose();
|
|
4569
|
+
},
|
|
4570
|
+
waitForTasks: monitorTaskRunner.waitForIdle,
|
|
4571
|
+
cleanup: () => threadBindingManager?.stop()
|
|
4572
|
+
};
|
|
4585
4573
|
try {
|
|
4586
|
-
|
|
4574
|
+
clientLease = await acquireSharedMatrixClient({
|
|
4587
4575
|
cfg,
|
|
4588
4576
|
auth: authWithLimit,
|
|
4589
4577
|
startClient: false,
|
|
4590
|
-
accountId: auth.accountId
|
|
4578
|
+
accountId: auth.accountId,
|
|
4579
|
+
abortSignal: opts.abortSignal,
|
|
4580
|
+
role: "monitor"
|
|
4591
4581
|
});
|
|
4592
|
-
|
|
4582
|
+
client = clientLease.client;
|
|
4583
|
+
monitorLifecycleSignal = opts.abortSignal ? AbortSignal.any([opts.abortSignal, clientLease.abortSignal]) : clientLease.abortSignal;
|
|
4584
|
+
clientLease.registerMonitorRetirement(monitorRetirement);
|
|
4593
4585
|
const inboundDeduper = createMatrixInboundEventDeduper({
|
|
4594
4586
|
auth,
|
|
4595
4587
|
env: process.env
|
|
@@ -4597,11 +4589,11 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4597
4589
|
syncLifecycle = createMatrixMonitorSyncLifecycle({
|
|
4598
4590
|
client,
|
|
4599
4591
|
statusController,
|
|
4600
|
-
isStopping: () => cleanedUp ||
|
|
4592
|
+
isStopping: () => cleanedUp || monitorLifecycleSignal?.aborted === true
|
|
4601
4593
|
});
|
|
4602
4594
|
client.on("sync.state", onSyncState);
|
|
4603
4595
|
const dropPreStartupMessages = !client.hasPersistedSyncState();
|
|
4604
|
-
const { getRoomInfo, getMemberDisplayName } = createMatrixRoomInfoResolver(client);
|
|
4596
|
+
const { getRoomInfo, getMemberDisplayName, invalidateMemberDisplayName } = createMatrixRoomInfoResolver(client);
|
|
4605
4597
|
const isExplicitlyConfiguredRoom = async (roomId) => {
|
|
4606
4598
|
const roomInfoForConfig = needsRoomAliasesForConfig ? await getRoomInfo(roomId, { includeAliases: true }) : void 0;
|
|
4607
4599
|
const aliases = roomInfoForConfig ? [roomInfoForConfig.canonicalAlias ?? "", ...roomInfoForConfig.altAliases].filter(Boolean) : [];
|
|
@@ -4639,10 +4631,11 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4639
4631
|
}
|
|
4640
4632
|
}
|
|
4641
4633
|
});
|
|
4642
|
-
registerMatrixAutoJoin({
|
|
4634
|
+
disposeAutoJoin = registerMatrixAutoJoin({
|
|
4643
4635
|
client,
|
|
4644
4636
|
accountConfig,
|
|
4645
|
-
runtime
|
|
4637
|
+
runtime,
|
|
4638
|
+
runDetachedTask: monitorTaskRunner.runDetachedTask
|
|
4646
4639
|
});
|
|
4647
4640
|
const handleRoomMessage = createMatrixRoomMessageHandler({
|
|
4648
4641
|
client,
|
|
@@ -4682,7 +4675,7 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4682
4675
|
getMemberDisplayName,
|
|
4683
4676
|
needsRoomAliasesForConfig
|
|
4684
4677
|
});
|
|
4685
|
-
|
|
4678
|
+
const createdThreadBindingManager = await createMatrixThreadBindingManager({
|
|
4686
4679
|
cfg,
|
|
4687
4680
|
accountId: effectiveAccountId,
|
|
4688
4681
|
auth,
|
|
@@ -4692,8 +4685,14 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4692
4685
|
maxAgeMs: threadBindingMaxAgeMs,
|
|
4693
4686
|
logVerboseMessage
|
|
4694
4687
|
});
|
|
4688
|
+
if (monitorSetupClosed) {
|
|
4689
|
+
await createdThreadBindingManager.stop();
|
|
4690
|
+
await cleanup("stop");
|
|
4691
|
+
return;
|
|
4692
|
+
}
|
|
4693
|
+
threadBindingManager = createdThreadBindingManager;
|
|
4695
4694
|
logVerboseMessage(`matrix: thread bindings ready account=${threadBindingManager.accountId} idleMs=${threadBindingIdleTimeoutMs} maxAgeMs=${threadBindingMaxAgeMs}`);
|
|
4696
|
-
registerMatrixMonitorEvents({
|
|
4695
|
+
disposeMonitorEvents = registerMatrixMonitorEvents({
|
|
4697
4696
|
cfg,
|
|
4698
4697
|
client,
|
|
4699
4698
|
auth,
|
|
@@ -4706,6 +4705,7 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4706
4705
|
accountId: effectiveAccountId
|
|
4707
4706
|
}).catch(() => []),
|
|
4708
4707
|
directTracker,
|
|
4708
|
+
invalidateMemberDisplayName,
|
|
4709
4709
|
logVerboseMessage,
|
|
4710
4710
|
warnedEncryptedRooms,
|
|
4711
4711
|
warnedCryptoMissingRooms,
|
|
@@ -4717,18 +4717,17 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4717
4717
|
runDetachedTask: monitorTaskRunner.runDetachedTask
|
|
4718
4718
|
});
|
|
4719
4719
|
logVerboseMessage("matrix: starting client");
|
|
4720
|
-
await
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
});
|
|
4720
|
+
await clientLease.start(monitorLifecycleSignal);
|
|
4721
|
+
if (monitorSetupClosed) {
|
|
4722
|
+
await cleanup("stop");
|
|
4723
|
+
return;
|
|
4724
|
+
}
|
|
4726
4725
|
logVerboseMessage("matrix: client started");
|
|
4727
4726
|
logger.info(`matrix: logged in as ${auth.userId}`);
|
|
4728
4727
|
backfillMatrixAuthDeviceIdAfterStartup({
|
|
4729
4728
|
auth,
|
|
4730
4729
|
env: process.env,
|
|
4731
|
-
abortSignal:
|
|
4730
|
+
abortSignal: monitorLifecycleSignal
|
|
4732
4731
|
}).catch((err) => {
|
|
4733
4732
|
logVerboseMessage(`matrix: failed to backfill deviceId after startup (${String(err)})`);
|
|
4734
4733
|
});
|
|
@@ -4738,7 +4737,7 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4738
4737
|
accountId: effectiveAccountId,
|
|
4739
4738
|
capability: CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
|
|
4740
4739
|
context: { client },
|
|
4741
|
-
abortSignal:
|
|
4740
|
+
abortSignal: monitorLifecycleSignal
|
|
4742
4741
|
});
|
|
4743
4742
|
await runMatrixStartupMaintenance({
|
|
4744
4743
|
client,
|
|
@@ -4757,9 +4756,13 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4757
4756
|
},
|
|
4758
4757
|
loadWebMedia: async (url, maxBytes) => await core.media.loadWebMedia(url, maxBytes),
|
|
4759
4758
|
env: process.env,
|
|
4760
|
-
abortSignal:
|
|
4759
|
+
abortSignal: monitorLifecycleSignal
|
|
4761
4760
|
});
|
|
4762
|
-
|
|
4761
|
+
if (monitorSetupClosed) {
|
|
4762
|
+
await cleanup("stop");
|
|
4763
|
+
return;
|
|
4764
|
+
}
|
|
4765
|
+
await Promise.race([waitUntilAbort(monitorLifecycleSignal, async () => {
|
|
4763
4766
|
try {
|
|
4764
4767
|
logVerboseMessage("matrix: stopping client");
|
|
4765
4768
|
await cleanup();
|
|
@@ -4767,8 +4770,13 @@ async function monitorMatrixProvider(opts = {}) {
|
|
|
4767
4770
|
logger.warn("matrix: failed during monitor shutdown cleanup", { error: String(err) });
|
|
4768
4771
|
}
|
|
4769
4772
|
}), syncLifecycle.waitForFatalStop()]);
|
|
4773
|
+
await cleanup();
|
|
4770
4774
|
} catch (err) {
|
|
4771
|
-
if (
|
|
4775
|
+
if (monitorSetupClosed) {
|
|
4776
|
+
await cleanup("stop");
|
|
4777
|
+
return;
|
|
4778
|
+
}
|
|
4779
|
+
if (monitorLifecycleSignal?.aborted === true && isMatrixStartupAbortError(err)) {
|
|
4772
4780
|
await cleanup("stop");
|
|
4773
4781
|
return;
|
|
4774
4782
|
}
|