@openclaw/whatsapp 2026.8.1-beta.2 → 2026.8.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/action-runtime-api.js +1 -1
  2. package/dist/{action-runtime-B4e3XFOY.js → action-runtime-pM-ExU0l.js} +1 -1
  3. package/dist/action-runtime.runtime.js +1 -1
  4. package/dist/api.js +6 -6
  5. package/dist/{approval-handler.runtime-fgGZhALv.js → approval-handler.runtime-CkMMvUjk.js} +2 -2
  6. package/dist/{approval-reactions-CmtJCxe_.js → approval-reactions-Jyr1JaAK.js} +9 -13
  7. package/dist/{auth-store-B_DQIdzp.js → auth-store-CtpBqH5S.js} +3 -6
  8. package/dist/{channel-DJVQHz_V.js → channel-DRMYRfZ8.js} +7 -7
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel-react-action-d6OacTNj.js → channel-react-action-CstrR0CT.js} +13 -11
  11. package/dist/{channel.runtime-RxuNGZ7w.js → channel.runtime-X3JC2gaq.js} +4 -4
  12. package/dist/{channel.setup-Cmvd967u.js → channel.setup-DhBBhbQv.js} +1 -1
  13. package/dist/{connection-controller-CUyZgGpf.js → connection-controller-CIYuBJrs.js} +2 -2
  14. package/dist/{directory-config-Pc4f07wB.js → directory-config-P7_3U73Z.js} +2 -2
  15. package/dist/directory-contract-api.js +1 -1
  16. package/dist/light-runtime-api.js +1 -1
  17. package/dist/{login-D6_rfxTZ.js → login-BkpKpndm.js} +3 -3
  18. package/dist/{login-qr-B0VyVSqQ.js → login-qr-1dpv6jjT.js} +3 -3
  19. package/dist/login-qr-runtime.js +1 -1
  20. package/dist/{monitor-BCe5Mm-1.js → monitor-IzwQKizW.js} +44 -459
  21. package/dist/runtime-api.js +7 -7
  22. package/dist/{send-prK8F7Vj.js → send-CwvTU4RI.js} +22 -8
  23. package/dist/{send-api-DimZST3E.js → send-api-obOSm2cC.js} +44 -34
  24. package/dist/{setup-finalize-D3n71Uyx.js → setup-finalize-n4K2I2gJ.js} +2 -2
  25. package/dist/setup-plugin-api.js +1 -1
  26. package/dist/{setup-surface-BCZszf3l.js → setup-surface-Cwn3zyxK.js} +2 -2
  27. package/dist/{shared-Dp9M3ZPX.js → shared-wg42NKFB.js} +11 -5
  28. package/dist/{socket-close-09FojDO2.js → socket-close-2T0_jZTN.js} +1 -1
  29. package/package.json +4 -4
@@ -1,19 +1,19 @@
1
1
  import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-BX2fZUyR.js";
2
- import { _ as resolveWhatsAppReactionLevel, a as normalizeWhatsAppOutboundPayload, c as prepareWhatsAppOutboundMedia, d as mergeWhatsAppAcceptedSendError, f as normalizeWhatsAppSendResult, h as withWhatsAppLogicalDeliveryActivity, m as rememberWhatsAppPartialSend, p as rememberWhatsAppAcceptedSend, r as sendReactionWhatsApp, s as normalizeWhatsAppPayloadTextPreservingIndentation, u as listWhatsAppSendResultMessageIds } from "./send-prK8F7Vj.js";
2
+ import { c as normalizeWhatsAppPayloadTextPreservingIndentation, d as listWhatsAppSendResultMessageIds, f as mergeWhatsAppAcceptedSendError, g as withWhatsAppLogicalDeliveryActivity, h as rememberWhatsAppPartialSend, l as prepareWhatsAppOutboundMedia, m as rememberWhatsAppAcceptedSend, o as normalizeWhatsAppOutboundPayload, p as normalizeWhatsAppSendResult, r as sendReactionWhatsApp, v as resolveWhatsAppReactionLevel } from "./send-CwvTU4RI.js";
3
3
  import { i as getWhatsAppRuntime } from "./runtime-BLlToOi6.js";
4
4
  import { r as getWhatsAppConnectionController } from "./connection-controller-runtime-context-DG0tuYuw.js";
5
5
  import { a as markdownToWhatsAppChunks, c as toWhatsappJid, l as toWhatsappJidWithLid, n as isSelfChatMode, o as resolveEquivalentWhatsAppDirectChatJids, r as jidToE164, s as resolveJidToE164 } from "./targets-runtime-TMk0lGuy.js";
6
6
  import { t as normalizeE164 } from "./text-runtime-CaKLhowd.js";
7
7
  import { a as cacheInboundMessageMeta, i as buildQuotedMessageOptions, n as resolveWhatsAppGroupSessionRoute, o as lookupInboundMessageMeta, r as resolveWhatsAppLegacyGroupSessionKey } from "./group-session-key-DmFc_Cqi.js";
8
- import { C as getMentionIdentities, D as getSenderIdentity, E as getSelfIdentity, O as identitiesOverlap, S as getComparableIdentityValues, T as getReplyContext, g as readWebSelfId, k as resolveComparableIdentity, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, v as readWebSelfIdentityForDecision, w as getPrimaryIdentityId } from "./auth-store-B_DQIdzp.js";
8
+ import { C as getMentionIdentities, D as getSenderIdentity, E as getSelfIdentity, O as identitiesOverlap, S as getComparableIdentityValues, T as getReplyContext, g as readWebSelfId, k as resolveComparableIdentity, o as getWebAuthAgeMs, r as WhatsAppAuthUnstableError, v as readWebSelfIdentityForDecision, w as getPrimaryIdentityId } from "./auth-store-CtpBqH5S.js";
9
9
  import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-BGyzT9Lg.js";
10
- import { a as waitForWaConnection, c as isWhatsAppSocketOperationTimeoutError, d as withWhatsAppSocketOperationTimeout, l as resolveWhatsAppSocketOperationTimeoutMs, r as createWaSocket, s as createWhatsAppSocketOperationTimeoutAdapter, u as resolveWhatsAppSocketTiming } from "./socket-close-09FojDO2.js";
10
+ import { a as waitForWaConnection, c as isWhatsAppSocketOperationTimeoutError, d as withWhatsAppSocketOperationTimeout, l as resolveWhatsAppSocketOperationTimeoutMs, r as createWaSocket, s as createWhatsAppSocketOperationTimeoutAdapter, u as resolveWhatsAppSocketTiming } from "./socket-close-2T0_jZTN.js";
11
11
  import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.js";
12
12
  import { t as BufferJSON } from "./session.runtime-Nsqaehbd.js";
13
- import { a as addWhatsAppImagePreviewFields, c as extractContextInfo, d as extractMediaKind, f as extractMentionedJids, g as resolveInboundMediaMimetype, h as hasInboundUserContent, i as resolveWhatsAppOutboundMentions, l as extractExternalAdReplyContext, n as addWhatsAppOutboundMentionsToContent, o as describeReplyContext, p as extractText, r as mayContainWhatsAppOutboundMention, s as extractContactContext, t as createWebSendApi, u as extractLocationData } from "./send-api-DimZST3E.js";
13
+ import { _ as resolveInboundMediaMimetype, a as addWhatsAppImagePreviewFields, c as extractContextInfo, d as extractMediaKind, f as extractMentionedJids, g as projectWhatsAppInboundMessage, h as hasInboundUserContent, i as resolveWhatsAppOutboundMentions, l as extractExternalAdReplyContext, n as addWhatsAppOutboundMentionsToContent, o as describeReplyContext, p as extractText, r as mayContainWhatsAppOutboundMention, s as extractContactContext, t as createWebSendApi, u as extractLocationData } from "./send-api-obOSm2cC.js";
14
14
  import { t as resolveWhatsAppRuntimeGroupPolicy } from "./runtime-group-policy-DeSRFXEV.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-CUyZgGpf.js";
16
- import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-CmtJCxe_.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-CIYuBJrs.js";
16
+ import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-Jyr1JaAK.js";
17
17
  import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-D3eAeB0i.js";
18
18
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
19
19
  import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
@@ -56,12 +56,14 @@ import { channelReadyPatch, channelStoppedPatch, createTransportActivityStatusPa
56
56
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
57
57
  import { resolveAgentIdentity, resolveIdentityNamePrefix as resolveIdentityNamePrefix$1 } from "openclaw/plugin-sdk/agent-runtime";
58
58
  import { normalizeGroupActivation, parseActivationCommand } from "openclaw/plugin-sdk/group-activation";
59
+ import { formatAudioTranscriptForAgent } from "openclaw/plugin-sdk/media-understanding-runtime";
59
60
  import { hasControlCommand, isControlCommandMessage, shouldComputeCommandAuthorized } from "openclaw/plugin-sdk/command-detection";
60
61
  import { createInternalHookEvent, deriveInboundMessageHookContext, fireAndForgetBoundedHook, toInternalMessageReceivedContext, toPluginMessageContext, toPluginMessageReceivedEvent, triggerInternalHook } from "openclaw/plugin-sdk/hook-runtime";
61
62
  import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
62
63
  import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
63
64
  import { LocalMediaAccessError, getDefaultLocalRoots, loadWebMedia, loadWebMediaRaw, optimizeImageToJpeg, optimizeImageToPng } from "openclaw/plugin-sdk/web-media";
64
65
  import { createChannelApiRetryRunner } from "openclaw/plugin-sdk/retry-runtime";
66
+ import { resolveAgentConfig } from "openclaw/plugin-sdk/agent-scope-runtime";
65
67
  //#region extensions/whatsapp/src/inbound/group-conversation.ts
66
68
  function resolveWhatsAppGroupConversationId(conversationId) {
67
69
  return resolveGroupSessionKey({
@@ -130,66 +132,10 @@ function buildWhatsAppInboundAdmission(params) {
130
132
  async function resolveWhatsAppAdmissionChannelIngress(admission, contextBinding) {
131
133
  return await ingressResolverByAdmission.get(admission)?.(contextBinding);
132
134
  }
133
- function buildDeprecatedFlatWhatsAppInboundAdmission(msg) {
134
- const conversationId = msg.conversationId || msg.from;
135
- if (!conversationId || !msg.accountId || !msg.chatType) throw new Error("WhatsApp legacy flat inbound messages must include deprecated top-level admission fields.");
136
- const accountId = msg.accountId;
137
- const admitted = msg.accessControlPassed !== false;
138
- const platformSender = msg.platform?.sender;
139
- const senderE164 = platformSender?.e164 ?? msg.platform?.senderE164 ?? msg.senderE164;
140
- const senderJid = platformSender?.jid ?? msg.platform?.senderJid ?? msg.senderJid;
141
- const senderName = platformSender?.name ?? msg.platform?.senderName ?? msg.senderName;
142
- const senderId = msg.chatType === "group" ? senderE164 ?? senderJid ?? senderName ?? conversationId : senderE164 ?? conversationId;
143
- const reasonCode = admitted ? msg.chatType === "group" ? "group_policy_allowed" : "dm_policy_allowlisted" : "no_policy_match";
144
- return buildWhatsAppInboundAdmission({
145
- policy: {
146
- account: {
147
- accountId,
148
- enabled: true,
149
- sendReadReceipts: true
150
- },
151
- isSelfChat: false,
152
- isSamePhone: () => false
153
- },
154
- access: {
155
- ingress: {
156
- admission: admitted ? "dispatch" : "drop",
157
- decision: admitted ? "allow" : "block",
158
- decisiveGateId: "legacy-flat-compat",
159
- reasonCode
160
- },
161
- senderAccess: {
162
- allowed: admitted,
163
- decision: admitted ? "allow" : "block",
164
- reasonCode,
165
- providerMissingFallbackApplied: false
166
- },
167
- commandAccess: {
168
- requested: false,
169
- authorized: false,
170
- shouldBlockControlCommand: false,
171
- reasonCode: "command_authorized"
172
- },
173
- activationAccess: {
174
- ran: false,
175
- allowed: admitted,
176
- shouldSkip: !admitted,
177
- reasonCode: admitted ? "activation_allowed" : "activation_skipped"
178
- }
179
- },
180
- isGroup: msg.chatType === "group",
181
- conversationId,
182
- senderId
183
- });
184
- }
185
135
  function requireWhatsAppInboundAdmission(params) {
186
136
  if (!params.admission) throw new Error("WhatsApp inbound message is missing admission facts");
187
137
  return params.admission;
188
138
  }
189
- function requireAdmittedWhatsAppInboundMessage(msg) {
190
- requireWhatsAppInboundAdmission(msg);
191
- return msg;
192
- }
193
139
  //#endregion
194
140
  //#region extensions/whatsapp/src/inbound-policy.ts
195
141
  function normalizeWhatsAppIngressPhone(value) {
@@ -324,353 +270,6 @@ function readWhatsAppBaileysCacheEntry(cache, key) {
324
270
  return entry.value;
325
271
  }
326
272
  //#endregion
327
- //#region extensions/whatsapp/src/inbound/message-aliases.ts
328
- function normalizeQuoteSender(sender) {
329
- if (!sender?.displayName && !sender?.jid && !sender?.e164) return;
330
- return sender;
331
- }
332
- function buildQuoteFromFlatAliases(msg) {
333
- if (msg.replyTo) return {
334
- context: msg.replyTo,
335
- id: msg.replyTo.id,
336
- body: msg.replyTo.body,
337
- sender: normalizeQuoteSender({
338
- displayName: msg.replyTo.sender?.label ?? msg.replyToSender,
339
- jid: msg.replyTo.sender?.jid ?? msg.replyToSenderJid,
340
- e164: msg.replyTo.sender?.e164 ?? msg.replyToSenderE164
341
- })
342
- };
343
- if (!msg.replyToId && !msg.replyToBody && !msg.replyToSender && !msg.replyToSenderJid && !msg.replyToSenderE164) return;
344
- return {
345
- id: msg.replyToId,
346
- body: msg.replyToBody,
347
- sender: normalizeQuoteSender({
348
- displayName: msg.replyToSender,
349
- jid: msg.replyToSenderJid,
350
- e164: msg.replyToSenderE164
351
- })
352
- };
353
- }
354
- function buildGroupFromFlatAliases(msg) {
355
- const mentionJids = msg.mentions ?? msg.mentionedJids;
356
- if (!msg.groupSubject && !msg.groupParticipants?.length && !mentionJids?.length) return;
357
- return {
358
- subject: msg.groupSubject,
359
- participants: msg.groupParticipants,
360
- mentions: mentionJids?.length ? { jids: mentionJids } : void 0
361
- };
362
- }
363
- function ensureQuote(msg) {
364
- return msg.quote ??= {};
365
- }
366
- function ensureQuoteSender(msg) {
367
- const quote = ensureQuote(msg);
368
- return quote.sender ??= {};
369
- }
370
- function ensureGroup(msg) {
371
- return msg.group ??= {};
372
- }
373
- function ensureGroupMentions(msg) {
374
- const group = ensureGroup(msg);
375
- return group.mentions ??= {};
376
- }
377
- function ensureMedia(msg) {
378
- return msg.payload.media ??= {};
379
- }
380
- function setMediaField(msg, key, value) {
381
- if (value === void 0 && !msg.payload.media) return;
382
- ensureMedia(msg)[key] = value;
383
- }
384
- function defineDeprecatedAccessors(msg, descriptors) {
385
- Object.defineProperties(msg, Object.fromEntries(Object.entries(descriptors).map(([key, descriptor]) => [key, {
386
- configurable: true,
387
- enumerable: true,
388
- get: descriptor.get,
389
- set: descriptor.set
390
- }])));
391
- return msg;
392
- }
393
- function defineDeprecatedAliasAccessors(msg, descriptors) {
394
- defineDeprecatedAccessors(msg, descriptors);
395
- return msg;
396
- }
397
- function defineDeprecatedStructuredContextPayloadAlias(msg) {
398
- const channelStructuredContext = msg.payload.channelStructuredContext ?? msg.payload.untrustedStructuredContext;
399
- if (channelStructuredContext !== void 0) msg.payload.channelStructuredContext = channelStructuredContext;
400
- Object.defineProperty(msg.payload, "untrustedStructuredContext", {
401
- configurable: true,
402
- enumerable: true,
403
- get: () => msg.payload.channelStructuredContext,
404
- set: (value) => {
405
- msg.payload.channelStructuredContext = value;
406
- }
407
- });
408
- }
409
- function defineDeprecatedAdmissionTopLevelAccessors(msg) {
410
- let fallbackConversationId = msg.conversationId || msg.from;
411
- let fallbackAccountId = msg.accountId;
412
- let fallbackAccessControlPassed = msg.accessControlPassed;
413
- let fallbackChatType = msg.chatType;
414
- const conversationId = () => msg.admission?.conversation.id ?? fallbackConversationId;
415
- const setConversationId = (value) => {
416
- const next = value;
417
- fallbackConversationId = next;
418
- if (msg.admission) {
419
- msg.admission.conversation.id = next;
420
- msg.admission.conversation.groupSessionId = resolveWhatsAppGroupConversationId(next);
421
- }
422
- };
423
- return defineDeprecatedAccessors(msg, {
424
- from: {
425
- get: conversationId,
426
- set: setConversationId
427
- },
428
- conversationId: {
429
- get: conversationId,
430
- set: setConversationId
431
- },
432
- accountId: {
433
- get: () => msg.admission?.accountId ?? fallbackAccountId,
434
- set: (value) => {
435
- const next = value;
436
- fallbackAccountId = next;
437
- if (msg.admission) {
438
- msg.admission.accountId = next;
439
- msg.admission.account.accountId = next;
440
- }
441
- }
442
- },
443
- accessControlPassed: {
444
- get: () => {
445
- if (msg.admission?.ingress.decisiveGateId === "legacy-flat-compat") return fallbackAccessControlPassed;
446
- return msg.admission ? msg.admission.ingress.decision === "allow" : fallbackAccessControlPassed;
447
- },
448
- set: (value) => {
449
- if (!msg.admission) fallbackAccessControlPassed = value;
450
- }
451
- },
452
- chatType: {
453
- get: () => msg.admission?.conversation.kind ?? fallbackChatType,
454
- set: (value) => {
455
- const next = value;
456
- fallbackChatType = next;
457
- if (msg.admission) msg.admission.conversation.kind = next;
458
- }
459
- }
460
- });
461
- }
462
- function withDeprecatedWebInboundMessageFlatAliases(msg) {
463
- defineDeprecatedStructuredContextPayloadAlias(msg);
464
- return defineDeprecatedAliasAccessors(defineDeprecatedAdmissionTopLevelAccessors(msg), {
465
- id: {
466
- get: () => msg.event.id,
467
- set: (value) => msg.event.id = value
468
- },
469
- to: {
470
- get: () => msg.platform.recipientJid,
471
- set: (value) => msg.platform.recipientJid = value
472
- },
473
- body: {
474
- get: () => msg.payload.body,
475
- set: (value) => msg.payload.body = value
476
- },
477
- pushName: {
478
- get: () => msg.platform.pushName,
479
- set: (value) => msg.platform.pushName = value
480
- },
481
- timestamp: {
482
- get: () => msg.event.timestamp,
483
- set: (value) => msg.event.timestamp = value
484
- },
485
- chatId: {
486
- get: () => msg.platform.chatJid,
487
- set: (value) => msg.platform.chatJid = value
488
- },
489
- sender: {
490
- get: () => msg.platform.sender,
491
- set: (value) => msg.platform.sender = value
492
- },
493
- senderJid: {
494
- get: () => msg.platform.senderJid,
495
- set: (value) => msg.platform.senderJid = value
496
- },
497
- senderE164: {
498
- get: () => msg.platform.senderE164,
499
- set: (value) => msg.platform.senderE164 = value
500
- },
501
- senderName: {
502
- get: () => msg.platform.senderName,
503
- set: (value) => msg.platform.senderName = value
504
- },
505
- replyTo: {
506
- get: () => msg.quote?.context,
507
- set: (value) => ensureQuote(msg).context = value
508
- },
509
- replyToId: {
510
- get: () => msg.quote?.id ?? msg.quote?.context?.id,
511
- set: (value) => ensureQuote(msg).id = value
512
- },
513
- replyToBody: {
514
- get: () => msg.quote?.body ?? msg.quote?.context?.body,
515
- set: (value) => ensureQuote(msg).body = value
516
- },
517
- replyToSender: {
518
- get: () => msg.quote?.context?.sender?.label ?? msg.quote?.sender?.displayName,
519
- set: (value) => {
520
- const sender = ensureQuoteSender(msg);
521
- sender.displayName = value;
522
- if (msg.quote?.context?.sender) msg.quote.context.sender.label = value;
523
- }
524
- },
525
- replyToSenderJid: {
526
- get: () => msg.quote?.context?.sender?.jid ?? msg.quote?.sender?.jid,
527
- set: (value) => {
528
- const jid = value;
529
- ensureQuoteSender(msg).jid = jid;
530
- if (msg.quote?.context?.sender) msg.quote.context.sender.jid = jid;
531
- }
532
- },
533
- replyToSenderE164: {
534
- get: () => msg.quote?.context?.sender?.e164 ?? msg.quote?.sender?.e164,
535
- set: (value) => {
536
- const e164 = value;
537
- ensureQuoteSender(msg).e164 = e164;
538
- if (msg.quote?.context?.sender) msg.quote.context.sender.e164 = e164;
539
- }
540
- },
541
- groupSubject: {
542
- get: () => msg.group?.subject,
543
- set: (value) => ensureGroup(msg).subject = value
544
- },
545
- groupParticipants: {
546
- get: () => msg.group?.participants,
547
- set: (value) => ensureGroup(msg).participants = value
548
- },
549
- mentions: {
550
- get: () => msg.group?.mentions?.jids,
551
- set: (value) => ensureGroupMentions(msg).jids = value
552
- },
553
- mentionedJids: {
554
- get: () => msg.group?.mentions?.jids,
555
- set: (value) => ensureGroupMentions(msg).jids = value
556
- },
557
- self: {
558
- get: () => msg.platform.self,
559
- set: (value) => msg.platform.self = value
560
- },
561
- selfJid: {
562
- get: () => msg.platform.selfJid,
563
- set: (value) => msg.platform.selfJid = value
564
- },
565
- selfLid: {
566
- get: () => msg.platform.selfLid,
567
- set: (value) => msg.platform.selfLid = value
568
- },
569
- selfE164: {
570
- get: () => msg.platform.selfE164,
571
- set: (value) => msg.platform.selfE164 = value
572
- },
573
- fromMe: {
574
- get: () => msg.platform.fromMe,
575
- set: (value) => msg.platform.fromMe = value
576
- },
577
- location: {
578
- get: () => msg.payload.location,
579
- set: (value) => msg.payload.location = value
580
- },
581
- sendComposing: {
582
- get: () => msg.platform.sendComposing,
583
- set: (value) => msg.platform.sendComposing = value
584
- },
585
- reply: {
586
- get: () => msg.platform.reply,
587
- set: (value) => msg.platform.reply = value
588
- },
589
- sendMedia: {
590
- get: () => msg.platform.sendMedia,
591
- set: (value) => msg.platform.sendMedia = value
592
- },
593
- mediaPath: {
594
- get: () => msg.payload.media?.path,
595
- set: (value) => setMediaField(msg, "path", value)
596
- },
597
- mediaType: {
598
- get: () => msg.payload.media?.type,
599
- set: (value) => setMediaField(msg, "type", value)
600
- },
601
- mediaFileName: {
602
- get: () => msg.payload.media?.fileName,
603
- set: (value) => setMediaField(msg, "fileName", value)
604
- },
605
- mediaUrl: {
606
- get: () => msg.payload.media?.url,
607
- set: (value) => setMediaField(msg, "url", value)
608
- },
609
- channelStructuredContext: {
610
- get: () => msg.payload.channelStructuredContext,
611
- set: (value) => msg.payload.channelStructuredContext = value
612
- },
613
- untrustedStructuredContext: {
614
- get: () => msg.payload.channelStructuredContext,
615
- set: (value) => msg.payload.channelStructuredContext = value
616
- },
617
- isBatched: {
618
- get: () => msg.event.isBatched,
619
- set: (value) => msg.event.isBatched = value
620
- }
621
- });
622
- }
623
- function normalizeLegacyFlatWebInboundMessage(msg) {
624
- const media = msg.mediaPath || msg.mediaType || msg.mediaFileName || msg.mediaUrl ? {
625
- path: msg.mediaPath,
626
- type: msg.mediaType,
627
- fileName: msg.mediaFileName,
628
- url: msg.mediaUrl
629
- } : void 0;
630
- return withDeprecatedWebInboundMessageFlatAliases({
631
- ...msg,
632
- admission: msg.admission ?? buildDeprecatedFlatWhatsAppInboundAdmission(msg),
633
- event: {
634
- id: msg.id,
635
- timestamp: msg.timestamp,
636
- isBatched: msg.isBatched
637
- },
638
- payload: {
639
- body: msg.body,
640
- media,
641
- location: msg.location,
642
- channelStructuredContext: msg.channelStructuredContext ?? msg.untrustedStructuredContext
643
- },
644
- platform: {
645
- chatJid: msg.chatId,
646
- recipientJid: msg.to,
647
- sender: msg.sender,
648
- senderJid: msg.senderJid,
649
- senderE164: msg.senderE164,
650
- senderName: msg.senderName,
651
- pushName: msg.pushName,
652
- self: msg.self,
653
- selfJid: msg.selfJid,
654
- selfLid: msg.selfLid,
655
- selfE164: msg.selfE164,
656
- fromMe: msg.fromMe,
657
- sendComposing: msg.sendComposing,
658
- reply: msg.reply,
659
- sendMedia: msg.sendMedia
660
- },
661
- quote: buildQuoteFromFlatAliases(msg),
662
- group: buildGroupFromFlatAliases(msg)
663
- });
664
- }
665
- function normalizeWebInboundMessage(msg) {
666
- if (msg.event && msg.payload && msg.platform) return withDeprecatedWebInboundMessageFlatAliases(msg);
667
- if (msg.event || msg.payload || msg.platform || msg.quote || msg.group) throw new Error("WhatsApp inbound messages must be either legacy flat or canonical nested; partial nested contexts are not supported.");
668
- return normalizeLegacyFlatWebInboundMessage(msg);
669
- }
670
- function normalizeAdmittedWebInboundMessage(msg) {
671
- return requireAdmittedWhatsAppInboundMessage(normalizeWebInboundMessage(msg));
672
- }
673
- //#endregion
674
273
  //#region extensions/whatsapp/src/inbound/durable-payload.ts
675
274
  var WhatsAppIngressPermanentError = class extends Error {
676
275
  constructor(reason, message, options) {
@@ -1063,7 +662,7 @@ function createWhatsAppInboundMessageDebouncer(options) {
1063
662
  ...last.group,
1064
663
  mentions: combinedMentions
1065
664
  } : void 0;
1066
- const combinedMessage = attachWhatsAppIngressLifecycle(withDeprecatedWebInboundMessageFlatAliases({
665
+ const combinedMessage = attachWhatsAppIngressLifecycle({
1067
666
  ...last,
1068
667
  turnAdoptionLifecycle: admissionLifecycle,
1069
668
  payload: {
@@ -1076,7 +675,7 @@ function createWhatsAppInboundMessageDebouncer(options) {
1076
675
  ...last.event,
1077
676
  isBatched: true
1078
677
  }
1079
- }), admissionLifecycle);
678
+ }, admissionLifecycle);
1080
679
  await options.onMessage(combinedMessage);
1081
680
  await settle();
1082
681
  await Promise.all(orderedEntries.map((entry) => options.markRead(entry.readReceipt)));
@@ -1145,8 +744,8 @@ function createWhatsAppInboundMessageDebouncer(options) {
1145
744
  function unwrapMessage(message) {
1146
745
  return normalizeMessageContent$1(message);
1147
746
  }
1148
- async function downloadInboundMedia(msg, sock, maxBytes = 50 * 1024 * 1024) {
1149
- const message = unwrapMessage(msg.message);
747
+ async function downloadInboundMedia(msg, sock, maxBytes = 50 * 1024 * 1024, normalizedMessage) {
748
+ const message = normalizedMessage ?? unwrapMessage(msg.message);
1150
749
  if (!message) return;
1151
750
  const mimetype = resolveInboundMediaMimetype(message);
1152
751
  const fileName = message.documentMessage?.fileName ?? void 0;
@@ -1214,17 +813,18 @@ function logMediaMaterializationFailure(params) {
1214
813
  }
1215
814
  async function enrichWhatsAppInboundMessage(params) {
1216
815
  const { msg, sock } = params;
1217
- const location = extractLocationData(msg.message ?? void 0);
816
+ const messageProjection = projectWhatsAppInboundMessage(msg.message ?? void 0);
817
+ const location = extractLocationData(messageProjection);
1218
818
  const locationText = location ? formatLocationText(location) : void 0;
1219
- const contactContext = extractContactContext(msg.message ?? void 0);
1220
- const externalAdReplyContext = extractExternalAdReplyContext(msg.message ?? void 0);
1221
- let mediaKind = extractMediaKind(msg.message ?? void 0);
1222
- let body = extractText(msg.message ?? void 0);
819
+ const contactContext = extractContactContext(messageProjection);
820
+ const externalAdReplyContext = extractExternalAdReplyContext(messageProjection);
821
+ let mediaKind = extractMediaKind(messageProjection);
822
+ let body = extractText(messageProjection);
1223
823
  if (locationText) body = [body, locationText].filter(Boolean).join("\n").trim();
1224
824
  if (!body && !mediaKind) return null;
1225
825
  body = body ?? "";
1226
826
  const commandBody = body;
1227
- const replyContext = describeReplyContext(msg.message);
827
+ const replyContext = describeReplyContext(messageProjection);
1228
828
  let mediaPath;
1229
829
  let mediaType = mediaKind ? resolveInboundMediaMimetype(msg.message) : void 0;
1230
830
  const nativeMedia = mediaKind ? {
@@ -1240,7 +840,7 @@ async function enrichWhatsAppInboundMessage(params) {
1240
840
  mediaFileName = inboundMedia.fileName;
1241
841
  };
1242
842
  try {
1243
- await saveInboundMedia(await downloadInboundMedia(msg, sock, maxBytes));
843
+ await saveInboundMedia(await downloadInboundMedia(msg, sock, maxBytes, messageProjection[0]));
1244
844
  } catch (error) {
1245
845
  logMediaMaterializationFailure({
1246
846
  messageId: msg.key?.id,
@@ -1284,7 +884,8 @@ async function enrichWhatsAppInboundMessage(params) {
1284
884
  mediaType,
1285
885
  mediaFileName,
1286
886
  mediaKind,
1287
- nativeMedia
887
+ nativeMedia,
888
+ mentionedJids: extractMentionedJids(messageProjection)
1288
889
  };
1289
890
  }
1290
891
  //#endregion
@@ -1617,7 +1218,7 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1617
1218
  return normalizeWhatsAppSendResult(await sendTrackedMessage(chatJid, await groupMetadata.applyOutboundMentions(chatJid, previewPayload), optionsValue), "media");
1618
1219
  };
1619
1220
  const timestamp = inbound.messageTimestampMs;
1620
- const mentionedJids = extractMentionedJids(msg.message);
1221
+ const mentionedJids = enriched.mentionedJids;
1621
1222
  const senderName = msg.pushName ?? void 0;
1622
1223
  inboundLogger.info({
1623
1224
  from: inbound.from,
@@ -1660,7 +1261,7 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1660
1261
  payload: enriched.externalAdReplyContext
1661
1262
  }] : []
1662
1263
  ];
1663
- const inboundMessage = withDeprecatedWebInboundMessageFlatAliases({
1264
+ const inboundMessage = {
1664
1265
  admission: inbound.access.admission,
1665
1266
  event: {
1666
1267
  id: inbound.id,
@@ -1709,7 +1310,7 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1709
1310
  turnAdoptionLifecycle: durable.turnAdoptionLifecycle,
1710
1311
  readReceipt: durable.readReceipt,
1711
1312
  receiveOrder: durable.receiveOrder
1712
- });
1313
+ };
1713
1314
  if (inboundMessage.event.id) {
1714
1315
  const admission = requireWhatsAppInboundAdmission(inboundMessage);
1715
1316
  cacheInboundMessageMeta(admission.accountId, inboundMessage.platform.chatJid, inboundMessage.event.id, {
@@ -2263,10 +1864,6 @@ async function monitorWebInbox(options) {
2263
1864
  }
2264
1865
  return attachWebInboxToSocket({
2265
1866
  ...options,
2266
- onMessage: async (msg) => {
2267
- await options.onMessage(normalizeAdmittedWebInboundMessage(msg));
2268
- },
2269
- shouldDebounce: options.shouldDebounce ? (msg) => options.shouldDebounce?.(normalizeAdmittedWebInboundMessage(msg)) ?? true : void 0,
2270
1867
  socketTiming,
2271
1868
  sock,
2272
1869
  recentMessageKeys,
@@ -2700,11 +2297,6 @@ async function maybeBroadcastMessage(params) {
2700
2297
  return true;
2701
2298
  }
2702
2299
  //#endregion
2703
- //#region extensions/whatsapp/src/auto-reply/monitor/audio-transcript.ts
2704
- function formatWhatsAppAudioTranscriptForAgent(transcript) {
2705
- return `[Audio transcript (machine-generated, untrusted)]: ${JSON.stringify(transcript)}`;
2706
- }
2707
- //#endregion
2708
2300
  //#region extensions/whatsapp/src/auto-reply/monitor/commands.ts
2709
2301
  function stripMentionsForCommand(text, mentionRegexes, selfE164) {
2710
2302
  let result = text;
@@ -2901,7 +2493,7 @@ async function applyGroupGating(params) {
2901
2493
  needsMentionText: true
2902
2494
  };
2903
2495
  }
2904
- const pendingHistoryBody = params.mentionText === void 0 ? void 0 : formatWhatsAppAudioTranscriptForAgent(params.mentionText);
2496
+ const pendingHistoryBody = params.mentionText === void 0 ? void 0 : formatAudioTranscriptForAgent(params.mentionText);
2905
2497
  return skipGroupMessageAndStoreHistory(params, `Group message stored for context (no mention detected) in ${conversationId}: ${mentionMsg.payload.body}`, pendingHistoryBody);
2906
2498
  }
2907
2499
  return { shouldProcess: true };
@@ -3923,8 +3515,7 @@ async function finalizeWhatsAppStatusReaction(params) {
3923
3515
  //#endregion
3924
3516
  //#region extensions/whatsapp/src/auto-reply/monitor/message-line.runtime.ts
3925
3517
  function resolveIdentityNamePrefix(cfg, agentId) {
3926
- const normalizedAgentId = normalizeAgentId(agentId);
3927
- const identityName = cfg.agents?.list?.find((agent) => normalizeAgentId(agent.id ?? "") === normalizedAgentId)?.identity?.name?.trim();
3518
+ const identityName = resolveAgentConfig(cfg, agentId)?.identity?.name?.trim();
3928
3519
  return identityName ? `[${identityName}]` : void 0;
3929
3520
  }
3930
3521
  function resolveMessagePrefix(cfg, agentId, opts) {
@@ -4092,7 +3683,7 @@ async function processMessage(params) {
4092
3683
  ...params.msg,
4093
3684
  payload: {
4094
3685
  ...params.msg.payload,
4095
- body: formatWhatsAppAudioTranscriptForAgent(audioTranscript)
3686
+ body: formatAudioTranscriptForAgent(audioTranscript)
4096
3687
  }
4097
3688
  } : params.msg;
4098
3689
  const visibleReplyTo = resolveVisibleWhatsAppReplyContext({
@@ -4323,6 +3914,7 @@ async function processMessage(params) {
4323
3914
  sessionKey: params.route.sessionKey
4324
3915
  },
4325
3916
  ctxPayload,
3917
+ dispatchReplyFromConfig: params.dispatchReplyFromConfig,
4326
3918
  record: {
4327
3919
  onRecordError: (err) => {
4328
3920
  params.replyLogger.warn({
@@ -4357,19 +3949,13 @@ async function processMessage(params) {
4357
3949
  }
4358
3950
  //#endregion
4359
3951
  //#region extensions/whatsapp/src/auto-reply/monitor/on-message.ts
4360
- function readDeprecatedAccessControlPassed(msg) {
4361
- return msg.accessControlPassed;
4362
- }
4363
3952
  function createWebOnMessageHandler(params) {
4364
- const hasExplicitlyPassedInboundAccess = (msg) => {
4365
- if (msg.admission.ingress.decisiveGateId === "legacy-flat-compat") return readDeprecatedAccessControlPassed(msg) === true;
4366
- return msg.admission.ingress.decision === "allow";
4367
- };
3953
+ const hasExplicitlyPassedInboundAccess = (msg) => msg.admission.ingress.decision === "allow";
4368
3954
  const withDirectSenderPeer = (msg, peerId) => {
4369
3955
  if (requireWhatsAppInboundAdmission(msg).conversation.kind === "group" || msg.platform.sender?.e164 || msg.platform.senderE164 || !peerId.startsWith("+")) return msg;
4370
3956
  const normalized = normalizeE164(peerId);
4371
3957
  if (!normalized) return msg;
4372
- return requireAdmittedWhatsAppInboundMessage(withDeprecatedWebInboundMessageFlatAliases({
3958
+ return {
4373
3959
  ...msg,
4374
3960
  platform: {
4375
3961
  ...msg.platform,
@@ -4379,7 +3965,7 @@ function createWebOnMessageHandler(params) {
4379
3965
  },
4380
3966
  senderE164: normalized
4381
3967
  }
4382
- }));
3968
+ };
4383
3969
  };
4384
3970
  const processForRoute = async (cfg, msg, route, groupHistoryKey, opts) => {
4385
3971
  const processParams = {
@@ -4396,7 +3982,8 @@ function createWebOnMessageHandler(params) {
4396
3982
  replyResolver: params.replyResolver,
4397
3983
  replyLogger: params.replyLogger,
4398
3984
  backgroundTasks: params.backgroundTasks,
4399
- buildContext: params.buildContext
3985
+ buildContext: params.buildContext,
3986
+ dispatchReplyFromConfig: params.dispatchReplyFromConfig
4400
3987
  };
4401
3988
  if (opts?.groupHistory !== void 0) processParams.groupHistory = opts.groupHistory;
4402
3989
  if (opts?.suppressGroupHistoryClear !== void 0) processParams.suppressGroupHistoryClear = opts.suppressGroupHistoryClear;
@@ -4745,15 +4332,12 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4745
4332
  cfg,
4746
4333
  channel: "whatsapp"
4747
4334
  });
4748
- const shouldDebounce = (msg) => {
4749
- const admitted = normalizeAdmittedWebInboundMessage(msg);
4750
- return shouldDebounceTextInbound({
4751
- text: admitted.payload.commandBody ?? admitted.payload.body,
4752
- cfg,
4753
- hasMedia: Boolean(admitted.payload.media?.path || admitted.payload.media?.type),
4754
- allowDebounce: !(admitted.payload.location || admitted.quote?.id || admitted.quote?.body)
4755
- });
4756
- };
4335
+ const shouldDebounce = (msg) => shouldDebounceTextInbound({
4336
+ text: msg.payload.commandBody ?? msg.payload.body,
4337
+ cfg,
4338
+ hasMedia: Boolean(msg.payload.media?.path || msg.payload.media?.type),
4339
+ allowDebounce: !(msg.payload.location || msg.quote?.id || msg.quote?.body)
4340
+ });
4757
4341
  let connection;
4758
4342
  try {
4759
4343
  connection = await controller.openConnection({
@@ -4764,6 +4348,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4764
4348
  return meta?.participants?.length ? meta : void 0;
4765
4349
  },
4766
4350
  createListener: async ({ sock, connection: connectionLocal }) => {
4351
+ const pluginChannelRuntime = tuning.channelRuntime;
4767
4352
  const onMessage = createWebOnMessageHandler({
4768
4353
  cfg,
4769
4354
  loadConfig: loadCurrentMonitorConfig,
@@ -4778,7 +4363,8 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4778
4363
  replyLogger,
4779
4364
  baseMentionConfig,
4780
4365
  account,
4781
- buildContext: tuning.channelRuntime?.inbound.buildContext
4366
+ buildContext: pluginChannelRuntime?.inbound.buildContext,
4367
+ dispatchReplyFromConfig: pluginChannelRuntime?.reply?.dispatchReplyFromConfig
4782
4368
  });
4783
4369
  return await (listenerFactory ?? attachWebInboxToSocket)({
4784
4370
  cfg,
@@ -4805,11 +4391,10 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4805
4391
  recentMessageKeys,
4806
4392
  baileysGroupMetaCache,
4807
4393
  onMessage: async (msg) => {
4808
- const admitted = normalizeAdmittedWebInboundMessage(msg);
4809
4394
  const inboundAt = Date.now();
4810
4395
  controller.noteInbound(inboundAt);
4811
4396
  statusController.noteInbound(inboundAt);
4812
- await onMessage(admitted);
4397
+ await onMessage(msg);
4813
4398
  },
4814
4399
  onPendingWorkChanged: (pendingWorkCount, at) => {
4815
4400
  statusController.noteBusy(pendingWorkCount > 0, at);