@openclaw/whatsapp 2026.6.11 → 2026.7.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.
Files changed (32) hide show
  1. package/dist/{access-control-_oQx0_UZ.js → access-control-88UPniDc.js} +4 -4
  2. package/dist/action-runtime-api.js +1 -1
  3. package/dist/{action-runtime-D-FTwc8j.js → action-runtime-hqza0J8B.js} +1 -1
  4. package/dist/action-runtime.runtime.js +1 -1
  5. package/dist/api.js +15 -9
  6. package/dist/{approval-handler.runtime-DNBh4thG.js → approval-handler.runtime-9_SV7vhc.js} +1 -1
  7. package/dist/{auth-store-BRv2o3w2.js → auth-store-ECx4h57q.js} +2 -2
  8. package/dist/{channel-C9zebxrw.js → channel-fcXxWXic.js} +14 -8
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel-react-action-C56UzM_r.js → channel-react-action-Dgy9uUMl.js} +12 -13
  11. package/dist/{channel.runtime-kVF_UONw.js → channel.runtime-B4ThooGF.js} +4 -4
  12. package/dist/{channel.setup-BTi6IdDT.js → channel.setup-C_WEdyJR.js} +2 -2
  13. package/dist/{connection-controller-Ds4puj_n.js → connection-controller-u-tfAFhJ.js} +3 -3
  14. package/dist/contract-api.js +1 -1
  15. package/dist/{identity-DdeafYji.js → identity-CmsTmkKR.js} +1 -1
  16. package/dist/light-runtime-api.js +1 -1
  17. package/dist/{login-FpqysWi0.js → login-8lHwLmXj.js} +3 -3
  18. package/dist/{login-qr-BjfpyyN0.js → login-qr-BEZZqrTb.js} +3 -3
  19. package/dist/login-qr-runtime.js +2 -5
  20. package/dist/{monitor-BVD90YEd.js → monitor-BqkJ4MpT.js} +85 -42
  21. package/dist/{quoted-message-DqmWlbN7.js → quoted-message-CpA_ujXK.js} +1 -1
  22. package/dist/runtime-api.js +7 -7
  23. package/dist/{send-api-11yoHJhM.js → send-api-DndiBJhN.js} +4 -4
  24. package/dist/{send-BplHdEjw.js → send-i8Xk5mBQ.js} +4 -6
  25. package/dist/{session-DlHpYSAl.js → session-WU4SVP8f.js} +20 -1
  26. package/dist/{setup-core-D0JxJ53T.js → setup-core-KjSBbWX4.js} +2 -2
  27. package/dist/{setup-finalize-BRTq3uPs.js → setup-finalize-WedNP30s.js} +2 -2
  28. package/dist/setup-plugin-api.js +1 -1
  29. package/dist/{setup-surface-BpdIDwDg.js → setup-surface-IOdkbWsQ.js} +2 -2
  30. package/dist/{text-runtime-CpiloI73.js → text-runtime-C88QkuU9.js} +6 -0
  31. package/npm-shrinkwrap.json +3 -3
  32. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  import { a as resolveWhatsAppAccount } from "./accounts-DgViSyJx.js";
2
- import { l as isSelfChatMode, n as normalizeE164 } from "./text-runtime-CpiloI73.js";
3
- import { a as getSelfIdentity, o as getSenderIdentity } from "./identity-DdeafYji.js";
2
+ import { l as isSelfChatMode, n as normalizeE164 } from "./text-runtime-C88QkuU9.js";
3
+ import { a as getSelfIdentity, o as getSenderIdentity } from "./identity-CmsTmkKR.js";
4
4
  import { defaultRuntime } from "openclaw/plugin-sdk/runtime-env";
5
5
  import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
6
6
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
@@ -233,7 +233,7 @@ async function resolveWhatsAppIngressAccess(params) {
233
233
  }
234
234
  async function resolveWhatsAppCommandAuthorized(params) {
235
235
  if (!(params.cfg.commands?.useAccessGroups !== false)) return true;
236
- const self = getSelfIdentity(params.msg);
236
+ const self = getSelfIdentity(params.msg, params.authDir);
237
237
  const admission = requireWhatsAppInboundAdmission(params.msg);
238
238
  const policy = params.policy ?? resolveWhatsAppInboundPolicy({
239
239
  cfg: params.cfg,
@@ -241,7 +241,7 @@ async function resolveWhatsAppCommandAuthorized(params) {
241
241
  selfE164: self.e164 ?? null
242
242
  });
243
243
  const isGroup = admission.conversation.kind === "group";
244
- const sender = getSenderIdentity(params.msg);
244
+ const sender = getSenderIdentity(params.msg, params.authDir);
245
245
  const dmSender = sender.e164 ?? admission.conversation.id;
246
246
  const groupSender = sender.e164 ?? "";
247
247
  if (!normalizeE164(isGroup ? groupSender : dmSender)) return false;
@@ -1,2 +1,2 @@
1
- import { t as handleWhatsAppAction } from "./action-runtime-D-FTwc8j.js";
1
+ import { t as handleWhatsAppAction } from "./action-runtime-hqza0J8B.js";
2
2
  export { handleWhatsAppAction };
@@ -1,6 +1,6 @@
1
1
  import { a as resolveWhatsAppAccount } from "./accounts-DgViSyJx.js";
2
2
  import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CcdugbDf.js";
3
- import { g as resolveWhatsAppReactionLevel, r as sendReactionWhatsApp } from "./send-BplHdEjw.js";
3
+ import { g as resolveWhatsAppReactionLevel, r as sendReactionWhatsApp } from "./send-i8Xk5mBQ.js";
4
4
  import { ToolAuthorizationError, createActionGate, jsonResult, readReactionParams, readStringParam } from "openclaw/plugin-sdk/channel-actions";
5
5
  //#region extensions/whatsapp/src/action-runtime-target-auth.ts
6
6
  function resolveAuthorizedWhatsAppOutboundTarget(params) {
@@ -1,2 +1,2 @@
1
- import { t as handleWhatsAppAction } from "./action-runtime-D-FTwc8j.js";
1
+ import { t as handleWhatsAppAction } from "./action-runtime-hqza0J8B.js";
2
2
  export { handleWhatsAppAction };
package/dist/api.js CHANGED
@@ -2,25 +2,28 @@ import { r as resolveDefaultWhatsAppAccountId, t as listAccountIds } from "./acc
2
2
  import { a as resolveWhatsAppAccount, i as listWhatsAppAuthDirs, n as hasAnyWhatsAppAuth, o as resolveWhatsAppAuthDir, r as listEnabledWhatsAppAccounts, s as resolveWhatsAppMediaMaxBytes, t as DEFAULT_WHATSAPP_MEDIA_MAX_MB } from "./accounts-DgViSyJx.js";
3
3
  import { a as normalizeWhatsAppAllowFromEntries, c as normalizeWhatsAppTarget, i as looksLikeWhatsAppTargetId, r as isWhatsAppUserTarget, s as normalizeWhatsAppMessagingTarget, t as isWhatsAppGroupJid } from "./normalize-target-bVWjgftN.js";
4
4
  import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CcdugbDf.js";
5
- import "./send-BplHdEjw.js";
5
+ import "./send-i8Xk5mBQ.js";
6
6
  import { n as getStatusCode, t as formatError } from "./session-errors-CbsoQqoy.js";
7
7
  import { n as createWhatsAppSocketOperationTimeoutAdapter, t as DEFAULT_WHATSAPP_SOCKET_TIMING } from "./socket-timing-DvMNkIge.js";
8
- import { c as assertWebChannel, d as markdownToWhatsApp, h as toWhatsappJidWithLid, l as isSelfChatMode, m as toWhatsappJid, n as normalizeE164, p as resolveJidToE164, r as resolveUserPath, u as jidToE164 } from "./text-runtime-CpiloI73.js";
9
- import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-C9zebxrw.js";
8
+ import { c as assertWebChannel, d as markdownToWhatsApp, h as toWhatsappJidWithLid, l as isSelfChatMode, m as toWhatsappJid, n as normalizeE164, p as resolveJidToE164, r as resolveUserPath, u as jidToE164 } from "./text-runtime-C88QkuU9.js";
9
+ import { n as WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS, t as whatsappPlugin } from "./channel-fcXxWXic.js";
10
10
  import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
11
- import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint } from "./setup-core-D0JxJ53T.js";
11
+ import { a as resolveWhatsAppGroupRequireMention, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint } from "./setup-core-KjSBbWX4.js";
12
12
  import "./config-schema-CROZuhT-.js";
13
- import { t as whatsappSetupPlugin } from "./channel.setup-BTi6IdDT.js";
13
+ import { t as whatsappSetupPlugin } from "./channel.setup-C_WEdyJR.js";
14
14
  import { t as DEFAULT_WEB_MEDIA_BYTES } from "./constants-HU41RHGI.js";
15
15
  import { n as listWhatsAppDirectoryGroupsFromConfig, r as listWhatsAppDirectoryPeersFromConfig } from "./directory-config-Dijefxc3.js";
16
- import { n as testing } from "./access-control-_oQx0_UZ.js";
17
- import { _ as extractLocationData, b as extractText, d as normalizeMessageContent, f as resolveInboundMediaMimetype, h as extractContextInfo, p as describeReplyContext, t as createWebSendApi } from "./send-api-11yoHJhM.js";
18
- import { r as waitForWaConnection, t as createWaSocket } from "./session-DlHpYSAl.js";
16
+ import { n as testing } from "./access-control-88UPniDc.js";
17
+ import { _ as extractLocationData, b as extractText, d as normalizeMessageContent, f as resolveInboundMediaMimetype, h as extractContextInfo, p as describeReplyContext, t as createWebSendApi } from "./send-api-DndiBJhN.js";
18
+ import { r as waitForWaConnection, t as createWaSocket } from "./session-WU4SVP8f.js";
19
19
  import "openclaw/plugin-sdk/channel-actions";
20
20
  import "openclaw/plugin-sdk/account-resolution";
21
21
  import "openclaw/plugin-sdk/core";
22
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
22
23
  import "openclaw/plugin-sdk/account-id";
23
24
  import { formatLocationText } from "openclaw/plugin-sdk/channel-inbound";
25
+ createLazyRuntimeModule(() => import("./channel.runtime-B4ThooGF.js"));
26
+ //#endregion
24
27
  //#region extensions/whatsapp/src/qa-driver.runtime.ts
25
28
  function isRecord(value) {
26
29
  return Boolean(value && typeof value === "object");
@@ -129,15 +132,18 @@ function normalizeObservedMessage(message, authDir) {
129
132
  const kind = reaction ? "reaction" : poll ? "poll" : media ? "media" : location ? "location" : text ? "text" : "unknown";
130
133
  if (!text && kind === "unknown") return null;
131
134
  const fromJid = message.key.remoteJid ?? void 0;
135
+ const senderJid = fromJid && isWhatsAppGroupJid(fromJid) ? message.key.participant ?? fromJid : fromJid;
136
+ const participantJid = message.key.participant ?? void 0;
132
137
  return {
133
138
  fromJid,
134
- fromPhoneE164: fromJid ? jidToE164(fromJid, { authDir }) : null,
139
+ fromPhoneE164: senderJid ? jidToE164(senderJid, { authDir }) : null,
135
140
  hasMedia: media ? true : void 0,
136
141
  kind,
137
142
  mediaFileName: media?.fileName,
138
143
  mediaType: media?.mediaType,
139
144
  messageId: message.key.id ?? void 0,
140
145
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
146
+ ...participantJid ? { participantJid } : {},
141
147
  poll,
142
148
  quoted,
143
149
  reaction,
@@ -1,5 +1,5 @@
1
1
  import { s as normalizeWhatsAppMessagingTarget } from "./normalize-target-bVWjgftN.js";
2
- import { f as registerWhatsAppApprovalReactionTarget, i as sendTypingWhatsApp, p as unregisterWhatsAppApprovalReactionTarget, t as sendMessageWhatsApp } from "./send-BplHdEjw.js";
2
+ import { f as registerWhatsAppApprovalReactionTarget, i as sendTypingWhatsApp, p as unregisterWhatsAppApprovalReactionTarget, t as sendMessageWhatsApp } from "./send-i8Xk5mBQ.js";
3
3
  import "./normalize-Bxwqo-bW.js";
4
4
  import { n as getWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
5
5
  import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { a as readWebCredsJsonRawSync, c as statWebCredsFileSync, i as readWebCredsJsonRaw, o as resolveWebCredsBackupPath, s as resolveWebCredsPath, t as assertWebCredsPathRegularFileOrMissing } from "./creds-files-B1kSWtBg.js";
3
- import { r as resolveUserPath } from "./text-runtime-CpiloI73.js";
4
- import { c as resolveComparableIdentity } from "./identity-DdeafYji.js";
3
+ import { r as resolveUserPath } from "./text-runtime-C88QkuU9.js";
4
+ import { c as resolveComparableIdentity } from "./identity-CmsTmkKR.js";
5
5
  import path from "node:path";
6
6
  import { resolveOAuthDir as resolveOAuthDir$1 } from "openclaw/plugin-sdk/state-paths";
7
7
  import { replaceFileAtomic } from "openclaw/plugin-sdk/security-runtime";
@@ -2,15 +2,15 @@ import { r as resolveDefaultWhatsAppAccountId, t as listAccountIds } from "./acc
2
2
  import { a as resolveWhatsAppAccount } from "./accounts-DgViSyJx.js";
3
3
  import { c as normalizeWhatsAppTarget, i as looksLikeWhatsAppTargetId, n as isWhatsAppNewsletterJid, o as normalizeWhatsAppAllowFromEntry, s as normalizeWhatsAppMessagingTarget, t as isWhatsAppGroupJid } from "./normalize-target-bVWjgftN.js";
4
4
  import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-CcdugbDf.js";
5
- import { a as normalizeWhatsAppOutboundPayload, g as resolveWhatsAppReactionLevel, h as whatsappApprovalAuth, i as sendTypingWhatsApp, m as getWhatsAppApprovalApprovers, n as sendPollWhatsApp, o as normalizeWhatsAppPayloadText, s as normalizeWhatsAppPayloadTextPreservingIndentation, t as sendMessageWhatsApp } from "./send-BplHdEjw.js";
5
+ import { a as normalizeWhatsAppOutboundPayload, g as resolveWhatsAppReactionLevel, h as whatsappApprovalAuth, i as sendTypingWhatsApp, m as getWhatsAppApprovalApprovers, n as sendPollWhatsApp, o as normalizeWhatsAppPayloadText, s as normalizeWhatsAppPayloadTextPreservingIndentation, t as sendMessageWhatsApp } from "./send-i8Xk5mBQ.js";
6
6
  import "./normalize-Bxwqo-bW.js";
7
7
  import { n as getWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
8
- import { m as toWhatsappJid } from "./text-runtime-CpiloI73.js";
8
+ import { m as toWhatsappJid } from "./text-runtime-C88QkuU9.js";
9
9
  import { t as createWhatsAppLoginTool } from "./agent-tools-login-BX7eHgDm.js";
10
- import { i as lookupInboundMessageMetaForTarget } from "./quoted-message-DqmWlbN7.js";
10
+ import { i as lookupInboundMessageMetaForTarget } from "./quoted-message-CpA_ujXK.js";
11
11
  import { t as whatsappCommandPolicy } from "./command-policy-BIOSHySD.js";
12
- import { a as resolveWhatsAppGroupRequireMention, c as resolveWhatsAppMentionStripRegexes, i as whatsappSetupWizardProxy, l as formatWhatsAppConfigAllowFromEntries, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, r as loadWhatsAppChannelRuntime, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-D0JxJ53T.js";
13
- import { f as readWebAuthExistsForDecision, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-BRv2o3w2.js";
12
+ import { a as resolveWhatsAppGroupRequireMention, c as resolveWhatsAppMentionStripRegexes, i as whatsappSetupWizardProxy, l as formatWhatsAppConfigAllowFromEntries, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, r as loadWhatsAppChannelRuntime, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-KjSBbWX4.js";
13
+ import { f as readWebAuthExistsForDecision, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-ECx4h57q.js";
14
14
  import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-D_BmQUR9.js";
15
15
  import { createActionGate as createActionGate$1 } from "openclaw/plugin-sdk/channel-actions";
16
16
  import { DEFAULT_ACCOUNT_ID, listCombinedAccountIds, normalizeOptionalAccountId, resolveListedDefaultAccountId } from "openclaw/plugin-sdk/account-core";
@@ -20,10 +20,10 @@ import { asString, collectIssuesForEnabledAccounts, createAsyncComputedAccountSt
20
20
  import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
21
21
  import { buildChannelOutboundSessionRoute } from "openclaw/plugin-sdk/core";
22
22
  import { buildApprovalReactionPromptPayloadForRequest } from "openclaw/plugin-sdk/approval-reaction-runtime";
23
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
23
24
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/account-id";
24
25
  import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
25
26
  import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
26
- import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
27
27
  import { createChannelApprovalCapability } from "openclaw/plugin-sdk/approval-delivery-runtime";
28
28
  import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
29
29
  import { createChannelApproverDmTargetResolver, createChannelNativeOriginTargetResolver, createNativeApprovalChannelRouteGates, createNativeApprovalForwardingFallbackSuppressor } from "openclaw/plugin-sdk/approval-native-runtime";
@@ -205,7 +205,7 @@ const whatsappApprovalCapability = createChannelApprovalCapability({
205
205
  accountId,
206
206
  request
207
207
  }),
208
- load: async () => (await import("./approval-handler.runtime-DNBh4thG.js")).whatsappApprovalNativeRuntime
208
+ load: async () => (await import("./approval-handler.runtime-9_SV7vhc.js")).whatsappApprovalNativeRuntime
209
209
  })
210
210
  });
211
211
  //#endregion
@@ -601,7 +601,7 @@ function collectWhatsAppStatusIssues(accounts) {
601
601
  //#endregion
602
602
  //#region extensions/whatsapp/src/channel.ts
603
603
  const loadWhatsAppDirectoryConfig = createLazyRuntimeModule(() => import("./directory-config-Dijefxc3.js").then((n) => n.t));
604
- const loadWhatsAppChannelReactAction = createLazyRuntimeModule(() => import("./channel-react-action-C56UzM_r.js"));
604
+ const loadWhatsAppChannelReactAction = createLazyRuntimeModule(() => import("./channel-react-action-Dgy9uUMl.js"));
605
605
  function resolveWhatsAppTargetInfo(raw) {
606
606
  const normalized = normalizeWhatsAppTarget(raw);
607
607
  if (!normalized) return null;
@@ -751,6 +751,8 @@ const whatsappPlugin = createChatChannelPlugin({
751
751
  lastInboundAt: null,
752
752
  lastMessageAt: null,
753
753
  lastEventAt: null,
754
+ busy: false,
755
+ lastRunActivityAt: null,
754
756
  healthState: "stopped"
755
757
  }),
756
758
  collectStatusIssues: collectWhatsAppStatusIssues,
@@ -790,6 +792,8 @@ const whatsappPlugin = createChatChannelPlugin({
790
792
  lastInboundAt: snapshot.lastInboundAt ?? snapshot.lastMessageAt ?? null,
791
793
  lastMessageAt: snapshot.lastMessageAt ?? null,
792
794
  lastEventAt: snapshot.lastEventAt ?? null,
795
+ busy: snapshot.busy ?? false,
796
+ lastRunActivityAt: snapshot.lastRunActivityAt ?? null,
793
797
  lastError: snapshot.lastError ?? null,
794
798
  healthState: snapshot.healthState ?? void 0
795
799
  };
@@ -811,6 +815,8 @@ const whatsappPlugin = createChatChannelPlugin({
811
815
  lastInboundAt: runtime?.lastInboundAt ?? runtime?.lastMessageAt ?? null,
812
816
  lastMessageAt: runtime?.lastMessageAt ?? null,
813
817
  lastEventAt: runtime?.lastEventAt ?? null,
818
+ busy: runtime?.busy ?? false,
819
+ lastRunActivityAt: runtime?.lastRunActivityAt ?? null,
814
820
  healthState: runtime?.healthState ?? void 0,
815
821
  dmPolicy: account.dmPolicy,
816
822
  allowFrom: account.allowFrom
@@ -1,2 +1,2 @@
1
- import { t as whatsappPlugin } from "./channel-C9zebxrw.js";
1
+ import { t as whatsappPlugin } from "./channel-fcXxWXic.js";
2
2
  export { whatsappPlugin };
@@ -1,9 +1,10 @@
1
1
  import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-DgViSyJx.js";
2
2
  import { c as normalizeWhatsAppTarget, t as isWhatsAppGroupJid } from "./normalize-target-bVWjgftN.js";
3
- import { r as resolveAuthorizedWhatsAppOutboundTarget, t as handleWhatsAppAction } from "./action-runtime-D-FTwc8j.js";
4
- import { t as sendMessageWhatsApp } from "./send-BplHdEjw.js";
3
+ import { r as resolveAuthorizedWhatsAppOutboundTarget, t as handleWhatsAppAction } from "./action-runtime-hqza0J8B.js";
4
+ import { t as sendMessageWhatsApp } from "./send-i8Xk5mBQ.js";
5
5
  import "./normalize-Bxwqo-bW.js";
6
6
  import { jsonResult, readStringOrNumberParam, readStringParam as readStringParam$1, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
7
+ import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
7
8
  //#region extensions/whatsapp/src/channel-react-action.ts
8
9
  const WHATSAPP_CHANNEL = "whatsapp";
9
10
  function readUploadFileMediaSource(args) {
@@ -12,17 +13,15 @@ function readUploadFileMediaSource(args) {
12
13
  function readUploadFileCaptionText(args) {
13
14
  return readStringParam$1(args, "message", { allowEmpty: true }) ?? readStringParam$1(args, "content", { allowEmpty: true }) ?? readStringParam$1(args, "caption", { allowEmpty: true }) ?? "";
14
15
  }
15
- function readBooleanParam(args, key) {
16
- const value = args[key];
17
- if (typeof value === "boolean") return value;
18
- if (typeof value !== "string") return;
19
- const normalized = value.trim().toLowerCase();
20
- if (normalized === "true") return true;
21
- if (normalized === "false") return false;
22
- }
23
16
  function hasUploadFileBufferPayload(args) {
24
17
  return readStringParam$1(args, "buffer", { trim: false }) !== void 0;
25
18
  }
19
+ function readWhatsAppActionChatJid(params) {
20
+ const explicit = readStringParam$1(params.params, "chatJid") ?? readStringParam$1(params.params, "to");
21
+ if (explicit) return explicit;
22
+ if (params.toolContext?.currentChannelProvider !== WHATSAPP_CHANNEL || !params.toolContext.currentChannelId) return;
23
+ return normalizeWhatsAppTarget(params.toolContext.currentChannelId) ?? void 0;
24
+ }
26
25
  function extractBase64Payload(encoded) {
27
26
  const match = /^data:[^;]+;base64,(.*)$/i.exec(encoded.trim());
28
27
  return match ? match[1] : encoded;
@@ -52,7 +51,7 @@ async function handleWhatsAppUploadFileAction(params) {
52
51
  const mediaUrl = readUploadFileMediaSource(params.params);
53
52
  const encodedPayload = readStringParam$1(params.params, "buffer", { trim: false });
54
53
  if (!mediaUrl && !hasUploadFileBufferPayload(params.params)) throw new Error("WhatsApp upload-file requires media, mediaUrl, filePath, path, fileUrl, or buffer.");
55
- const to = readStringParam$1(params.params, "to", { required: true });
54
+ const to = readWhatsAppActionChatJid(params) ?? readStringParam$1(params.params, "to", { required: true });
56
55
  const resolved = resolveAuthorizedWhatsAppOutboundTarget({
57
56
  cfg: params.cfg,
58
57
  chatJid: to,
@@ -93,7 +92,7 @@ async function handleWhatsAppMessageAction(params) {
93
92
  if (params.action === "upload-file") return await handleWhatsAppUploadFileAction(params);
94
93
  if (params.action !== "react") throw new Error(`Action ${params.action} is not supported for provider ${WHATSAPP_CHANNEL}.`);
95
94
  const isWhatsAppSource = params.toolContext?.currentChannelProvider === WHATSAPP_CHANNEL;
96
- const explicitTarget = readStringParam$1(params.params, "chatJid") ?? readStringParam$1(params.params, "to");
95
+ const explicitTarget = readWhatsAppActionChatJid(params);
97
96
  const normalizedTarget = explicitTarget ? normalizeWhatsAppTarget(explicitTarget) : null;
98
97
  const normalizedCurrent = isWhatsAppSource && params.toolContext?.currentChannelId ? normalizeWhatsAppTarget(params.toolContext.currentChannelId) : null;
99
98
  const isCrossChat = normalizedTarget != null && (normalizedCurrent == null || normalizedTarget !== normalizedCurrent);
@@ -115,7 +114,7 @@ async function handleWhatsAppMessageAction(params) {
115
114
  const inferredParticipant = explicitParticipant || explicitMessageId != null || !isWhatsAppSource || isCrossChat || !isWhatsAppGroupJid(explicitTarget ?? params.toolContext?.currentChannelId ?? "") ? void 0 : typeof params.requesterSenderId === "string" && params.requesterSenderId.trim().length > 0 ? params.requesterSenderId.trim() : void 0;
116
115
  return await handleWhatsAppAction({
117
116
  action: "react",
118
- chatJid: readStringParam$1(params.params, "chatJid") ?? readStringParam$1(params.params, "to", { required: true }),
117
+ chatJid: readWhatsAppActionChatJid(params) ?? readStringParam$1(params.params, "to", { required: true }),
119
118
  messageId,
120
119
  emoji,
121
120
  remove,
@@ -1,9 +1,9 @@
1
1
  import { startWebLoginWithQr as startWebLoginWithQr$1, waitForWebLogin as waitForWebLogin$1 } from "./login-qr-runtime.js";
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-BRv2o3w2.js";
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-ECx4h57q.js";
3
3
  import { t as getActiveWebListener$1 } from "./active-listener-CFwkn3ho.js";
4
- import { t as monitorWebChannel$1 } from "./monitor-BVD90YEd.js";
5
- import { t as loginWeb$1 } from "./login-FpqysWi0.js";
6
- import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-BpdIDwDg.js";
4
+ import { t as monitorWebChannel$1 } from "./monitor-BqkJ4MpT.js";
5
+ import { t as loginWeb$1 } from "./login-8lHwLmXj.js";
6
+ import { whatsappSetupWizard as whatsappSetupWizard$1 } from "./setup-surface-IOdkbWsQ.js";
7
7
  //#region extensions/whatsapp/src/channel.runtime.ts
8
8
  function getActiveWebListener(...args) {
9
9
  return getActiveWebListener$1(...args);
@@ -1,8 +1,8 @@
1
- import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupWizardProxy, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-D0JxJ53T.js";
1
+ import { a as resolveWhatsAppGroupRequireMention, i as whatsappSetupWizardProxy, n as createWhatsAppPluginBase, o as resolveWhatsAppGroupToolPolicy, s as resolveWhatsAppGroupIntroHint, t as whatsappSetupAdapter } from "./setup-core-KjSBbWX4.js";
2
2
  import { t as detectWhatsAppLegacyStateMigrations } from "./state-migrations-D_BmQUR9.js";
3
3
  //#region extensions/whatsapp/src/channel.setup.ts
4
4
  async function isWhatsAppAuthConfigured(account) {
5
- const { readWebAuthState } = await import("./auth-store-BRv2o3w2.js").then((n) => n.i);
5
+ const { readWebAuthState } = await import("./auth-store-ECx4h57q.js").then((n) => n.i);
6
6
  return await readWebAuthState(account.authDir) === "linked";
7
7
  }
8
8
  const whatsappSetupPlugin = {
@@ -1,8 +1,8 @@
1
1
  import { a as unregisterWhatsAppConnectionController, i as registerWhatsAppConnectionController, n as getStatusCode, t as formatError } from "./session-errors-CbsoQqoy.js";
2
2
  import { t as DEFAULT_WHATSAPP_SOCKET_TIMING } from "./socket-timing-DvMNkIge.js";
3
- import { c as logoutWeb, f as readWebAuthExistsForDecision, r as WhatsAppAuthUnstableError } from "./auth-store-BRv2o3w2.js";
4
- import { c as resolveComparableIdentity } from "./identity-DdeafYji.js";
5
- import { r as waitForWaConnection, t as createWaSocket } from "./session-DlHpYSAl.js";
3
+ import { c as logoutWeb, f as readWebAuthExistsForDecision, r as WhatsAppAuthUnstableError } from "./auth-store-ECx4h57q.js";
4
+ import { c as resolveComparableIdentity } from "./identity-CmsTmkKR.js";
5
+ import { r as waitForWaConnection, t as createWaSocket } from "./session-WU4SVP8f.js";
6
6
  import { computeBackoff, info, sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
7
7
  import { clamp } from "openclaw/plugin-sdk/text-utility-runtime";
8
8
  import { randomUUID } from "node:crypto";
@@ -2,7 +2,7 @@ import { c as normalizeWhatsAppTarget$1, t as isWhatsAppGroupJid$1 } from "./nor
2
2
  import { t as whatsappCommandPolicy$1 } from "./command-policy-BIOSHySD.js";
3
3
  import { t as resolveLegacyGroupSessionKey$1 } from "./group-session-contract-DDnZSsJ1.js";
4
4
  import { r as isLegacyGroupSessionKey$1, t as canonicalizeLegacySessionKey$1 } from "./session-contract-DMTm6Q_L.js";
5
- import { a as resolveWhatsAppRuntimeGroupPolicy$1, n as testing } from "./access-control-_oQx0_UZ.js";
5
+ import { a as resolveWhatsAppRuntimeGroupPolicy$1, n as testing } from "./access-control-88UPniDc.js";
6
6
  //#region extensions/whatsapp/contract-api.ts
7
7
  const canonicalizeLegacySessionKey = canonicalizeLegacySessionKey$1;
8
8
  const isLegacyGroupSessionKey = isLegacyGroupSessionKey$1;
@@ -1,4 +1,4 @@
1
- import { n as normalizeE164, u as jidToE164 } from "./text-runtime-CpiloI73.js";
1
+ import { n as normalizeE164, u as jidToE164 } from "./text-runtime-C88QkuU9.js";
2
2
  //#region extensions/whatsapp/src/identity.ts
3
3
  const WHATSAPP_LID_RE = /@(lid|hosted\.lid)$/i;
4
4
  function normalizeDeviceScopedJid(jid) {
@@ -1,5 +1,5 @@
1
1
  import { n as getStatusCode, t as formatError } from "./session-errors-CbsoQqoy.js";
2
2
  import { t as createWhatsAppLoginTool } from "./agent-tools-login-BX7eHgDm.js";
3
- import { c as logoutWeb, g as readWebSelfId, l as pickWebChannel, o as getWebAuthAgeMs, s as logWebSelfId, t as WA_WEB_AUTH_DIR, x as webAuthExists, y as resolveDefaultWebAuthDir } from "./auth-store-BRv2o3w2.js";
3
+ import { c as logoutWeb, g as readWebSelfId, l as pickWebChannel, o as getWebAuthAgeMs, s as logWebSelfId, t as WA_WEB_AUTH_DIR, x as webAuthExists, y as resolveDefaultWebAuthDir } from "./auth-store-ECx4h57q.js";
4
4
  import { t as getActiveWebListener } from "./active-listener-CFwkn3ho.js";
5
5
  export { WA_WEB_AUTH_DIR, createWhatsAppLoginTool, formatError, getActiveWebListener, getStatusCode, getWebAuthAgeMs, logWebSelfId, logoutWeb, pickWebChannel, readWebSelfId, resolveDefaultWebAuthDir, webAuthExists };
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { a as resolveWhatsAppAccount } from "./accounts-DgViSyJx.js";
3
3
  import { a as resolveWhatsAppSocketTiming } from "./socket-timing-DvMNkIge.js";
4
- import { b as restoreCredsFromBackupIfNeeded } from "./auth-store-BRv2o3w2.js";
5
- import { i as renderQrTerminal, t as createWaSocket } from "./session-DlHpYSAl.js";
6
- import { a as closeWaSocketSoon, o as waitForWhatsAppLoginResult } from "./connection-controller-Ds4puj_n.js";
4
+ import { b as restoreCredsFromBackupIfNeeded } from "./auth-store-ECx4h57q.js";
5
+ import { i as renderQrTerminal, t as createWaSocket } from "./session-WU4SVP8f.js";
6
+ import { a as closeWaSocketSoon, o as waitForWhatsAppLoginResult } from "./connection-controller-u-tfAFhJ.js";
7
7
  import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
8
8
  import { logInfo } from "openclaw/plugin-sdk/logging-core";
9
9
  import { danger, defaultRuntime, success } from "openclaw/plugin-sdk/runtime-env";
@@ -1,10 +1,10 @@
1
1
  import { a as resolveWhatsAppAccount } from "./accounts-DgViSyJx.js";
2
2
  import { t as formatError } from "./session-errors-CbsoQqoy.js";
3
3
  import { a as resolveWhatsAppSocketTiming } from "./socket-timing-DvMNkIge.js";
4
- import { c as logoutWeb, f as readWebAuthExistsForDecision, g as readWebSelfId, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-BRv2o3w2.js";
5
- import { t as createWaSocket } from "./session-DlHpYSAl.js";
4
+ import { c as logoutWeb, f as readWebAuthExistsForDecision, g as readWebSelfId, n as WHATSAPP_AUTH_UNSTABLE_CODE } from "./auth-store-ECx4h57q.js";
5
+ import { t as createWaSocket } from "./session-WU4SVP8f.js";
6
6
  import { t as getActiveWebListener } from "./active-listener-CFwkn3ho.js";
7
- import { i as closeWaSocket, o as waitForWhatsAppLoginResult, t as WHATSAPP_LOGGED_OUT_QR_MESSAGE } from "./connection-controller-Ds4puj_n.js";
7
+ import { i as closeWaSocket, o as waitForWhatsAppLoginResult, t as WHATSAPP_LOGGED_OUT_QR_MESSAGE } from "./connection-controller-u-tfAFhJ.js";
8
8
  import { logInfo } from "openclaw/plugin-sdk/logging-core";
9
9
  import { danger, defaultRuntime, info, success } from "openclaw/plugin-sdk/runtime-env";
10
10
  import { renderQrPngDataUrl } from "openclaw/plugin-sdk/media-runtime";
@@ -1,9 +1,6 @@
1
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
1
2
  //#region extensions/whatsapp/login-qr-runtime.ts
2
- let loginQrModulePromise = null;
3
- function loadLoginQrModule() {
4
- loginQrModulePromise ??= import("./login-qr-BjfpyyN0.js");
5
- return loginQrModulePromise;
6
- }
3
+ const loadLoginQrModule = createLazyRuntimeModule(() => import("./login-qr-BEZZqrTb.js"));
7
4
  async function startWebLoginWithQr(...args) {
8
5
  const { startWebLoginWithQr: startWebLoginWithQrLocal } = await loadLoginQrModule();
9
6
  return await startWebLoginWithQrLocal(...args);
@@ -1,18 +1,18 @@
1
1
  import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-DgViSyJx.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-BplHdEjw.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-i8Xk5mBQ.js";
3
3
  import { n as getWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
4
4
  import { n as getStatusCode, r as getRegisteredWhatsAppConnectionController, t as formatError } from "./session-errors-CbsoQqoy.js";
5
5
  import { a as resolveWhatsAppSocketTiming, i as resolveWhatsAppSocketOperationTimeoutMs, n as createWhatsAppSocketOperationTimeoutAdapter, o as withWhatsAppSocketOperationTimeout, r as isWhatsAppSocketOperationTimeoutError } from "./socket-timing-DvMNkIge.js";
6
- import { d as markdownToWhatsApp, f as resolveEquivalentWhatsAppDirectChatJids, l as isSelfChatMode, n as normalizeE164, p as resolveJidToE164, t as convertMarkdownTables$1, u as jidToE164 } from "./text-runtime-CpiloI73.js";
7
- import { n as cacheInboundMessageMeta, r as lookupInboundMessageMeta, t as buildQuotedMessageOptions } from "./quoted-message-DqmWlbN7.js";
8
- import { g as readWebSelfId, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, v as readWebSelfIdentityForDecision } from "./auth-store-BRv2o3w2.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-DdeafYji.js";
6
+ import { d as markdownToWhatsApp, f as resolveEquivalentWhatsAppDirectChatJids, l as isSelfChatMode, n as normalizeE164, p as resolveJidToE164, t as convertMarkdownTables$1, u as jidToE164 } from "./text-runtime-C88QkuU9.js";
7
+ import { n as cacheInboundMessageMeta, r as lookupInboundMessageMeta, t as buildQuotedMessageOptions } from "./quoted-message-CpA_ujXK.js";
8
+ import { g as readWebSelfId, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, v as readWebSelfIdentityForDecision } from "./auth-store-ECx4h57q.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-CmsTmkKR.js";
10
10
  import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-BGyzT9Lg.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-_oQx0_UZ.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-11yoHJhM.js";
13
- import { r as waitForWaConnection, t as createWaSocket } from "./session-DlHpYSAl.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-88UPniDc.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-DndiBJhN.js";
13
+ import { r as waitForWaConnection, t as createWaSocket } from "./session-WU4SVP8f.js";
14
14
  import { t as BufferJSON } from "./session.runtime-CyooSQvj.js";
15
- 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-Ds4puj_n.js";
15
+ 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-u-tfAFhJ.js";
16
16
  import { resolveAccountEntry } from "openclaw/plugin-sdk/account-core";
17
17
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
18
18
  import { createChannelMessageReplyPipeline, createDurableInboundReceiveJournalFromQueue, createMessageReceiptFromOutboundResults, deliverInboundReplyWithMessageSendContext, resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-outbound";
@@ -22,14 +22,16 @@ import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
22
22
  import { getChildLogger } from "openclaw/plugin-sdk/logging-core";
23
23
  import { resolveMarkdownTableMode as resolveMarkdownTableMode$1 } from "openclaw/plugin-sdk/markdown-table-runtime";
24
24
  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";
25
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
25
26
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
26
27
  import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
28
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
27
29
  import { LocalMediaAccessError, getDefaultLocalRoots, loadWebMedia as loadWebMedia$1, loadWebMediaRaw, optimizeImageToJpeg, optimizeImageToPng } from "openclaw/plugin-sdk/web-media";
28
30
  import { chunkMarkdownTextWithMode } from "openclaw/plugin-sdk/reply-chunking";
29
31
  import { isReasoningReplyPayload, resolveSendableOutboundReplyParts, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
30
32
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, DEFAULT_MAIN_KEY, buildAgentMainSessionKey, buildAgentSessionKey, buildGroupHistoryKey, deriveLastRoutePolicy, normalizeAccountId as normalizeAccountId$1, normalizeAgentId, resolveAgentRoute, resolveInboundLastRouteSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
31
33
  import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";
32
- import { loadSessionStore, resolveStorePath, updateLastRoute, updateSessionStore } from "openclaw/plugin-sdk/session-store-runtime";
34
+ import { getSessionEntry, patchSessionEntry, resolveStorePath, resolveStorePath as resolveStorePath$1, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
33
35
  import { buildChannelInboundEventContext, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundEnvelope as formatInboundEnvelope$1, formatLocationText, hasVisibleInboundReplyDispatch, resolveInboundSessionEnvelopeContext, runChannelInboundEvent, toInboundMediaFacts, toLocationContext } from "openclaw/plugin-sdk/channel-inbound";
34
36
  import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
35
37
  import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
@@ -704,6 +706,11 @@ async function attachWebInboxToSocket(options) {
704
706
  const inboundDebounceMs = Math.max(0, Math.trunc(options.debounceMs ?? 0));
705
707
  const pendingDebounceKeys = /* @__PURE__ */ new Set();
706
708
  const activeInboundFlushes = /* @__PURE__ */ new Set();
709
+ const pendingMessageHandlers = /* @__PURE__ */ new Set();
710
+ let nextReceiveOrder = 0;
711
+ const publishPendingWorkState = (at = Date.now()) => {
712
+ options.onPendingWorkChanged?.(pendingMessageHandlers.size + pendingDebounceKeys.size + activeInboundFlushes.size, at);
713
+ };
707
714
  const buildInboundDebounceKey = (msg) => {
708
715
  const admission = requireWhatsAppInboundAdmission(msg);
709
716
  const sender = msg.platform.sender;
@@ -739,6 +746,7 @@ async function attachWebInboxToSocket(options) {
739
746
  finishFlush = resolve;
740
747
  });
741
748
  activeInboundFlushes.add(flushTask);
749
+ publishPendingWorkState();
742
750
  try {
743
751
  const orderedEntries = orderDebouncedInboundEntries(entries);
744
752
  const last = orderedEntries.at(-1);
@@ -782,6 +790,7 @@ async function attachWebInboxToSocket(options) {
782
790
  for (const entry of entries) if (entry.debounceKey) pendingDebounceKeys.delete(entry.debounceKey);
783
791
  activeInboundFlushes.delete(flushTask);
784
792
  finishFlush();
793
+ publishPendingWorkState();
785
794
  }
786
795
  },
787
796
  onError: (err) => {
@@ -1245,7 +1254,10 @@ async function attachWebInboxToSocket(options) {
1245
1254
  const debounceKey = buildInboundDebounceKey(inboundMessage);
1246
1255
  if (debounceKey) {
1247
1256
  inboundMessage.debounceKey = debounceKey;
1248
- if (inboundDebounceMs > 0 && shouldDebounceInboundMessage(inboundMessage)) pendingDebounceKeys.add(debounceKey);
1257
+ if (inboundDebounceMs > 0 && shouldDebounceInboundMessage(inboundMessage)) {
1258
+ pendingDebounceKeys.add(debounceKey);
1259
+ publishPendingWorkState();
1260
+ }
1249
1261
  }
1250
1262
  if (inboundMessage.event.id) {
1251
1263
  const admission = requireWhatsAppInboundAdmission(inboundMessage);
@@ -1266,8 +1278,6 @@ async function attachWebInboxToSocket(options) {
1266
1278
  inboundConsoleLog.error(`Failed handling inbound web message: ${String(err)}`);
1267
1279
  }
1268
1280
  };
1269
- const pendingMessageHandlers = /* @__PURE__ */ new Set();
1270
- let nextReceiveOrder = 0;
1271
1281
  const handleMessagesUpsert = async (upsert) => {
1272
1282
  if (upsert.type !== "notify" && upsert.type !== "append") return;
1273
1283
  for (const msg of upsert.messages ?? []) {
@@ -1292,8 +1302,10 @@ async function attachWebInboxToSocket(options) {
1292
1302
  inboundConsoleLog.error(`Messages upsert handler error: ${String(err)}`);
1293
1303
  });
1294
1304
  pendingMessageHandlers.add(task);
1305
+ publishPendingWorkState();
1295
1306
  task.finally(() => {
1296
1307
  pendingMessageHandlers.delete(task);
1308
+ publishPendingWorkState();
1297
1309
  });
1298
1310
  };
1299
1311
  const waitForPendingMessageHandlers = async () => {
@@ -1386,8 +1398,10 @@ async function attachWebInboxToSocket(options) {
1386
1398
  inboundConsoleLog.error(`Failed replaying durable WhatsApp inbound: ${String(err)}`);
1387
1399
  });
1388
1400
  pendingMessageHandlers.add(replayTask);
1401
+ publishPendingWorkState();
1389
1402
  replayTask.finally(() => {
1390
1403
  pendingMessageHandlers.delete(replayTask);
1404
+ publishPendingWorkState();
1391
1405
  });
1392
1406
  (async () => {
1393
1407
  try {
@@ -1563,6 +1577,8 @@ function createWebChannelStatusController(statusSink) {
1563
1577
  lastMessageAt: null,
1564
1578
  lastEventAt: null,
1565
1579
  lastError: null,
1580
+ busy: false,
1581
+ lastRunActivityAt: null,
1566
1582
  healthState: "starting"
1567
1583
  };
1568
1584
  const emit = () => {
@@ -1596,6 +1612,13 @@ function createWebChannelStatusController(statusSink) {
1596
1612
  Object.assign(status, createTransportActivityStatusPatch(at));
1597
1613
  emit();
1598
1614
  },
1615
+ noteBusy(busy, at = Date.now()) {
1616
+ if (status.busy === busy && status.lastRunActivityAt === at) return;
1617
+ status.busy = busy;
1618
+ status.lastRunActivityAt = at;
1619
+ if (status.connected && busy) status.healthState = "healthy";
1620
+ emit();
1621
+ },
1599
1622
  noteWatchdogStale(at = Date.now()) {
1600
1623
  status.lastEventAt = at;
1601
1624
  if (status.connected) status.healthState = "stale";
@@ -1714,23 +1737,37 @@ function hasNamedWhatsAppAccounts(cfg) {
1714
1737
  function isActivationOnlyEntry(entry) {
1715
1738
  return entry?.groupActivation !== void 0 && typeof entry?.sessionId !== "string" && typeof entry?.updatedAt !== "number";
1716
1739
  }
1740
+ /** Resolves group activation for a WhatsApp conversation and backfills scoped session metadata. */
1717
1741
  async function resolveGroupActivationFor(params) {
1718
- const storePath = resolveStorePath(params.cfg.session?.store, { agentId: params.agentId });
1719
- const store = loadSessionStore(storePath);
1742
+ const sessionScope = {
1743
+ storePath: resolveStorePath(params.cfg.session?.store, { agentId: params.agentId }),
1744
+ agentId: params.agentId
1745
+ };
1720
1746
  const legacySessionKey = resolveWhatsAppLegacyGroupSessionKey({
1721
1747
  sessionKey: params.sessionKey,
1722
1748
  accountId: params.accountId
1723
1749
  });
1724
- const legacyEntry = legacySessionKey ? store[legacySessionKey] : void 0;
1725
- const scopedEntry = store[params.sessionKey];
1750
+ const legacyEntry = legacySessionKey ? getSessionEntry({
1751
+ ...sessionScope,
1752
+ sessionKey: legacySessionKey
1753
+ }) : void 0;
1754
+ const scopedEntry = getSessionEntry({
1755
+ ...sessionScope,
1756
+ sessionKey: params.sessionKey
1757
+ });
1726
1758
  const activation = (normalizeAccountId$1(params.accountId) === DEFAULT_ACCOUNT_ID$1 && hasNamedWhatsAppAccounts(params.cfg) && isActivationOnlyEntry(scopedEntry) ? void 0 : scopedEntry?.groupActivation) ?? legacyEntry?.groupActivation;
1727
- if (activation !== void 0 && scopedEntry?.groupActivation === void 0) await updateSessionStore(storePath, (nextStore) => {
1728
- const nextScopedEntry = nextStore[params.sessionKey];
1729
- if (nextScopedEntry?.groupActivation !== void 0) return;
1730
- nextStore[params.sessionKey] = {
1731
- ...nextScopedEntry,
1732
- groupActivation: activation
1733
- };
1759
+ if (activation !== void 0 && scopedEntry?.groupActivation === void 0) await patchSessionEntry({
1760
+ ...sessionScope,
1761
+ sessionKey: params.sessionKey,
1762
+ fallbackEntry: {},
1763
+ replaceEntry: true,
1764
+ update: (entry) => {
1765
+ if (entry.groupActivation !== void 0) return null;
1766
+ return {
1767
+ ...entry,
1768
+ groupActivation: activation
1769
+ };
1770
+ }
1734
1771
  });
1735
1772
  const defaultActivation = !resolveWhatsAppInboundPolicy({
1736
1773
  cfg: params.cfg,
@@ -1771,7 +1808,7 @@ async function maybeSendAckReaction(params) {
1771
1808
  isGroup,
1772
1809
  directEnabled,
1773
1810
  groupMode,
1774
- wasMentioned: params.msg.wasMentioned === true,
1811
+ wasMentioned: (params.msg.groupMention?.wasMentioned ?? params.msg.wasMentioned) === true,
1775
1812
  groupActivated: activation === "always"
1776
1813
  });
1777
1814
  if (!shouldSendReaction()) return null;
@@ -1943,10 +1980,10 @@ function shouldWarnForGroupDrop(warnKey) {
1943
1980
  }
1944
1981
  return true;
1945
1982
  }
1946
- function isOwnerSender(baseMentionConfig, msg) {
1947
- const sender = normalizeE164(getSenderIdentity(msg).e164 ?? "");
1983
+ function isOwnerSender(baseMentionConfig, msg, authDir) {
1984
+ const sender = normalizeE164(getSenderIdentity(msg, authDir).e164 ?? "");
1948
1985
  if (!sender) return false;
1949
- return resolveOwnerList(baseMentionConfig, getSelfIdentity(msg).e164 ?? void 0).includes(sender);
1986
+ return resolveOwnerList(baseMentionConfig, getSelfIdentity(msg, authDir).e164 ?? void 0).includes(sender);
1950
1987
  }
1951
1988
  function recordPendingGroupHistoryEntry(params) {
1952
1989
  const senderIdentity = getSenderIdentity(params.msg);
@@ -2023,7 +2060,7 @@ async function applyGroupGating(params) {
2023
2060
  } : params.msg;
2024
2061
  const commandBody = stripMentionsForCommand(mentionMsg.payload.body, mentionConfig.mentionRegexes, self.e164);
2025
2062
  const activationCommand = parseActivationCommand(commandBody);
2026
- const owner = isOwnerSender(baseMentionConfig, params.msg);
2063
+ const owner = isOwnerSender(baseMentionConfig, params.msg, params.authDir);
2027
2064
  const shouldBypassMention = owner && hasControlCommand(commandBody, params.cfg);
2028
2065
  if (activationCommand.hasCommand && !owner) return skipGroupMessageAndStoreHistory(params, `Ignoring /activation from non-owner in group ${conversationId}`);
2029
2066
  const mentionDebug = debugMention(mentionMsg, mentionConfig, params.authDir);
@@ -2056,7 +2093,10 @@ async function applyGroupGating(params) {
2056
2093
  }
2057
2094
  });
2058
2095
  const effectiveWasMentioned = mentionDecision.effectiveWasMentioned || shouldBypassMention;
2059
- params.msg.wasMentioned = effectiveWasMentioned;
2096
+ params.msg.groupMention = {
2097
+ wasMentioned: effectiveWasMentioned,
2098
+ requireMention
2099
+ };
2060
2100
  if (!shouldBypassMention && requireMention && mentionDecision.shouldSkip) {
2061
2101
  if (params.deferMissingMention === true) {
2062
2102
  params.logVerbose(`Deferring group mention skip until audio preflight completes in ${conversationId}`);
@@ -2079,7 +2119,7 @@ function trackBackgroundTask(backgroundTasks, task) {
2079
2119
  task.then(cleanup, cleanup);
2080
2120
  }
2081
2121
  function updateLastRouteInBackground(params) {
2082
- const storePath = resolveStorePath(params.cfg.session?.store, { agentId: params.storeAgentId });
2122
+ const storePath = resolveStorePath$1(params.cfg.session?.store, { agentId: params.storeAgentId });
2083
2123
  const task = updateLastRoute({
2084
2124
  storePath,
2085
2125
  sessionKey: params.sessionKey,
@@ -2133,7 +2173,8 @@ function resolveWhatsAppDirectSystemPrompt(params) {
2133
2173
  function elide(text, limit = 400) {
2134
2174
  if (!text) return text;
2135
2175
  if (text.length <= limit) return text;
2136
- return `${text.slice(0, limit)}… (truncated ${text.length - limit} chars)`;
2176
+ const truncated = truncateUtf16Safe(text, limit);
2177
+ return `${truncated}… (truncated ${text.length - truncated.length} chars)`;
2137
2178
  }
2138
2179
  function markWhatsAppVisibleDeliveryError(error) {
2139
2180
  if (typeof error === "object" && error !== null && !Array.isArray(error)) try {
@@ -2519,6 +2560,7 @@ async function buildWhatsAppInboundContext(params) {
2519
2560
  const admission = requireWhatsAppInboundAdmission(params.msg);
2520
2561
  const conversationId = admission.conversation.id;
2521
2562
  const conversationKind = admission.conversation.kind;
2563
+ const wasMentioned = params.msg.groupMention?.wasMentioned ?? params.msg.wasMentioned;
2522
2564
  const inboundHistory = conversationKind === "group" ? buildInboundHistoryFromEntries({
2523
2565
  entries: (params.groupHistory ?? []).map((entry) => ({
2524
2566
  sender: entry.sender,
@@ -2575,9 +2617,10 @@ async function buildWhatsAppInboundContext(params) {
2575
2617
  commandBody: params.commandBody ?? params.msg.payload.body
2576
2618
  },
2577
2619
  access: {
2578
- ...params.msg.wasMentioned !== void 0 ? { mentions: {
2620
+ ...wasMentioned !== void 0 ? { mentions: {
2579
2621
  canDetectMention: conversationKind === "group",
2580
- wasMentioned: params.msg.wasMentioned
2622
+ wasMentioned,
2623
+ requireMention: params.msg.groupMention?.requireMention
2581
2624
  } } : {},
2582
2625
  commands: { authorized: params.commandAuthorized }
2583
2626
  },
@@ -2848,7 +2891,7 @@ async function dispatchWhatsAppBufferedReply(params) {
2848
2891
  }
2849
2892
  },
2850
2893
  replyOptions: {
2851
- suppressTyping: sourceRepliesAreToolOnly && conversationKind === "group" && !params.msg.wasMentioned,
2894
+ suppressTyping: sourceRepliesAreToolOnly && conversationKind === "group" && !(params.msg.groupMention?.wasMentioned ?? params.msg.wasMentioned),
2852
2895
  disableBlockStreaming,
2853
2896
  ...sourceReplyDeliveryMode ? { sourceReplyDeliveryMode } : {},
2854
2897
  onModelSelected: params.onModelSelected,
@@ -2998,7 +3041,7 @@ async function createWhatsAppStatusReactionController(params) {
2998
3041
  isGroup,
2999
3042
  directEnabled,
3000
3043
  groupMode,
3001
- wasMentioned: params.msg.wasMentioned === true,
3044
+ wasMentioned: (params.msg.groupMention?.wasMentioned ?? params.msg.wasMentioned) === true,
3002
3045
  groupActivated: activation === "always"
3003
3046
  })) return null;
3004
3047
  const sender = getSenderIdentity(params.msg);
@@ -3218,7 +3261,8 @@ async function processMessage(params) {
3218
3261
  const commandAuthorized = shouldCheckCommandAuth ? await resolveWhatsAppCommandAuthorized({
3219
3262
  cfg: params.cfg,
3220
3263
  msg: params.msg,
3221
- policy: inboundPolicy
3264
+ policy: inboundPolicy,
3265
+ authDir: account.authDir
3222
3266
  }) : void 0;
3223
3267
  const commandTurn = isTextCommand ? {
3224
3268
  kind: "text-slash",
@@ -3665,11 +3709,7 @@ function createWebOnMessageHandler(params) {
3665
3709
  function isNonRetryableWebCloseStatus(statusCode) {
3666
3710
  return statusCode === 440;
3667
3711
  }
3668
- let replyResolverRuntimePromise = null;
3669
- function loadReplyResolverRuntime() {
3670
- replyResolverRuntimePromise ??= import("./reply-resolver.runtime-Ded8D58Y.js");
3671
- return replyResolverRuntimePromise;
3672
- }
3712
+ const loadReplyResolverRuntime = createLazyRuntimeModule(() => import("./reply-resolver.runtime-Ded8D58Y.js"));
3673
3713
  function resolveWebMonitorConfigSnapshot(params) {
3674
3714
  const account = resolveWhatsAppAccount({
3675
3715
  cfg: params.cfg,
@@ -3861,6 +3901,9 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
3861
3901
  statusController.noteInbound(inboundAt);
3862
3902
  await onMessage(normalized);
3863
3903
  },
3904
+ onPendingWorkChanged: (pendingWorkCount, at) => {
3905
+ statusController.noteBusy(pendingWorkCount > 0, at);
3906
+ },
3864
3907
  sock
3865
3908
  });
3866
3909
  },
@@ -1,4 +1,4 @@
1
- import { u as jidToE164 } from "./text-runtime-CpiloI73.js";
1
+ import { u as jidToE164 } from "./text-runtime-C88QkuU9.js";
2
2
  //#region extensions/whatsapp/src/quoted-message.ts
3
3
  const CACHE_TTL_MS = 600 * 1e3;
4
4
  const MAX_ENTRIES = 500;
@@ -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-D-FTwc8j.js";
3
- import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-BplHdEjw.js";
2
+ import { n as whatsAppActionRuntime, t as handleWhatsAppAction } from "./action-runtime-hqza0J8B.js";
3
+ import { i as sendTypingWhatsApp, n as sendPollWhatsApp, r as sendReactionWhatsApp, t as sendMessageWhatsApp } from "./send-i8Xk5mBQ.js";
4
4
  import { r as setWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
5
5
  import { n as getStatusCode, t as formatError } from "./session-errors-CbsoQqoy.js";
6
6
  import { startWebLoginWithQr, waitForWebLogin } from "./login-qr-runtime.js";
7
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-BRv2o3w2.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-ECx4h57q.js";
9
9
  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-11yoHJhM.js";
11
- import { n as newConnectionId, r as waitForWaConnection, t as createWaSocket } from "./session-DlHpYSAl.js";
10
+ import { _ as extractLocationData, b as extractText, m as extractContactContext, v as extractMediaPlaceholder } from "./send-api-DndiBJhN.js";
11
+ import { n as newConnectionId, r as waitForWaConnection, t as createWaSocket } from "./session-WU4SVP8f.js";
12
12
  import { n as resolveWebAccountId, t as getActiveWebListener } from "./active-listener-CFwkn3ho.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-BVD90YEd.js";
14
- import { t as loginWeb } from "./login-FpqysWi0.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-BqkJ4MpT.js";
14
+ import { t as loginWeb } from "./login-8lHwLmXj.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 };
@@ -1,9 +1,9 @@
1
1
  import { n as isWhatsAppNewsletterJid } from "./normalize-target-bVWjgftN.js";
2
- import { u as resolveWhatsAppDocumentFileName } from "./send-BplHdEjw.js";
2
+ import { u as resolveWhatsAppDocumentFileName } from "./send-i8Xk5mBQ.js";
3
3
  import "./normalize-Bxwqo-bW.js";
4
- import { h as toWhatsappJidWithLid, m as toWhatsappJid, u as jidToE164 } from "./text-runtime-CpiloI73.js";
5
- import { t as buildQuotedMessageOptions } from "./quoted-message-DqmWlbN7.js";
6
- import { c as resolveComparableIdentity } from "./identity-DdeafYji.js";
4
+ import { h as toWhatsappJidWithLid, m as toWhatsappJid, u as jidToE164 } from "./text-runtime-C88QkuU9.js";
5
+ import { t as buildQuotedMessageOptions } from "./quoted-message-CpA_ujXK.js";
6
+ import { c as resolveComparableIdentity } from "./identity-CmsTmkKR.js";
7
7
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { createMessageReceiptFromOutboundResults, listMessageReceiptPlatformIds } from "openclaw/plugin-sdk/channel-outbound";
9
9
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -6,7 +6,7 @@ import "./normalize-Bxwqo-bW.js";
6
6
  import { t as getOptionalWhatsAppRuntime } from "./runtime-BfAdAEYT.js";
7
7
  import { r as getRegisteredWhatsAppConnectionController, t as formatError } from "./session-errors-CbsoQqoy.js";
8
8
  import { r as isWhatsAppSocketOperationTimeoutError } from "./socket-timing-DvMNkIge.js";
9
- import { a as sanitizeAssistantVisibleTextWithProfile, d as markdownToWhatsApp, i as sanitizeAssistantVisibleText, m as toWhatsappJid, o as sleep, s as stripToolCallXmlTags } from "./text-runtime-CpiloI73.js";
9
+ import { a as sanitizeAssistantVisibleTextWithProfile, d as markdownToWhatsApp, i as sanitizeAssistantVisibleText, m as toWhatsappJid, o as sleep, s as stripToolCallXmlTags } from "./text-runtime-C88QkuU9.js";
10
10
  import path from "node:path";
11
11
  import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
12
12
  import { sanitizeForPlainText } from "openclaw/plugin-sdk/channel-outbound";
@@ -20,6 +20,7 @@ import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime"
20
20
  import { normalizePollInput } from "openclaw/plugin-sdk/poll-runtime";
21
21
  import { createSubsystemLogger, getChildLogger as getChildLogger$1 } from "openclaw/plugin-sdk/runtime-env";
22
22
  import { createApprovalReactionTargetStore, listApprovalReactionBindings, resolveApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
23
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
23
24
  import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
24
25
  import { extensionForMime } from "openclaw/plugin-sdk/media-mime";
25
26
  import { MEDIA_FFMPEG_MAX_AUDIO_DURATION_SECS, runFfmpeg } from "openclaw/plugin-sdk/media-runtime";
@@ -82,7 +83,7 @@ const whatsappApprovalAuth = { authorizeActorAction({ cfg, accountId, senderId,
82
83
  const PERSISTENT_NAMESPACE = "whatsapp.approval-reactions";
83
84
  const PERSISTENT_MAX_ENTRIES = 1e3;
84
85
  const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
85
- let resolverRuntimePromise;
86
+ const resolverRuntimeLoader = createLazyRuntimeModule(() => import("./approval-resolver-e1hAVRRy.js"));
86
87
  const whatsappApprovalReactionTargets = createApprovalReactionTargetStore({
87
88
  namespace: PERSISTENT_NAMESPACE,
88
89
  maxEntries: PERSISTENT_MAX_ENTRIES,
@@ -91,10 +92,7 @@ const whatsappApprovalReactionTargets = createApprovalReactionTargetStore({
91
92
  logPersistentError: reportPersistentApprovalReactionError,
92
93
  readPersistedTarget
93
94
  });
94
- function loadApprovalResolver() {
95
- resolverRuntimePromise ??= import("./approval-resolver-e1hAVRRy.js");
96
- return resolverRuntimePromise;
97
- }
95
+ const loadApprovalResolver = resolverRuntimeLoader;
98
96
  function buildReactionTargetKey(params) {
99
97
  const accountId = params.accountId.trim();
100
98
  const remoteJid = params.remoteJid.trim();
@@ -1,7 +1,7 @@
1
1
  import { o as resolveWebCredsBackupPath, s as resolveWebCredsPath, t as assertWebCredsPathRegularFileOrMissing } from "./creds-files-B1kSWtBg.js";
2
2
  import { n as getStatusCode } from "./session-errors-CbsoQqoy.js";
3
3
  import { t as DEFAULT_WHATSAPP_SOCKET_TIMING } from "./socket-timing-DvMNkIge.js";
4
- import { E as writeWebCredsRawAtomically, S as enqueueCredsSave, T as writeCredsJsonAtomically, b as restoreCredsFromBackupIfNeeded, u as readCredsJsonRaw, w as waitForCredsSaveQueueWithTimeout, y as resolveDefaultWebAuthDir } from "./auth-store-BRv2o3w2.js";
4
+ import { E as writeWebCredsRawAtomically, S as enqueueCredsSave, T as writeCredsJsonAtomically, b as restoreCredsFromBackupIfNeeded, u as readCredsJsonRaw, w as waitForCredsSaveQueueWithTimeout, y as resolveDefaultWebAuthDir } from "./auth-store-ECx4h57q.js";
5
5
  import { i as makeWASocket, n as fetchLatestBaileysVersion, o as useMultiFileAuthState, r as makeCacheableSignalKeyStore } from "./session.runtime-CyooSQvj.js";
6
6
  import { VERSION, formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
7
7
  import { danger, getChildLogger, success, toPinoLikeLogger } from "openclaw/plugin-sdk/runtime-env";
@@ -13,6 +13,7 @@ import { createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAge
13
13
  const LOGGED_OUT_STATUS = 401;
14
14
  const WHATSAPP_WEBSOCKET_PROXY_TARGET = "https://mmg.whatsapp.net/";
15
15
  const CREDS_FLUSH_TIMEOUT_MESSAGE = "Queued WhatsApp creds save did not finish before auth bootstrap; skipping repair and continuing with primary creds.";
16
+ const OPENCLAW_WHATSAPP_WEB_SOCKET_URL_ENV = "OPENCLAW_WHATSAPP_WEB_SOCKET_URL";
16
17
  async function rejectUnsafeWebCredsPath(authDir) {
17
18
  await assertWebCredsPathRegularFileOrMissing(resolveWebCredsPath(authDir));
18
19
  }
@@ -45,6 +46,22 @@ async function printTerminalQr(qr) {
45
46
  const output = await renderQrTerminal(qr, { small: true });
46
47
  process.stdout.write(output.endsWith("\n") ? output : `${output}\n`);
47
48
  }
49
+ function resolveWaWebSocketUrl(value) {
50
+ if (typeof value !== "string") return value;
51
+ return value.trim() || void 0;
52
+ }
53
+ function resolveEnvWaWebSocketUrl() {
54
+ const value = resolveWaWebSocketUrl(process.env[OPENCLAW_WHATSAPP_WEB_SOCKET_URL_ENV]);
55
+ if (!value) return;
56
+ let url;
57
+ try {
58
+ url = new URL(value);
59
+ } catch {
60
+ throw new Error(`${OPENCLAW_WHATSAPP_WEB_SOCKET_URL_ENV} must be a valid URL.`);
61
+ }
62
+ if (url.protocol !== "ws:" && url.protocol !== "wss:") throw new Error(`${OPENCLAW_WHATSAPP_WEB_SOCKET_URL_ENV} must use ws:// or wss://.`);
63
+ return url.toString();
64
+ }
48
65
  /**
49
66
  * Create a Baileys socket backed by the multi-file auth store we keep on disk.
50
67
  * Consumers can opt into QR printing for interactive login flows.
@@ -66,6 +83,7 @@ async function createWaSocket(printQr, verbose, opts = {}) {
66
83
  await writeCredsJsonAtomically(authDir, state.creds);
67
84
  };
68
85
  const { version } = await fetchLatestBaileysVersion();
86
+ const waWebSocketUrl = resolveWaWebSocketUrl(opts.waWebSocketUrl) ?? resolveEnvWaWebSocketUrl();
69
87
  const agent = await resolveEnvProxyAgent(sessionLogger);
70
88
  const fetchAgent = await resolveEnvFetchDispatcher(sessionLogger, agent);
71
89
  const socketTiming = {
@@ -91,6 +109,7 @@ async function createWaSocket(printQr, verbose, opts = {}) {
91
109
  ...socketTiming,
92
110
  agent,
93
111
  fetchAgent,
112
+ ...waWebSocketUrl ? { waWebSocketUrl } : {},
94
113
  ...opts.getMessage ? { getMessage: opts.getMessage } : {},
95
114
  ...opts.cachedGroupMetadata ? { cachedGroupMetadata: opts.cachedGroupMetadata } : {}
96
115
  });
@@ -99,10 +99,10 @@ async function applyWhatsAppSecurityConfigFixes(params) {
99
99
  //#region extensions/whatsapp/src/shared.ts
100
100
  const WHATSAPP_CHANNEL = "whatsapp";
101
101
  async function loadWhatsAppChannelRuntime() {
102
- return await import("./channel.runtime-kVF_UONw.js");
102
+ return await import("./channel.runtime-B4ThooGF.js");
103
103
  }
104
104
  async function loadWhatsAppSetupSurface() {
105
- return await import("./setup-surface-BpdIDwDg.js");
105
+ return await import("./setup-surface-IOdkbWsQ.js");
106
106
  }
107
107
  const whatsappSetupWizardProxy = createWhatsAppSetupWizardProxy(async () => (await loadWhatsAppSetupSurface()).whatsappSetupWizard);
108
108
  const whatsappConfigAdapter = createScopedChannelConfigAdapter({
@@ -2,7 +2,7 @@ import { r as resolveDefaultWhatsAppAccountId } from "./account-ids-CB5SOWjc.js"
2
2
  import { r as hasWebCredsSync } from "./creds-files-B1kSWtBg.js";
3
3
  import { a as resolveWhatsAppAccount, o as resolveWhatsAppAuthDir } from "./accounts-DgViSyJx.js";
4
4
  import { a as normalizeWhatsAppAllowFromEntries, o as normalizeWhatsAppAllowFromEntry } from "./normalize-target-bVWjgftN.js";
5
- import { t as whatsappSetupAdapter } from "./setup-core-D0JxJ53T.js";
5
+ import { t as whatsappSetupAdapter } from "./setup-core-KjSBbWX4.js";
6
6
  import { DEFAULT_ACCOUNT_ID, createSetupTranslator, splitSetupEntries } from "openclaw/plugin-sdk/setup";
7
7
  import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
8
8
  //#region extensions/whatsapp/src/setup-finalize.ts
@@ -280,7 +280,7 @@ async function finalizeWhatsAppSetup(params) {
280
280
  message: linked ? t("wizard.whatsapp.relinkPrompt") : t("wizard.whatsapp.linkNowPrompt"),
281
281
  initialValue: !linked
282
282
  })) try {
283
- const { loginWeb } = await import("./login-FpqysWi0.js").then((n) => n.n);
283
+ const { loginWeb } = await import("./login-8lHwLmXj.js").then((n) => n.n);
284
284
  await loginWeb(false, void 0, params.runtime, accountId);
285
285
  } catch (error) {
286
286
  params.runtime.error(`WhatsApp login failed: ${String(error)}`);
@@ -1,2 +1,2 @@
1
- import { t as whatsappSetupPlugin } from "./channel.setup-BTi6IdDT.js";
1
+ import { t as whatsappSetupPlugin } from "./channel.setup-C_WEdyJR.js";
2
2
  export { whatsappSetupPlugin };
@@ -1,6 +1,6 @@
1
1
  import { t as listAccountIds } from "./account-ids-CB5SOWjc.js";
2
2
  import { o as resolveWhatsAppAuthDir } from "./accounts-DgViSyJx.js";
3
- import { a as formatWhatsAppWebAuthStatusState, h as readWebAuthState } from "./auth-store-BRv2o3w2.js";
3
+ import { a as formatWhatsAppWebAuthStatusState, h as readWebAuthState } from "./auth-store-ECx4h57q.js";
4
4
  import { DEFAULT_ACCOUNT_ID, createSetupTranslator, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
5
5
  //#region extensions/whatsapp/src/setup-surface.ts
6
6
  const t = createSetupTranslator();
@@ -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-BRTq3uPs.js")).finalizeWhatsAppSetup(params),
39
+ finalize: async (params) => await (await import("./setup-finalize-WedNP30s.js")).finalizeWhatsAppSetup(params),
40
40
  disable: (cfg) => setSetupChannelEnabled(cfg, channel, false),
41
41
  onAccountRecorded: (accountId, options) => {
42
42
  options?.onAccountId?.(channel, accountId);
@@ -171,6 +171,12 @@ function markdownToWhatsApp(text) {
171
171
  inlineCodes.push(match);
172
172
  return `${WHATSAPP_INLINE_CODE_PLACEHOLDER}${inlineCodes.length - 1}${WHATSAPP_PLACEHOLDER_TERMINATOR}`;
173
173
  });
174
+ result = result.replace(/\*\*\*(.+?)\*\*\*/g, "*_$1_*");
175
+ result = result.replace(/___(.+?)___/g, "*_$1_*");
176
+ result = result.replace(/\*\*_(.+?)_\*\*/g, "*_$1_*");
177
+ result = result.replace(/__\*(.+?)\*__/g, "*_$1_*");
178
+ result = result.replace(/_\*\*(.+?)\*\*_/g, "*_$1_*");
179
+ result = result.replace(/\*__(.+?)__\*/g, "*_$1_*");
174
180
  result = result.replace(/\*\*(.+?)\*\*/g, "*$1*");
175
181
  result = result.replace(/__(.+?)__/g, "*$1*");
176
182
  result = result.replace(/~~(.+?)~~/g, "~$1~");
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@openclaw/whatsapp",
3
- "version": "2026.6.11",
3
+ "version": "2026.7.1-beta.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/whatsapp",
9
- "version": "2026.6.11",
9
+ "version": "2026.7.1-beta.2",
10
10
  "dependencies": {
11
11
  "audio-decode": "2.2.3",
12
12
  "baileys": "7.0.0-rc13",
13
13
  "typebox": "1.1.39"
14
14
  },
15
15
  "peerDependencies": {
16
- "openclaw": ">=2026.6.11"
16
+ "openclaw": ">=2026.7.1-beta.2"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/whatsapp",
3
- "version": "2026.6.11",
3
+ "version": "2026.7.1-beta.2",
4
4
  "description": "OpenClaw WhatsApp channel plugin for WhatsApp Web chats.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -13,7 +13,7 @@
13
13
  "typebox": "1.1.39"
14
14
  },
15
15
  "peerDependencies": {
16
- "openclaw": ">=2026.6.11"
16
+ "openclaw": ">=2026.7.1-beta.2"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
@@ -56,10 +56,10 @@
56
56
  "minHostVersion": ">=2026.4.25"
57
57
  },
58
58
  "compat": {
59
- "pluginApi": ">=2026.6.11"
59
+ "pluginApi": ">=2026.7.1-beta.2"
60
60
  },
61
61
  "build": {
62
- "openclawVersion": "2026.6.11"
62
+ "openclawVersion": "2026.7.1-beta.2"
63
63
  },
64
64
  "release": {
65
65
  "publishToClawHub": true,