@openclaw/whatsapp 2026.9.6 → 2026.9.8

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 (354) hide show
  1. package/assets/icon.png +0 -0
  2. package/dist/.setup/{accounts-D_NGDjCx.mjs → accounts-CtRPAQCL.mjs} +3 -9
  3. package/dist/.setup/{action-runtime-DZZFamfl.mjs → action-runtime-DeVk5V7r.mjs} +2 -2
  4. package/dist/.setup/{approval-handler.runtime-C0hzmMSj.mjs → approval-handler.runtime-CjqMlPOX.mjs} +6 -26
  5. package/dist/.setup/{approval-reactions-BnXw-UZI.mjs → approval-reactions-DiOFvb1s.mjs} +8 -14
  6. package/dist/.setup/{auth-store-Dh8a3cba.mjs → auth-store-BBonwKks.mjs} +9 -33
  7. package/dist/.setup/{channel-Bg_fS2iF.mjs → channel-CJFE0kD_.mjs} +82 -154
  8. package/dist/.setup/{channel-react-action-1iBiEnq7.mjs → channel-react-action-2r_hjLZV.mjs} +4 -8
  9. package/dist/.setup/{channel.runtime-rurG-kbr.mjs → channel.runtime-C94goLw9.mjs} +4 -4
  10. package/dist/.setup/{channel.setup-C8P5q8uD.mjs → channel.setup-CfN1UfdY.mjs} +1 -1
  11. package/dist/.setup/{connection-controller-C60mU7j7.mjs → connection-controller-CHo1oRJA.mjs} +13 -63
  12. package/dist/.setup/{creds-files-Drg3usj1.mjs → creds-files-CDATZWWM.mjs} +5 -11
  13. package/dist/.setup/{directory-config-BHPoBklt.mjs → directory-config-DUiJ5d8I.mjs} +13 -14
  14. package/dist/.setup/doctor-iMwg0Vhr.mjs +222 -0
  15. package/dist/.setup/group-config-path-DZr3ucUO.mjs +40 -0
  16. package/dist/.setup/{group-session-key-D22hYMdE.mjs → group-session-key-2-mja4OF.mjs} +3 -9
  17. package/dist/.setup/{login-2dmd1TfE.mjs → login-BFlvSh9h.mjs} +9 -11
  18. package/dist/.setup/{login-qr-CgKtO_ef.mjs → login-qr-Ayb8i25J.mjs} +29 -77
  19. package/dist/.setup/{monitor-By82ehLA.mjs → monitor-CGpV2VNN.mjs} +376 -504
  20. package/dist/.setup/{question-reactions-D3Zq9Gbn.mjs → question-reactions-CPyyi5AY.mjs} +2 -2
  21. package/dist/.setup/rolldown-runtime-BBjsoOtd.mjs +27 -0
  22. package/dist/.setup/{send-C6jDmcL9.mjs → send-BGdvf5cC.mjs} +31 -80
  23. package/dist/.setup/{send-api-B4DOt2RJ.mjs → send-api-H4AkQJjT.mjs} +45 -109
  24. package/dist/.setup/{session-errors-JuazczrA.mjs → session-errors-B8UcAnZN.mjs} +1 -4
  25. package/dist/.setup/{session.runtime-DcJuO42v.mjs → session.runtime-st1konFI.mjs} +1 -1
  26. package/dist/.setup/{setup-finalize-pGqWOiFX.mjs → setup-finalize-DmPX4EaW.mjs} +32 -70
  27. package/dist/.setup/setup-plugin-api-vJlxKzca.mjs +3 -0
  28. package/dist/.setup/{setup-surface-B9CYwDPZ.mjs → setup-surface-43fj197P.mjs} +3 -3
  29. package/dist/.setup/{shared-DVgQ8kRG.mjs → shared-DgOG5Iqr.mjs} +26 -37
  30. package/dist/.setup/{socket-close-CCVSFufF.mjs → socket-close-CT__V2fz.mjs} +80 -92
  31. package/dist/.setup/{targets-runtime-RBjx3pg_.mjs → targets-runtime-DmiqXIXO.mjs} +2 -7
  32. package/dist/action-runtime-api.js +1 -1
  33. package/dist/action-runtime.runtime.js +1 -1
  34. package/dist/agent-tools-api.js +5 -12
  35. package/dist/api.js +10 -10
  36. package/dist/auth-presence.js +1 -1
  37. package/dist/channel-plugin-api.js +1 -1
  38. package/dist/contract-api.js +2 -2
  39. package/dist/directory-contract-api.js +1 -1
  40. package/dist/doctor-contract-api.js +9 -10
  41. package/dist/light-runtime-api.js +2 -2
  42. package/dist/login-qr-runtime.js +1 -1
  43. package/dist/runtime-api.js +9 -9
  44. package/dist/setup-entry.js +1 -1
  45. package/dist/setup-plugin-api.js +1 -1
  46. package/node_modules/audio-decode/LICENSE +9 -10
  47. package/node_modules/audio-decode/README.md +16 -0
  48. package/node_modules/audio-decode/audio-decode.d.ts +2 -14
  49. package/node_modules/audio-decode/audio-decode.js +4 -92
  50. package/node_modules/audio-decode/meta.js +1 -0
  51. package/node_modules/audio-decode/node_modules/{audio-buffer → @audio/decode}/LICENSE +1 -1
  52. package/node_modules/audio-decode/node_modules/@audio/decode/audio-decode.d.ts +52 -0
  53. package/node_modules/audio-decode/node_modules/@audio/decode/audio-decode.js +242 -0
  54. package/node_modules/audio-decode/node_modules/@audio/decode/meta.js +14 -0
  55. package/node_modules/audio-decode/node_modules/@audio/decode/package.json +114 -0
  56. package/node_modules/audio-decode/node_modules/@audio/decode/readme.md +191 -0
  57. package/node_modules/audio-decode/node_modules/@audio/decode/stream.d.ts +12 -0
  58. package/node_modules/audio-decode/node_modules/@audio/decode/stream.js +1 -0
  59. package/node_modules/audio-decode/node_modules/@audio/decode/test.html +52 -0
  60. package/node_modules/audio-decode/node_modules/@audio/decode-aac/LICENSE +9 -0
  61. package/node_modules/audio-decode/node_modules/@audio/decode-aac/README.md +80 -0
  62. package/node_modules/audio-decode/node_modules/@audio/decode-aac/alac.js +326 -0
  63. package/node_modules/audio-decode/node_modules/@audio/decode-aac/audio.d.ts +15 -0
  64. package/node_modules/audio-decode/node_modules/@audio/decode-aac/audio.js +10 -0
  65. package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.d.ts +24 -0
  66. package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.js +452 -0
  67. package/node_modules/audio-decode/node_modules/@audio/decode-aac/meta.js +81 -0
  68. package/node_modules/audio-decode/node_modules/@audio/decode-aac/package.json +63 -0
  69. package/node_modules/audio-decode/node_modules/@audio/decode-aac/src/aac.wasm.js +0 -0
  70. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/LICENSE +12 -0
  71. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/LICENSE.liba52 +340 -0
  72. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/README.md +41 -0
  73. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/audio.d.ts +15 -0
  74. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/audio.js +9 -0
  75. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/decode-ac3.d.ts +20 -0
  76. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/decode-ac3.js +131 -0
  77. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/package.json +64 -0
  78. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/src/ac3.wasm.js +0 -0
  79. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/LICENSE +21 -0
  80. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/README.md +46 -0
  81. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/audio.d.ts +15 -0
  82. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/audio.js +10 -0
  83. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/decode-aiff.d.ts +16 -0
  84. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/decode-aiff.js +583 -0
  85. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/package.json +52 -0
  86. package/node_modules/audio-decode/node_modules/@audio/decode-amr/LICENSE +191 -0
  87. package/node_modules/audio-decode/node_modules/@audio/decode-amr/README.md +65 -0
  88. package/node_modules/audio-decode/node_modules/@audio/decode-amr/audio.d.ts +15 -0
  89. package/node_modules/audio-decode/node_modules/@audio/decode-amr/audio.js +10 -0
  90. package/node_modules/audio-decode/node_modules/@audio/decode-amr/decode-amr.d.ts +16 -0
  91. package/node_modules/audio-decode/node_modules/@audio/decode-amr/decode-amr.js +150 -0
  92. package/node_modules/audio-decode/node_modules/@audio/decode-amr/package.json +58 -0
  93. package/node_modules/audio-decode/node_modules/@audio/decode-amr/src/amr.wasm.js +0 -0
  94. package/node_modules/audio-decode/node_modules/@audio/decode-avi/LICENSE +21 -0
  95. package/node_modules/audio-decode/node_modules/@audio/decode-avi/README.md +53 -0
  96. package/node_modules/audio-decode/node_modules/@audio/decode-avi/audio.d.ts +15 -0
  97. package/node_modules/audio-decode/node_modules/@audio/decode-avi/audio.js +9 -0
  98. package/node_modules/audio-decode/node_modules/@audio/decode-avi/decode-avi.d.ts +21 -0
  99. package/node_modules/audio-decode/node_modules/@audio/decode-avi/decode-avi.js +241 -0
  100. package/node_modules/audio-decode/node_modules/@audio/decode-avi/package.json +66 -0
  101. package/node_modules/audio-decode/node_modules/@audio/decode-caf/LICENSE +21 -0
  102. package/node_modules/audio-decode/node_modules/@audio/decode-caf/README.md +48 -0
  103. package/node_modules/audio-decode/node_modules/@audio/decode-caf/audio.d.ts +15 -0
  104. package/node_modules/audio-decode/node_modules/@audio/decode-caf/audio.js +10 -0
  105. package/node_modules/audio-decode/node_modules/@audio/decode-caf/decode-caf.d.ts +16 -0
  106. package/node_modules/audio-decode/node_modules/@audio/decode-caf/decode-caf.js +238 -0
  107. package/node_modules/audio-decode/node_modules/@audio/decode-caf/package.json +53 -0
  108. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/LICENSE +21 -0
  109. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/README.md +73 -0
  110. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/audio.d.ts +21 -0
  111. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/audio.js +15 -0
  112. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/decode-dsd.d.ts +29 -0
  113. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/decode-dsd.js +423 -0
  114. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/meta.js +40 -0
  115. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/package.json +64 -0
  116. package/node_modules/audio-decode/node_modules/@audio/decode-dts/LICENSE +12 -0
  117. package/node_modules/audio-decode/node_modules/@audio/decode-dts/LICENSE.libdca +339 -0
  118. package/node_modules/audio-decode/node_modules/@audio/decode-dts/README.md +41 -0
  119. package/node_modules/audio-decode/node_modules/@audio/decode-dts/audio.d.ts +15 -0
  120. package/node_modules/audio-decode/node_modules/@audio/decode-dts/audio.js +9 -0
  121. package/node_modules/audio-decode/node_modules/@audio/decode-dts/decode-dts.d.ts +20 -0
  122. package/node_modules/audio-decode/node_modules/@audio/decode-dts/decode-dts.js +139 -0
  123. package/node_modules/audio-decode/node_modules/@audio/decode-dts/package.json +64 -0
  124. package/node_modules/audio-decode/node_modules/@audio/decode-dts/src/dts.wasm.js +0 -0
  125. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/LICENSE +12 -0
  126. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/LICENSE.ffmpeg +502 -0
  127. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/README.md +45 -0
  128. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/audio.d.ts +15 -0
  129. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/audio.js +9 -0
  130. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/decode-eac3.d.ts +20 -0
  131. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/decode-eac3.js +124 -0
  132. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/package.json +68 -0
  133. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/src/eac3.wasm.js +0 -0
  134. package/node_modules/audio-decode/node_modules/@audio/decode-flac/LICENSE +25 -0
  135. package/node_modules/audio-decode/node_modules/@audio/decode-flac/README.md +23 -0
  136. package/node_modules/audio-decode/node_modules/@audio/decode-flac/audio.d.ts +15 -0
  137. package/node_modules/audio-decode/node_modules/@audio/decode-flac/audio.js +10 -0
  138. package/node_modules/audio-decode/node_modules/@audio/decode-flac/decode-flac.d.ts +18 -0
  139. package/node_modules/audio-decode/node_modules/@audio/decode-flac/decode-flac.js +3172 -0
  140. package/node_modules/audio-decode/node_modules/@audio/decode-flac/meta.js +115 -0
  141. package/node_modules/audio-decode/node_modules/@audio/decode-flac/package.json +60 -0
  142. package/node_modules/audio-decode/node_modules/@audio/decode-mod/LICENSE +23 -0
  143. package/node_modules/audio-decode/node_modules/@audio/decode-mod/LICENSE.libopenmpt +25 -0
  144. package/node_modules/audio-decode/node_modules/@audio/decode-mod/README.md +86 -0
  145. package/node_modules/audio-decode/node_modules/@audio/decode-mod/audio.d.ts +20 -0
  146. package/node_modules/audio-decode/node_modules/@audio/decode-mod/audio.js +12 -0
  147. package/node_modules/audio-decode/node_modules/@audio/decode-mod/decode-mod.d.ts +58 -0
  148. package/node_modules/audio-decode/node_modules/@audio/decode-mod/decode-mod.js +148 -0
  149. package/node_modules/audio-decode/node_modules/@audio/decode-mod/package.json +68 -0
  150. package/node_modules/audio-decode/node_modules/@audio/decode-mod/src/mod.wasm.js +0 -0
  151. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/LICENSE +25 -0
  152. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/README.md +20 -0
  153. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/audio.d.ts +15 -0
  154. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/audio.js +10 -0
  155. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/decode-mp3.d.ts +16 -0
  156. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/decode-mp3.js +793 -0
  157. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/meta.js +143 -0
  158. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/package.json +60 -0
  159. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/LICENSE +21 -0
  160. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/README.md +58 -0
  161. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/audio.d.ts +15 -0
  162. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/audio.js +9 -0
  163. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/decode-mp4.d.ts +21 -0
  164. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/decode-mp4.js +455 -0
  165. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/package.json +74 -0
  166. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/LICENSE +31 -0
  167. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/LICENSE.libmpcdec +31 -0
  168. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/README.md +60 -0
  169. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/audio.d.ts +15 -0
  170. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/audio.js +9 -0
  171. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/decode-mpc.d.ts +20 -0
  172. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/decode-mpc.js +158 -0
  173. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/package.json +64 -0
  174. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/src/mpc.wasm.js +0 -0
  175. package/node_modules/audio-decode/node_modules/@audio/decode-opus/LICENSE +25 -0
  176. package/node_modules/audio-decode/node_modules/@audio/decode-opus/LICENSE.libopus +44 -0
  177. package/node_modules/audio-decode/node_modules/@audio/decode-opus/README.md +32 -0
  178. package/node_modules/audio-decode/node_modules/@audio/decode-opus/audio.d.ts +15 -0
  179. package/node_modules/audio-decode/node_modules/@audio/decode-opus/audio.js +10 -0
  180. package/node_modules/audio-decode/node_modules/@audio/decode-opus/core.d.ts +33 -0
  181. package/node_modules/audio-decode/node_modules/@audio/decode-opus/core.js +147 -0
  182. package/node_modules/audio-decode/node_modules/@audio/decode-opus/decode-opus.d.ts +18 -0
  183. package/node_modules/audio-decode/node_modules/@audio/decode-opus/decode-opus.js +1 -0
  184. package/node_modules/audio-decode/node_modules/@audio/decode-opus/meta.js +103 -0
  185. package/node_modules/audio-decode/node_modules/@audio/decode-opus/package.json +68 -0
  186. package/node_modules/audio-decode/node_modules/@audio/decode-opus/src/decode-opus.js +2 -0
  187. package/node_modules/audio-decode/node_modules/@audio/decode-opus/src/opus.wasm.js +0 -0
  188. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/LICENSE +25 -0
  189. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/README.md +19 -0
  190. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/audio.d.ts +15 -0
  191. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/audio.js +10 -0
  192. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/decode-qoa.d.ts +16 -0
  193. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/decode-qoa.js +275 -0
  194. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/package.json +56 -0
  195. package/node_modules/audio-decode/node_modules/@audio/decode-tta/LICENSE +21 -0
  196. package/node_modules/audio-decode/node_modules/@audio/decode-tta/LICENSE.ttadec +39 -0
  197. package/node_modules/audio-decode/node_modules/@audio/decode-tta/README.md +58 -0
  198. package/node_modules/audio-decode/node_modules/@audio/decode-tta/audio.d.ts +15 -0
  199. package/node_modules/audio-decode/node_modules/@audio/decode-tta/audio.js +9 -0
  200. package/node_modules/audio-decode/node_modules/@audio/decode-tta/decode-tta.d.ts +17 -0
  201. package/node_modules/audio-decode/node_modules/@audio/decode-tta/decode-tta.js +302 -0
  202. package/node_modules/audio-decode/node_modules/@audio/decode-tta/package.json +58 -0
  203. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/LICENSE +25 -0
  204. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/README.md +33 -0
  205. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/audio.d.ts +15 -0
  206. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/audio.js +10 -0
  207. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/decode-vorbis.d.ts +18 -0
  208. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/decode-vorbis.js +2984 -0
  209. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/meta.js +102 -0
  210. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/package.json +60 -0
  211. package/node_modules/audio-decode/node_modules/@audio/decode-wav/LICENSE +21 -0
  212. package/node_modules/audio-decode/node_modules/@audio/decode-wav/README.md +23 -0
  213. package/node_modules/audio-decode/node_modules/@audio/decode-wav/audio.d.ts +15 -0
  214. package/node_modules/audio-decode/node_modules/@audio/decode-wav/audio.js +10 -0
  215. package/node_modules/audio-decode/node_modules/@audio/decode-wav/decode-wav.d.ts +8 -0
  216. package/node_modules/audio-decode/node_modules/@audio/decode-wav/decode-wav.js +256 -0
  217. package/node_modules/audio-decode/node_modules/@audio/decode-wav/meta.js +114 -0
  218. package/node_modules/audio-decode/node_modules/@audio/decode-wav/package.json +52 -0
  219. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/LICENSE +29 -0
  220. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/LICENSE.wavpack +25 -0
  221. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/README.md +41 -0
  222. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/audio.d.ts +15 -0
  223. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/audio.js +9 -0
  224. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/decode-wavpack.d.ts +18 -0
  225. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/decode-wavpack.js +140 -0
  226. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/package.json +62 -0
  227. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/src/wavpack.wasm.js +0 -0
  228. package/node_modules/audio-decode/node_modules/@audio/decode-webm/LICENSE +21 -0
  229. package/node_modules/audio-decode/node_modules/@audio/decode-webm/LICENSE.libopus +44 -0
  230. package/node_modules/audio-decode/node_modules/@audio/decode-webm/README.md +59 -0
  231. package/node_modules/audio-decode/node_modules/@audio/decode-webm/audio.d.ts +15 -0
  232. package/node_modules/audio-decode/node_modules/@audio/decode-webm/audio.js +10 -0
  233. package/node_modules/audio-decode/node_modules/@audio/decode-webm/decode-webm.d.ts +18 -0
  234. package/node_modules/audio-decode/node_modules/@audio/decode-webm/decode-webm.js +141 -0
  235. package/node_modules/audio-decode/node_modules/@audio/decode-webm/package.json +76 -0
  236. package/node_modules/audio-decode/node_modules/@audio/decode-webm/src/opus.wasm.js +0 -0
  237. package/node_modules/audio-decode/node_modules/@audio/decode-wma/LICENSE +12 -0
  238. package/node_modules/audio-decode/node_modules/@audio/decode-wma/README.md +74 -0
  239. package/node_modules/audio-decode/node_modules/@audio/decode-wma/audio.d.ts +15 -0
  240. package/node_modules/audio-decode/node_modules/@audio/decode-wma/audio.js +10 -0
  241. package/node_modules/audio-decode/node_modules/@audio/decode-wma/decode-wma.d.ts +33 -0
  242. package/node_modules/audio-decode/node_modules/@audio/decode-wma/decode-wma.js +516 -0
  243. package/node_modules/audio-decode/node_modules/@audio/decode-wma/package.json +57 -0
  244. package/node_modules/audio-decode/node_modules/@audio/decode-wma/src/wma.wasm.js +0 -0
  245. package/node_modules/audio-decode/package.json +37 -39
  246. package/node_modules/audio-decode/stream.d.ts +2 -0
  247. package/node_modules/audio-decode/stream.js +2 -0
  248. package/node_modules/baileys/lib/Utils/messages-media.js +1 -1
  249. package/node_modules/baileys/node_modules/file-type/package.json +1 -1
  250. package/node_modules/baileys/node_modules/file-type/readme.md +2 -0
  251. package/node_modules/baileys/node_modules/file-type/source/detectors/zip.js +9 -4
  252. package/node_modules/baileys/package.json +1 -1
  253. package/node_modules/typebox/build/compile/code.mjs +1 -2
  254. package/node_modules/typebox/build/compile/validator.mjs +5 -1
  255. package/node_modules/typebox/build/format/iri.mjs +16 -9
  256. package/node_modules/typebox/build/guard/emit.mjs +2 -2
  257. package/node_modules/typebox/build/guard/guard.d.mts +7 -5
  258. package/node_modules/typebox/build/guard/guard.mjs +14 -9
  259. package/node_modules/typebox/build/guard/index.mjs +6 -0
  260. package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
  261. package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
  262. package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
  263. package/node_modules/typebox/build/schema/build.mjs +2 -3
  264. package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
  265. package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
  266. package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
  267. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
  268. package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
  269. package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
  270. package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
  271. package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
  272. package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
  273. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
  274. package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
  275. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
  276. package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
  277. package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
  278. package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
  279. package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
  280. package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
  281. package/node_modules/typebox/build/schema/parse.mjs +3 -0
  282. package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
  283. package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
  284. package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
  285. package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
  286. package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
  287. package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
  288. package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
  289. package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
  290. package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
  291. package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
  292. package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
  293. package/node_modules/typebox/package.json +1 -1
  294. package/node_modules/typebox/readme.md +3 -1
  295. package/package.json +6 -6
  296. package/dist/.setup/doctor-BPb-SjdE.mjs +0 -65
  297. package/dist/.setup/group-config-path-BGyzT9Lg.mjs +0 -54
  298. package/dist/.setup/normalize-DdsROMMa.mjs +0 -2
  299. package/dist/.setup/rolldown-runtime-D7D4PA-g.mjs +0 -13
  300. package/dist/.setup/runtime-group-policy-DeSRFXEV.mjs +0 -11
  301. package/dist/.setup/setup-plugin-api-2wUapweU.mjs +0 -3
  302. package/dist/.setup/text-runtime-CHl0iPYe.mjs +0 -4
  303. package/node_modules/audio-decode/.eslintrc.json +0 -43
  304. package/node_modules/audio-decode/.github/workflows/test.js.yml +0 -31
  305. package/node_modules/audio-decode/.travis.yml +0 -13
  306. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/README.md +0 -293
  307. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/dist/opus-ml-decoder.min.js +0 -11646
  308. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/dist/opus-ml-decoder.min.js.map +0 -1
  309. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/index.js +0 -8
  310. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/package.json +0 -58
  311. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/EmscriptenWasm.js +0 -0
  312. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/OpusMLDecoder.js +0 -253
  313. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/OpusMLDecoderWebWorker.js +0 -17
  314. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/types.d.ts +0 -77
  315. package/node_modules/audio-decode/node_modules/audio-buffer/.eslintrc.json +0 -44
  316. package/node_modules/audio-decode/node_modules/audio-buffer/.github/workflows/node.js.yml +0 -31
  317. package/node_modules/audio-decode/node_modules/audio-buffer/.travis.yml +0 -7
  318. package/node_modules/audio-decode/node_modules/audio-buffer/index.js +0 -76
  319. package/node_modules/audio-decode/node_modules/audio-buffer/package.json +0 -37
  320. package/node_modules/audio-decode/node_modules/audio-buffer/readme.md +0 -56
  321. package/node_modules/audio-decode/node_modules/node-wav/README.md +0 -35
  322. package/node_modules/audio-decode/node_modules/node-wav/file.wav +0 -0
  323. package/node_modules/audio-decode/node_modules/node-wav/index.js +0 -291
  324. package/node_modules/audio-decode/node_modules/node-wav/package.json +0 -29
  325. package/node_modules/audio-decode/node_modules/node-wav/tests/file1.wav +0 -0
  326. package/node_modules/audio-decode/node_modules/node-wav/tests/test.js +0 -66
  327. package/node_modules/audio-decode/node_modules/node-wav/x.js +0 -12
  328. package/node_modules/audio-decode/node_modules/node-wav/x.json +0 -86702
  329. package/node_modules/audio-decode/node_modules/node-wav/x.js~ +0 -13
  330. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/README.md +0 -320
  331. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.min.js +0 -232
  332. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.min.js.map +0 -1
  333. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.opus-ml.min.js +0 -0
  334. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.opus-ml.min.js.map +0 -1
  335. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/index.js +0 -8
  336. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/package.json +0 -74
  337. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/src/OggOpusDecoder.js +0 -226
  338. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/src/OggOpusDecoderWebWorker.js +0 -17
  339. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/types.d.ts +0 -37
  340. package/node_modules/audio-decode/node_modules/opus-decoder/README.md +0 -265
  341. package/node_modules/audio-decode/node_modules/opus-decoder/dist/opus-decoder.min.js +0 -232
  342. package/node_modules/audio-decode/node_modules/opus-decoder/dist/opus-decoder.min.js.map +0 -1
  343. package/node_modules/audio-decode/node_modules/opus-decoder/index.js +0 -8
  344. package/node_modules/audio-decode/node_modules/opus-decoder/package.json +0 -56
  345. package/node_modules/audio-decode/node_modules/opus-decoder/src/EmscriptenWasm.js +0 -0
  346. package/node_modules/audio-decode/node_modules/opus-decoder/src/OpusDecoder.js +0 -239
  347. package/node_modules/audio-decode/node_modules/opus-decoder/src/OpusDecoderWebWorker.js +0 -17
  348. package/node_modules/audio-decode/node_modules/opus-decoder/types.d.ts +0 -74
  349. package/node_modules/audio-decode/readme.md +0 -49
  350. package/node_modules/audio-decode/tea.yaml +0 -6
  351. package/node_modules/audio-decode/test-case.js +0 -11
  352. package/node_modules/audio-decode/test.html +0 -15
  353. package/node_modules/audio-decode/test.js +0 -107
  354. /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
@@ -1,20 +1,19 @@
1
- import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-D_NGDjCx.mjs";
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-C6jDmcL9.mjs";
3
- import { i as getWhatsAppRuntime, r as getWhatsAppChannelRuntime } from "./runtime-BLlToOi6.mjs";
1
+ import { n as __reExport, t as __exportAll } from "./rolldown-runtime-BBjsoOtd.mjs";
2
+ import { a as resolveWhatsAppAccount, s as resolveWhatsAppMediaMaxBytes } from "./accounts-CtRPAQCL.mjs";
3
+ 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-BGdvf5cC.mjs";
4
+ import { i as getWhatsAppRuntime } from "./runtime-BLlToOi6.mjs";
4
5
  import { r as getWhatsAppConnectionController } from "./connection-controller-runtime-context-hgLJoRc8.mjs";
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-RBjx3pg_.mjs";
6
- import { t as normalizeE164 } from "./text-runtime-CHl0iPYe.mjs";
7
- import { a as cacheInboundMessageMeta, i as buildQuotedMessageOptions, n as resolveWhatsAppGroupSessionRoute, o as lookupInboundMessageMeta, r as resolveWhatsAppLegacyGroupSessionKey } from "./group-session-key-D22hYMdE.mjs";
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-Dh8a3cba.mjs";
9
- import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-BGyzT9Lg.mjs";
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-CCVSFufF.mjs";
11
- import { n as getStatusCode, t as formatError } from "./session-errors-JuazczrA.mjs";
12
- import { t as BufferJSON } from "./session.runtime-DcJuO42v.mjs";
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-B4DOt2RJ.mjs";
14
- import { t as resolveWhatsAppRuntimeGroupPolicy } from "./runtime-group-policy-DeSRFXEV.mjs";
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-C60mU7j7.mjs";
16
- import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-BnXw-UZI.mjs";
17
- import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-D3Zq9Gbn.mjs";
6
+ 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-DmiqXIXO.mjs";
7
+ import { a as cacheInboundMessageMeta, i as buildQuotedMessageOptions, n as resolveWhatsAppGroupSessionRoute, o as lookupInboundMessageMeta, r as resolveWhatsAppLegacyGroupSessionKey } from "./group-session-key-2-mja4OF.mjs";
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-BBonwKks.mjs";
9
+ import { n as resolveWhatsAppGroupsConfigPath } from "./group-config-path-DZr3ucUO.mjs";
10
+ import { a as DEFAULT_RECONNECT_POLICY, c as resolveHeartbeatSeconds, f as createWhatsAppSocketOperationTimeoutAdapter, g as withWhatsAppSocketOperationTimeout, h as resolveWhatsAppSocketTiming, i as waitForWaConnection, l as resolveReconnectPolicy, m as resolveWhatsAppSocketOperationTimeoutMs, o as computeBackoff, p as isWhatsAppSocketOperationTimeoutError, r as createWaSocket, s as newConnectionId, u as sleepWithAbort } from "./socket-close-CT__V2fz.mjs";
11
+ import { n as getStatusCode, t as formatError } from "./session-errors-B8UcAnZN.mjs";
12
+ import { t as BufferJSON } from "./session.runtime-st1konFI.mjs";
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-H4AkQJjT.mjs";
14
+ import { n as WHATSAPP_WATCHDOG_TIMEOUT_ERROR, r as WhatsAppConnectionController } from "./connection-controller-CHo1oRJA.mjs";
15
+ import { n as maybeResolveWhatsAppApprovalReaction } from "./approval-reactions-DiOFvb1s.mjs";
16
+ import { t as maybeResolveWhatsAppQuestionReaction } from "./question-reactions-CPyyi5AY.mjs";
18
17
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
19
18
  import { createAckReactionHandle, createStatusReactionController, logAckFailure, removeAckReactionHandleAfterReply, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
20
19
  import { bindIngressLifecycleToReplyOptions, createChannelIngressMonitor, createChannelMessageReplyPipeline, createMessageReceiptFromOutboundResults, listMessageReceiptPlatformIds, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
@@ -28,7 +27,7 @@ import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runt
28
27
  import { buildChannelInboundEventContext, createChannelPartialDeliveryError, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundEnvelope as formatInboundEnvelope$1, formatInboundMediaUnavailableText, formatLocationText, formatMediaPlaceholderText, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, readAgentRunTerminalOutcome, resolveGroupThreadConfig, resolveInboundSessionEnvelopeContext, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, runGroupThread, shouldDebounceTextInbound, toInboundMediaFactsWithMetadata, toLocationContext } from "openclaw/plugin-sdk/channel-inbound";
29
28
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
30
29
  import { isReasoningReplyPayload, resolveSendableOutboundReplyParts, resolveTextChunksWithFallback, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
31
- import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
30
+ import { normalizeE164, normalizeE164 as normalizeE164$1, normalizeE164 as normalizeE164$2, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
32
31
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
33
32
  import { DisconnectReason, downloadMediaMessage, isHostedLidUser, isHostedPnUser, isJidGroup, isJidGroup as isJidGroup$1, jidDecode, jidEncode, jidNormalizedUser, normalizeMessageContent as normalizeMessageContent$1 } from "baileys";
34
33
  import { DEFAULT_ACCOUNT_ID, DEFAULT_MAIN_KEY, buildAgentMainSessionKey, buildAgentSessionKey, buildGroupHistoryKey, deriveLastRoutePolicy, normalizeAccountId, resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
@@ -36,13 +35,15 @@ import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurat
36
35
  import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
37
36
  import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
38
37
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
38
+ import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
39
39
  import { createHash } from "node:crypto";
40
- import { resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
40
+ import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
41
41
  import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
42
42
  import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
43
43
  import { drainPendingDeliveries } from "openclaw/plugin-sdk/delivery-queue-runtime";
44
44
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
45
45
  import { getSessionEntry, patchSessionEntry, resolveGroupSessionKey, resolveStorePath, resolveStorePath as resolveStorePath$1, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
46
+ import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
46
47
  import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
47
48
  import { fanInChannelIngressLifecycles } from "openclaw/plugin-sdk/channel-ingress-runtime";
48
49
  import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
@@ -50,7 +51,6 @@ import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-ru
50
51
  import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
51
52
  import { getRuntimeConfig as getRuntimeConfig$1 } from "openclaw/plugin-sdk/runtime-config-snapshot";
52
53
  import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
53
- import { buildMentionRegexes, implicitMentionKindWhen, normalizeMentionText, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-mention-gating";
54
54
  import { channelReadyPatch, channelStoppedPatch, createTransportActivityStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
55
55
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
56
56
  import { resolveAgentIdentity, resolveIdentityNamePrefix } from "openclaw/plugin-sdk/agent-runtime";
@@ -142,12 +142,6 @@ function normalizeWhatsAppIngressPhone(value) {
142
142
  if (!trimmed) return null;
143
143
  return normalizeE164(trimmed);
144
144
  }
145
- function buildResolvedWhatsAppGroupConfig(params) {
146
- return { channels: { whatsapp: {
147
- groupPolicy: params.groupPolicy,
148
- groups: params.groups
149
- } } };
150
- }
151
145
  function resolveWhatsAppInboundPolicy(params) {
152
146
  const account = resolveWhatsAppAccount({
153
147
  cfg: params.cfg,
@@ -158,15 +152,15 @@ function resolveWhatsAppInboundPolicy(params) {
158
152
  const dmAllowFrom = configuredAllowFrom.length > 0 ? configuredAllowFrom : params.selfE164 ? [params.selfE164] : [];
159
153
  const groupAllowFrom = (Array.isArray(account.groupAllowFrom) && account.groupAllowFrom.length > 0 ? account.groupAllowFrom : void 0) ?? (configuredAllowFrom.length > 0 ? configuredAllowFrom : void 0) ?? [];
160
154
  const defaultGroupPolicy = resolveDefaultGroupPolicy(params.cfg);
161
- const { groupPolicy, providerMissingFallbackApplied } = resolveWhatsAppRuntimeGroupPolicy({
155
+ const { groupPolicy, providerMissingFallbackApplied } = resolveOpenProviderRuntimeGroupPolicy({
162
156
  providerConfigPresent: params.cfg.channels?.whatsapp !== void 0,
163
157
  groupPolicy: account.groupPolicy,
164
158
  defaultGroupPolicy
165
159
  });
166
- const resolvedGroupCfg = buildResolvedWhatsAppGroupConfig({
160
+ const resolvedGroupCfg = { channels: { whatsapp: {
167
161
  groupPolicy,
168
162
  groups: account.groups
169
- });
163
+ } } };
170
164
  const isSamePhone = (value) => typeof value === "string" && typeof params.selfE164 === "string" && value === params.selfE164;
171
165
  return {
172
166
  account,
@@ -192,7 +186,7 @@ function resolveWhatsAppInboundPolicy(params) {
192
186
  };
193
187
  }
194
188
  async function resolveWhatsAppIngressAccess(params) {
195
- return await getWhatsAppChannelRuntime().inbound.ingress.resolveStable({
189
+ return await getWhatsAppRuntime().channel.inbound.ingress.resolveStable({
196
190
  channelId: "whatsapp",
197
191
  accountId: params.policy.account.accountId,
198
192
  identity: {
@@ -251,11 +245,7 @@ function rememberWhatsAppBaileysCacheEntry(cache, key, value, ttlMs) {
251
245
  expiresAt: Date.now() + ttlMs,
252
246
  value
253
247
  });
254
- while (cache.size > WHATSAPP_BAILEYS_CACHE_MAX_ENTRIES) {
255
- const oldest = cache.keys().next();
256
- if (oldest.done) break;
257
- cache.delete(oldest.value);
258
- }
248
+ pruneMapToMaxSize(cache, WHATSAPP_BAILEYS_CACHE_MAX_ENTRIES);
259
249
  }
260
250
  function readWhatsAppBaileysCacheEntry(cache, key) {
261
251
  const entry = cache.get(key);
@@ -269,117 +259,6 @@ function readWhatsAppBaileysCacheEntry(cache, key) {
269
259
  return entry.value;
270
260
  }
271
261
  //#endregion
272
- //#region extensions/whatsapp/src/inbound/durable-payload.ts
273
- var WhatsAppIngressPermanentError = class extends Error {
274
- constructor(reason, message, options) {
275
- super(message, options);
276
- this.reason = reason;
277
- this.name = "WhatsAppIngressPermanentError";
278
- }
279
- };
280
- function serializeWhatsAppDurableInboundMessage(message) {
281
- const timestamp = message.messageTimestamp;
282
- let serializedMessage = message;
283
- if (timestamp != null && typeof timestamp === "object") try {
284
- const numericTimestamp = Number(timestamp);
285
- if (Number.isFinite(numericTimestamp)) serializedMessage = {
286
- ...message,
287
- messageTimestamp: numericTimestamp
288
- };
289
- } catch {}
290
- return JSON.parse(JSON.stringify(serializedMessage, BufferJSON.replacer));
291
- }
292
- function deserializeWhatsAppDurableInboundMessage(message) {
293
- try {
294
- return JSON.parse(JSON.stringify(message), BufferJSON.reviver);
295
- } catch (error) {
296
- throw new WhatsAppIngressPermanentError("invalid-payload", "WhatsApp ingress row contains an invalid serialized message", { cause: error });
297
- }
298
- }
299
- //#endregion
300
- //#region extensions/whatsapp/src/inbound/durable-receive.ts
301
- const WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION = 1;
302
- function hashNamespacePart(value) {
303
- return createHash("sha256").update(value).digest("hex").slice(0, 24);
304
- }
305
- function createWhatsAppDurableInboundMessageId(params) {
306
- return createHash("sha256").update(`${params.remoteJid}\n${params.id}`).digest("hex");
307
- }
308
- function inspectWhatsAppIngressMessage(message) {
309
- const remoteJid = message.key?.remoteJid?.trim();
310
- const id = message.key?.id?.trim();
311
- if (!remoteJid || !id) throw new WhatsAppIngressPermanentError("missing-message-key", "WhatsApp ingress message is missing key.remoteJid or key.id");
312
- return {
313
- eventId: createWhatsAppDurableInboundMessageId({
314
- remoteJid,
315
- id
316
- }),
317
- laneKey: remoteJid
318
- };
319
- }
320
- /** Account-scoped queue shared with the pre-drain WhatsApp receive journal. */
321
- function createWhatsAppDurableInboundQueue(accountId) {
322
- return getWhatsAppRuntime().state.openChannelIngressQueue({
323
- accountId: hashNamespacePart(accountId),
324
- stateDir: getWhatsAppRuntime().state.resolveStateDir()
325
- });
326
- }
327
- function resolveWhatsAppIngressNonRetryableFailure(error) {
328
- return error instanceof WhatsAppIngressPermanentError ? {
329
- reason: error.reason,
330
- message: error.message
331
- } : null;
332
- }
333
- /** Shared monitor with per-conversation lanes and completion at reply-lane adoption. */
334
- function createWhatsAppIngressMonitor(params) {
335
- return createChannelIngressMonitor({
336
- queue: params.queue,
337
- inspect: (admission) => inspectWhatsAppIngressMessage(admission.message),
338
- payload: {
339
- version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
340
- serialize: (admission, { receivedAt }) => ({
341
- ...admission,
342
- message: serializeWhatsAppDurableInboundMessage(admission.message),
343
- receivedAt
344
- }),
345
- deserialize: (payload) => ({
346
- ...payload,
347
- message: deserializeWhatsAppDurableInboundMessage(payload.message)
348
- }),
349
- encode: ({ body }) => body,
350
- decode: (payload) => ({
351
- version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
352
- body: payload
353
- }),
354
- createClaimError: (kind) => new WhatsAppIngressPermanentError(kind === "invalid-version" ? "invalid-payload" : "event-id-mismatch", kind === "invalid-version" ? "WhatsApp ingress row has an invalid payload version" : "WhatsApp ingress row identity does not match its transport message key")
355
- },
356
- deliver: (admission, lifecycle) => params.dispatch(admission, lifecycle),
357
- pollIntervalMs: params.pollIntervalMs,
358
- retention: {
359
- completedTtlMs: 6048e5,
360
- completedMaxEntries: 5e3,
361
- failedMaxEntries: 450
362
- },
363
- drain: {
364
- deferredLaneOccupancy: "release",
365
- resolveNonRetryableFailure: resolveWhatsAppIngressNonRetryableFailure,
366
- deriveLaneKey: (record) => {
367
- try {
368
- return inspectWhatsAppIngressMessage(deserializeWhatsAppDurableInboundMessage(record.payload.message)).laneKey;
369
- } catch {
370
- return record.id;
371
- }
372
- },
373
- ...params.onLog ? { onLog: params.onLog } : {}
374
- },
375
- ...params.abortSignal ? { abortSignal: params.abortSignal } : {},
376
- admissionMode: "while-running",
377
- createStoppedError: () => /* @__PURE__ */ new Error("WhatsApp ingress monitor is stopped."),
378
- ...params.onError ? { onError: params.onError } : {},
379
- ...params.onActivityChange ? { onActivityChange: params.onActivityChange } : {}
380
- });
381
- }
382
- //#endregion
383
262
  //#region extensions/whatsapp/src/inbound/group-metadata-cache.ts
384
263
  const GROUP_META_TTL_MS = 3e5;
385
264
  const WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES = 500;
@@ -394,11 +273,7 @@ function rememberGroupMetadataCacheEntry(cache, jid, entry) {
394
273
  }
395
274
  if (cache.has(jid)) cache.delete(jid);
396
275
  cache.set(jid, entry);
397
- while (cache.size > WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES) {
398
- const oldest = cache.keys().next();
399
- if (oldest.done) break;
400
- cache.delete(oldest.value);
401
- }
276
+ pruneMapToMaxSize(cache, WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES);
402
277
  }
403
278
  function readGroupMetadataCacheEntry(cache, jid) {
404
279
  const entry = cache.get(jid);
@@ -588,6 +463,117 @@ function closeInboundMonitorSocket(sock) {
588
463
  sock.ws?.close?.();
589
464
  }
590
465
  //#endregion
466
+ //#region extensions/whatsapp/src/inbound/durable-payload.ts
467
+ var WhatsAppIngressPermanentError = class extends Error {
468
+ constructor(reason, message, options) {
469
+ super(message, options);
470
+ this.reason = reason;
471
+ this.name = "WhatsAppIngressPermanentError";
472
+ }
473
+ };
474
+ function serializeWhatsAppDurableInboundMessage(message) {
475
+ const timestamp = message.messageTimestamp;
476
+ let serializedMessage = message;
477
+ if (timestamp != null && typeof timestamp === "object") try {
478
+ const numericTimestamp = Number(timestamp);
479
+ if (Number.isFinite(numericTimestamp)) serializedMessage = {
480
+ ...message,
481
+ messageTimestamp: numericTimestamp
482
+ };
483
+ } catch {}
484
+ return JSON.parse(JSON.stringify(serializedMessage, BufferJSON.replacer));
485
+ }
486
+ function deserializeWhatsAppDurableInboundMessage(message) {
487
+ try {
488
+ return JSON.parse(JSON.stringify(message), BufferJSON.reviver);
489
+ } catch (error) {
490
+ throw new WhatsAppIngressPermanentError("invalid-payload", "WhatsApp ingress row contains an invalid serialized message", { cause: error });
491
+ }
492
+ }
493
+ //#endregion
494
+ //#region extensions/whatsapp/src/inbound/durable-receive.ts
495
+ const WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION = 1;
496
+ function hashNamespacePart(value) {
497
+ return createHash("sha256").update(value).digest("hex").slice(0, 24);
498
+ }
499
+ function createWhatsAppDurableInboundMessageId(params) {
500
+ return createHash("sha256").update(`${params.remoteJid}\n${params.id}`).digest("hex");
501
+ }
502
+ function inspectWhatsAppIngressMessage(message) {
503
+ const remoteJid = message.key?.remoteJid?.trim();
504
+ const id = message.key?.id?.trim();
505
+ if (!remoteJid || !id) throw new WhatsAppIngressPermanentError("missing-message-key", "WhatsApp ingress message is missing key.remoteJid or key.id");
506
+ return {
507
+ eventId: createWhatsAppDurableInboundMessageId({
508
+ remoteJid,
509
+ id
510
+ }),
511
+ laneKey: remoteJid
512
+ };
513
+ }
514
+ /** Account-scoped queue shared with the pre-drain WhatsApp receive journal. */
515
+ function createWhatsAppDurableInboundQueue(accountId) {
516
+ return getWhatsAppRuntime().state.openChannelIngressQueue({
517
+ accountId: hashNamespacePart(accountId),
518
+ stateDir: getWhatsAppRuntime().state.resolveStateDir()
519
+ });
520
+ }
521
+ function resolveWhatsAppIngressNonRetryableFailure(error) {
522
+ return error instanceof WhatsAppIngressPermanentError ? {
523
+ reason: error.reason,
524
+ message: error.message
525
+ } : null;
526
+ }
527
+ /** Shared monitor with per-conversation lanes and completion at reply-lane adoption. */
528
+ function createWhatsAppIngressMonitor(params) {
529
+ return createChannelIngressMonitor({
530
+ queue: params.queue,
531
+ inspect: (admission) => inspectWhatsAppIngressMessage(admission.message),
532
+ payload: {
533
+ version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
534
+ serialize: (admission, { receivedAt }) => ({
535
+ ...admission,
536
+ message: serializeWhatsAppDurableInboundMessage(admission.message),
537
+ receivedAt
538
+ }),
539
+ deserialize: (payload) => ({
540
+ ...payload,
541
+ message: deserializeWhatsAppDurableInboundMessage(payload.message)
542
+ }),
543
+ encode: ({ body }) => body,
544
+ decode: (payload) => ({
545
+ version: WHATSAPP_DURABLE_INBOUND_PAYLOAD_VERSION,
546
+ body: payload
547
+ }),
548
+ createClaimError: (kind) => new WhatsAppIngressPermanentError(kind === "invalid-version" ? "invalid-payload" : "event-id-mismatch", kind === "invalid-version" ? "WhatsApp ingress row has an invalid payload version" : "WhatsApp ingress row identity does not match its transport message key")
549
+ },
550
+ deliver: (admission, lifecycle) => params.dispatch(admission, lifecycle),
551
+ pollIntervalMs: params.pollIntervalMs,
552
+ retention: {
553
+ completedTtlMs: 6048e5,
554
+ completedMaxEntries: 5e3,
555
+ failedMaxEntries: 450
556
+ },
557
+ drain: {
558
+ deferredLaneOccupancy: "release",
559
+ resolveNonRetryableFailure: resolveWhatsAppIngressNonRetryableFailure,
560
+ deriveLaneKey: (record) => {
561
+ try {
562
+ return inspectWhatsAppIngressMessage(deserializeWhatsAppDurableInboundMessage(record.payload.message)).laneKey;
563
+ } catch {
564
+ return record.id;
565
+ }
566
+ },
567
+ ...params.onLog ? { onLog: params.onLog } : {}
568
+ },
569
+ ...params.abortSignal ? { abortSignal: params.abortSignal } : {},
570
+ admissionMode: "while-running",
571
+ createStoppedError: () => /* @__PURE__ */ new Error("WhatsApp ingress monitor is stopped."),
572
+ ...params.onError ? { onError: params.onError } : {},
573
+ ...params.onActivityChange ? { onActivityChange: params.onActivityChange } : {}
574
+ });
575
+ }
576
+ //#endregion
591
577
  //#region extensions/whatsapp/src/inbound/ingress-lifecycle.ts
592
578
  const ingressLifecycleKey = Symbol("whatsappIngressLifecycle");
593
579
  function attachWhatsAppIngressLifecycle(message, lifecycle) {
@@ -708,17 +694,15 @@ function createWhatsAppInboundMessageDebouncer(options) {
708
694
  debounceMs: options.resolveDebounceMs()
709
695
  };
710
696
  const key = buildKey(message);
711
- if (key) {
712
- message.debounceKey = key;
713
- const senderKey = resolveSenderKey(message);
714
- const pending = pendingKeys.get(key);
715
- if (pending && pending.senderKey !== senderKey) await debouncer.flushKey(key);
716
- if (message.debounceMs > 0 && shouldDebounce(message)) {
717
- message.debounceKeyTracked = true;
718
- trackKey(key, senderKey);
719
- options.onPendingWorkChanged();
720
- notifyWork();
721
- }
697
+ message.debounceKey = key;
698
+ const senderKey = resolveSenderKey(message);
699
+ const pending = pendingKeys.get(key);
700
+ if (pending && pending.senderKey !== senderKey) await debouncer.flushKey(key);
701
+ if (message.debounceMs > 0 && shouldDebounce(message)) {
702
+ message.debounceKeyTracked = true;
703
+ trackKey(key, senderKey);
704
+ options.onPendingWorkChanged();
705
+ notifyWork();
722
706
  }
723
707
  await debouncer.enqueue(message);
724
708
  };
@@ -753,11 +737,8 @@ function createWhatsAppInboundMessageDebouncer(options) {
753
737
  }
754
738
  //#endregion
755
739
  //#region extensions/whatsapp/src/inbound/media.ts
756
- function unwrapMessage(message) {
757
- return normalizeMessageContent$1(message);
758
- }
759
740
  async function downloadInboundMedia(msg, sock, maxBytes = 52428800, normalizedMessage) {
760
- const message = normalizedMessage ?? unwrapMessage(msg.message);
741
+ const message = normalizedMessage ?? normalizeMessageContent$1(msg.message);
761
742
  if (!message) return;
762
743
  const mimetype = resolveInboundMediaMimetype(message);
763
744
  const fileName = message.documentMessage?.fileName ?? void 0;
@@ -773,7 +754,7 @@ async function downloadInboundMedia(msg, sock, maxBytes = 52428800, normalizedMe
773
754
  };
774
755
  }
775
756
  async function downloadQuotedInboundMedia(msg, sock, maxBytes = 52428800) {
776
- const message = unwrapMessage(msg.message);
757
+ const message = normalizeMessageContent$1(msg.message);
777
758
  const contextInfo = extractContextInfo(message);
778
759
  if (!contextInfo?.quotedMessage) return;
779
760
  const quotedMessage = contextInfo.quotedMessage;
@@ -1180,12 +1161,9 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1180
1161
  logWhatsAppVerbose$1(options.verbose, `Failed to mark message ${id} read: ${String(err)}`);
1181
1162
  }
1182
1163
  };
1183
- const maybeLogSkippedSelfChatReadReceipt = (inbound, target) => {
1184
- if (target?.id && inbound.access.isSelfChat && options.verbose) logWhatsAppVerbose$1(options.verbose, `Self-chat mode: skipping read receipt for ${target.id}`);
1185
- };
1186
1164
  const maybeMarkNonSelfChatReadReceipt = async (inbound, target) => {
1187
1165
  if (inbound.access.isSelfChat) {
1188
- maybeLogSkippedSelfChatReadReceipt(inbound, target);
1166
+ if (target?.id) logWhatsAppVerbose$1(options.verbose, `Self-chat mode: skipping read receipt for ${target.id}`);
1189
1167
  return;
1190
1168
  }
1191
1169
  await maybeMarkInboundAsRead(target);
@@ -1261,25 +1239,27 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1261
1239
  mentions: groupMentions
1262
1240
  } : void 0;
1263
1241
  const channelStructuredContext = [
1264
- ...enriched.nativeMedia ? [{
1265
- label: "WhatsApp media",
1266
- source: "whatsapp",
1267
- type: "media",
1268
- payload: enriched.nativeMedia
1269
- }] : [],
1270
- ...enriched.contactContext ? [{
1271
- label: "WhatsApp contact",
1272
- source: "whatsapp",
1273
- type: enriched.contactContext.kind,
1274
- payload: enriched.contactContext
1275
- }] : [],
1276
- ...enriched.externalAdReplyContext ? [{
1277
- label: "WhatsApp external ad reply",
1278
- source: "whatsapp",
1279
- type: "external_ad_reply",
1280
- payload: enriched.externalAdReplyContext
1281
- }] : []
1282
- ];
1242
+ [
1243
+ "WhatsApp media",
1244
+ "media",
1245
+ enriched.nativeMedia
1246
+ ],
1247
+ [
1248
+ "WhatsApp contact",
1249
+ enriched.contactContext?.kind,
1250
+ enriched.contactContext
1251
+ ],
1252
+ [
1253
+ "WhatsApp external ad reply",
1254
+ "external_ad_reply",
1255
+ enriched.externalAdReplyContext
1256
+ ]
1257
+ ].flatMap(([label, type, payload]) => payload ? [{
1258
+ label,
1259
+ source: "whatsapp",
1260
+ type,
1261
+ payload
1262
+ }] : []);
1283
1263
  const inboundMessage = {
1284
1264
  admission: inbound.access.admission,
1285
1265
  event: {
@@ -1342,25 +1322,29 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1342
1322
  }
1343
1323
  await messageDebouncer.enqueue(inboundMessage);
1344
1324
  };
1325
+ const resolveApprovalReaction = (msg) => maybeResolveWhatsAppApprovalReaction({
1326
+ cfg: options.loadConfig?.() ?? options.cfg,
1327
+ accountId: options.accountId,
1328
+ msg,
1329
+ selfJid: self.jid,
1330
+ selfLid: self.lid,
1331
+ resolveInboundJid,
1332
+ resolveReactionTargetJids,
1333
+ logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
1334
+ });
1345
1335
  const processDurableInboundMessage = async (admission, lifecycle) => {
1346
1336
  const { message: msg, ...context } = admission;
1347
1337
  rememberBaileysMessage(msg.key?.remoteJid, msg.key?.id, msg.message);
1348
1338
  const remoteJid = msg.key?.remoteJid;
1349
1339
  const id = msg.key?.id;
1350
- const durableId = remoteJid && id ? createHash("sha256").update(`${remoteJid}\n${id}`).digest("hex") : void 0;
1340
+ const durableId = remoteJid && id ? createWhatsAppDurableInboundMessageId({
1341
+ remoteJid,
1342
+ id
1343
+ }) : void 0;
1351
1344
  const preparation = durableId ? preparedInboundByDurableId.get(durableId) : void 0;
1352
1345
  if (durableId) preparedInboundByDurableId.delete(durableId);
1353
1346
  if (context.skipRecentOutboundEcho === true) return "completed";
1354
- if (await maybeResolveWhatsAppApprovalReaction({
1355
- cfg: options.loadConfig?.() ?? options.cfg,
1356
- accountId: options.accountId,
1357
- msg,
1358
- selfJid: self.jid,
1359
- selfLid: self.lid,
1360
- resolveInboundJid,
1361
- resolveReactionTargetJids,
1362
- logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
1363
- })) return "completed";
1347
+ if (await resolveApprovalReaction(msg)) return "completed";
1364
1348
  const prepared = await preparation;
1365
1349
  if (prepared === null) return "completed";
1366
1350
  const inbound = prepared ?? await normalizeInboundMessage(msg);
@@ -1415,16 +1399,7 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1415
1399
  const receiveOrder = nextReceiveOrder++;
1416
1400
  let approvalReactionResolved = false;
1417
1401
  try {
1418
- approvalReactionResolved = await maybeResolveWhatsAppApprovalReaction({
1419
- cfg: options.loadConfig?.() ?? options.cfg,
1420
- accountId: options.accountId,
1421
- msg,
1422
- selfJid: self.jid,
1423
- selfLid: self.lid,
1424
- resolveInboundJid,
1425
- resolveReactionTargetJids,
1426
- logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
1427
- });
1402
+ approvalReactionResolved = await resolveApprovalReaction(msg);
1428
1403
  } catch (error) {
1429
1404
  inboundLogger.warn({ error: formatError(error) }, "whatsapp approval reaction resolution failed; admitting reaction for durable replay");
1430
1405
  }
@@ -1434,16 +1409,19 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1434
1409
  const skipRecentOutboundEcho = shouldSkipRecentOutboundEcho(msg);
1435
1410
  const remoteJid = msg.key?.remoteJid;
1436
1411
  const id = msg.key?.id;
1437
- const durableId = remoteJid && id ? createHash("sha256").update(`${remoteJid}\n${id}`).digest("hex") : void 0;
1412
+ const durableId = remoteJid && id ? createWhatsAppDurableInboundMessageId({
1413
+ remoteJid,
1414
+ id
1415
+ }) : void 0;
1438
1416
  let resolvePrepared;
1439
1417
  if (durableId && !preparedInboundByDurableId.has(durableId)) {
1440
1418
  if (preparedInboundByDurableId.size >= 1e3) {
1441
1419
  const oldest = preparedInboundByDurableId.keys().next().value;
1442
1420
  if (oldest !== void 0) preparedInboundByDurableId.delete(oldest);
1443
1421
  }
1444
- preparedInboundByDurableId.set(durableId, new Promise((resolve) => {
1445
- resolvePrepared = resolve;
1446
- }));
1422
+ const prepared = createDeferred();
1423
+ resolvePrepared = prepared.resolve;
1424
+ preparedInboundByDurableId.set(durableId, prepared.promise);
1447
1425
  }
1448
1426
  const finishPreparation = (inbound, keepForDrain = false) => {
1449
1427
  resolvePrepared?.(inbound);
@@ -1493,22 +1471,19 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1493
1471
  publishPendingWorkState();
1494
1472
  });
1495
1473
  };
1496
- const drainDebouncedInboundMessages = async () => {
1497
- await messageDebouncer.drain();
1498
- };
1499
1474
  const drainInboundBeforeSocketClose = async () => {
1500
1475
  for (;;) {
1501
- await drainDebouncedInboundMessages();
1476
+ await messageDebouncer.drain();
1502
1477
  if (pendingMessageHandlers.size === 0) break;
1503
1478
  const handlers = Array.from(pendingMessageHandlers);
1504
1479
  await Promise.race([Promise.allSettled(handlers), messageDebouncer.waitForWorkOrIdle(handlers, pendingMessageHandlers.size === 0)]);
1505
1480
  if (pendingMessageHandlers.size === 0 && !messageDebouncer.hasPendingWork()) break;
1506
1481
  }
1507
- await drainDebouncedInboundMessages();
1482
+ await messageDebouncer.drain();
1508
1483
  for (;;) {
1509
1484
  await durableInboundMonitor.waitForIdle();
1510
1485
  if (!messageDebouncer.hasPendingWork()) break;
1511
- await drainDebouncedInboundMessages();
1486
+ await messageDebouncer.drain();
1512
1487
  }
1513
1488
  await durableInboundMonitor.stop();
1514
1489
  };
@@ -1574,16 +1549,7 @@ async function createWhatsAppAttachedSocketSession(options) {
1574
1549
  const disconnectRetryPolicy = options.disconnectRetryPolicy ?? DEFAULT_RECONNECT_POLICY;
1575
1550
  const sendRetryMaxAttempts = disconnectRetryPolicy.maxAttempts > 0 ? disconnectRetryPolicy.maxAttempts : DEFAULT_RECONNECT_POLICY.maxAttempts;
1576
1551
  const sendOperationTimeoutMs = resolveWhatsAppSocketOperationTimeoutMs(options.socketTiming.defaultQueryTimeoutMs);
1577
- let onCloseResolve = null;
1578
- const onClose = new Promise((resolve) => {
1579
- onCloseResolve = resolve;
1580
- });
1581
- const resolveClose = (reason) => {
1582
- if (!onCloseResolve) return;
1583
- const resolver = onCloseResolve;
1584
- onCloseResolve = null;
1585
- resolver(reason);
1586
- };
1552
+ const { promise: onClose, resolve: resolveClose } = createDeferred();
1587
1553
  const presence = options.selfChatMode ? "unavailable" : "available";
1588
1554
  try {
1589
1555
  await createWhatsAppSocketOperationTimeoutAdapter(sock, sendOperationTimeoutMs).sendPresenceUpdate(presence);
@@ -1618,14 +1584,14 @@ async function createWhatsAppAttachedSocketSession(options) {
1618
1584
  rememberWhatsAppBaileysCacheEntry(options.recentMessageKeys, `${remoteJid}:${messageId}`, message, BAILEYS_MESSAGE_TTL_MS);
1619
1585
  };
1620
1586
  const rememberOutboundMessage = (remoteJid, result) => {
1621
- const messageId = typeof result === "object" && result && "key" in result ? result.key?.id ?? "" : "";
1587
+ const messageId = result?.key?.id;
1622
1588
  if (!messageId) return;
1623
1589
  rememberRecentOutboundMessage({
1624
1590
  accountId: options.accountId,
1625
1591
  remoteJid,
1626
1592
  messageId
1627
1593
  });
1628
- const message = typeof result === "object" && result && "message" in result ? result.message : void 0;
1594
+ const message = result?.message;
1629
1595
  rememberBaileysMessage(remoteJid, messageId, message);
1630
1596
  cacheInboundMessageMeta(options.accountId, remoteJid, messageId, {
1631
1597
  fromMe: true,
@@ -1715,7 +1681,7 @@ async function createWhatsAppAttachedSocketSession(options) {
1715
1681
  }
1716
1682
  };
1717
1683
  const socketOperations = {
1718
- sendMessage: (jid, content, sendOptions) => sendTrackedMessage(jid, content, sendOptions),
1684
+ sendMessage: sendTrackedMessage,
1719
1685
  sendPresenceUpdate: async (presenceLocal, jid) => {
1720
1686
  const currentSock = getCurrentSock();
1721
1687
  if (!currentSock) throw new Error(RECONNECT_IN_PROGRESS_ERROR);
@@ -1846,7 +1812,7 @@ async function attachWebInboxToSocket(options) {
1846
1812
  appendReplyWindow: options.appendReplyWindow,
1847
1813
  shouldDebounce: options.shouldDebounce,
1848
1814
  onPendingWorkChanged: options.onPendingWorkChanged,
1849
- durableInboundQueue: options.durableInboundQueue ?? createWhatsAppDurableInboundQueue(options.accountId)
1815
+ durableInboundQueue: options.durableInboundQueue
1850
1816
  });
1851
1817
  const sendApi = createWebSendApi({
1852
1818
  sock: socketSession.socketOperations,
@@ -1913,64 +1879,6 @@ const whatsappInboundLog = whatsappLog.child("inbound");
1913
1879
  const whatsappOutboundLog = whatsappLog.child("outbound");
1914
1880
  const whatsappHeartbeatLog = whatsappLog.child("heartbeat");
1915
1881
  //#endregion
1916
- //#region extensions/whatsapp/src/auto-reply/mentions.ts
1917
- function buildMentionConfig(cfg, agentId, options) {
1918
- return {
1919
- mentionRegexes: buildMentionRegexes(cfg, agentId, options),
1920
- allowFrom: cfg.channels?.whatsapp?.allowFrom
1921
- };
1922
- }
1923
- function resolveMentionTargets(msg, authDir) {
1924
- return {
1925
- normalizedMentions: getMentionIdentities(msg, authDir),
1926
- self: getSelfIdentity(msg, authDir)
1927
- };
1928
- }
1929
- function isBotMentionedFromTargets(msg, mentionCfg, targets) {
1930
- const clean = (text) => normalizeMentionText(text);
1931
- const explicitSelfChatOverride = typeof mentionCfg.isSelfChat === "boolean";
1932
- const isGroupConversation = requireWhatsAppInboundAdmission(msg).conversation.kind === "group";
1933
- const isSelfChat = explicitSelfChatOverride ? Boolean(mentionCfg.isSelfChat) : isSelfChatMode(targets.self.e164, mentionCfg.allowFrom) && !isGroupConversation;
1934
- const hasMentions = targets.normalizedMentions.length > 0;
1935
- const hasNativeMentionsOutsideSelfChat = hasMentions && !isSelfChat;
1936
- if (hasNativeMentionsOutsideSelfChat) {
1937
- for (const mention of targets.normalizedMentions) if (identitiesOverlap(targets.self, mention)) return true;
1938
- } else if (hasMentions && isSelfChat) {}
1939
- const bodyClean = clean(msg.payload.body);
1940
- if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) return true;
1941
- if (hasNativeMentionsOutsideSelfChat) return false;
1942
- if (targets.self.e164) {
1943
- const selfDigits = targets.self.e164.replace(/\D/g, "");
1944
- if (selfDigits) {
1945
- if (bodyClean.replace(/[^\d]/g, "").includes(selfDigits)) return true;
1946
- const bodyNoSpace = msg.payload.body.replace(/[\s-]/g, "");
1947
- if (new RegExp(`\\+?${selfDigits}`, "i").test(bodyNoSpace)) return true;
1948
- }
1949
- }
1950
- return false;
1951
- }
1952
- function debugMention(msg, mentionCfg, authDir) {
1953
- const mentionTargets = resolveMentionTargets(msg, authDir);
1954
- return {
1955
- wasMentioned: isBotMentionedFromTargets(msg, mentionCfg, mentionTargets),
1956
- details: {
1957
- from: requireWhatsAppInboundAdmission(msg).conversation.id,
1958
- body: msg.payload.body,
1959
- bodyClean: normalizeMentionText(msg.payload.body),
1960
- mentionedJids: msg.group?.mentions?.jids ?? null,
1961
- normalizedMentionedJids: mentionTargets.normalizedMentions.length ? mentionTargets.normalizedMentions.map((identity) => getComparableIdentityValues(identity)) : null,
1962
- selfJid: msg.platform.self?.jid ?? msg.platform.selfJid ?? null,
1963
- selfLid: msg.platform.self?.lid ?? msg.platform.selfLid ?? null,
1964
- selfE164: msg.platform.self?.e164 ?? msg.platform.selfE164 ?? null,
1965
- resolvedSelf: mentionTargets.self
1966
- }
1967
- };
1968
- }
1969
- function resolveOwnerList(mentionCfg, selfE164) {
1970
- const allowFrom = mentionCfg.allowFrom;
1971
- return (Array.isArray(allowFrom) && allowFrom.length > 0 ? allowFrom : selfE164 ? [selfE164] : []).filter((entry) => Boolean(entry && entry !== "*")).map((entry) => normalizeE164(entry)).filter((entry) => Boolean(entry));
1972
- }
1973
- //#endregion
1974
1882
  //#region extensions/whatsapp/src/auto-reply/monitor-state.ts
1975
1883
  const LIFECYCLE_BY_HEALTH_STATE = {
1976
1884
  starting: "starting",
@@ -2112,6 +2020,76 @@ function formatWhatsAppInboundListeningLog(account) {
2112
2020
  return `Listening for WhatsApp inbound messages (DM + ${explicitGroupCount} configured ${explicitGroupCount === 1 ? "group" : "groups"}).`;
2113
2021
  }
2114
2022
  //#endregion
2023
+ //#region src/channels/mention-gating.ts
2024
+ function resolveBotThreadMentionPolicy(params) {
2025
+ if (!params.isBotOwnedThread || params.requireMentionInBotThreads === void 0) return {
2026
+ requireMention: params.requireMention,
2027
+ implicitMentionKinds: params.implicitMentionKinds
2028
+ };
2029
+ return {
2030
+ requireMention: params.requireMentionInBotThreads,
2031
+ implicitMentionKinds: params.requireMentionInBotThreads ? params.implicitMentionKinds?.filter((kind) => kind === "native") : params.implicitMentionKinds
2032
+ };
2033
+ }
2034
+ //#endregion
2035
+ //#region \0openclaw:bundled-sdk:openclaw/plugin-sdk/channel-mention-gating
2036
+ var channel_mention_gating_exports = /* @__PURE__ */ __exportAll({ resolveBotThreadMentionPolicy: () => resolveBotThreadMentionPolicy });
2037
+ import * as import_openclaw_plugin_sdk_channel_mention_gating from "openclaw/plugin-sdk/channel-mention-gating";
2038
+ __reExport(channel_mention_gating_exports, import_openclaw_plugin_sdk_channel_mention_gating);
2039
+ //#endregion
2040
+ //#region extensions/whatsapp/src/auto-reply/mentions.ts
2041
+ function buildMentionConfig(cfg, agentId, options) {
2042
+ return {
2043
+ mentionRegexes: (0, channel_mention_gating_exports.buildMentionRegexes)(cfg, agentId, options),
2044
+ allowFrom: cfg.channels?.whatsapp?.allowFrom
2045
+ };
2046
+ }
2047
+ function isBotMentionedFromTargets(msg, mentionCfg, targets) {
2048
+ const explicitSelfChatOverride = typeof mentionCfg.isSelfChat === "boolean";
2049
+ const isGroupConversation = requireWhatsAppInboundAdmission(msg).conversation.kind === "group";
2050
+ const isSelfChat = explicitSelfChatOverride ? Boolean(mentionCfg.isSelfChat) : isSelfChatMode(targets.self.e164, mentionCfg.allowFrom) && !isGroupConversation;
2051
+ const hasNativeMentionsOutsideSelfChat = targets.normalizedMentions.length > 0 && !isSelfChat;
2052
+ if (hasNativeMentionsOutsideSelfChat) {
2053
+ for (const mention of targets.normalizedMentions) if (identitiesOverlap(targets.self, mention)) return true;
2054
+ }
2055
+ const bodyClean = (0, channel_mention_gating_exports.normalizeMentionText)(msg.payload.body);
2056
+ if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) return true;
2057
+ if (hasNativeMentionsOutsideSelfChat) return false;
2058
+ if (targets.self.e164) {
2059
+ const selfDigits = targets.self.e164.replace(/\D/g, "");
2060
+ if (selfDigits) {
2061
+ if (bodyClean.replace(/[^\d]/g, "").includes(selfDigits)) return true;
2062
+ const bodyNoSpace = msg.payload.body.replace(/[\s-]/g, "");
2063
+ if (new RegExp(`\\+?${selfDigits}`, "i").test(bodyNoSpace)) return true;
2064
+ }
2065
+ }
2066
+ return false;
2067
+ }
2068
+ function debugMention(msg, mentionCfg, authDir) {
2069
+ const mentionTargets = {
2070
+ normalizedMentions: getMentionIdentities(msg, authDir),
2071
+ self: getSelfIdentity(msg, authDir)
2072
+ };
2073
+ return {
2074
+ wasMentioned: isBotMentionedFromTargets(msg, mentionCfg, mentionTargets),
2075
+ details: {
2076
+ from: requireWhatsAppInboundAdmission(msg).conversation.id,
2077
+ body: msg.payload.body,
2078
+ bodyClean: (0, channel_mention_gating_exports.normalizeMentionText)(msg.payload.body),
2079
+ mentionedJids: msg.group?.mentions?.jids ?? null,
2080
+ normalizedMentionedJids: mentionTargets.normalizedMentions.length ? mentionTargets.normalizedMentions.map((identity) => getComparableIdentityValues(identity)) : null,
2081
+ selfJid: msg.platform.self?.jid ?? msg.platform.selfJid ?? null,
2082
+ selfLid: msg.platform.self?.lid ?? msg.platform.selfLid ?? null,
2083
+ selfE164: msg.platform.self?.e164 ?? msg.platform.selfE164 ?? null,
2084
+ resolvedSelf: mentionTargets.self
2085
+ }
2086
+ };
2087
+ }
2088
+ function resolveOwnerList(mentionCfg, selfE164) {
2089
+ const allowFrom = mentionCfg.allowFrom;
2090
+ return (Array.isArray(allowFrom) && allowFrom.length > 0 ? allowFrom : selfE164 ? [selfE164] : []).filter((entry) => Boolean(entry && entry !== "*")).map((entry) => normalizeE164(entry)).filter((entry) => Boolean(entry));
2091
+ }
2092
+ //#endregion
2115
2093
  //#region extensions/whatsapp/src/auto-reply/monitor/ack-emoji.ts
2116
2094
  const DEFAULT_WHATSAPP_ACK_REACTION = "👀";
2117
2095
  function resolveWhatsAppAckEmoji(params) {
@@ -2228,13 +2206,7 @@ async function resolveWhatsAppReactionEligibility(params) {
2228
2206
  //#endregion
2229
2207
  //#region extensions/whatsapp/src/auto-reply/monitor/ack-reaction.ts
2230
2208
  async function maybeSendAckReaction(params) {
2231
- const eligibility = await resolveWhatsAppReactionEligibility({
2232
- cfg: params.cfg,
2233
- msg: params.msg,
2234
- agentId: params.agentId,
2235
- sessionKey: params.sessionKey,
2236
- verbose: params.verbose
2237
- });
2209
+ const eligibility = await resolveWhatsAppReactionEligibility(params);
2238
2210
  if (eligibility.status === "disabled") return null;
2239
2211
  const { chatId, messageId, emoji, reactionOptions } = eligibility;
2240
2212
  params.info({
@@ -2257,6 +2229,33 @@ async function maybeSendAckReaction(params) {
2257
2229
  });
2258
2230
  }
2259
2231
  //#endregion
2232
+ //#region extensions/whatsapp/src/auto-reply/monitor/audio-preflight.ts
2233
+ function hasWhatsAppAudioBody(msg) {
2234
+ return (msg.payload.media?.kind === "audio" || msg.payload.media?.type?.startsWith("audio/") === true) && !msg.payload.body.trim();
2235
+ }
2236
+ async function transcribeWhatsAppAudioMessage(cfg, msg, accountId) {
2237
+ const { transcribeFirstAudio } = await import("./audio-preflight.runtime-C_glQhZY.mjs");
2238
+ const media = msg.payload.media;
2239
+ const conversationId = msg.admission.conversation.id;
2240
+ return await transcribeFirstAudio({
2241
+ ctx: {
2242
+ media: [{
2243
+ path: media?.path,
2244
+ contentType: media?.type,
2245
+ kind: media?.kind ?? void 0
2246
+ }],
2247
+ From: conversationId,
2248
+ To: msg.platform.recipientJid,
2249
+ Provider: "whatsapp",
2250
+ Surface: "whatsapp",
2251
+ OriginatingChannel: "whatsapp",
2252
+ OriginatingTo: conversationId,
2253
+ AccountId: accountId
2254
+ },
2255
+ cfg
2256
+ });
2257
+ }
2258
+ //#endregion
2260
2259
  //#region extensions/whatsapp/src/auto-reply/monitor/broadcast.ts
2261
2260
  function buildBroadcastRouteKeys(params) {
2262
2261
  const admission = requireWhatsAppInboundAdmission(params.msg);
@@ -2388,11 +2387,8 @@ const groupDropWarned = createDedupeCache({
2388
2387
  ttlMs: 0,
2389
2388
  maxSize: 100
2390
2389
  });
2391
- function shouldWarnForGroupDrop(warnKey) {
2392
- return !groupDropWarned.check(warnKey);
2393
- }
2394
2390
  function isOwnerSender(baseMentionConfig, msg, authDir) {
2395
- const sender = normalizeE164(getSenderIdentity(msg, authDir).e164 ?? "");
2391
+ const sender = normalizeE164$2(getSenderIdentity(msg, authDir).e164 ?? "");
2396
2392
  if (!sender) return false;
2397
2393
  return resolveOwnerList(baseMentionConfig, getSelfIdentity(msg, authDir).e164 ?? void 0).includes(sender);
2398
2394
  }
@@ -2441,11 +2437,12 @@ async function applyGroupGating(params) {
2441
2437
  const conversationGroupPolicy = inboundPolicy.resolveConversationGroupPolicy(conversationId);
2442
2438
  if (conversationGroupPolicy.allowlistEnabled && !conversationGroupPolicy.allowed) {
2443
2439
  const accountId = inboundPolicy.account.accountId;
2444
- if (shouldWarnForGroupDrop(JSON.stringify([
2440
+ const warnKey = JSON.stringify([
2445
2441
  accountId,
2446
2442
  conversationId,
2447
2443
  "group registry"
2448
- ]))) {
2444
+ ]);
2445
+ if (!groupDropWarned.check(warnKey)) {
2449
2446
  const groupsPath = resolveWhatsAppGroupsConfigPath({
2450
2447
  cfg: params.cfg,
2451
2448
  accountId
@@ -2472,17 +2469,11 @@ async function applyGroupGating(params) {
2472
2469
  }),
2473
2470
  allowFrom: inboundPolicy.configuredAllowFrom
2474
2471
  };
2475
- const mentionMsg = params.mentionText !== void 0 ? {
2476
- ...params.msg,
2477
- payload: {
2478
- ...params.msg.payload,
2479
- body: params.mentionText
2480
- }
2481
- } : {
2472
+ const mentionMsg = {
2482
2473
  ...params.msg,
2483
2474
  payload: {
2484
2475
  ...params.msg.payload,
2485
- body: params.msg.payload.commandBody ?? params.msg.payload.body
2476
+ body: params.mentionText ?? params.msg.payload.commandBody ?? params.msg.payload.body
2486
2477
  }
2487
2478
  };
2488
2479
  const commandBody = stripMentionsForCommand(mentionMsg.payload.body, mentionConfig.mentionRegexes, self.e164);
@@ -2506,8 +2497,8 @@ async function applyGroupGating(params) {
2506
2497
  }) !== "always";
2507
2498
  const replyContext = getReplyContext(params.msg, params.authDir);
2508
2499
  const implicitReplyToSelf = params.selfChatMode === true && identitiesOverlap(self, sender);
2509
- const implicitMentionKinds = implicitMentionKindWhen("quoted_bot", !implicitReplyToSelf && identitiesOverlap(self, replyContext?.sender));
2510
- const mentionDecision = resolveInboundMentionDecision({
2500
+ const implicitMentionKinds = (0, channel_mention_gating_exports.implicitMentionKindWhen)("quoted_bot", !implicitReplyToSelf && identitiesOverlap(self, replyContext?.sender));
2501
+ const mentionDecision = (0, channel_mention_gating_exports.resolveInboundMentionDecision)({
2511
2502
  facts: {
2512
2503
  canDetectMention: true,
2513
2504
  wasMentioned,
@@ -2535,7 +2526,7 @@ async function applyGroupGating(params) {
2535
2526
  };
2536
2527
  }
2537
2528
  const accountId = inboundPolicy.account.accountId;
2538
- if (shouldWarnForGroupDrop(JSON.stringify([
2529
+ if (!groupDropWarned.check(JSON.stringify([
2539
2530
  accountId,
2540
2531
  conversationId,
2541
2532
  "no mention"
@@ -2692,15 +2683,12 @@ function isLikelyWhatsAppCryptoError(reason) {
2692
2683
  } catch {
2693
2684
  return Object.prototype.toString.call(value);
2694
2685
  }
2695
- if (typeof value === "number") return String(value);
2696
- if (typeof value === "boolean") return String(value);
2697
- if (typeof value === "bigint") return String(value);
2686
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
2698
2687
  if (typeof value === "symbol") return value.description ?? value.toString();
2699
2688
  if (typeof value === "function") return value.name ? `[function ${value.name}]` : "[function]";
2700
2689
  return Object.prototype.toString.call(value);
2701
2690
  };
2702
- const raw = reason instanceof Error ? `${reason.message}\n${reason.stack ?? ""}` : formatReason(reason);
2703
- const haystack = normalizeLowercaseStringOrEmpty(raw);
2691
+ const haystack = normalizeLowercaseStringOrEmpty(formatReason(reason));
2704
2692
  if (!(haystack.includes("unsupported state or unable to authenticate data") || haystack.includes("bad mac"))) return false;
2705
2693
  return haystack.includes("baileys") || haystack.includes("noise-handler") || haystack.includes("aesdecryptgcm");
2706
2694
  }
@@ -2930,7 +2918,6 @@ async function deliverWebReplyInActivityScope(params) {
2930
2918
  return;
2931
2919
  }
2932
2920
  const fallbackText = [caption ?? "", "⚠️ Media failed."].filter(Boolean).join("\n");
2933
- if (!fallbackText) return;
2934
2921
  whatsappOutboundLog.warn(`Media skipped; sent text-only to ${conversationId}`);
2935
2922
  rememberSendResult(await sendWithRetry(() => transport.reply(fallbackText, getQuote()), "media:fallback-text", "text"));
2936
2923
  }
@@ -3065,9 +3052,6 @@ function normalizeErrForLog(err) {
3065
3052
  };
3066
3053
  return err;
3067
3054
  }
3068
- function whatsAppReplyDeliveryVisibility(visibleReplySent) {
3069
- return { visibleReplySent };
3070
- }
3071
3055
  function createWhatsAppChannelDeliveryResult(params) {
3072
3056
  const messageIds = listMessageReceiptPlatformIds(params.delivery.receipt);
3073
3057
  return {
@@ -3154,18 +3138,13 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
3154
3138
  };
3155
3139
  return {
3156
3140
  defer(pending) {
3157
- let resolveFinalization;
3158
- let rejectFinalization;
3159
- const finalization = new Promise((resolve, reject) => {
3160
- resolveFinalization = resolve;
3161
- rejectFinalization = reject;
3162
- });
3141
+ const finalization = createDeferred();
3163
3142
  pendingMediaOnlyPayloads.push({
3164
3143
  ...pending,
3165
- resolveFinalization,
3166
- rejectFinalization
3144
+ resolveFinalization: finalization.resolve,
3145
+ rejectFinalization: finalization.reject
3167
3146
  });
3168
- return finalization;
3147
+ return finalization.promise;
3169
3148
  },
3170
3149
  flushNonDuplicateMedia: (mediaUrls) => flushWhere((pending) => !hasWhatsAppMediaUrlOverlap(pending.mediaUrls, mediaUrls)),
3171
3150
  supersedeMedia(mediaUrl) {
@@ -3185,7 +3164,7 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
3185
3164
  };
3186
3165
  }
3187
3166
  if (pending.mediaUrls.size === 0) {
3188
- pending.resolveFinalization(whatsAppReplyDeliveryVisibility(false));
3167
+ pending.resolveFinalization({ visibleReplySent: false });
3189
3168
  continue;
3190
3169
  }
3191
3170
  retained.push(pending);
@@ -3376,7 +3355,7 @@ function createWhatsAppReplyPlan(params) {
3376
3355
  };
3377
3356
  const deliverNormalizedPayload = async (normalizedDeliveryPayload, info, options) => {
3378
3357
  const reply = resolveSendableOutboundReplyParts(normalizedDeliveryPayload);
3379
- if (!reply.hasMedia && !reply.text.trim()) return whatsAppReplyDeliveryVisibility(false);
3358
+ if (!reply.hasMedia && !reply.text.trim()) return { visibleReplySent: false };
3380
3359
  let delivery;
3381
3360
  try {
3382
3361
  delivery = await params.deliverReply({
@@ -3437,7 +3416,7 @@ function createWhatsAppReplyPlan(params) {
3437
3416
  onSettled: async () => {
3438
3417
  const flushResult = await mediaOnlyCoalescer.flushAll();
3439
3418
  logWhatsAppMediaOnlyFlushResult(flushResult);
3440
- return whatsAppReplyDeliveryVisibility(didSendReply || flushResult.delivered > 0);
3419
+ return { visibleReplySent: didSendReply || flushResult.delivered > 0 };
3441
3420
  },
3442
3421
  onReplyStart: params.transport.sendComposing
3443
3422
  },
@@ -3485,7 +3464,7 @@ function createWhatsAppReplyPlan(params) {
3485
3464
  deliver: async (payload, info) => {
3486
3465
  const normalizedDeliveryPayload = payload;
3487
3466
  const reply = resolveSendableOutboundReplyParts(normalizedDeliveryPayload);
3488
- if (!reply.hasMedia && !reply.text.trim()) return whatsAppReplyDeliveryVisibility(false);
3467
+ if (!reply.hasMedia && !reply.text.trim()) return { visibleReplySent: false };
3489
3468
  if (!reply.hasMedia) return await deliverNormalizedPayload(normalizedDeliveryPayload, info, { recordDelivery: false });
3490
3469
  const mediaUrls = new Set(normalizedDeliveryPayload.mediaUrls);
3491
3470
  if (shouldDeferWhatsAppMediaOnlyPayload({
@@ -3546,20 +3525,11 @@ function createWhatsAppReplyPlan(params) {
3546
3525
  finalize: (dispatchResult) => {
3547
3526
  const didQueueVisibleReply = hasVisibleInboundReplyDispatch(dispatchResult);
3548
3527
  const didDeliverVisibleReply = didSendReply || dispatchResult.observedReplyDelivery === true;
3549
- if (!didQueueVisibleReply && !didDeliverVisibleReply) {
3550
- if (statusReactionController) finalizeWhatsAppStatusReaction({
3551
- controller: statusReactionController,
3552
- outcome: "error"
3553
- });
3554
- if (params.shouldClearGroupHistory) params.groupHistories.set(params.groupHistoryKey, []);
3555
- logVerbose$1("Skipping auto-reply: silent token or no text/media returned from resolver");
3556
- return false;
3557
- }
3558
3528
  if (statusReactionController) finalizeWhatsAppStatusReaction({
3559
3529
  controller: statusReactionController,
3560
3530
  outcome: readAgentRunTerminalOutcome(dispatchResult) === "failed" || !didDeliverVisibleReply ? "error" : "done"
3561
3531
  });
3562
- if (params.shouldClearGroupHistory) params.groupHistories.set(params.groupHistoryKey, []);
3532
+ if (!didQueueVisibleReply && !didDeliverVisibleReply) logVerbose$1("Skipping auto-reply: silent token or no text/media returned from resolver");
3563
3533
  return didDeliverVisibleReply;
3564
3534
  }
3565
3535
  };
@@ -3575,15 +3545,12 @@ function formatReplyTarget(replyTo) {
3575
3545
  if (!replyTo?.body) return null;
3576
3546
  return `[Replying to ${replyTo.sender?.label ?? replyTo.sender?.e164 ?? "unknown sender"}${replyTo.id ? ` id:${replyTo.id}` : ""}]\n${replyTo.body}\n[/Replying]`;
3577
3547
  }
3578
- function formatReplyContext(msg) {
3579
- return formatReplyTarget(getReplyContext(msg));
3580
- }
3581
3548
  function buildInboundLine(params) {
3582
3549
  const { msg, previousTimestamp, envelope } = params;
3583
3550
  const admission = requireWhatsAppInboundAdmission(msg);
3584
3551
  const conversationId = admission.conversation.id;
3585
3552
  const conversationKind = admission.conversation.kind;
3586
- const replyContext = params.visibleReplyTo === void 0 ? formatReplyContext(msg) : formatReplyTarget(params.visibleReplyTo);
3553
+ const replyContext = formatReplyTarget(params.visibleReplyTo === void 0 ? getReplyContext(msg) : params.visibleReplyTo);
3587
3554
  const baseLine = `${msg.payload.body}${replyContext ? `\n\n${replyContext}` : ""}`;
3588
3555
  const sender = getSenderIdentity(msg);
3589
3556
  return formatInboundEnvelope({
@@ -3607,13 +3574,7 @@ function buildInboundLine(params) {
3607
3574
  async function createWhatsAppStatusReactionController(params) {
3608
3575
  if (!params.msg.event.id) return null;
3609
3576
  if ((params.cfg.messages?.statusReactions)?.enabled !== true) return null;
3610
- const eligibility = await resolveWhatsAppReactionEligibility({
3611
- cfg: params.cfg,
3612
- msg: params.msg,
3613
- agentId: params.agentId,
3614
- sessionKey: params.sessionKey,
3615
- verbose: params.verbose
3616
- });
3577
+ const eligibility = await resolveWhatsAppReactionEligibility(params);
3617
3578
  if (eligibility.status === "disabled") return null;
3618
3579
  const { chatId, messageId, emoji: initialEmoji, reactionOptions } = eligibility;
3619
3580
  return createStatusReactionController({
@@ -3640,39 +3601,37 @@ const WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS = {
3640
3601
  maxQueue: 128,
3641
3602
  timeoutMs: 2e3
3642
3603
  };
3643
- function readWhatsAppMessageReceivedHookOptIn(value) {
3644
- if (!value || typeof value !== "object") return;
3645
- const pluginHooks = value.pluginHooks;
3646
- if (pluginHooks?.messageReceived === void 0) return;
3647
- return pluginHooks.messageReceived;
3604
+ function mapWhatsAppIngressToTurnAdmission(ingress) {
3605
+ const reason = ingress.reasonCode;
3606
+ if (ingress.admission === "dispatch") return {
3607
+ kind: "dispatch",
3608
+ reason
3609
+ };
3610
+ if (ingress.admission === "observe") return {
3611
+ kind: "observeOnly",
3612
+ reason
3613
+ };
3614
+ if (ingress.admission === "skip") return {
3615
+ kind: "handled",
3616
+ reason
3617
+ };
3618
+ return {
3619
+ kind: "drop",
3620
+ reason,
3621
+ recordHistory: false
3622
+ };
3648
3623
  }
3649
3624
  function shouldEmitWhatsAppMessageReceivedHooks(params) {
3650
3625
  const channelConfig = params.cfg.channels?.whatsapp;
3651
- return readWhatsAppMessageReceivedHookOptIn(params.accountId && channelConfig?.accounts ? channelConfig.accounts[params.accountId] : void 0) ?? readWhatsAppMessageReceivedHookOptIn(channelConfig) ?? false;
3626
+ return (params.accountId ? channelConfig?.accounts?.[params.accountId] : void 0)?.pluginHooks?.messageReceived ?? channelConfig?.pluginHooks?.messageReceived ?? false;
3652
3627
  }
3653
- function emitWhatsAppMessageReceivedHooks(params) {
3628
+ function emitWhatsAppMessageReceivedHooksIfEnabled(params) {
3629
+ if (!shouldEmitWhatsAppMessageReceivedHooks(params)) return;
3654
3630
  const canonical = deriveInboundMessageHookContext(params.ctx);
3655
3631
  const hookRunner = getGlobalHookRunner();
3656
3632
  if (hookRunner?.hasHooks("message_received")) fireAndForgetBoundedHook(() => hookRunner.runMessageReceived(toPluginMessageReceivedEvent(canonical), toPluginMessageContext(canonical)), "whatsapp: message_received plugin hook failed", void 0, WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS);
3657
3633
  fireAndForgetBoundedHook(() => triggerInternalHook(createInternalHookEvent("message", "received", params.sessionKey, toInternalMessageReceivedContext(canonical))), "whatsapp: message_received internal hook failed", void 0, WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS);
3658
3634
  }
3659
- function emitWhatsAppMessageReceivedHooksIfEnabled(params) {
3660
- if (!shouldEmitWhatsAppMessageReceivedHooks({
3661
- cfg: params.cfg,
3662
- accountId: params.accountId
3663
- })) return;
3664
- emitWhatsAppMessageReceivedHooks({
3665
- ctx: params.ctx,
3666
- sessionKey: params.sessionKey
3667
- });
3668
- }
3669
- function resolvePinnedMainDmRecipient(params) {
3670
- return resolvePinnedMainDmOwnerFromAllowlist({
3671
- dmScope: params.cfg.session?.dmScope,
3672
- allowFrom: params.allowFrom,
3673
- normalizeEntry: (entry) => normalizeE164(entry)
3674
- });
3675
- }
3676
3635
  async function processMessage(params) {
3677
3636
  const admission = requireWhatsAppInboundAdmission(params.msg);
3678
3637
  if (admission.ingress.admission !== "dispatch" && admission.ingress.admission !== "observe") return false;
@@ -3696,26 +3655,8 @@ async function processMessage(params) {
3696
3655
  sessionKey: params.route.sessionKey
3697
3656
  });
3698
3657
  let audioTranscript = params.preflightAudioTranscript ?? void 0;
3699
- const hasAudioBody = (params.msg.payload.media?.kind === "audio" || params.msg.payload.media?.type?.startsWith("audio/") === true) && !params.msg.payload.body.trim();
3700
- if (params.preflightAudioTranscript === void 0 && hasAudioBody && params.msg.payload.media?.path) try {
3701
- const { transcribeFirstAudio } = await import("./audio-preflight.runtime-C_glQhZY.mjs");
3702
- audioTranscript = await transcribeFirstAudio({
3703
- ctx: {
3704
- media: [{
3705
- path: params.msg.payload.media.path,
3706
- contentType: params.msg.payload.media.type,
3707
- kind: params.msg.payload.media.kind ?? void 0
3708
- }],
3709
- From: conversationId,
3710
- To: params.msg.platform.recipientJid,
3711
- Provider: "whatsapp",
3712
- Surface: "whatsapp",
3713
- OriginatingChannel: "whatsapp",
3714
- OriginatingTo: conversationId,
3715
- AccountId: params.route.accountId
3716
- },
3717
- cfg: params.cfg
3718
- });
3658
+ if (params.preflightAudioTranscript === void 0 && hasWhatsAppAudioBody(params.msg) && params.msg.payload.media?.path) try {
3659
+ audioTranscript = await transcribeWhatsAppAudioMessage(params.cfg, params.msg, params.route.accountId);
3719
3660
  } catch {
3720
3661
  if (shouldLogVerbose$1()) logVerbose$1("whatsapp: audio preflight transcription failed, keeping structured audio");
3721
3662
  }
@@ -3739,7 +3680,6 @@ async function processMessage(params) {
3739
3680
  envelope: envelopeOptions,
3740
3681
  visibleReplyTo
3741
3682
  });
3742
- let shouldClearGroupHistory = false;
3743
3683
  const visibleGroupHistory = conversationKind === "group" ? resolveVisibleWhatsAppGroupHistory({
3744
3684
  history: params.groupHistory ?? params.groupHistories.get(params.groupHistoryKey) ?? [],
3745
3685
  mode: contextVisibilityMode,
@@ -3773,7 +3713,6 @@ async function processMessage(params) {
3773
3713
  }
3774
3714
  });
3775
3715
  }
3776
- shouldClearGroupHistory = !(params.suppressGroupHistoryClear ?? false);
3777
3716
  }
3778
3717
  const statusReactionController = params.statusReactionController ?? (params.cfg.messages?.statusReactions?.enabled === true && !params.ackAlreadySent ? await createWhatsAppStatusReactionController({
3779
3718
  cfg: params.cfg,
@@ -3803,16 +3742,15 @@ async function processMessage(params) {
3803
3742
  mediaType: params.msg.payload.media?.type ?? null,
3804
3743
  mediaPath: params.msg.payload.media?.path ?? null
3805
3744
  }, "inbound web message");
3806
- const fromDisplay = conversationId;
3807
3745
  const kindLabel = params.msg.payload.media?.type ? `, ${params.msg.payload.media?.type}` : "";
3808
- whatsappInboundLog.info(`Inbound message ${fromDisplay} -> ${params.msg.platform.recipientJid} (${conversationKind}${kindLabel}, ${combinedBody.length} chars)`);
3746
+ whatsappInboundLog.info(`Inbound message ${conversationId} -> ${params.msg.platform.recipientJid} (${conversationKind}${kindLabel}, ${combinedBody.length} chars)`);
3809
3747
  if (shouldLogVerbose$1()) whatsappInboundLog.debug(`Inbound body: ${elide(combinedBody, 400)}`);
3810
3748
  const sender = getSenderIdentity(params.msg);
3811
3749
  const commandBody = params.msg.payload.commandBody ?? params.msg.payload.body;
3812
3750
  const dmRouteTarget = resolveWhatsAppDmRouteTarget({
3813
3751
  msg: params.msg,
3814
3752
  senderE164: sender.e164 ?? void 0,
3815
- normalizeE164
3753
+ normalizeE164: normalizeE164$1
3816
3754
  });
3817
3755
  const shouldCheckCommandAuth = shouldComputeCommandAuthorized(commandBody, params.cfg);
3818
3756
  const isTextCommand = isControlCommandMessage(commandBody, params.cfg);
@@ -3870,6 +3808,8 @@ async function processMessage(params) {
3870
3808
  visibleReplyTo: visibleReplyTo ?? void 0,
3871
3809
  suppressMessageReceivedHooks: true
3872
3810
  });
3811
+ const turnAdmission = mapWhatsAppIngressToTurnAdmission(inbound.channelIngress?.ingress ?? admission.ingress);
3812
+ const shouldClearGroupHistory = conversationKind === "group" && params.suppressGroupHistoryClear !== true;
3873
3813
  const transport = buildWhatsAppInboundTransportContext(params.msg);
3874
3814
  const ingressLifecycle = resolveWhatsAppIngressLifecycle(params.msg);
3875
3815
  const turnAdoptionLifecycle = ingressLifecycle ? bindIngressLifecycleToReplyOptions(ingressLifecycle).turnAdoptionLifecycle : void 0;
@@ -3879,9 +3819,10 @@ async function processMessage(params) {
3879
3819
  accountId: params.route.accountId,
3880
3820
  sessionKey: params.route.sessionKey
3881
3821
  });
3882
- const pinnedMainDmRecipient = resolvePinnedMainDmRecipient({
3883
- cfg: params.cfg,
3884
- allowFrom: inboundPolicy.configuredAllowFrom
3822
+ const pinnedMainDmRecipient = resolvePinnedMainDmOwnerFromAllowlist({
3823
+ dmScope: params.cfg.session?.dmScope,
3824
+ allowFrom: inboundPolicy.configuredAllowFrom,
3825
+ normalizeEntry: normalizeE164$1
3885
3826
  });
3886
3827
  updateWhatsAppMainLastRoute({
3887
3828
  backgroundTasks: params.backgroundTasks,
@@ -3901,25 +3842,9 @@ async function processMessage(params) {
3901
3842
  ...turnAdoptionLifecycle ? { turnAdoptionLifecycle } : {},
3902
3843
  adapter: {
3903
3844
  ingest: () => turnInput,
3904
- preflight: () => {
3905
- const reason = admission.ingress.reasonCode;
3906
- if (admission.ingress.admission === "dispatch") return { admission: {
3907
- kind: "dispatch",
3908
- reason
3909
- } };
3910
- if (admission.ingress.admission === "observe") return { admission: {
3911
- kind: "observeOnly",
3912
- reason
3913
- } };
3914
- if (admission.ingress.admission === "skip") return { admission: {
3915
- kind: "handled",
3916
- reason
3917
- } };
3918
- return { admission: {
3919
- kind: "drop",
3920
- reason,
3921
- recordHistory: false
3922
- } };
3845
+ preflight: () => ({ admission: turnAdmission }),
3846
+ onFinalize: (result) => {
3847
+ if (result.dispatched && turnAdmission.kind === "dispatch" && shouldClearGroupHistory) params.groupHistories.set(params.groupHistoryKey, []);
3923
3848
  },
3924
3849
  resolveTurn: () => {
3925
3850
  const { finalize, ...replyPlan } = createWhatsAppReplyPlan({
@@ -3927,8 +3852,6 @@ async function processMessage(params) {
3927
3852
  connectionId: params.connectionId,
3928
3853
  context: ctxPayload,
3929
3854
  deliverReply: deliverWebReply,
3930
- groupHistories: params.groupHistories,
3931
- groupHistoryKey: params.groupHistoryKey,
3932
3855
  maxMediaBytes: params.maxMediaBytes,
3933
3856
  maxMediaTextChunkLimit: params.maxMediaTextChunkLimit,
3934
3857
  inbound,
@@ -3940,7 +3863,6 @@ async function processMessage(params) {
3940
3863
  },
3941
3864
  replyResolver: params.replyResolver,
3942
3865
  route: params.route,
3943
- shouldClearGroupHistory,
3944
3866
  statusReactionController,
3945
3867
  transport,
3946
3868
  turnAdoptionLifecycle
@@ -3991,7 +3913,6 @@ async function processMessage(params) {
3991
3913
  //#endregion
3992
3914
  //#region extensions/whatsapp/src/auto-reply/monitor/on-message.ts
3993
3915
  function createWebOnMessageHandler(params) {
3994
- const hasExplicitlyPassedInboundAccess = (msg) => msg.admission.ingress.decision === "allow";
3995
3916
  const withDirectSenderPeer = (msg, peerId) => {
3996
3917
  if (requireWhatsAppInboundAdmission(msg).conversation.kind === "group" || msg.platform.sender?.e164 || msg.platform.senderE164 || !peerId.startsWith("+")) return msg;
3997
3918
  const normalized = normalizeE164(peerId);
@@ -4009,7 +3930,7 @@ function createWebOnMessageHandler(params) {
4009
3930
  };
4010
3931
  };
4011
3932
  const processForRoute = async (cfg, msg, route, groupHistoryKey, opts) => {
4012
- const processParams = {
3933
+ return processMessage({
4013
3934
  cfg,
4014
3935
  msg,
4015
3936
  route,
@@ -4024,18 +3945,12 @@ function createWebOnMessageHandler(params) {
4024
3945
  replyLogger: params.replyLogger,
4025
3946
  backgroundTasks: params.backgroundTasks,
4026
3947
  buildContext: params.buildContext,
4027
- dispatchReplyFromConfig: params.dispatchReplyFromConfig
4028
- };
4029
- if (opts?.groupHistory !== void 0) processParams.groupHistory = opts.groupHistory;
4030
- if (opts?.suppressGroupHistoryClear !== void 0) processParams.suppressGroupHistoryClear = opts.suppressGroupHistoryClear;
4031
- if (opts?.preflightAudioTranscript !== void 0) processParams.preflightAudioTranscript = opts.preflightAudioTranscript;
4032
- if (opts?.ackAlreadySent === true) processParams.ackAlreadySent = true;
4033
- if (opts?.ackReaction !== void 0) processParams.ackReaction = opts.ackReaction;
4034
- if (opts?.statusReactionController !== void 0) processParams.statusReactionController = opts.statusReactionController;
4035
- return processMessage(processParams);
3948
+ dispatchReplyFromConfig: params.dispatchReplyFromConfig,
3949
+ ...opts
3950
+ });
4036
3951
  };
4037
3952
  return async (normalizedMsg) => {
4038
- const canRunDirectEarlyAudioPreflight = hasExplicitlyPassedInboundAccess(normalizedMsg);
3953
+ const canRunDirectEarlyAudioPreflight = normalizedMsg.admission.ingress.decision === "allow";
4039
3954
  const cfg = params.loadConfig?.() ?? params.cfg;
4040
3955
  const peerId = resolvePeerId(normalizedMsg);
4041
3956
  const msg = withDirectSenderPeer(normalizedMsg, peerId);
@@ -4075,7 +3990,7 @@ function createWebOnMessageHandler(params) {
4075
3990
  peerId
4076
3991
  }) : route.sessionKey;
4077
3992
  let preflightAudioTranscript;
4078
- const hasAudioBody = (msg.payload.media?.kind === "audio" || msg.payload.media?.type?.startsWith("audio/") === true) && !msg.payload.body.trim();
3993
+ const hasAudioBody = hasWhatsAppAudioBody(msg);
4079
3994
  const canRunEarlyAudioPreflight = conversationKind === "group" || canRunDirectEarlyAudioPreflight;
4080
3995
  let ackAlreadySent = false;
4081
3996
  let ackReaction = null;
@@ -4098,24 +4013,7 @@ function createWebOnMessageHandler(params) {
4098
4013
  const transcribeAudioOnce = async () => {
4099
4014
  if (preflightAudioTranscript !== void 0 || !hasAudioBody || !msg.payload.media?.path) return;
4100
4015
  try {
4101
- const { transcribeFirstAudio } = await import("./audio-preflight.runtime-C_glQhZY.mjs");
4102
- preflightAudioTranscript = await transcribeFirstAudio({
4103
- ctx: {
4104
- media: [{
4105
- path: msg.payload.media.path,
4106
- contentType: msg.payload.media.type,
4107
- kind: msg.payload.media.kind ?? void 0
4108
- }],
4109
- From: conversationId,
4110
- To: msg.platform.recipientJid,
4111
- Provider: "whatsapp",
4112
- Surface: "whatsapp",
4113
- OriginatingChannel: "whatsapp",
4114
- OriginatingTo: conversationId,
4115
- AccountId: route.accountId
4116
- },
4117
- cfg
4118
- }) ?? null;
4016
+ preflightAudioTranscript = await transcribeWhatsAppAudioMessage(cfg, msg, route.accountId) ?? null;
4119
4017
  } catch {
4120
4018
  preflightAudioTranscript = null;
4121
4019
  }
@@ -4175,10 +4073,9 @@ function createWebOnMessageHandler(params) {
4175
4073
  warn: params.replyLogger.warn.bind(params.replyLogger)
4176
4074
  });
4177
4075
  recordAcceptedConfiguredGroupRoute = recordGroupRoute;
4178
- let gating = await applyGroupGating({
4076
+ const gatingParams = {
4179
4077
  cfg,
4180
4078
  msg,
4181
- deferMissingMention: hasAudioBody && Boolean(msg.payload.media?.path),
4182
4079
  groupHistoryKey,
4183
4080
  agentId: route.agentId,
4184
4081
  sessionKey: route.sessionKey,
@@ -4191,25 +4088,16 @@ function createWebOnMessageHandler(params) {
4191
4088
  groupMemberNames: params.groupMemberNames,
4192
4089
  logVerbose,
4193
4090
  replyLogger: params.replyLogger
4091
+ };
4092
+ let gating = await applyGroupGating({
4093
+ ...gatingParams,
4094
+ deferMissingMention: hasAudioBody && Boolean(msg.payload.media?.path)
4194
4095
  });
4195
4096
  if (!gating.shouldProcess && "needsMentionText" in gating && gating.needsMentionText === true) {
4196
4097
  await runAudioPreflightOnce();
4197
4098
  gating = await applyGroupGating({
4198
- cfg,
4199
- msg,
4200
- ...typeof preflightAudioTranscript === "string" ? { mentionText: preflightAudioTranscript } : {},
4201
- groupHistoryKey,
4202
- agentId: route.agentId,
4203
- sessionKey: route.sessionKey,
4204
- baseMentionConfig,
4205
- providerMentionPatterns: account.mentionPatterns,
4206
- authDir: account.authDir,
4207
- selfChatMode: account.selfChatMode,
4208
- groupHistories: params.groupHistories,
4209
- groupHistoryLimit: params.groupHistoryLimit,
4210
- groupMemberNames: params.groupMemberNames,
4211
- logVerbose,
4212
- replyLogger: params.replyLogger
4099
+ ...gatingParams,
4100
+ ...typeof preflightAudioTranscript === "string" ? { mentionText: preflightAudioTranscript } : {}
4213
4101
  });
4214
4102
  }
4215
4103
  if (!gating.shouldProcess) {
@@ -4332,7 +4220,6 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4332
4220
  const heartbeatSeconds = resolveHeartbeatSeconds(cfg, tuning.heartbeatSeconds);
4333
4221
  const reconnectPolicy = resolveReconnectPolicy(cfg, tuning.reconnect);
4334
4222
  const socketTiming = resolveWhatsAppSocketTiming(tuning.socketTiming);
4335
- const baseMentionConfig = buildMentionConfig(cfg);
4336
4223
  const groupHistoryLimit = resolvePromptHistoryLimit(account.historyLimit ?? cfg.channels?.whatsapp?.historyLimit ?? cfg.messages?.groupChat?.historyLimit);
4337
4224
  const groupHistories = /* @__PURE__ */ new Map();
4338
4225
  const groupMemberNames = /* @__PURE__ */ new Map();
@@ -4402,8 +4289,6 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4402
4289
  backgroundTasks: connectionLocal.backgroundTasks,
4403
4290
  replyResolver: activeReplyResolver,
4404
4291
  replyLogger,
4405
- baseMentionConfig,
4406
- account,
4407
4292
  buildContext: pluginChannelRuntime?.inbound.buildContext,
4408
4293
  dispatchReplyFromConfig: pluginChannelRuntime?.reply?.dispatchReplyFromConfig
4409
4294
  });
@@ -4583,38 +4468,25 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4583
4468
  });
4584
4469
  enqueueSystemEvent(`WhatsApp gateway connected${selfE164 ? ` as ${selfE164}` : ""}.`, { sessionKey: connectRoute.sessionKey });
4585
4470
  const normalizedAccountId = normalizeReconnectAccountId(account.accountId);
4586
- drainPendingDeliveries({
4587
- drainKey: `whatsapp:${normalizedAccountId}`,
4588
- logLabel: "WhatsApp reconnect drain",
4589
- cfg,
4590
- log: reconnectLogger,
4591
- selectEntry: (entry) => ({
4592
- match: entry.channel === "whatsapp" && normalizeReconnectAccountId(entry.accountId) === normalizedAccountId,
4593
- bypassBackoff: isNoListenerReconnectError(entry.lastError)
4594
- })
4595
- }).catch((err) => {
4596
- reconnectLogger.warn({
4597
- connectionId: connection.connectionId,
4598
- error: String(err)
4599
- }, "reconnect drain failed");
4600
- });
4601
- const periodicDrainInterval = setInterval(() => {
4471
+ const drainDeliveries = (mode) => {
4602
4472
  drainPendingDeliveries({
4603
4473
  drainKey: `whatsapp:${normalizedAccountId}`,
4604
- logLabel: "WhatsApp periodic drain",
4474
+ logLabel: `WhatsApp ${mode} drain`,
4605
4475
  cfg,
4606
4476
  log: reconnectLogger,
4607
4477
  selectEntry: (entry) => ({
4608
4478
  match: entry.channel === "whatsapp" && normalizeReconnectAccountId(entry.accountId) === normalizedAccountId,
4609
- bypassBackoff: false
4479
+ bypassBackoff: mode === "reconnect" && isNoListenerReconnectError(entry.lastError)
4610
4480
  })
4611
4481
  }).catch((err) => {
4612
4482
  reconnectLogger.warn({
4613
4483
  connectionId: connection.connectionId,
4614
4484
  error: String(err)
4615
- }, "periodic drain failed");
4485
+ }, `${mode} drain failed`);
4616
4486
  });
4617
- }, 3e4);
4487
+ };
4488
+ drainDeliveries("reconnect");
4489
+ const periodicDrainInterval = setInterval(() => drainDeliveries("periodic"), 3e4);
4618
4490
  const inboundPolicy = resolveWhatsAppInboundPolicy({
4619
4491
  cfg,
4620
4492
  accountId: account.accountId,