@openclaw/whatsapp 2026.9.1 → 2026.9.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.
Files changed (26) hide show
  1. package/dist/api.js +3 -3
  2. package/dist/{channel-DebjeuFC.js → channel-dwfgnadr.js} +1 -5
  3. package/dist/channel-plugin-api.js +1 -1
  4. package/dist/{channel.runtime-B90_wffD.js → channel.runtime-Bn3K5Ygb.js} +2 -2
  5. package/dist/{channel.setup-D1-jE0aE.js → channel.setup-DckQm9ma.js} +1 -1
  6. package/dist/{monitor-DyPdOPRx.js → monitor-Bc6DC5jl.js} +44 -26
  7. package/dist/runtime-api.js +1 -1
  8. package/dist/{setup-finalize-C5QtbrWV.js → setup-finalize-gLmc3FTV.js} +1 -1
  9. package/dist/setup-plugin-api.js +1 -1
  10. package/dist/{setup-surface-WsAzq337.js → setup-surface-twIi4TdN.js} +1 -1
  11. package/dist/{shared-BzKxoeKY.js → shared-ByeKDmh0.js} +7 -3
  12. package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
  13. package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
  14. package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
  15. package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
  16. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  17. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  18. package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
  19. package/node_modules/typebox/build/system/memory/create.mjs +3 -4
  20. package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
  21. package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
  22. package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
  23. package/node_modules/typebox/build/system/memory/update.mjs +3 -2
  24. package/node_modules/typebox/package.json +1 -1
  25. package/openclaw.plugin.json +0 -1
  26. package/package.json +5 -5
package/dist/api.js CHANGED
@@ -4,10 +4,10 @@ import { a as normalizeWhatsAppAllowFromEntries, c as normalizeWhatsAppTarget, i
4
4
  import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-1GqbT1uX.js";
5
5
  import { c as toWhatsappJid, i as markdownToWhatsApp, l as toWhatsappJidWithLid, n as isSelfChatMode, r as jidToE164, s as resolveJidToE164, t as assertWebChannel } from "./targets-runtime-RBjx3pg_.js";
6
6
  import { n as resolveUserPath, t as normalizeE164 } from "./text-runtime-DyfmcATV.js";
7
- import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-DebjeuFC.js";
8
- import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy } from "./shared-BzKxoeKY.js";
7
+ import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-dwfgnadr.js";
8
+ import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy } from "./shared-ByeKDmh0.js";
9
9
  import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
10
- import { t as whatsappSetupPlugin } from "./channel.setup-D1-jE0aE.js";
10
+ import { t as whatsappSetupPlugin } from "./channel.setup-DckQm9ma.js";
11
11
  import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-C7m81BNe.js";
12
12
  import { a as waitForWaConnection, o as DEFAULT_WHATSAPP_SOCKET_TIMING, r as createWaSocket, s as createWhatsAppSocketOperationTimeoutAdapter } from "./socket-close-B3X9uerq.js";
13
13
  import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
@@ -8,7 +8,7 @@ import "./normalize-C7Hkc_vE.js";
8
8
  import { c as toWhatsappJid } from "./targets-runtime-RBjx3pg_.js";
9
9
  import "./text-runtime-DyfmcATV.js";
10
10
  import { c as getWhatsAppApprovalApprovers, l as whatsappApprovalAuth, s as lookupInboundMessageMetaForTarget, t as resolveWhatsAppGroupSessionKey } from "./group-session-key-BmVDSPr1.js";
11
- import { a as resolveWhatsAppGroupRequireMention, c as loadWhatsAppChannelRuntime, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, s as formatWhatsAppConfigAllowFromEntries, t as createWhatsAppPluginBase } from "./shared-BzKxoeKY.js";
11
+ import { a as resolveWhatsAppGroupRequireMention, c as loadWhatsAppChannelRuntime, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, s as formatWhatsAppConfigAllowFromEntries, t as createWhatsAppPluginBase } from "./shared-ByeKDmh0.js";
12
12
  import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
13
13
  import { f as readWebAuthExistsForDecision, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-ZWaclAbd.js";
14
14
  import { createActionGate as createActionGate$1 } from "openclaw/plugin-sdk/channel-actions";
@@ -229,10 +229,6 @@ function createWhatsAppOutboundBase({ sendMessageWhatsApp, sendPollWhatsApp, sho
229
229
  return {
230
230
  ...outbound,
231
231
  sendPayload: async (ctx) => {
232
- if (ctx.payload.isError === true) return {
233
- channel: "whatsapp",
234
- messageId: ""
235
- };
236
232
  const payload = normalizeWhatsAppOutboundPayload(ctx.payload, { normalizeText });
237
233
  if (!payload.text && !(payload.mediaUrl || payload.mediaUrls?.length)) {
238
234
  if (ctx.payload.interactive || ctx.payload.presentation || ctx.payload.channelData) throw new Error("WhatsApp sendPayload does not support structured-only payloads without text or media.");
@@ -1,2 +1,2 @@
1
- import { t as whatsappPlugin } from "./channel-DebjeuFC.js";
1
+ import { t as whatsappPlugin } from "./channel-dwfgnadr.js";
2
2
  export { whatsappPlugin };
@@ -1,9 +1,9 @@
1
1
  import { startWebLoginWithQr as startWebLoginWithQr$1, waitForWebLogin as waitForWebLogin$1 } from "./login-qr-runtime.js";
2
2
  import { c as logoutWeb$1, d as readWebAuthExistsBestEffort$1, f as readWebAuthExistsForDecision$1, g as readWebSelfId$1, h as readWebAuthState$1, m as readWebAuthSnapshotBestEffort$1, o as getWebAuthAgeMs$1, p as readWebAuthSnapshot$1, s as logWebSelfId$1, x as webAuthExists$1 } from "./auth-store-ZWaclAbd.js";
3
3
  import { t as getActiveWebListener$1 } from "./active-listener-BEjWsCNM.js";
4
- import { t as monitorWebChannel$1 } from "./monitor-DyPdOPRx.js";
4
+ import { t as monitorWebChannel$1 } from "./monitor-Bc6DC5jl.js";
5
5
  import { t as loginWeb$1 } from "./login-6j2iP9nR.js";
6
- import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-WsAzq337.js";
6
+ import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-twIi4TdN.js";
7
7
  //#region extensions/whatsapp/src/channel.runtime.ts
8
8
  function getActiveWebListener(...args) {
9
9
  return getActiveWebListener$1(...args);
@@ -1,4 +1,4 @@
1
- import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, t as createWhatsAppPluginBase } from "./shared-BzKxoeKY.js";
1
+ import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupContract, l as readWhatsAppAccountLinkState, n as whatsappSetupWizardProxy, o as resolveWhatsAppGroupToolPolicy, t as createWhatsAppPluginBase } from "./shared-ByeKDmh0.js";
2
2
  //#region extensions/whatsapp/src/channel.setup.ts
3
3
  const whatsappSetupPlugin = { ...createWhatsAppPluginBase({
4
4
  groups: {
@@ -40,12 +40,12 @@ import { createHash } from "node:crypto";
40
40
  import { resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
41
41
  import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
42
42
  import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
43
- import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
44
43
  import { drainPendingDeliveries } from "openclaw/plugin-sdk/delivery-queue-runtime";
45
44
  import { DEFAULT_GROUP_HISTORY_LIMIT, buildHistoryContextFromEntries, buildInboundHistoryFromEntries, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
46
45
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
47
46
  import { fanInChannelIngressLifecycles, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
48
47
  import { getSessionEntry, patchSessionEntry, resolveGroupSessionKey, resolveStorePath, resolveStorePath as resolveStorePath$1, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
48
+ import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
49
49
  import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
50
50
  import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
51
51
  import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
@@ -529,10 +529,10 @@ function createWhatsAppGroupMetadataCacheOwner(params) {
529
529
  const listen = (event, listener) => {
530
530
  detachListeners.push(params.listen(event, listener));
531
531
  };
532
- listen("groups.upsert", ((groups) => {
532
+ listen("groups.upsert", (groups) => {
533
533
  for (const group of groups) if (group.id) rememberFullUpdate(group.id, group);
534
- }));
535
- listen("groups.update", ((updates) => {
534
+ });
535
+ listen("groups.update", (updates) => {
536
536
  for (const update of updates) {
537
537
  if (!update.id) continue;
538
538
  if (typeof update.subject === "string" && Array.isArray(update.participants)) {
@@ -541,10 +541,10 @@ function createWhatsAppGroupMetadataCacheOwner(params) {
541
541
  }
542
542
  forgetFullMetadata(update.id);
543
543
  }
544
- }));
545
- listen("group-participants.update", ((update) => {
544
+ });
545
+ listen("group-participants.update", (update) => {
546
546
  forgetFullMetadata(update.id);
547
- }));
547
+ });
548
548
  (async () => {
549
549
  try {
550
550
  const groups = await params.sock.groupFetchAllParticipating();
@@ -578,13 +578,7 @@ function createWhatsAppGroupMetadataCacheOwner(params) {
578
578
  //#region extensions/whatsapp/src/inbound/lifecycle.ts
579
579
  function attachEmitterListener(emitter, event, listener) {
580
580
  emitter.on(event, listener);
581
- return () => {
582
- if (typeof emitter.off === "function") {
583
- emitter.off(event, listener);
584
- return;
585
- }
586
- if (typeof emitter.removeListener === "function") emitter.removeListener(event, listener);
587
- };
581
+ return () => emitter.off(event, listener);
588
582
  }
589
583
  function closeInboundMonitorSocket(sock) {
590
584
  if (typeof sock.end === "function") {
@@ -606,7 +600,6 @@ function resolveWhatsAppIngressLifecycle(message) {
606
600
  //#endregion
607
601
  //#region extensions/whatsapp/src/inbound/message-debounce.ts
608
602
  function createWhatsAppInboundMessageDebouncer(options) {
609
- const debounceMs = Math.max(0, Math.trunc(options.debounceMs ?? 0));
610
603
  const pendingKeys = /* @__PURE__ */ new Map();
611
604
  const activeFlushes = /* @__PURE__ */ new Set();
612
605
  const workWaiters = /* @__PURE__ */ new Set();
@@ -636,7 +629,8 @@ function createWhatsAppInboundMessageDebouncer(options) {
636
629
  return timestampDiff !== 0 ? timestampDiff : (a.receiveOrder ?? 0) - (b.receiveOrder ?? 0);
637
630
  });
638
631
  const debouncer = createInboundDebouncer({
639
- debounceMs,
632
+ debounceMs: options.resolveDebounceMs(),
633
+ resolveDebounceMs: (entry) => entry.debounceMs,
640
634
  buildKey: (msg) => msg.debounceKey ?? buildKey(msg),
641
635
  shouldDebounce,
642
636
  onFlush: (entries, createFlush) => {
@@ -702,11 +696,15 @@ function createWhatsAppInboundMessageDebouncer(options) {
702
696
  },
703
697
  onError: options.onError
704
698
  });
705
- const enqueue = async (message) => {
699
+ const enqueue = async (input) => {
700
+ const message = {
701
+ ...input,
702
+ debounceMs: options.resolveDebounceMs()
703
+ };
706
704
  const key = buildKey(message);
707
705
  if (key) {
708
706
  message.debounceKey = key;
709
- if (debounceMs > 0 && shouldDebounce(message)) {
707
+ if (message.debounceMs > 0 && shouldDebounce(message)) {
710
708
  message.debounceKeyTracked = true;
711
709
  trackKey(key);
712
710
  options.onPendingWorkChanged();
@@ -1184,7 +1182,11 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1184
1182
  await maybeMarkInboundAsRead(target);
1185
1183
  };
1186
1184
  const messageDebouncer = createWhatsAppInboundMessageDebouncer({
1187
- debounceMs: options.debounceMs,
1185
+ resolveDebounceMs: () => resolveInboundDebounceMs({
1186
+ cfg: options.loadConfig?.() ?? options.cfg,
1187
+ channel: "whatsapp",
1188
+ overrideMs: options.debounceMs
1189
+ }),
1188
1190
  onMessage: options.onMessage,
1189
1191
  shouldDebounce: options.shouldDebounce,
1190
1192
  markRead: maybeMarkInboundAsRead,
@@ -2415,7 +2417,11 @@ async function applyGroupGating(params) {
2415
2417
  const conversationGroupPolicy = inboundPolicy.resolveConversationGroupPolicy(conversationId);
2416
2418
  if (conversationGroupPolicy.allowlistEnabled && !conversationGroupPolicy.allowed) {
2417
2419
  const accountId = inboundPolicy.account.accountId;
2418
- if (shouldWarnForGroupDrop(`${accountId}:${conversationId}`)) {
2420
+ if (shouldWarnForGroupDrop(JSON.stringify([
2421
+ accountId,
2422
+ conversationId,
2423
+ "group registry"
2424
+ ]))) {
2419
2425
  const groupsPath = resolveWhatsAppGroupsConfigPath({
2420
2426
  cfg: params.cfg,
2421
2427
  accountId
@@ -2504,6 +2510,22 @@ async function applyGroupGating(params) {
2504
2510
  needsMentionText: true
2505
2511
  };
2506
2512
  }
2513
+ const accountId = inboundPolicy.account.accountId;
2514
+ if (shouldWarnForGroupDrop(JSON.stringify([
2515
+ accountId,
2516
+ conversationId,
2517
+ "no mention"
2518
+ ]))) {
2519
+ const groupsPath = resolveWhatsAppGroupsConfigPath({
2520
+ cfg: params.cfg,
2521
+ accountId
2522
+ });
2523
+ params.replyLogger.warn({
2524
+ conversationId,
2525
+ accountId,
2526
+ groupsPath
2527
+ }, `WhatsApp group ${conversationId}: skipping messages without a mention. Mention patterns can be derived from the agent identity name. Use /activation always for this session, or set ${groupsPath}[${JSON.stringify(conversationId)}].requireMention=false for the default. Preserve existing groups entries; when adding the first groups map, include "*": {} to keep other chats admitted.`);
2528
+ }
2507
2529
  const pendingHistoryBody = params.mentionText === void 0 ? void 0 : formatAudioTranscriptForAgent(params.mentionText);
2508
2530
  return skipGroupMessageAndStoreHistory(params, `Group message stored for context (no mention detected) in ${conversationId}: ${mentionMsg.payload.body}`, pendingHistoryBody);
2509
2531
  }
@@ -3071,7 +3093,7 @@ function resolveWhatsAppDurableReplyToId(params) {
3071
3093
  }
3072
3094
  function resolveWhatsAppDeliverablePayload(payload, info) {
3073
3095
  if (payload.isReasoning === true || payload.isCompactionNotice === true) return null;
3074
- if (payload.isError === true) return null;
3096
+ if (payload.isError === true && info.kind !== "final") return null;
3075
3097
  if (info.kind === "tool") {
3076
3098
  if (!resolveSendableOutboundReplyParts(payload).hasMedia) return null;
3077
3099
  return {
@@ -4348,10 +4370,6 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4348
4370
  while (true) {
4349
4371
  if (stopRequested()) break;
4350
4372
  const connectionId = newConnectionId();
4351
- const inboundDebounceMs = resolveInboundDebounceMs({
4352
- cfg,
4353
- channel: "whatsapp"
4354
- });
4355
4373
  const shouldDebounce = (msg) => shouldDebounceTextInbound({
4356
4374
  text: msg.payload.commandBody ?? msg.payload.body,
4357
4375
  cfg,
@@ -4396,7 +4414,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4396
4414
  selfChatMode: account.selfChatMode,
4397
4415
  sendReadReceipts: account.sendReadReceipts,
4398
4416
  socketTiming,
4399
- debounceMs: inboundDebounceMs,
4417
+ debounceMs: tuning.debounceMs,
4400
4418
  appendReplyWindow: connectionLocal.openedAfterRecentInbound ? {
4401
4419
  afterMs: connectionLocal.startedAt - reconnectCatchUpWindowMs,
4402
4420
  untilMs: connectionLocal.startedAt + reconnectCatchUpWindowMs,
@@ -10,7 +10,7 @@ import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-li
10
10
  import { a as waitForWaConnection, i as newConnectionId, r as createWaSocket } from "./socket-close-B3X9uerq.js";
11
11
  import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
12
12
  import { p as extractText, s as extractContactContext, u as extractLocationData } from "./send-api-C_Zn4Ij-.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-DyPdOPRx.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-Bc6DC5jl.js";
14
14
  import { t as loginWeb } from "./login-6j2iP9nR.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, 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 };
@@ -2,7 +2,7 @@ import { a as resolveWhatsAppAccount, o as resolveWhatsAppAuthDir } from "./acco
2
2
  import { r as resolveDefaultWhatsAppAccountId } from "./account-ids-CB5SOWjc.js";
3
3
  import { r as hasWebCredsSync } from "./creds-files-Drg3usj1.js";
4
4
  import { a as normalizeWhatsAppAllowFromEntries, o as normalizeWhatsAppAllowFromEntry } from "./normalize-target-CugRyONv.js";
5
- import { r as whatsappSetupAdapter } from "./shared-BzKxoeKY.js";
5
+ import { r as whatsappSetupAdapter } from "./shared-ByeKDmh0.js";
6
6
  import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
7
7
  import { DEFAULT_ACCOUNT_ID, createSetupTranslator, splitSetupEntries } from "openclaw/plugin-sdk/setup";
8
8
  //#region extensions/whatsapp/src/setup-finalize.ts
@@ -1,2 +1,2 @@
1
- import { t as whatsappSetupPlugin } from "./channel.setup-D1-jE0aE.js";
1
+ import { t as whatsappSetupPlugin } from "./channel.setup-DckQm9ma.js";
2
2
  export { whatsappSetupPlugin };
@@ -36,7 +36,7 @@ const whatsappSetupWizard = {
36
36
  },
37
37
  resolveShouldPromptAccountIds: ({ shouldPromptAccountIds }) => shouldPromptAccountIds,
38
38
  credentials: [],
39
- finalize: async (params) => await (await import("./setup-finalize-C5QtbrWV.js")).finalizeWhatsAppSetup(params),
39
+ finalize: async (params) => await (await import("./setup-finalize-gLmc3FTV.js")).finalizeWhatsAppSetup(params),
40
40
  disable: (cfg) => setSetupChannelEnabled(cfg, channel, false),
41
41
  onAccountRecorded: (accountId, options) => {
42
42
  options?.onAccountId?.(channel, accountId);
@@ -27,7 +27,7 @@ async function readWhatsAppAccountLinkState(authDir) {
27
27
  }
28
28
  const loadWhatsAppChannelRuntime = createLazyRuntimeModule(async () => {
29
29
  await loadWhatsAppAuthStore();
30
- return await import("./channel.runtime-B90_wffD.js");
30
+ return await import("./channel.runtime-Bn3K5Ygb.js");
31
31
  });
32
32
  //#endregion
33
33
  //#region extensions/whatsapp/src/config-accessors.ts
@@ -116,7 +116,7 @@ async function applyWhatsAppSecurityConfigFixes(params) {
116
116
  //#region extensions/whatsapp/src/shared.ts
117
117
  const WHATSAPP_CHANNEL = "whatsapp";
118
118
  async function loadWhatsAppSetupSurface() {
119
- return await import("./setup-surface-WsAzq337.js");
119
+ return await import("./setup-surface-twIi4TdN.js");
120
120
  }
121
121
  const whatsappSetupWizardProxy = createWhatsAppSetupWizardProxy(async () => (await loadWhatsAppSetupSurface()).whatsappSetupWizard);
122
122
  const whatsappConfigAdapter = createScopedChannelConfigAdapter({
@@ -252,7 +252,11 @@ function createWhatsAppPluginBase(params) {
252
252
  "channels.whatsapp.accounts",
253
253
  "channels.whatsapp.selfChatMode"
254
254
  ],
255
- noopPrefixes: ["channels.whatsapp"]
255
+ noopPrefixes: [
256
+ "channels.whatsapp",
257
+ "messages.inbound",
258
+ "messages.ackReactionScope"
259
+ ]
256
260
  },
257
261
  gatewayMethodDescriptors: [{ name: "web.login.start" }, { name: "web.login.wait" }],
258
262
  configSchema: WhatsAppChannelConfigSchema,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a json pointer
3
- * @specification
4
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
4
+ * @source https://github.com/ajv-validator/ajv-formats
5
5
  */
6
6
  export declare function IsJsonPointer(value: string): boolean;
@@ -1,8 +1,8 @@
1
1
  const JsonPointer = /^(?:\/(?:[^~/]|~0|~1)*)*$/;
2
2
  /**
3
3
  * Returns true if the value is a json pointer
4
- * @specification
5
- * @source ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
5
+ * @source https://github.com/ajv-validator/ajv-formats
6
6
  */
7
7
  export function IsJsonPointer(value) {
8
8
  return JsonPointer.test(value);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a json pointer uri fragment
3
- * @specification
4
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
4
+ * @source https://github.com/ajv-validator/ajv-formats
5
5
  */
6
6
  export declare function IsJsonPointerUriFragment(value: string): boolean;
@@ -1,8 +1,8 @@
1
1
  const JsonPointerUriFragment = /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i;
2
2
  /**
3
3
  * Returns true if the value is a json pointer uri fragment
4
- * @specification
5
- * @source ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
5
+ * @source https://github.com/ajv-validator/ajv-formats
6
6
  */
7
7
  export function IsJsonPointerUriFragment(value) {
8
8
  return JsonPointerUriFragment.test(value);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a relative json pointer
3
- * @specification
4
- * @source ajv-formats
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
4
+ * @source https://github.com/ajv-validator/ajv-formats
5
5
  */
6
6
  export declare function IsRelativeJsonPointer(value: string): boolean;
@@ -1,8 +1,8 @@
1
1
  const RelativeJsonPointer = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;
2
2
  /**
3
3
  * Returns true if the value is a relative json pointer
4
- * @specification
5
- * @source ajv-formats
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
5
+ * @source https://github.com/ajv-validator/ajv-formats
6
6
  */
7
7
  export function IsRelativeJsonPointer(value) {
8
8
  return RelativeJsonPointer.test(value);
@@ -1,11 +1,12 @@
1
1
  // deno-lint-ignore-file ban-types no-explicit-any
2
2
  // deno-fmt-ignore-file
3
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
4
5
  /**
5
6
  * Performs an Object assign using the Left and Right object types. We track this operation as it
6
7
  * creates a new GC handle per assignment.
7
8
  */
8
9
  export function Assign(left, right) {
9
10
  Metrics.assign += 1;
10
- return { ...left, ...right };
11
+ return Freeze({ ...left, ...right });
11
12
  }
@@ -1,7 +1,7 @@
1
1
  // deno-lint-ignore-file no-explicit-any
2
- // deno-fmt-ignore-file
3
2
  import { Settings } from '../settings/index.mjs';
4
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
5
5
  function MergeHidden(left, right) {
6
6
  for (const key of Object.keys(right)) {
7
7
  Object.defineProperty(left, key, {
@@ -23,8 +23,7 @@ function Merge(left, right) {
23
23
  */
24
24
  export function Create(hidden, enumerable, options = {}) {
25
25
  Metrics.create += 1;
26
- const settings = Settings.Get();
27
26
  const withOptions = Merge(enumerable, options);
28
- const withHidden = settings.enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
29
- return settings.immutableTypes ? Object.freeze(withHidden) : withHidden;
27
+ const withHidden = Settings.Get().enumerableKind ? Merge(withOptions, hidden) : MergeHidden(withOptions, hidden);
28
+ return Freeze(withHidden);
30
29
  }
@@ -1,7 +1,7 @@
1
1
  // deno-lint-ignore-file no-explicit-any
2
- // deno-fmt-ignore-file
3
2
  import { Guard } from '../../guard/index.mjs';
4
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
5
5
  import { Clone } from './clone.mjs';
6
6
  /** Discards multiple property keys from the given object value */
7
7
  export function Discard(value, propertyKeys) {
@@ -14,5 +14,5 @@ export function Discard(value, propertyKeys) {
14
14
  descriptor.value = Clone(descriptor.value);
15
15
  Object.defineProperty(result, key, descriptor);
16
16
  }
17
- return result;
17
+ return Freeze(result);
18
18
  }
@@ -0,0 +1,4 @@
1
+ type ObjectLike = Record<PropertyKey, any>;
2
+ /** Conditionally freezes the value if `immutableTypes` is true, otherwise no action. */
3
+ export declare function Freeze(value: ObjectLike): ObjectLike;
4
+ export {};
@@ -0,0 +1,6 @@
1
+ // deno-lint-ignore-file no-explicit-any
2
+ import { Settings } from '../settings/index.mjs';
3
+ /** Conditionally freezes the value if `immutableTypes` is true, otherwise no action. */
4
+ export function Freeze(value) {
5
+ return Settings.Get().immutableTypes ? Object.freeze(value) : value;
6
+ }
@@ -1,6 +1,7 @@
1
- // deno-fmt-ignore-file
1
+ // deno-lint-ignore-file no-explicit-any
2
2
  import { Settings } from '../settings/index.mjs';
3
3
  import { Metrics } from './metrics.mjs';
4
+ import { Freeze } from './freeze.mjs';
4
5
  import { Clone } from './clone.mjs';
5
6
  /**
6
7
  * Updates a value with new properties while preserving property enumerability. Use this function to modify
@@ -28,5 +29,5 @@ export function Update(current, hidden, enumerable) {
28
29
  value: enumerable[key]
29
30
  });
30
31
  }
31
- return result;
32
+ return Freeze(result);
32
33
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typebox",
3
3
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
4
- "version": "1.3.17",
4
+ "version": "1.3.18",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "jsonschema"
@@ -6,7 +6,6 @@
6
6
  },
7
7
  "name": "WhatsApp",
8
8
  "description": "OpenClaw WhatsApp channel plugin for WhatsApp Web chats.",
9
- "icon": "https://cdn.simpleicons.org/whatsapp",
10
9
  "skills": [
11
10
  "./skills"
12
11
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/whatsapp",
3
- "version": "2026.9.1",
3
+ "version": "2026.9.2",
4
4
  "description": "OpenClaw WhatsApp channel plugin for WhatsApp Web chats.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,10 +10,10 @@
10
10
  "dependencies": {
11
11
  "audio-decode": "2.2.3",
12
12
  "baileys": "7.0.0-rc14",
13
- "typebox": "1.3.17"
13
+ "typebox": "1.3.18"
14
14
  },
15
15
  "peerDependencies": {
16
- "openclaw": ">=2026.9.1"
16
+ "openclaw": ">=2026.9.2"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
@@ -65,11 +65,11 @@
65
65
  "minHostVersion": ">=2026.4.25"
66
66
  },
67
67
  "compat": {
68
- "pluginApi": ">=2026.9.1"
68
+ "pluginApi": ">=2026.9.2"
69
69
  },
70
70
  "build": {
71
71
  "bundledDist": false,
72
- "openclawVersion": "2026.9.1"
72
+ "openclawVersion": "2026.9.2"
73
73
  },
74
74
  "release": {
75
75
  "publishToClawHub": true,