@openclaw/signal 2026.7.2-beta.5 → 2026.8.1-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/api.js +7 -7
- package/dist/{approval-handler.runtime-C-XYgcxE.js → approval-handler.runtime-Bi5yNhnj.js} +2 -2
- package/dist/{approval-reactions-DtL47gSK.js → approval-reactions-BulCzhdB.js} +15 -45
- package/dist/{channel-CBIljGCH.js → channel-CzDJMDtX.js} +50 -91
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-B8GXmuol.js → channel.runtime-D12iYzJB.js} +2 -2
- package/dist/{client-BazXTH7O.js → client-CvnR8_XA.js} +31 -34
- package/dist/{client-adapter-mXGeEHQJ.js → client-adapter-D9SNPaNx.js} +13 -6
- package/dist/{config-schema-DLvpQPN5.js → config-schema-CkMIK7zp.js} +4 -7
- package/dist/contract-api.js +1 -1
- package/dist/{doctor-contract-api-DbUCknbC.js → doctor-contract-api-Dnp5eQQJ.js} +46 -54
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{install-signal-cli-qJF7iC4h.js → install-signal-cli-Cpiyk0k1.js} +8 -5
- package/dist/{monitor-CHBkf7lk.js → monitor-DiN2hKnG.js} +177 -126
- package/dist/{probe-Br9abaGp.js → probe-C_THuQzn.js} +23 -7
- package/dist/question-reactions-ByjH5qST.js +80 -0
- package/dist/{reaction-runtime-api-BjeDyKcz.js → reaction-runtime-api-Cf6QHcE5.js} +8 -19
- package/dist/reaction-runtime-api.js +1 -1
- package/dist/runtime-api.js +7 -7
- package/dist/{send-B_Ks4MZr.js → send-BvGgByMd.js} +12 -3
- package/dist/{send.runtime-CbuXycZT.js → send.runtime-CtTBBrjL.js} +1 -1
- package/dist/{transport-detection-Da06-LOL.js → transport-detection-BItHawMq.js} +50 -145
- package/dist/{transport-detection.runtime-D_190UUL.js → transport-detection.runtime-DoiwPcrG.js} +1 -1
- package/dist/{transport-probes.runtime-CV6Qs0Og.js → transport-probes.runtime-BsJdp0oI.js} +1 -1
- package/openclaw.plugin.json +4 -1
- package/package.json +5 -5
- package/dist/approval-resolver-B3m0D2R0.js +0 -16
- package/dist/question-reactions-Ds48FtEu.js +0 -109
|
@@ -2,24 +2,24 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
|
2
2
|
import { i as resolveSignalAccount, o as resolveSignalReplyToMode } from "./accounts-DrStJjiK.js";
|
|
3
3
|
import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine } from "./identity-BQ4OzXXk.js";
|
|
4
4
|
import { t as getOptionalSignalRuntime } from "./runtime-JPrGlV7h.js";
|
|
5
|
-
import { i as materializeSignalPresentationFallback, n as registerSignalReplyContext, o as resolveSignalReactionLevel, s as formatSignalMediaText, u as isSignalNativeApprovalHandlerConfigured } from "./transport-detection-
|
|
6
|
-
import { n as signalRpcRequest, r as streamSignalEvents, t as signalCheck } from "./client-adapter-
|
|
7
|
-
import { n as sendReactionSignal } from "./reaction-runtime-api-
|
|
8
|
-
import { a as maybeResolveSignalApprovalReaction, l as resolveSignalApprovalConversationKey, s as registerSignalApprovalReactionTargetForDeliveredPayload, t as addSignalApprovalReactionHintToStructuredPayload } from "./approval-reactions-
|
|
9
|
-
import { r as registerSignalQuestionReactionTargetForDeliveredPayload, t as maybeResolveSignalQuestionReaction } from "./question-reactions-
|
|
10
|
-
import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-
|
|
11
|
-
import { bindIngressLifecycleToReplyOptions, createChannelIngressMonitor, createChannelMessageReplyPipeline, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
5
|
+
import { i as materializeSignalPresentationFallback, n as registerSignalReplyContext, o as resolveSignalReactionLevel, s as formatSignalMediaText, u as isSignalNativeApprovalHandlerConfigured } from "./transport-detection-BItHawMq.js";
|
|
6
|
+
import { n as signalRpcRequest, r as streamSignalEvents, t as signalCheck } from "./client-adapter-D9SNPaNx.js";
|
|
7
|
+
import { n as sendReactionSignal } from "./reaction-runtime-api-Cf6QHcE5.js";
|
|
8
|
+
import { a as maybeResolveSignalApprovalReaction, l as resolveSignalApprovalConversationKey, s as registerSignalApprovalReactionTargetForDeliveredPayload, t as addSignalApprovalReactionHintToStructuredPayload } from "./approval-reactions-BulCzhdB.js";
|
|
9
|
+
import { r as registerSignalQuestionReactionTargetForDeliveredPayload, t as maybeResolveSignalQuestionReaction } from "./question-reactions-ByjH5qST.js";
|
|
10
|
+
import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-BvGgByMd.js";
|
|
11
|
+
import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
12
12
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
13
|
-
import { detectMime, estimateBase64DecodedBytes, kindFromMime, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
|
|
13
|
+
import { canonicalizeBase64, detectMime, estimateBase64DecodedBytes, kindFromMime, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
|
|
14
14
|
import { resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
15
|
-
import { normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
15
|
+
import { asPositiveSafeInteger, isRecord, normalizeNullableString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
16
16
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
17
17
|
import { normalizeE164, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
18
|
-
import { buildChannelInboundEventContext, buildMentionRegexes, createChannelInboundDebouncer, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundFromLabel, formatInboundMediaUnavailableText, hasVisibleInboundReplyDispatch, logInboundDrop, matchesMentionPatterns, resolveEnvelopeFormatOptions, resolveInboundMentionDecision, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, shouldDebounceTextInbound, toHistoryMediaEntries,
|
|
19
|
-
import nodePath from "node:path";
|
|
18
|
+
import { buildChannelInboundEventContext, buildMentionRegexes, createChannelInboundDebouncer, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundFromLabel, formatInboundMediaUnavailableText, hasVisibleInboundReplyDispatch, logInboundDrop, matchesMentionPatterns, readAgentRunTerminalOutcome, resolveEnvelopeFormatOptions, resolveInboundMentionDecision, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, shouldDebounceTextInbound, toHistoryMediaEntries, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
|
|
20
19
|
import { collectErrorGraphCandidates, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
21
20
|
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
|
22
21
|
import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
|
|
22
|
+
import path from "node:path";
|
|
23
23
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
24
24
|
import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
25
25
|
import { deliverTextOrMediaReply, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
@@ -44,6 +44,7 @@ import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-ru
|
|
|
44
44
|
import { listChatCommands, maybeResolveTextAlias, normalizeCommandBody } from "openclaw/plugin-sdk/command-auth-native";
|
|
45
45
|
import { isAbortRequestText } from "openclaw/plugin-sdk/command-primitives-runtime";
|
|
46
46
|
import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
|
|
47
|
+
import { channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
47
48
|
//#region extensions/signal/src/daemon.ts
|
|
48
49
|
const SIGNAL_DAEMON_STOP_KILL_TIMEOUT_MS = 1500;
|
|
49
50
|
function formatSignalDaemonExit(exit) {
|
|
@@ -71,7 +72,7 @@ function bindSignalCliOutput(params) {
|
|
|
71
72
|
function resolveSignalCliConfigPath(raw) {
|
|
72
73
|
const value = raw.trim();
|
|
73
74
|
if (value === "~") return os.homedir();
|
|
74
|
-
if (value.startsWith("~/") || value.startsWith("~\\")) return
|
|
75
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) return path.join(os.homedir(), value.slice(2));
|
|
75
76
|
return value;
|
|
76
77
|
}
|
|
77
78
|
function buildDaemonArgs(opts) {
|
|
@@ -179,6 +180,37 @@ function spawnSignalDaemon(opts) {
|
|
|
179
180
|
};
|
|
180
181
|
}
|
|
181
182
|
//#endregion
|
|
183
|
+
//#region extensions/signal/src/daemon-lifecycle.ts
|
|
184
|
+
function createSignalDaemonLifecycle(params) {
|
|
185
|
+
let daemonHandle = null;
|
|
186
|
+
let daemonStopRequested = false;
|
|
187
|
+
let daemonStopPromise;
|
|
188
|
+
let daemonExitError;
|
|
189
|
+
const daemonAbortController = new AbortController();
|
|
190
|
+
const abortSignal = params.abortSignal ? AbortSignal.any([params.abortSignal, daemonAbortController.signal]) : daemonAbortController.signal;
|
|
191
|
+
const stop = () => {
|
|
192
|
+
if (daemonStopPromise) return daemonStopPromise;
|
|
193
|
+
daemonStopRequested = true;
|
|
194
|
+
if (!daemonAbortController.signal.aborted) daemonAbortController.abort(params.abortSignal?.reason ?? /* @__PURE__ */ new Error("Signal monitor stopped"));
|
|
195
|
+
daemonStopPromise = daemonHandle?.stop() ?? Promise.resolve();
|
|
196
|
+
return daemonStopPromise;
|
|
197
|
+
};
|
|
198
|
+
const attach = (handle) => {
|
|
199
|
+
daemonHandle = handle;
|
|
200
|
+
handle.exited.then((exit) => {
|
|
201
|
+
if (daemonStopRequested || params.abortSignal?.aborted) return;
|
|
202
|
+
daemonExitError = new Error(formatSignalDaemonExit(exit));
|
|
203
|
+
if (!daemonAbortController.signal.aborted) daemonAbortController.abort(daemonExitError);
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
return {
|
|
207
|
+
attach,
|
|
208
|
+
stop,
|
|
209
|
+
getExitError: () => daemonExitError,
|
|
210
|
+
abortSignal
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
//#endregion
|
|
182
214
|
//#region extensions/signal/src/monitor/access-policy.ts
|
|
183
215
|
const SIGNAL_UUID_KIND = "plugin:signal-uuid";
|
|
184
216
|
const SIGNAL_GROUP_KIND = "plugin:signal-group";
|
|
@@ -273,6 +305,7 @@ async function resolveSignalAccessState(params) {
|
|
|
273
305
|
kind: isGroup ? "group" : "direct",
|
|
274
306
|
id: isGroup ? params.groupId ?? "unknown" : params.sender.raw
|
|
275
307
|
},
|
|
308
|
+
contextBinding: params.contextBinding,
|
|
276
309
|
...isGroup ? { event: { mayPair: false } } : {},
|
|
277
310
|
dmPolicy: params.dmPolicy,
|
|
278
311
|
groupPolicy: params.groupPolicy,
|
|
@@ -387,17 +420,9 @@ function createSignalPendingInboundRegistry(accountId) {
|
|
|
387
420
|
if (!conversationKey) return;
|
|
388
421
|
for (const inboundKey of countsByConversation.get(conversationKey)?.keys() ?? []) cancelKey(inboundKey);
|
|
389
422
|
};
|
|
390
|
-
const completeAfter = (flush) => async (entries) => {
|
|
391
|
-
try {
|
|
392
|
-
await flush(entries);
|
|
393
|
-
} finally {
|
|
394
|
-
complete(entries);
|
|
395
|
-
}
|
|
396
|
-
};
|
|
397
423
|
return {
|
|
398
424
|
track,
|
|
399
425
|
complete,
|
|
400
|
-
completeAfter,
|
|
401
426
|
cancelPendingOnAbort
|
|
402
427
|
};
|
|
403
428
|
}
|
|
@@ -612,8 +637,8 @@ function createSignalEventHandler(deps) {
|
|
|
612
637
|
chatType: entry.isGroup ? "group" : "direct"
|
|
613
638
|
});
|
|
614
639
|
const replyThreading = resolveBatchedReplyThreadingPolicy(replyToMode, entry.isBatched === true);
|
|
615
|
-
const media =
|
|
616
|
-
const ctxPayload = buildChannelInboundEventContext({
|
|
640
|
+
const media = await toInboundMediaFactsWithMetadata(entry.media);
|
|
641
|
+
const ctxPayload = (deps.channelRuntime?.inbound.buildContext ?? buildChannelInboundEventContext)({
|
|
617
642
|
channel: "signal",
|
|
618
643
|
supplemental: { quote: entry.replyToBody ? {
|
|
619
644
|
body: entry.replyToBody,
|
|
@@ -657,6 +682,7 @@ function createSignalEventHandler(deps) {
|
|
|
657
682
|
} } : {},
|
|
658
683
|
commands: { authorized: entry.commandAuthorized }
|
|
659
684
|
},
|
|
685
|
+
channelIngress: entry.channelIngress,
|
|
660
686
|
media,
|
|
661
687
|
extra: {
|
|
662
688
|
GroupSubject: entry.isGroup ? entry.groupName ?? void 0 : void 0,
|
|
@@ -664,7 +690,7 @@ function createSignalEventHandler(deps) {
|
|
|
664
690
|
}
|
|
665
691
|
});
|
|
666
692
|
if (shouldLogVerbose()) {
|
|
667
|
-
const preview = truncateUtf16Safe(body, 200).replace(
|
|
693
|
+
const preview = truncateUtf16Safe(body, 200).replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
668
694
|
logVerbose(`signal inbound: from=${ctxPayload.From} len=${body.length} preview="${preview}"`);
|
|
669
695
|
}
|
|
670
696
|
const statusReactionTimestamp = resolveSignalStatusReactionTimestamp(entry);
|
|
@@ -682,7 +708,6 @@ function createSignalEventHandler(deps) {
|
|
|
682
708
|
isDirect: !entry.isGroup,
|
|
683
709
|
isGroup: entry.isGroup,
|
|
684
710
|
isMentionableGroup: entry.isGroup,
|
|
685
|
-
requireMention: entry.requireMention === true,
|
|
686
711
|
canDetectMention: entry.canDetectMention === true,
|
|
687
712
|
effectiveWasMentioned: entry.wasMentioned === true
|
|
688
713
|
}));
|
|
@@ -846,13 +871,16 @@ function createSignalEventHandler(deps) {
|
|
|
846
871
|
onToolStart: async (payload) => {
|
|
847
872
|
const toolName = payload.name?.trim();
|
|
848
873
|
if (toolName) await statusReactionController.setTool(toolName);
|
|
874
|
+
return false;
|
|
849
875
|
},
|
|
850
876
|
onCompactionStart: async () => {
|
|
851
877
|
await statusReactionController.setCompacting();
|
|
878
|
+
return false;
|
|
852
879
|
},
|
|
853
880
|
onCompactionEnd: async () => {
|
|
854
881
|
statusReactionController.cancelPending();
|
|
855
882
|
await statusReactionController.setThinking();
|
|
883
|
+
return false;
|
|
856
884
|
}
|
|
857
885
|
} : {},
|
|
858
886
|
onModelSelected
|
|
@@ -862,9 +890,10 @@ function createSignalEventHandler(deps) {
|
|
|
862
890
|
if (!statusReactionController) return;
|
|
863
891
|
const hasFinalResponse = result.dispatched && hasVisibleInboundReplyDispatch(result.dispatchResult);
|
|
864
892
|
const hasDeliveryFailure = result.dispatched && hasSignalStatusReplyDeliveryFailure(result.dispatchResult);
|
|
893
|
+
const hasAgentRunFailure = result.dispatched && readAgentRunTerminalOutcome(result.dispatchResult) === "failed";
|
|
865
894
|
finalizeSignalStatusReaction({
|
|
866
895
|
controller: statusReactionController,
|
|
867
|
-
outcome: hasFinalResponse && !hasDeliveryFailure ? "done" : "error"
|
|
896
|
+
outcome: hasFinalResponse && !hasDeliveryFailure && !hasAgentRunFailure ? "done" : "error"
|
|
868
897
|
}).catch((err) => {
|
|
869
898
|
logVerbose(`signal: status reaction finalize failed: ${String(err)}`);
|
|
870
899
|
});
|
|
@@ -872,15 +901,21 @@ function createSignalEventHandler(deps) {
|
|
|
872
901
|
}
|
|
873
902
|
});
|
|
874
903
|
}
|
|
875
|
-
async function flushSignalInboundEntries(entries) {
|
|
904
|
+
async function flushSignalInboundEntries(entries, lifecycle, settle) {
|
|
876
905
|
const last = entries.at(-1);
|
|
877
906
|
if (!last) return;
|
|
878
|
-
const
|
|
907
|
+
const channelIngress = await resolveSignalBatchChannelIngress(entries, last);
|
|
908
|
+
if (channelIngress.some((entry) => !entry.senderAccess.allowed)) {
|
|
909
|
+
logVerbose("signal: authorization changed before dispatch");
|
|
910
|
+
await settle();
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
879
913
|
if (entries.length === 1) {
|
|
880
|
-
await handleSignalInboundMessage(
|
|
914
|
+
await handleSignalInboundMessage({
|
|
881
915
|
...last,
|
|
916
|
+
channelIngress,
|
|
882
917
|
turnAdoptionLifecycle: lifecycle
|
|
883
|
-
}
|
|
918
|
+
});
|
|
884
919
|
await settle();
|
|
885
920
|
return;
|
|
886
921
|
}
|
|
@@ -894,14 +929,34 @@ function createSignalEventHandler(deps) {
|
|
|
894
929
|
...last,
|
|
895
930
|
bodyText: combinedText,
|
|
896
931
|
commandBody: combinedCommandBody,
|
|
897
|
-
|
|
932
|
+
turnAdoptionLifecycle: lifecycle,
|
|
898
933
|
isBatched: true,
|
|
899
934
|
nativeReplyBody: last.nativeReplyBody ?? last.bodyText,
|
|
900
|
-
media: entries.flatMap((entry) => entry.media ?? [])
|
|
935
|
+
media: entries.flatMap((entry) => entry.media ?? []),
|
|
936
|
+
channelIngress
|
|
901
937
|
});
|
|
902
938
|
await settle();
|
|
903
939
|
}
|
|
904
|
-
async function
|
|
940
|
+
async function resolveSignalBatchChannelIngress(entries, last) {
|
|
941
|
+
if (last.boundChannelIngress) return last.boundChannelIngress;
|
|
942
|
+
const route = resolveSignalInboundRoute({
|
|
943
|
+
cfg: deps.cfg,
|
|
944
|
+
accountId: deps.accountId,
|
|
945
|
+
isGroup: last.isGroup,
|
|
946
|
+
groupId: last.groupId,
|
|
947
|
+
senderPeerId: last.senderPeerId
|
|
948
|
+
});
|
|
949
|
+
const contextBinding = {
|
|
950
|
+
agentId: route.agentId,
|
|
951
|
+
sessionKey: route.sessionKey,
|
|
952
|
+
...last.messageId ? { messageId: last.messageId } : {},
|
|
953
|
+
inboundEventKind: "user_request"
|
|
954
|
+
};
|
|
955
|
+
const resolved = await Promise.all(entries.flatMap((entry) => entry.resolveChannelIngress ? [entry.resolveChannelIngress(contextBinding)] : (entry.channelIngress ?? []).map(async (ingress) => ingress)));
|
|
956
|
+
last.boundChannelIngress = resolved;
|
|
957
|
+
return resolved;
|
|
958
|
+
}
|
|
959
|
+
async function retrySignalInboundFlush(entries, lifecycle, settle, initialError) {
|
|
905
960
|
let lastError = initialError;
|
|
906
961
|
for (const [attemptIndex, delayMs] of RETRYABLE_FLUSH_RETRY_DELAYS_MS.entries()) {
|
|
907
962
|
const attempt = attemptIndex + 1;
|
|
@@ -917,7 +972,7 @@ function createSignalEventHandler(deps) {
|
|
|
917
972
|
}
|
|
918
973
|
if (deps.abortSignal?.aborted) return;
|
|
919
974
|
try {
|
|
920
|
-
await flushSignalInboundEntries(entries);
|
|
975
|
+
await flushSignalInboundEntries(entries, lifecycle, settle);
|
|
921
976
|
return;
|
|
922
977
|
} catch (err) {
|
|
923
978
|
if (deps.abortSignal?.aborted) return;
|
|
@@ -927,26 +982,41 @@ function createSignalEventHandler(deps) {
|
|
|
927
982
|
}
|
|
928
983
|
throw lastError;
|
|
929
984
|
}
|
|
930
|
-
const flushDebouncedSignalInboundEntries =
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
985
|
+
const flushDebouncedSignalInboundEntries = (entries, createFlush) => {
|
|
986
|
+
const { lifecycle, settle } = fanInChannelIngressLifecycles(entries.map((entry) => entry.turnAdoptionLifecycle));
|
|
987
|
+
return createFlush({
|
|
988
|
+
lifecycle,
|
|
989
|
+
dispatch: async (admissionLifecycle) => {
|
|
990
|
+
if (!entries.some((entry) => activeEnqueueEntries.has(entry)) && deps.abortSignal?.aborted) return;
|
|
991
|
+
try {
|
|
992
|
+
await flushSignalInboundEntries(entries, admissionLifecycle, settle);
|
|
993
|
+
} catch (err) {
|
|
994
|
+
if (!isSignalReplySessionInitConflictError(err)) throw err;
|
|
995
|
+
if (deps.abortSignal?.aborted) return;
|
|
996
|
+
await retrySignalInboundFlush(entries, admissionLifecycle, settle, err).catch(async (terminalError) => {
|
|
997
|
+
await Promise.all(entries.map((entry) => Promise.resolve(entry.turnAdoptionLifecycle?.onAbandoned())));
|
|
998
|
+
throw terminalError;
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
944
1003
|
};
|
|
945
1004
|
const reportSignalInboundFlushError = (err) => {
|
|
946
1005
|
deps.runtime.error?.(`signal debounce flush failed: ${String(err)}`);
|
|
947
1006
|
};
|
|
948
1007
|
const pendingInboundRegistry = createSignalPendingInboundRegistry(deps.accountId);
|
|
949
|
-
const
|
|
1008
|
+
const trackSignalInboundFlush = (flush) => {
|
|
1009
|
+
deps.runTrackedTask?.(() => flush.completion.catch(() => void 0));
|
|
1010
|
+
return flush;
|
|
1011
|
+
};
|
|
1012
|
+
const flushNormalSignalInboundEntries = (entries, createFlush) => {
|
|
1013
|
+
const flush = flushDebouncedSignalInboundEntries(entries, createFlush);
|
|
1014
|
+
const completion = flush.completion.finally(() => pendingInboundRegistry.complete(entries));
|
|
1015
|
+
return trackSignalInboundFlush({
|
|
1016
|
+
admission: flush.admission,
|
|
1017
|
+
completion
|
|
1018
|
+
});
|
|
1019
|
+
};
|
|
950
1020
|
const { debouncer } = createChannelInboundDebouncer({
|
|
951
1021
|
cfg: deps.cfg,
|
|
952
1022
|
channel: "signal",
|
|
@@ -966,7 +1036,7 @@ function createSignalEventHandler(deps) {
|
|
|
966
1036
|
serializeImmediate: true,
|
|
967
1037
|
buildKey: (entry) => resolveSignalControlLaneKey(deps.accountId, entry),
|
|
968
1038
|
shouldDebounce: () => false,
|
|
969
|
-
onFlush: flushDebouncedSignalInboundEntries,
|
|
1039
|
+
onFlush: (entries, createFlush) => trackSignalInboundFlush(flushDebouncedSignalInboundEntries(entries, createFlush)),
|
|
970
1040
|
onError: reportSignalInboundFlushError
|
|
971
1041
|
});
|
|
972
1042
|
async function handleReactionOnlyInbound(params) {
|
|
@@ -1011,6 +1081,7 @@ function createSignalEventHandler(deps) {
|
|
|
1011
1081
|
if (!deps.shouldEmitSignalReactionNotification({
|
|
1012
1082
|
mode: deps.reactionMode,
|
|
1013
1083
|
account: deps.account,
|
|
1084
|
+
accountUuid: deps.accountUuid,
|
|
1014
1085
|
targets,
|
|
1015
1086
|
sender: params.sender,
|
|
1016
1087
|
allowlist: deps.reactionAllowlist
|
|
@@ -1071,7 +1142,7 @@ function createSignalEventHandler(deps) {
|
|
|
1071
1142
|
const isGroup = Boolean(groupId);
|
|
1072
1143
|
const hasControlCommandInMessage = isControlCommandMessage(messageText, deps.cfg);
|
|
1073
1144
|
const senderDisplay = formatSignalSenderDisplay(sender);
|
|
1074
|
-
const
|
|
1145
|
+
const resolveChannelIngress = async (contextBinding) => await resolveSignalAccessState({
|
|
1075
1146
|
accountId: deps.accountId,
|
|
1076
1147
|
dmPolicy: deps.dmPolicy,
|
|
1077
1148
|
groupPolicy: deps.groupPolicy,
|
|
@@ -1081,8 +1152,10 @@ function createSignalEventHandler(deps) {
|
|
|
1081
1152
|
groupId,
|
|
1082
1153
|
isGroup,
|
|
1083
1154
|
cfg: deps.cfg,
|
|
1084
|
-
hasControlCommand: hasControlCommandInMessage
|
|
1155
|
+
hasControlCommand: hasControlCommandInMessage,
|
|
1156
|
+
contextBinding
|
|
1085
1157
|
});
|
|
1158
|
+
const { senderAccess, commandAccess } = await resolveChannelIngress();
|
|
1086
1159
|
const quoteText = normalizeOptionalString(dataMessage?.quote?.text) ?? "";
|
|
1087
1160
|
const { contextVisibilityMode, quoteSenderAllowed, visibleQuoteText, visibleQuoteSender } = resolveSignalQuoteContext({
|
|
1088
1161
|
cfg: deps.cfg,
|
|
@@ -1212,8 +1285,8 @@ function createSignalEventHandler(deps) {
|
|
|
1212
1285
|
sender: envelope.sourceName ?? senderDisplay,
|
|
1213
1286
|
body: messageText || visibleQuoteText,
|
|
1214
1287
|
media: toHistoryMediaEntries(pendingMedia),
|
|
1215
|
-
timestamp:
|
|
1216
|
-
messageId
|
|
1288
|
+
timestamp: inboundTimestamp,
|
|
1289
|
+
messageId
|
|
1217
1290
|
}
|
|
1218
1291
|
});
|
|
1219
1292
|
await registerSignalReplyContext({
|
|
@@ -1343,7 +1416,8 @@ function createSignalEventHandler(deps) {
|
|
|
1343
1416
|
replyToBody: visibleQuoteText || void 0,
|
|
1344
1417
|
replyToSender: visibleQuoteSender,
|
|
1345
1418
|
replyToIsQuote: visibleQuoteText ? true : void 0,
|
|
1346
|
-
turnAdoptionLifecycle
|
|
1419
|
+
turnAdoptionLifecycle,
|
|
1420
|
+
resolveChannelIngress
|
|
1347
1421
|
};
|
|
1348
1422
|
pendingInboundRegistry.cancelPendingOnAbort(entry, debouncer.cancelKey);
|
|
1349
1423
|
const inboundLane = resolveSignalControlLaneKey(deps.accountId, entry) ? controlDebouncer : debouncer;
|
|
@@ -1365,26 +1439,10 @@ function registerSignalReactionTargetsForDeliveredPayload(params) {
|
|
|
1365
1439
|
}
|
|
1366
1440
|
//#endregion
|
|
1367
1441
|
//#region extensions/signal/src/signal-ingress.ts
|
|
1368
|
-
const SIGNAL_INGRESS_COMPLETED_TTL_MS = 720 * 60 * 60 * 1e3;
|
|
1369
|
-
const SIGNAL_INGRESS_COMPLETED_MAX_ENTRIES = 1e3;
|
|
1370
|
-
const SIGNAL_INGRESS_FAILED_TTL_MS = 720 * 60 * 60 * 1e3;
|
|
1371
|
-
const SIGNAL_INGRESS_FAILED_MAX_ENTRIES = 1e3;
|
|
1372
1442
|
const SIGNAL_INGRESS_DRAIN_INTERVAL_MS = 1e3;
|
|
1373
|
-
|
|
1374
|
-
constructor(reason, message, options) {
|
|
1375
|
-
super(message, options);
|
|
1376
|
-
this.reason = reason;
|
|
1377
|
-
this.name = "SignalIngressPermanentError";
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
function isRecord$1(value) {
|
|
1381
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1382
|
-
}
|
|
1383
|
-
function normalizeRawString(value) {
|
|
1384
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
1385
|
-
}
|
|
1443
|
+
const SignalIngressPermanentError = createChannelIngressError("SignalIngressPermanentError", { withReason: true });
|
|
1386
1444
|
function normalizeTimestamp(value) {
|
|
1387
|
-
return
|
|
1445
|
+
return asPositiveSafeInteger(value) ?? null;
|
|
1388
1446
|
}
|
|
1389
1447
|
function parseReceiveEnvelope(event) {
|
|
1390
1448
|
if (event.event !== "receive" || !event.data) return null;
|
|
@@ -1394,31 +1452,32 @@ function parseReceiveEnvelope(event) {
|
|
|
1394
1452
|
} catch (error) {
|
|
1395
1453
|
throw new SignalIngressPermanentError("parse-error", "Signal receive event contains invalid JSON", { cause: error });
|
|
1396
1454
|
}
|
|
1397
|
-
if (!isRecord
|
|
1398
|
-
return isRecord
|
|
1455
|
+
if (!isRecord(parsed)) throw new SignalIngressPermanentError("parse-error", "Signal receive event must contain a JSON object");
|
|
1456
|
+
return isRecord(parsed.envelope) ? parsed.envelope : null;
|
|
1399
1457
|
}
|
|
1400
1458
|
function resolveDataMessage(envelope) {
|
|
1401
|
-
if (isRecord
|
|
1402
|
-
return isRecord
|
|
1459
|
+
if (isRecord(envelope.dataMessage)) return envelope.dataMessage;
|
|
1460
|
+
return isRecord(envelope.editMessage?.dataMessage) ? envelope.editMessage.dataMessage : null;
|
|
1403
1461
|
}
|
|
1404
1462
|
function inspectSignalIngressEvent(event) {
|
|
1405
1463
|
const envelope = parseReceiveEnvelope(event);
|
|
1406
1464
|
if (!envelope || "syncMessage" in envelope) return null;
|
|
1407
1465
|
const dataMessage = resolveDataMessage(envelope);
|
|
1408
|
-
const reactionMessage = isRecord
|
|
1466
|
+
const reactionMessage = isRecord(envelope.reactionMessage) ? envelope.reactionMessage : null;
|
|
1409
1467
|
if (!dataMessage && !reactionMessage) return null;
|
|
1410
|
-
const senderUuid =
|
|
1411
|
-
const senderNumber =
|
|
1468
|
+
const senderUuid = normalizeNullableString(envelope.sourceUuid);
|
|
1469
|
+
const senderNumber = normalizeNullableString(envelope.sourceNumber);
|
|
1412
1470
|
const senderKey = senderUuid ? `uuid:${senderUuid}` : senderNumber ? `number:${senderNumber}` : null;
|
|
1413
1471
|
if (!senderKey) throw new SignalIngressPermanentError("missing-sender", "Signal dispatchable envelope is missing sourceUuid/sourceNumber");
|
|
1414
1472
|
const timestamp = normalizeTimestamp(envelope.timestamp) ?? normalizeTimestamp(dataMessage?.timestamp);
|
|
1415
1473
|
if (timestamp === null) throw new SignalIngressPermanentError("missing-timestamp", "Signal dispatchable envelope is missing a stable timestamp");
|
|
1416
|
-
const dataGroup = isRecord
|
|
1417
|
-
const reactionGroup = isRecord
|
|
1418
|
-
const groupId =
|
|
1474
|
+
const dataGroup = isRecord(dataMessage?.groupInfo) ? dataMessage.groupInfo : null;
|
|
1475
|
+
const reactionGroup = isRecord(reactionMessage?.groupInfo) ? reactionMessage.groupInfo : null;
|
|
1476
|
+
const groupId = normalizeNullableString(dataGroup?.groupId) ?? normalizeNullableString(reactionGroup?.groupId);
|
|
1419
1477
|
return {
|
|
1420
1478
|
eventId: JSON.stringify([senderKey, timestamp]),
|
|
1421
|
-
laneKey: groupId ? `group:${groupId}` : `direct:${senderKey}
|
|
1479
|
+
laneKey: groupId ? `group:${groupId}` : `direct:${senderKey}`,
|
|
1480
|
+
...senderUuid && senderNumber ? { numberAliasEventId: JSON.stringify([`number:${senderNumber}`, timestamp]) } : {}
|
|
1422
1481
|
};
|
|
1423
1482
|
}
|
|
1424
1483
|
function resolveSignalIngressNonRetryableFailure(error) {
|
|
@@ -1435,8 +1494,9 @@ async function startSignalIngressMonitor(params) {
|
|
|
1435
1494
|
if (!pluginRuntime) throw new Error("Signal runtime not initialized for durable ingress");
|
|
1436
1495
|
queue = pluginRuntime.state.openChannelIngressQueue({ accountId: params.accountId });
|
|
1437
1496
|
}
|
|
1497
|
+
const ingressQueue = queue;
|
|
1438
1498
|
const monitor = createChannelIngressMonitor({
|
|
1439
|
-
queue,
|
|
1499
|
+
queue: ingressQueue,
|
|
1440
1500
|
inspect: (event) => inspectSignalIngressEvent(event),
|
|
1441
1501
|
payload: {
|
|
1442
1502
|
version: 1,
|
|
@@ -1456,13 +1516,16 @@ async function startSignalIngressMonitor(params) {
|
|
|
1456
1516
|
createClaimError: (_kind, claim) => new SignalIngressPermanentError("unsupported-event", `Signal ingress row ${claim.id} has an invalid payload`)
|
|
1457
1517
|
},
|
|
1458
1518
|
deliver: (event, lifecycle) => params.dispatch(event, lifecycle),
|
|
1519
|
+
onDurableAdmission: async (_event, { facts }) => {
|
|
1520
|
+
const { numberAliasEventId } = facts;
|
|
1521
|
+
if (!numberAliasEventId) return;
|
|
1522
|
+
if (!await ingressQueue.complete(numberAliasEventId)) await ingressQueue.complete(facts.eventId);
|
|
1523
|
+
},
|
|
1459
1524
|
pollIntervalMs: SIGNAL_INGRESS_DRAIN_INTERVAL_MS,
|
|
1460
1525
|
retention: {
|
|
1461
1526
|
pruneIntervalMs: 0,
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
failedTtlMs: SIGNAL_INGRESS_FAILED_TTL_MS,
|
|
1465
|
-
failedMaxEntries: SIGNAL_INGRESS_FAILED_MAX_ENTRIES
|
|
1527
|
+
completedMaxEntries: 2e3,
|
|
1528
|
+
failedMaxEntries: 1e3
|
|
1466
1529
|
},
|
|
1467
1530
|
appendRetryDelaysMs: [0],
|
|
1468
1531
|
drain: {
|
|
@@ -1489,7 +1552,14 @@ const DEFAULT_RECONNECT_POLICY = {
|
|
|
1489
1552
|
factor: 2,
|
|
1490
1553
|
jitter: .2
|
|
1491
1554
|
};
|
|
1492
|
-
|
|
1555
|
+
function publishSignalRecovering(statusSink, lastError) {
|
|
1556
|
+
statusSink?.({
|
|
1557
|
+
connected: false,
|
|
1558
|
+
lifecycle: "recovering",
|
|
1559
|
+
...lastError ? { lastError } : {}
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
async function runSignalSseLoop({ baseUrl, account, abortSignal, runtime, onEvent, timeoutMs, transportKind, policy, statusSink }) {
|
|
1493
1563
|
const reconnectPolicy = {
|
|
1494
1564
|
...DEFAULT_RECONNECT_POLICY,
|
|
1495
1565
|
...policy
|
|
@@ -1508,6 +1578,9 @@ async function runSignalSseLoop({ baseUrl, account, abortSignal, runtime, onEven
|
|
|
1508
1578
|
abortSignal,
|
|
1509
1579
|
timeoutMs,
|
|
1510
1580
|
transportKind,
|
|
1581
|
+
onStreamOpen: () => {
|
|
1582
|
+
statusSink?.(channelReadyPatch());
|
|
1583
|
+
},
|
|
1511
1584
|
onEvent: async (event) => {
|
|
1512
1585
|
reconnectAttempts = 0;
|
|
1513
1586
|
await onEvent(event);
|
|
@@ -1518,6 +1591,7 @@ async function runSignalSseLoop({ baseUrl, account, abortSignal, runtime, onEven
|
|
|
1518
1591
|
}
|
|
1519
1592
|
});
|
|
1520
1593
|
if (abortSignal?.aborted) return;
|
|
1594
|
+
publishSignalRecovering(statusSink);
|
|
1521
1595
|
reconnectAttempts += 1;
|
|
1522
1596
|
const delayMs = computeBackoff(reconnectPolicy, reconnectAttempts);
|
|
1523
1597
|
logReconnectVerbose(`Signal stream ended, reconnecting in ${delayMs / 1e3}s...`);
|
|
@@ -1525,6 +1599,7 @@ async function runSignalSseLoop({ baseUrl, account, abortSignal, runtime, onEven
|
|
|
1525
1599
|
} catch (err) {
|
|
1526
1600
|
if (abortSignal?.aborted) return;
|
|
1527
1601
|
runtime.error?.(`Signal stream error: ${String(err)}`);
|
|
1602
|
+
publishSignalRecovering(statusSink, String(err));
|
|
1528
1603
|
reconnectAttempts += 1;
|
|
1529
1604
|
const delayMs = computeBackoff(reconnectPolicy, reconnectAttempts);
|
|
1530
1605
|
runtime.log?.(`Signal connection lost, reconnecting in ${delayMs / 1e3}s...`);
|
|
@@ -1558,36 +1633,6 @@ function createSignalMonitorTaskRunner(runtime) {
|
|
|
1558
1633
|
}
|
|
1559
1634
|
};
|
|
1560
1635
|
}
|
|
1561
|
-
function createSignalDaemonLifecycle(params) {
|
|
1562
|
-
let daemonHandle = null;
|
|
1563
|
-
let daemonStopRequested = false;
|
|
1564
|
-
let daemonStopPromise;
|
|
1565
|
-
let daemonExitError;
|
|
1566
|
-
const daemonAbortController = new AbortController();
|
|
1567
|
-
const abortSignal = params.abortSignal ? AbortSignal.any([params.abortSignal, daemonAbortController.signal]) : daemonAbortController.signal;
|
|
1568
|
-
const stop = () => {
|
|
1569
|
-
if (daemonStopPromise) return daemonStopPromise;
|
|
1570
|
-
daemonStopRequested = true;
|
|
1571
|
-
if (!daemonAbortController.signal.aborted) daemonAbortController.abort(params.abortSignal?.reason ?? /* @__PURE__ */ new Error("Signal monitor stopped"));
|
|
1572
|
-
daemonStopPromise = daemonHandle?.stop() ?? Promise.resolve();
|
|
1573
|
-
return daemonStopPromise;
|
|
1574
|
-
};
|
|
1575
|
-
const attach = (handle) => {
|
|
1576
|
-
daemonHandle = handle;
|
|
1577
|
-
handle.exited.then((exit) => {
|
|
1578
|
-
if (daemonStopRequested || params.abortSignal?.aborted) return;
|
|
1579
|
-
daemonExitError = new Error(formatSignalDaemonExit(exit));
|
|
1580
|
-
if (!daemonAbortController.signal.aborted) daemonAbortController.abort(daemonExitError);
|
|
1581
|
-
});
|
|
1582
|
-
};
|
|
1583
|
-
const getExitError = () => daemonExitError;
|
|
1584
|
-
return {
|
|
1585
|
-
attach,
|
|
1586
|
-
stop,
|
|
1587
|
-
getExitError,
|
|
1588
|
-
abortSignal
|
|
1589
|
-
};
|
|
1590
|
-
}
|
|
1591
1636
|
function resolveSignalReactionTargets(reaction) {
|
|
1592
1637
|
const targets = [];
|
|
1593
1638
|
const uuid = reaction.targetAuthorUuid?.trim();
|
|
@@ -1615,16 +1660,17 @@ function isSignalReactionMessage(reaction) {
|
|
|
1615
1660
|
return Boolean(emoji && typeof timestamp === "number" && timestamp > 0 && hasTarget);
|
|
1616
1661
|
}
|
|
1617
1662
|
function shouldEmitSignalReactionNotification(params) {
|
|
1618
|
-
const { mode, account, targets, sender, allowlist } = params;
|
|
1663
|
+
const { mode, account, accountUuid, targets, sender, allowlist } = params;
|
|
1619
1664
|
const effectiveMode = mode ?? "own";
|
|
1620
1665
|
if (effectiveMode === "off") return false;
|
|
1621
1666
|
if (effectiveMode === "own") {
|
|
1622
|
-
const accountId = account
|
|
1623
|
-
|
|
1624
|
-
|
|
1667
|
+
const accountId = normalizeOptionalString(account);
|
|
1668
|
+
const normalizedAccountUuid = normalizeOptionalString(accountUuid);
|
|
1669
|
+
if (!accountId && !normalizedAccountUuid || !targets || targets.length === 0) return false;
|
|
1670
|
+
const normalizedAccount = accountId ? normalizeE164(accountId) : void 0;
|
|
1625
1671
|
return targets.some((target) => {
|
|
1626
|
-
if (target.kind === "uuid") return accountId === target.id ||
|
|
1627
|
-
return normalizedAccount === target.id;
|
|
1672
|
+
if (target.kind === "uuid") return [accountId, normalizedAccountUuid].some((candidate) => candidate === target.id || candidate === `uuid:${target.id}`);
|
|
1673
|
+
return Boolean(normalizedAccount) && normalizedAccount === target.id;
|
|
1628
1674
|
});
|
|
1629
1675
|
}
|
|
1630
1676
|
if (effectiveMode === "allowlist") {
|
|
@@ -1680,7 +1726,9 @@ async function fetchAttachment(params) {
|
|
|
1680
1726
|
});
|
|
1681
1727
|
if (!result?.data) return null;
|
|
1682
1728
|
if (estimateBase64DecodedBytes(result.data) > params.maxBytes) throw new Error(`Signal attachment ${attachment.id} exceeds ${(params.maxBytes / (1024 * 1024)).toFixed(0)}MB limit`);
|
|
1683
|
-
const
|
|
1729
|
+
const canonicalData = canonicalizeBase64(result.data);
|
|
1730
|
+
if (!canonicalData) throw new Error(`Signal attachment ${attachment.id} returned malformed base64 data`);
|
|
1731
|
+
const buffer = Buffer.from(canonicalData, "base64");
|
|
1684
1732
|
const originalFilename = normalizeOptionalString(attachment.filename ?? void 0);
|
|
1685
1733
|
const saved = await saveMediaBuffer(buffer, normalizeOptionalString(attachment.contentType ?? void 0) ?? await detectMime({
|
|
1686
1734
|
buffer,
|
|
@@ -1903,6 +1951,7 @@ async function monitorSignalProvider(opts = {}) {
|
|
|
1903
1951
|
});
|
|
1904
1952
|
const handleEvent = createSignalEventHandler({
|
|
1905
1953
|
runtime,
|
|
1954
|
+
channelRuntime: opts.channelRuntime,
|
|
1906
1955
|
abortSignal: daemonLifecycle.abortSignal,
|
|
1907
1956
|
runTrackedTask: (task) => {
|
|
1908
1957
|
monitorTaskRunner.runTask(task);
|
|
@@ -1953,6 +2002,7 @@ async function monitorSignalProvider(opts = {}) {
|
|
|
1953
2002
|
timeoutMs: 0,
|
|
1954
2003
|
transportKind,
|
|
1955
2004
|
policy: opts.reconnectPolicy,
|
|
2005
|
+
statusSink: opts.statusSink,
|
|
1956
2006
|
onEvent: (event) => monitorTaskRunner.runTask(async () => await ingressMonitor?.receive(event))
|
|
1957
2007
|
});
|
|
1958
2008
|
const daemonExitError = daemonLifecycle.getExitError();
|
|
@@ -1960,6 +2010,7 @@ async function monitorSignalProvider(opts = {}) {
|
|
|
1960
2010
|
} catch (err) {
|
|
1961
2011
|
const daemonExitError = daemonLifecycle.getExitError();
|
|
1962
2012
|
if (opts.abortSignal?.aborted && !daemonExitError) return;
|
|
2013
|
+
if (daemonExitError) publishSignalRecovering(opts.statusSink, daemonExitError.message);
|
|
1963
2014
|
throw err;
|
|
1964
2015
|
} finally {
|
|
1965
2016
|
await ingressMonitor?.stop();
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { t as detectSignalTransport } from "./transport-detection-
|
|
3
|
-
import { n as signalRpcRequest, t as signalCheck } from "./client-adapter-
|
|
2
|
+
import { t as detectSignalTransport } from "./transport-detection-BItHawMq.js";
|
|
3
|
+
import { n as signalRpcRequest, t as signalCheck } from "./client-adapter-D9SNPaNx.js";
|
|
4
4
|
import { runChannelProbe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
5
5
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
6
6
|
//#region extensions/signal/src/probe.ts
|
|
7
|
-
var probe_exports = /* @__PURE__ */ __exportAll({
|
|
7
|
+
var probe_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
probeSignal: () => probeSignal,
|
|
9
|
+
probeSignalAccount: () => probeSignalAccount
|
|
10
|
+
});
|
|
8
11
|
function parseSignalVersion(value) {
|
|
9
12
|
if (typeof value === "string" && value.trim()) return value.trim();
|
|
10
13
|
if (typeof value === "object" && value !== null) {
|
|
11
|
-
const version = value
|
|
14
|
+
const { version, versions } = value;
|
|
12
15
|
if (typeof version === "string" && version.trim()) return version.trim();
|
|
16
|
+
if (Array.isArray(versions)) {
|
|
17
|
+
const normalizedVersions = versions.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean);
|
|
18
|
+
if (normalizedVersions.length > 0) return normalizedVersions.join(", ");
|
|
19
|
+
}
|
|
13
20
|
}
|
|
14
21
|
return null;
|
|
15
22
|
}
|
|
16
|
-
async function
|
|
23
|
+
async function probeSignalTransport(baseUrl, timeoutMs, options, account) {
|
|
17
24
|
return await runChannelProbe(void 0, async () => {
|
|
18
25
|
const result = {
|
|
19
26
|
ok: false,
|
|
@@ -30,7 +37,10 @@ async function probeSignal(baseUrl, timeoutMs, options = {}) {
|
|
|
30
37
|
error: formatErrorMessage(error)
|
|
31
38
|
};
|
|
32
39
|
}
|
|
33
|
-
const check = await signalCheck(baseUrl, timeoutMs, {
|
|
40
|
+
const check = await signalCheck(baseUrl, timeoutMs, {
|
|
41
|
+
transportKind,
|
|
42
|
+
...account && transportKind === "container" ? { account } : {}
|
|
43
|
+
});
|
|
34
44
|
if (!check.ok) return {
|
|
35
45
|
...result,
|
|
36
46
|
status: check.status ?? null,
|
|
@@ -47,11 +57,17 @@ async function probeSignal(baseUrl, timeoutMs, options = {}) {
|
|
|
47
57
|
}
|
|
48
58
|
return {
|
|
49
59
|
...result,
|
|
50
|
-
ok:
|
|
60
|
+
ok: result.error === null,
|
|
51
61
|
status: check.status ?? null
|
|
52
62
|
};
|
|
53
63
|
});
|
|
54
64
|
}
|
|
65
|
+
async function probeSignal(baseUrl, timeoutMs, options = {}) {
|
|
66
|
+
return await probeSignalTransport(baseUrl, timeoutMs, options);
|
|
67
|
+
}
|
|
68
|
+
async function probeSignalAccount(params) {
|
|
69
|
+
return await probeSignalTransport(params.baseUrl, params.timeoutMs, { transportKind: params.transportKind }, params.account);
|
|
70
|
+
}
|
|
55
71
|
async function resolveProbeTransportKind(baseUrl, timeoutMs, options) {
|
|
56
72
|
if (options.transportKind) return options.transportKind;
|
|
57
73
|
if (options.apiMode === "container") return "container";
|