@openclaw/whatsapp 2026.7.1 → 2026.7.2-beta.1

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.
Files changed (59) hide show
  1. package/dist/{access-control-DYE5dXna.js → access-control-DazDX3RB.js} +4 -4
  2. package/dist/{account-config-6PTOSfaI.js → account-config-LiT9wWH9.js} +4 -8
  3. package/dist/{accounts-4YgwroRU.js → accounts-CKOFMPf-.js} +2 -3
  4. package/dist/{action-runtime-DPahAqxV.js → action-runtime-Bf-12TIH.js} +3 -3
  5. package/dist/action-runtime-api.js +1 -1
  6. package/dist/action-runtime.runtime.js +1 -1
  7. package/dist/{active-listener-B4SDebQ6.js → active-listener-5kHap439.js} +2 -2
  8. package/dist/{agent-tools-login-BX7eHgDm.js → agent-tools-login-DfyToBpG.js} +1 -4
  9. package/dist/api.js +17 -18
  10. package/dist/{approval-handler.runtime-DNWS4aYQ.js → approval-handler.runtime-CBiGQuZ5.js} +19 -13
  11. package/dist/approval-reactions-BGQoz25s.js +373 -0
  12. package/dist/{approval-resolver-DF-lu8k5.js → approval-resolver-DoeBBt22.js} +2 -1
  13. package/dist/{auth-store-Db-wfApd.js → auth-store-BQi9pZqQ.js} +31 -19
  14. package/dist/call-tool-api.js +6 -14
  15. package/dist/{channel-BWp7h1uY.js → channel-D_1cK7-w.js} +72 -33
  16. package/dist/channel-config-api.js +1 -1
  17. package/dist/channel-plugin-api.js +1 -1
  18. package/dist/{channel-react-action-CKJHL_Wf.js → channel-react-action-PoRWfP9x.js} +7 -7
  19. package/dist/{channel.runtime-CAssfx9p.js → channel.runtime-BPrKzcYd.js} +5 -5
  20. package/dist/{channel.setup-CURc5rEt.js → channel.setup-eX64WZDx.js} +3 -4
  21. package/dist/config-schema-BZ8h1hWA.js +40 -0
  22. package/dist/{connection-controller-DkbrFSIn.js → connection-controller-C1rwfWb4.js} +52 -12
  23. package/dist/connection-controller-runtime-context-CbTsqmPT.js +14 -0
  24. package/dist/contract-api.js +2 -2
  25. package/dist/{directory-config-Dijefxc3.js → directory-config-CLBQrjtC.js} +3 -3
  26. package/dist/directory-contract-api.js +1 -1
  27. package/dist/doctor-contract-api.js +89 -4
  28. package/dist/{group-session-key-BhC1RQOE.js → group-session-key-CLTZeH_F.js} +31 -3
  29. package/dist/{identity-Dqft3mFA.js → identity-D7L8LCuH.js} +2 -2
  30. package/dist/light-runtime-api.js +4 -4
  31. package/dist/{login-C48y0jlx.js → login-DGIoToX8.js} +48 -8
  32. package/dist/{login-qr-BjId7dll.js → login-qr-X-CZHOk9.js} +6 -7
  33. package/dist/login-qr-runtime.js +1 -1
  34. package/dist/{monitor-DD8bXohk.js → monitor-BKtA0lzq.js} +102 -100
  35. package/dist/normalize-C-Z16y7Q.js +2 -0
  36. package/dist/{normalize-target-bVWjgftN.js → normalize-target-DSZnHkKF.js} +14 -10
  37. package/dist/{resolve-outbound-target-CcdugbDf.js → resolve-outbound-target-BR97fAbB.js} +1 -1
  38. package/dist/runtime-api.js +10 -10
  39. package/dist/{send-C5CpFcBG.js → send-D9Ydnn4o.js} +25 -320
  40. package/dist/{send-api-DLlXl8CH.js → send-api-W33lI2nR.js} +28 -88
  41. package/dist/{session-errors-BAj9D2La.js → session-errors-JuazczrA.js} +2 -1
  42. package/dist/{session-DriaHt7V.js → session-mxWFn0eS.js} +181 -19
  43. package/dist/session.runtime-Nsqaehbd.js +16 -0
  44. package/dist/{setup-core-DH-DFPLY.js → setup-core-BXDFGqky.js} +18 -33
  45. package/dist/{setup-finalize-c8dl34sO.js → setup-finalize-DzOHXnPj.js} +41 -11
  46. package/dist/setup-plugin-api.js +1 -1
  47. package/dist/{setup-surface-DlWb0Z09.js → setup-surface-5EUmMLHS.js} +3 -3
  48. package/dist/{targets-runtime-C-GiVn6Y.js → targets-runtime-Bsh0HR9y.js} +13 -6
  49. package/dist/targets.js +1 -1
  50. package/dist/text-runtime-BTGkMN0o.js +4 -0
  51. package/npm-shrinkwrap.json +3 -3
  52. package/openclaw.plugin.json +72 -48
  53. package/package.json +4 -4
  54. package/dist/config-schema-mBX2nmn1.js +0 -47
  55. package/dist/connection-controller-registry-TSX_udJp.js +0 -22
  56. package/dist/normalize-Bxwqo-bW.js +0 -2
  57. package/dist/session.runtime-CyooSQvj.js +0 -12
  58. package/dist/socket-timing-DhbVFjah.js +0 -77
  59. package/dist/text-runtime-DdX6-mC_.js +0 -4
@@ -1,53 +1,54 @@
1
- import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-4YgwroRU.js";
2
- import { a as normalizeWhatsAppOutboundPayload, c as prepareWhatsAppOutboundMedia, d as maybeResolveWhatsAppApprovalReaction, g as resolveWhatsAppReactionLevel, l as sendWhatsAppOutboundWithRetry, r as sendReactionWhatsApp, s as normalizeWhatsAppPayloadTextPreservingIndentation } from "./send-C5CpFcBG.js";
1
+ import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-CKOFMPf-.js";
2
+ import { a as normalizeWhatsAppOutboundPayload, c as prepareWhatsAppOutboundMedia, r as sendReactionWhatsApp, s as normalizeWhatsAppPayloadTextPreservingIndentation, u as resolveWhatsAppReactionLevel } from "./send-D9Ydnn4o.js";
3
3
  import { n as getWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
4
- import { t as getRegisteredWhatsAppConnectionController } from "./connection-controller-registry-TSX_udJp.js";
5
- import { n as getStatusCode, t as formatError } from "./session-errors-BAj9D2La.js";
6
- import { a as resolveWhatsAppSocketTiming, i as resolveWhatsAppSocketOperationTimeoutMs, n as createWhatsAppSocketOperationTimeoutAdapter, o as withWhatsAppSocketOperationTimeout, r as isWhatsAppSocketOperationTimeoutError } from "./socket-timing-DhbVFjah.js";
7
- import { a as resolveEquivalentWhatsAppDirectChatJids, c as toWhatsappJidWithLid, i as markdownToWhatsApp, n as isSelfChatMode, o as resolveJidToE164, r as jidToE164, s as toWhatsappJid } from "./targets-runtime-C-GiVn6Y.js";
8
- import { n as normalizeE164, t as convertMarkdownTables$1 } from "./text-runtime-DdX6-mC_.js";
9
- import { a as cacheInboundMessageMeta, i as buildQuotedMessageOptions, n as resolveWhatsAppGroupSessionRoute, o as lookupInboundMessageMeta, r as resolveWhatsAppLegacyGroupSessionKey } from "./group-session-key-BhC1RQOE.js";
10
- import { g as readWebSelfId, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, v as readWebSelfIdentityForDecision } from "./auth-store-Db-wfApd.js";
11
- import { a as getSelfIdentity, c as resolveComparableIdentity, i as getReplyContext, n as getMentionIdentities, o as getSenderIdentity, r as getPrimaryIdentityId, s as identitiesOverlap, t as getComparableIdentityValues } from "./identity-Dqft3mFA.js";
4
+ import { n as getWhatsAppConnectionController } from "./connection-controller-runtime-context-CbTsqmPT.js";
5
+ import { a as resolveEquivalentWhatsAppDirectChatJids, c as toWhatsappJidWithLid, i as markdownToWhatsApp, n as isSelfChatMode, o as resolveJidToE164, r as jidToE164, s as toWhatsappJid } from "./targets-runtime-Bsh0HR9y.js";
6
+ import { n as normalizeE164, t as convertMarkdownTables$1 } from "./text-runtime-BTGkMN0o.js";
7
+ import { a as cacheInboundMessageMeta, i as buildQuotedMessageOptions, n as resolveWhatsAppGroupSessionRoute, o as lookupInboundMessageMeta, r as resolveWhatsAppLegacyGroupSessionKey } from "./group-session-key-CLTZeH_F.js";
8
+ import { g as readWebSelfId, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, v as readWebSelfIdentityForDecision } from "./auth-store-BQi9pZqQ.js";
9
+ import { a as getSelfIdentity, c as resolveComparableIdentity, i as getReplyContext, n as getMentionIdentities, o as getSenderIdentity, r as getPrimaryIdentityId, s as identitiesOverlap, t as getComparableIdentityValues } from "./identity-D7L8LCuH.js";
12
10
  import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-BGyzT9Lg.js";
13
- import { c as requireWhatsAppInboundAdmission, i as resolveWhatsAppInboundPolicy, l as resolveWhatsAppGroupConversationId, o as buildDeprecatedFlatWhatsAppInboundAdmission, r as resolveWhatsAppCommandAuthorized, s as requireAdmittedWhatsAppInboundMessage, t as checkInboundAccessControl } from "./access-control-DYE5dXna.js";
14
- import { _ as extractLocationData, a as mayContainWhatsAppOutboundMention, b as extractText, c as DisconnectReason, d as normalizeMessageContent, f as resolveInboundMediaMimetype, g as extractExternalAdReplyContext, h as extractContextInfo, i as addWhatsAppOutboundMentionsToContent, l as downloadMediaMessage, m as extractContactContext, n as listWhatsAppSendResultMessageIds, o as resolveWhatsAppOutboundMentions, p as describeReplyContext, r as normalizeWhatsAppSendResult, s as addWhatsAppImagePreviewFields, t as createWebSendApi, u as isJidGroup, v as extractMediaPlaceholder, x as hasInboundUserContent, y as extractMentionedJids } from "./send-api-DLlXl8CH.js";
15
- import { r as waitForWaConnection, t as createWaSocket } from "./session-DriaHt7V.js";
16
- import { t as BufferJSON } from "./session.runtime-CyooSQvj.js";
17
- import { c as computeBackoff, d as resolveReconnectPolicy, f as sleepWithAbort, l as newConnectionId, n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController, s as DEFAULT_RECONNECT_POLICY, u as resolveHeartbeatSeconds } from "./connection-controller-DkbrFSIn.js";
11
+ import { c as requireWhatsAppInboundAdmission, i as resolveWhatsAppInboundPolicy, l as resolveWhatsAppGroupConversationId, o as buildDeprecatedFlatWhatsAppInboundAdmission, r as resolveWhatsAppCommandAuthorized, s as requireAdmittedWhatsAppInboundMessage, t as checkInboundAccessControl } from "./access-control-DazDX3RB.js";
12
+ import { _ as extractLocationData, a as mayContainWhatsAppOutboundMention, b as extractText, c as DisconnectReason, d as normalizeMessageContent, f as resolveInboundMediaMimetype, g as extractExternalAdReplyContext, h as extractContextInfo, i as addWhatsAppOutboundMentionsToContent, l as downloadMediaMessage, m as extractContactContext, n as listWhatsAppSendResultMessageIds, o as resolveWhatsAppOutboundMentions, p as describeReplyContext, r as normalizeWhatsAppSendResult, s as addWhatsAppImagePreviewFields, t as createWebSendApi, u as isJidGroup, v as extractMediaPlaceholder, x as hasInboundUserContent, y as extractMentionedJids } from "./send-api-W33lI2nR.js";
13
+ import { a as createWhatsAppSocketOperationTimeoutAdapter, c as resolveWhatsAppSocketTiming, l as withWhatsAppSocketOperationTimeout, o as isWhatsAppSocketOperationTimeoutError, r as waitForWaConnection, s as resolveWhatsAppSocketOperationTimeoutMs, t as createWaSocket } from "./session-mxWFn0eS.js";
14
+ import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
15
+ import { t as BufferJSON } from "./session.runtime-Nsqaehbd.js";
16
+ import { c as computeBackoff, d as resolveReconnectPolicy, f as sleepWithAbort, l as newConnectionId, n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController, s as DEFAULT_RECONNECT_POLICY, u as resolveHeartbeatSeconds } from "./connection-controller-C1rwfWb4.js";
17
+ import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-BGQoz25s.js";
18
18
  import { resolveAccountEntry } from "openclaw/plugin-sdk/account-core";
19
19
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
20
- import { createChannelMessageReplyPipeline, createDurableInboundReceiveJournalFromQueue, createMessageReceiptFromOutboundResults, deliverInboundReplyWithMessageSendContext, resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-outbound";
21
20
  import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
22
21
  import { DEFAULT_TIMING, createAckReactionHandle, createStatusReactionController, logAckFailure, removeAckReactionHandleAfterReply, shouldAckReactionForWhatsApp } from "openclaw/plugin-sdk/channel-feedback";
23
22
  import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
23
+ import { collectErrorGraphCandidates, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
24
24
  import { getChildLogger } from "openclaw/plugin-sdk/logging-core";
25
25
  import { resolveMarkdownTableMode as resolveMarkdownTableMode$1 } from "openclaw/plugin-sdk/markdown-table-runtime";
26
26
  import { createSubsystemLogger, defaultRuntime, formatDurationPrecise, getChildLogger as getChildLogger$1, logVerbose, logVerbose as logVerbose$1, registerUnhandledRejectionHandler, shouldLogVerbose, shouldLogVerbose as shouldLogVerbose$1, warn } from "openclaw/plugin-sdk/runtime-env";
27
- import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
27
+ import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
28
+ import { createChannelMessageReplyPipeline, createDurableInboundReceiveJournalFromQueue, createMessageReceiptFromOutboundResults, deliverInboundReplyWithMessageSendContext, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
28
29
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
29
- import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
30
+ import { isReasoningReplyPayload, resolveSendableOutboundReplyParts, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
30
31
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
31
32
  import { LocalMediaAccessError, getDefaultLocalRoots, loadWebMedia as loadWebMedia$1, loadWebMediaRaw, optimizeImageToJpeg, optimizeImageToPng } from "openclaw/plugin-sdk/web-media";
33
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
32
34
  import { chunkMarkdownTextWithMode } from "openclaw/plugin-sdk/reply-chunking";
33
- import { isReasoningReplyPayload, resolveSendableOutboundReplyParts, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
34
35
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, DEFAULT_MAIN_KEY, buildAgentMainSessionKey, buildAgentSessionKey, buildGroupHistoryKey, deriveLastRoutePolicy, normalizeAccountId as normalizeAccountId$1, normalizeAgentId, resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
36
+ import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
35
37
  import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";
36
38
  import { getSessionEntry, patchSessionEntry, resolveStorePath, resolveStorePath as resolveStorePath$1, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
37
39
  import { buildChannelInboundEventContext, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundEnvelope as formatInboundEnvelope$1, formatInboundMediaUnavailableText, formatLocationText, hasVisibleInboundReplyDispatch, resolveInboundSessionEnvelopeContext, runChannelInboundEvent, toInboundMediaFacts, toLocationContext } from "openclaw/plugin-sdk/channel-inbound";
38
- import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
39
40
  import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
40
41
  import { createHash } from "node:crypto";
41
42
  import { dispatchReplyWithBufferedBlockDispatcher, finalizeInboundContext, resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
42
43
  import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
43
44
  import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
44
- import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
45
45
  import { hasControlCommand, isControlCommandMessage, isControlCommandMessage as isControlCommandMessage$1, shouldComputeCommandAuthorized } from "openclaw/plugin-sdk/command-detection";
46
46
  import { drainPendingDeliveries } from "openclaw/plugin-sdk/delivery-queue-runtime";
47
47
  import { DEFAULT_GROUP_HISTORY_LIMIT, buildHistoryContextFromEntries, buildInboundHistoryFromEntries, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
48
48
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
49
+ import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
49
50
  import { createClaimableDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
50
- import { collectErrorGraphCandidates, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
51
+ import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
51
52
  import { getRuntimeConfig as getRuntimeConfig$1, getRuntimeConfigSourceSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
52
53
  import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
53
54
  import { buildMentionRegexes, implicitMentionKindWhen, normalizeMentionText, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-mention-gating";
@@ -58,6 +59,7 @@ import { normalizeGroupActivation, parseActivationCommand } from "openclaw/plugi
58
59
  import { createInternalHookEvent, deriveInboundMessageHookContext, fireAndForgetBoundedHook, toInternalMessageReceivedContext, toPluginMessageContext, toPluginMessageReceivedEvent, triggerInternalHook } from "openclaw/plugin-sdk/hook-runtime";
59
60
  import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
60
61
  import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
62
+ import { retryAsync } from "openclaw/plugin-sdk/retry-runtime";
61
63
  //#region extensions/whatsapp/src/inbound/dedupe.ts
62
64
  const WHATSAPP_INBOUND_DEDUPE_TTL_MS = 20 * 6e4;
63
65
  const RECENT_WEB_MESSAGE_MAX = 5e3;
@@ -67,48 +69,10 @@ const claimableInboundMessages = createClaimableDedupe({
67
69
  ttlMs: WHATSAPP_INBOUND_DEDUPE_TTL_MS,
68
70
  memoryMaxSize: RECENT_WEB_MESSAGE_MAX
69
71
  });
70
- const recentOutboundMessages = createRecentMessageCache({
72
+ const recentOutboundMessages = createDedupeCache({
71
73
  ttlMs: RECENT_OUTBOUND_MESSAGE_TTL_MS,
72
74
  maxSize: RECENT_OUTBOUND_MESSAGE_MAX
73
75
  });
74
- function createRecentMessageCache(options) {
75
- const ttlMs = Math.max(0, options.ttlMs);
76
- const maxSize = Math.max(0, Math.floor(options.maxSize));
77
- const cache = /* @__PURE__ */ new Map();
78
- const prune = (now) => {
79
- if (ttlMs > 0) {
80
- const cutoff = now - ttlMs;
81
- for (const [key, timestamp] of cache) if (timestamp < cutoff) cache.delete(key);
82
- }
83
- while (cache.size > maxSize) {
84
- const oldest = cache.keys().next().value;
85
- if (!oldest) break;
86
- cache.delete(oldest);
87
- }
88
- };
89
- const peek = (key, now = Date.now()) => {
90
- if (!key) return false;
91
- const timestamp = cache.get(key);
92
- if (timestamp === void 0) return false;
93
- if (ttlMs > 0 && now - timestamp >= ttlMs) {
94
- cache.delete(key);
95
- return false;
96
- }
97
- return true;
98
- };
99
- return {
100
- check: (key, now = Date.now()) => {
101
- if (!key) return false;
102
- const existed = peek(key, now);
103
- cache.delete(key);
104
- cache.set(key, now);
105
- prune(now);
106
- return existed;
107
- },
108
- peek,
109
- clear: () => cache.clear()
110
- };
111
- }
112
76
  var WhatsAppRetryableInboundError = class extends Error {
113
77
  constructor(message, options) {
114
78
  super(message, options);
@@ -570,12 +534,13 @@ async function downloadQuotedInboundMedia(msg, sock, maxBytes = 50 * 1024 * 1024
570
534
  }
571
535
  //#endregion
572
536
  //#region extensions/whatsapp/src/inbound/monitor.ts
573
- const LOGGED_OUT_STATUS = DisconnectReason?.loggedOut ?? 401;
537
+ const LOGGED_OUT_STATUS = DisconnectReason.loggedOut;
574
538
  const RECONNECT_IN_PROGRESS_ERROR = "no active socket - reconnection in progress";
575
539
  const GROUP_META_TTL_MS = 300 * 1e3;
576
540
  const BAILEYS_MESSAGE_TTL_MS = 600 * 1e3;
577
541
  const INBOUND_CLOSE_DRAIN_TIMEOUT_MS = 5e3;
578
542
  const REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE = /reply session initialization conflicted for \S+/u;
543
+ const WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES = 500;
579
544
  function resolveRetryableWhatsAppInboundError(error) {
580
545
  if (error instanceof WhatsAppRetryableInboundError) return error;
581
546
  if (!collectErrorGraphCandidates(error, (current) => [current.cause, current.error]).some((candidate) => REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE.test(formatErrorMessage(candidate)))) return null;
@@ -598,7 +563,7 @@ function rememberGroupMetadataCacheEntry(cache, jid, entry) {
598
563
  }
599
564
  if (cache.has(jid)) cache.delete(jid);
600
565
  cache.set(jid, entry);
601
- while (cache.size > 500) {
566
+ while (cache.size > WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES) {
602
567
  const oldest = cache.keys().next();
603
568
  if (oldest.done) break;
604
569
  cache.delete(oldest.value);
@@ -624,7 +589,7 @@ function rememberWhatsAppBaileysCacheEntry(cache, key, value, ttlMs) {
624
589
  expiresAt: Date.now() + ttlMs,
625
590
  value
626
591
  });
627
- while (cache.size > 500) {
592
+ while (cache.size > WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES) {
628
593
  const oldest = cache.keys().next();
629
594
  if (oldest.done) break;
630
595
  cache.delete(oldest.value);
@@ -645,9 +610,6 @@ function logWhatsAppVerbose(enabled, message) {
645
610
  if (!enabled) return;
646
611
  defaultRuntime.log(message);
647
612
  }
648
- function isGroupJid(jid) {
649
- return (typeof isJidGroup === "function" ? isJidGroup(jid) : jid.endsWith("@g.us")) === true;
650
- }
651
613
  function isDirectUserJid(jid) {
652
614
  return /^(\d+)(?::\d+)?@(s\.whatsapp\.net|c\.us|lid|hosted|hosted\.lid)$/i.test(jid.trim());
653
615
  }
@@ -711,7 +673,7 @@ async function attachWebInboxToSocket(options) {
711
673
  if (!options.socketRef) return sock;
712
674
  if (options.socketRef.current) return options.socketRef.current;
713
675
  if (!self.e164 && !self.jid && !self.lid) return null;
714
- const successor = getRegisteredWhatsAppConnectionController(options.accountId);
676
+ const successor = getWhatsAppConnectionController(options.accountId);
715
677
  if (!successor) return null;
716
678
  const successorIdentity = successor.getSelfIdentity();
717
679
  if (!successorIdentity || !identitiesOverlap(self, successorIdentity)) return null;
@@ -988,7 +950,7 @@ async function attachWebInboxToSocket(options) {
988
950
  }
989
951
  };
990
952
  const resolveOutboundMentionsForGroup = async (jid, text) => {
991
- if (!isGroupJid(jid) || !mayContainWhatsAppOutboundMention(text)) return {
953
+ if (isJidGroup(jid) !== true || !mayContainWhatsAppOutboundMention(text)) return {
992
954
  text,
993
955
  mentionedJids: []
994
956
  };
@@ -1021,7 +983,7 @@ async function attachWebInboxToSocket(options) {
1021
983
  const remoteJid = msg.key?.remoteJid;
1022
984
  if (!remoteJid) return null;
1023
985
  if (remoteJid.endsWith("@status") || remoteJid.endsWith("@broadcast")) return null;
1024
- const group = isGroupJid(remoteJid);
986
+ const group = isJidGroup(remoteJid) === true;
1025
987
  if (Boolean(msg.key?.fromMe) && id && isRecentOutboundMessage({
1026
988
  accountId: options.accountId,
1027
989
  remoteJid,
@@ -1770,7 +1732,7 @@ function createEchoTracker(params) {
1770
1732
  sessionKey: opts.combinedBodySessionKey,
1771
1733
  combinedBody: opts.combinedBody
1772
1734
  }));
1773
- if (opts.logVerboseMessage) params.logVerbose?.(`Added to echo detection set (size now: ${recentlySent.size}): ${text.slice(0, 50)}...`);
1735
+ if (opts.logVerboseMessage) params.logVerbose?.(`Added to echo detection set (size now: ${recentlySent.size}): ${truncateUtf16Safe(text, 50)}...`);
1774
1736
  trim();
1775
1737
  };
1776
1738
  return {
@@ -1831,19 +1793,20 @@ async function resolveGroupActivationFor(params) {
1831
1793
  sessionKey: params.sessionKey
1832
1794
  });
1833
1795
  const activation = (normalizeAccountId$1(params.accountId) === DEFAULT_ACCOUNT_ID$1 && hasNamedWhatsAppAccounts(params.cfg) && isActivationOnlyEntry(scopedEntry) ? void 0 : scopedEntry?.groupActivation) ?? legacyEntry?.groupActivation;
1834
- if (activation !== void 0 && scopedEntry?.groupActivation === void 0) await patchSessionEntry({
1835
- ...sessionScope,
1836
- sessionKey: params.sessionKey,
1837
- fallbackEntry: {},
1838
- replaceEntry: true,
1839
- update: (entry) => {
1840
- if (entry.groupActivation !== void 0) return null;
1841
- return {
1842
- ...entry,
1843
- groupActivation: activation
1844
- };
1845
- }
1846
- });
1796
+ if (activation !== void 0 && scopedEntry?.groupActivation === void 0) {
1797
+ if (scopedEntry) await patchSessionEntry({
1798
+ ...sessionScope,
1799
+ sessionKey: params.sessionKey,
1800
+ replaceEntry: true,
1801
+ update: (entry) => {
1802
+ if (entry.groupActivation !== void 0) return null;
1803
+ return {
1804
+ ...entry,
1805
+ groupActivation: activation
1806
+ };
1807
+ }
1808
+ });
1809
+ }
1847
1810
  const defaultActivation = !resolveWhatsAppInboundPolicy({
1848
1811
  cfg: params.cfg,
1849
1812
  accountId: params.accountId
@@ -2043,17 +2006,12 @@ function formatGroupMembers(params) {
2043
2006
  }
2044
2007
  //#endregion
2045
2008
  //#region extensions/whatsapp/src/auto-reply/monitor/group-gating.ts
2046
- const MAX_GROUP_DROP_WARNINGS = 100;
2047
- const groupDropWarned = /* @__PURE__ */ new Set();
2009
+ const groupDropWarned = createDedupeCache({
2010
+ ttlMs: 0,
2011
+ maxSize: 100
2012
+ });
2048
2013
  function shouldWarnForGroupDrop(warnKey) {
2049
- if (groupDropWarned.has(warnKey)) return false;
2050
- groupDropWarned.add(warnKey);
2051
- while (groupDropWarned.size > MAX_GROUP_DROP_WARNINGS) {
2052
- const oldest = groupDropWarned.values().next().value;
2053
- if (!oldest) break;
2054
- groupDropWarned.delete(oldest);
2055
- }
2056
- return true;
2014
+ return !groupDropWarned.check(warnKey);
2057
2015
  }
2058
2016
  function isOwnerSender(baseMentionConfig, msg, authDir) {
2059
2017
  const sender = normalizeE164(getSenderIdentity(msg, authDir).e164 ?? "");
@@ -2250,6 +2208,52 @@ function resolveWhatsAppDirectSystemPrompt(params) {
2250
2208
  return wildcard != null ? wildcard.trim() || void 0 : void 0;
2251
2209
  }
2252
2210
  //#endregion
2211
+ //#region extensions/whatsapp/src/outbound-retry.ts
2212
+ const WHATSAPP_OUTBOUND_MAX_ATTEMPTS = 3;
2213
+ const WHATSAPP_OUTBOUND_MIN_DELAY_MS = 500;
2214
+ const WHATSAPP_OUTBOUND_MAX_DELAY_MS = 1e3;
2215
+ const WHATSAPP_RETRYABLE_OUTBOUND_ERROR_PATTERN = /closed|reset|timed\s*out|disconnect/i;
2216
+ var WhatsAppOutboundRetryError = class extends Error {
2217
+ constructor(original) {
2218
+ super(formatError(original), { cause: original });
2219
+ this.original = original;
2220
+ }
2221
+ };
2222
+ function isRetryableWhatsAppOutboundError(error) {
2223
+ if (isWhatsAppSocketOperationTimeoutError(error)) return false;
2224
+ return WHATSAPP_RETRYABLE_OUTBOUND_ERROR_PATTERN.test(formatError(error));
2225
+ }
2226
+ async function sendWhatsAppOutboundWithRetry(params) {
2227
+ try {
2228
+ return await retryAsync(async () => {
2229
+ try {
2230
+ return await params.send();
2231
+ } catch (error) {
2232
+ throw new WhatsAppOutboundRetryError(error);
2233
+ }
2234
+ }, {
2235
+ attempts: WHATSAPP_OUTBOUND_MAX_ATTEMPTS,
2236
+ minDelayMs: WHATSAPP_OUTBOUND_MIN_DELAY_MS,
2237
+ maxDelayMs: WHATSAPP_OUTBOUND_MAX_DELAY_MS,
2238
+ jitter: 0,
2239
+ shouldRetry: (error) => error instanceof WhatsAppOutboundRetryError && isRetryableWhatsAppOutboundError(error.original),
2240
+ onRetry: ({ attempt, maxAttempts, delayMs, err }) => {
2241
+ if (!(err instanceof WhatsAppOutboundRetryError)) return;
2242
+ params.onRetry?.({
2243
+ attempt,
2244
+ maxAttempts,
2245
+ backoffMs: delayMs,
2246
+ error: err.original,
2247
+ errorText: formatError(err.original)
2248
+ });
2249
+ }
2250
+ });
2251
+ } catch (error) {
2252
+ if (error instanceof WhatsAppOutboundRetryError) throw error.original;
2253
+ throw error;
2254
+ }
2255
+ }
2256
+ //#endregion
2253
2257
  //#region extensions/whatsapp/src/auto-reply/util.ts
2254
2258
  function elide(text, limit = 400) {
2255
2259
  if (!text) return text;
@@ -2369,11 +2373,10 @@ async function deliverWebReply(params) {
2369
2373
  messageText: cached?.body ?? ""
2370
2374
  });
2371
2375
  };
2372
- const sendWithRetry = async (fn, label, maxAttempts = 3) => {
2376
+ const sendWithRetry = async (fn, label) => {
2373
2377
  try {
2374
2378
  return await sendWhatsAppOutboundWithRetry({
2375
2379
  send: fn,
2376
- maxAttempts,
2377
2380
  onRetry: ({ attempt, maxAttempts: retryMaxAttempts, backoffMs, errorText }) => {
2378
2381
  logVerbose(`Retrying ${label} to ${conversationId} after failure (${attempt}/${retryMaxAttempts - 1}) in ${backoffMs}ms: ${errorText}`);
2379
2382
  }
@@ -2575,8 +2578,8 @@ function resolveWhatsAppDurableReplyToId(params) {
2575
2578
  return null;
2576
2579
  }
2577
2580
  function resolveWhatsAppDisableBlockStreaming(cfg) {
2578
- if (typeof cfg.channels?.whatsapp?.blockStreaming !== "boolean") return;
2579
- return !cfg.channels.whatsapp.blockStreaming;
2581
+ const enabled = resolveChannelStreamingBlockEnabled(cfg.channels?.whatsapp);
2582
+ return typeof enabled === "boolean" ? !enabled : void 0;
2580
2583
  }
2581
2584
  function resolveWhatsAppDeliverablePayload(payload, info) {
2582
2585
  if (payload.isReasoning === true || payload.isCompactionNotice === true) return null;
@@ -3811,9 +3814,8 @@ function resolveWebMonitorConfigSnapshot(params) {
3811
3814
  groupAllowFrom: account.groupAllowFrom,
3812
3815
  groupPolicy: account.groupPolicy,
3813
3816
  textChunkLimit: account.textChunkLimit,
3814
- chunkMode: account.chunkMode,
3817
+ streaming: account.streaming,
3815
3818
  mediaMaxMb: account.mediaMaxMb,
3816
- blockStreaming: account.blockStreaming,
3817
3819
  groups: account.groups
3818
3820
  }
3819
3821
  }
@@ -0,0 +1,2 @@
1
+ import "./normalize-target-DSZnHkKF.js";
2
+ export {};
@@ -1,4 +1,4 @@
1
- import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { normalizeLowercaseStringOrEmpty, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  import { normalizeE164 } from "openclaw/plugin-sdk/account-resolution";
3
3
  //#region extensions/whatsapp/src/normalize-target.ts
4
4
  const WHATSAPP_USER_JID_RE = /^(\d+)(?::\d+)?@s\.whatsapp\.net$/i;
@@ -34,11 +34,20 @@ function isWhatsAppUserTarget(value) {
34
34
  }
35
35
  function extractUserJidPhone(jid) {
36
36
  const userMatch = jid.match(WHATSAPP_USER_JID_RE);
37
- if (userMatch) return userMatch[1];
37
+ if (userMatch) {
38
+ const phone = userMatch[1];
39
+ return phone ? phone : null;
40
+ }
38
41
  const legacyUserMatch = jid.match(WHATSAPP_LEGACY_USER_JID_RE);
39
- if (legacyUserMatch) return legacyUserMatch[1];
42
+ if (legacyUserMatch) {
43
+ const phone = legacyUserMatch[1];
44
+ return phone ? phone : null;
45
+ }
40
46
  const lidMatch = jid.match(WHATSAPP_LID_RE);
41
- if (lidMatch) return lidMatch[1];
47
+ if (lidMatch) {
48
+ const phone = lidMatch[1];
49
+ return phone ? phone : null;
50
+ }
42
51
  return null;
43
52
  }
44
53
  function normalizeWhatsAppTarget(value) {
@@ -67,12 +76,7 @@ function normalizeWhatsAppMessagingTarget(raw) {
67
76
  return normalizeWhatsAppTarget(trimmed) ?? void 0;
68
77
  }
69
78
  function normalizeWhatsAppAllowFromEntries(allowFrom) {
70
- const seen = /* @__PURE__ */ new Set();
71
- return allowFrom.map((entry) => String(entry).trim()).filter((entry) => Boolean(entry)).map(normalizeWhatsAppAllowFromEntry).filter((entry) => Boolean(entry)).filter((entry) => {
72
- if (seen.has(entry)) return false;
73
- seen.add(entry);
74
- return true;
75
- });
79
+ return uniqueStrings(normalizeStringEntries(allowFrom).map(normalizeWhatsAppAllowFromEntry).filter((entry) => Boolean(entry)));
76
80
  }
77
81
  function normalizeWhatsAppAllowFromEntry(entry) {
78
82
  if (entry === "*") return entry;
@@ -1,4 +1,4 @@
1
- import { c as normalizeWhatsAppTarget, n as isWhatsAppNewsletterJid, t as isWhatsAppGroupJid } from "./normalize-target-bVWjgftN.js";
1
+ import { c as normalizeWhatsAppTarget, n as isWhatsAppNewsletterJid, t as isWhatsAppGroupJid } from "./normalize-target-DSZnHkKF.js";
2
2
  import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { missingTargetError } from "openclaw/plugin-sdk/channel-feedback";
4
4
  //#region extensions/whatsapp/src/resolve-outbound-target.ts
@@ -1,16 +1,16 @@
1
1
  import { o as resolveWebCredsBackupPath, r as hasWebCredsSync, s as resolveWebCredsPath } from "./creds-files-B1kSWtBg.js";
2
- import { n as whatsAppActionRuntime, t as handleWhatsAppAction } from "./action-runtime-DPahAqxV.js";
3
- import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-C5CpFcBG.js";
2
+ import { n as whatsAppActionRuntime, t as handleWhatsAppAction } from "./action-runtime-Bf-12TIH.js";
3
+ import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-D9Ydnn4o.js";
4
4
  import { r as setWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
5
- import { n as getStatusCode, t as formatError } from "./session-errors-BAj9D2La.js";
6
5
  import { startWebLoginWithQr, waitForWebLogin } from "./login-qr-runtime.js";
7
- import { t as createWhatsAppLoginTool } from "./agent-tools-login-BX7eHgDm.js";
8
- import { C as waitForCredsSaveQueue, T as writeCredsJsonAtomically, _ as readWebSelfIdentity, a as formatWhatsAppWebAuthStatusState, b as restoreCredsFromBackupIfNeeded, c as logoutWeb, d as readWebAuthExistsBestEffort, f as readWebAuthExistsForDecision, g as readWebSelfId, h as readWebAuthState, l as pickWebChannel, m as readWebAuthSnapshotBestEffort, n as WHATSAPP_AUTH_UNSTABLE_CODE, o as getWebAuthAgeMs, p as readWebAuthSnapshot, r as WhatsAppAuthUnstableError, s as logWebSelfId, t as WA_WEB_AUTH_DIR, u as readCredsJsonRaw, v as readWebSelfIdentityForDecision, w as waitForCredsSaveQueueWithTimeout, x as webAuthExists, y as resolveDefaultWebAuthDir } from "./auth-store-Db-wfApd.js";
6
+ import { t as createWhatsAppLoginTool } from "./agent-tools-login-DfyToBpG.js";
7
+ import { C as waitForCredsSaveQueue, T as writeCredsJsonAtomically, _ as readWebSelfIdentity, a as formatWhatsAppWebAuthStatusState, b as restoreCredsFromBackupIfNeeded, c as logoutWeb, d as readWebAuthExistsBestEffort, f as readWebAuthExistsForDecision, g as readWebSelfId, h as readWebAuthState, l as pickWebChannel, m as readWebAuthSnapshotBestEffort, n as WHATSAPP_AUTH_UNSTABLE_CODE, o as getWebAuthAgeMs, p as readWebAuthSnapshot, r as WhatsAppAuthUnstableError, s as logWebSelfId, t as WA_WEB_AUTH_DIR, u as readCredsJsonRaw, v as readWebSelfIdentityForDecision, w as waitForCredsSaveQueueWithTimeout, x as webAuthExists, y as resolveDefaultWebAuthDir } from "./auth-store-BQi9pZqQ.js";
9
8
  import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-HU41RHGI.js";
10
- import { _ as extractLocationData, b as extractText, m as extractContactContext, v as extractMediaPlaceholder } from "./send-api-DLlXl8CH.js";
11
- import { n as newConnectionId, r as waitForWaConnection, t as createWaSocket } from "./session-DriaHt7V.js";
12
- import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-listener-B4SDebQ6.js";
13
- import { a as loadWebMediaRaw, c as monitorWebInbox, i as loadWebMedia, l as resetWebInboundDedupe, n as LocalMediaAccessError, o as optimizeImageToJpeg, r as getDefaultLocalRoots, s as optimizeImageToPng, t as monitorWebChannel } from "./monitor-DD8bXohk.js";
14
- import { t as loginWeb } from "./login-C48y0jlx.js";
9
+ import { _ as extractLocationData, b as extractText, m as extractContactContext, v as extractMediaPlaceholder } from "./send-api-W33lI2nR.js";
10
+ import { n as newConnectionId, r as waitForWaConnection, t as createWaSocket } from "./session-mxWFn0eS.js";
11
+ import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
12
+ import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-listener-5kHap439.js";
13
+ import { a as loadWebMediaRaw, c as monitorWebInbox, i as loadWebMedia, l as resetWebInboundDedupe, n as LocalMediaAccessError, o as optimizeImageToJpeg, r as getDefaultLocalRoots, s as optimizeImageToPng, t as monitorWebChannel } from "./monitor-BKtA0lzq.js";
14
+ import { t as loginWeb } from "./login-DGIoToX8.js";
15
15
  import { HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, SILENT_REPLY_TOKEN, stripHeartbeatToken } from "openclaw/plugin-sdk/reply-runtime";
16
16
  export { DEFAULT_WEB_MEDIA_BYTES, HEARTBEAT_PROMPT, HEARTBEAT_TOKEN, LocalMediaAccessError, SILENT_REPLY_TOKEN, WA_WEB_AUTH_DIR, WHATSAPP_AUTH_UNSTABLE_CODE, WhatsAppAuthUnstableError, createWaSocket, createWhatsAppLoginTool, extractContactContext, extractLocationData, extractMediaPlaceholder, extractText, formatError, formatWhatsAppWebAuthStatusState, getActiveWebListener, getDefaultLocalRoots, getStatusCode, getWebAuthAgeMs, handleWhatsAppAction, hasWebCredsSync, loadWebMedia, loadWebMediaRaw, logWebSelfId, loginWeb, logoutWeb, monitorWebChannel, monitorWebInbox, newConnectionId, optimizeImageToJpeg, optimizeImageToPng, pickWebChannel, readCredsJsonRaw, readWebAuthExistsBestEffort, readWebAuthExistsForDecision, readWebAuthSnapshot, readWebAuthSnapshotBestEffort, readWebAuthState, readWebSelfId, readWebSelfIdentity, readWebSelfIdentityForDecision, resetWebInboundDedupe, resolveDefaultWebAuthDir, resolveWebAccountId, resolveWebCredsBackupPath, resolveWebCredsPath, restoreCredsFromBackupIfNeeded, sendMessageWhatsApp, sendPollWhatsApp, sendReactionWhatsApp, sendTypingWhatsApp, setWhatsAppRuntime, startWebLoginWithQr, stripHeartbeatToken, waitForCredsSaveQueue, waitForCredsSaveQueueWithTimeout, waitForWaConnection, waitForWebLogin, webAuthExists, whatsAppActionRuntime, writeCredsJsonAtomically };