@openclaw/whatsapp 2026.9.5 → 2026.9.7

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 (359) 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/{agent-tools-login-B6MAs75N.mjs → agent-tools-login-CL5C1rA2.mjs} +5 -1
  5. package/dist/.setup/{approval-handler.runtime-C0hzmMSj.mjs → approval-handler.runtime-CjqMlPOX.mjs} +6 -26
  6. package/dist/.setup/{approval-reactions-BnXw-UZI.mjs → approval-reactions-DiOFvb1s.mjs} +8 -14
  7. package/dist/.setup/{auth-store-Dh8a3cba.mjs → auth-store-BBonwKks.mjs} +9 -33
  8. package/dist/.setup/{channel-CSclZYjU.mjs → channel-CJFE0kD_.mjs} +82 -154
  9. package/dist/.setup/{channel-react-action-1iBiEnq7.mjs → channel-react-action-2r_hjLZV.mjs} +4 -8
  10. package/dist/.setup/{channel.runtime-ddGY37w8.mjs → channel.runtime-C94goLw9.mjs} +4 -4
  11. package/dist/.setup/{channel.setup-CqUl8COe.mjs → channel.setup-CfN1UfdY.mjs} +1 -1
  12. package/dist/.setup/{connection-controller-C60mU7j7.mjs → connection-controller-CHo1oRJA.mjs} +13 -63
  13. package/dist/.setup/{creds-files-Drg3usj1.mjs → creds-files-CDATZWWM.mjs} +5 -11
  14. package/dist/.setup/{directory-config-BHPoBklt.mjs → directory-config-DUiJ5d8I.mjs} +13 -14
  15. package/dist/.setup/doctor-iMwg0Vhr.mjs +222 -0
  16. package/dist/.setup/group-config-path-DZr3ucUO.mjs +40 -0
  17. package/dist/.setup/{group-session-key-D22hYMdE.mjs → group-session-key-2-mja4OF.mjs} +3 -9
  18. package/dist/.setup/{login-2dmd1TfE.mjs → login-BFlvSh9h.mjs} +9 -11
  19. package/dist/.setup/{login-qr-CgKtO_ef.mjs → login-qr-Ayb8i25J.mjs} +29 -77
  20. package/dist/.setup/{monitor-BblvzLpX.mjs → monitor-CGpV2VNN.mjs} +391 -509
  21. package/dist/.setup/{question-reactions-D3Zq9Gbn.mjs → question-reactions-CPyyi5AY.mjs} +2 -2
  22. package/dist/.setup/rolldown-runtime-BBjsoOtd.mjs +27 -0
  23. package/dist/.setup/{send-C6jDmcL9.mjs → send-BGdvf5cC.mjs} +31 -80
  24. package/dist/.setup/{send-api-B4DOt2RJ.mjs → send-api-H4AkQJjT.mjs} +45 -109
  25. package/dist/.setup/{session-errors-JuazczrA.mjs → session-errors-B8UcAnZN.mjs} +1 -4
  26. package/dist/.setup/{session.runtime-DcJuO42v.mjs → session.runtime-st1konFI.mjs} +1 -1
  27. package/dist/.setup/{setup-finalize-BYEgU0hb.mjs → setup-finalize-DmPX4EaW.mjs} +32 -70
  28. package/dist/.setup/setup-plugin-api-vJlxKzca.mjs +3 -0
  29. package/dist/.setup/{setup-surface-Cd3wN5HD.mjs → setup-surface-43fj197P.mjs} +3 -3
  30. package/dist/.setup/{shared-C9OEtKgc.mjs → shared-DgOG5Iqr.mjs} +26 -37
  31. package/dist/.setup/{socket-close-CCVSFufF.mjs → socket-close-CT__V2fz.mjs} +80 -92
  32. package/dist/.setup/{targets-runtime-RBjx3pg_.mjs → targets-runtime-DmiqXIXO.mjs} +2 -7
  33. package/dist/action-runtime-api.js +1 -1
  34. package/dist/action-runtime.runtime.js +1 -1
  35. package/dist/agent-tools-api.js +6 -13
  36. package/dist/api.js +10 -10
  37. package/dist/auth-presence.js +1 -1
  38. package/dist/channel-plugin-api.js +1 -1
  39. package/dist/contract-api.js +2 -2
  40. package/dist/directory-contract-api.js +1 -1
  41. package/dist/doctor-contract-api.js +9 -10
  42. package/dist/light-runtime-api.js +3 -3
  43. package/dist/login-qr-runtime.js +1 -1
  44. package/dist/runtime-api.js +10 -10
  45. package/dist/setup-entry.js +1 -1
  46. package/dist/setup-plugin-api.js +1 -1
  47. package/node_modules/audio-decode/LICENSE +9 -10
  48. package/node_modules/audio-decode/README.md +16 -0
  49. package/node_modules/audio-decode/audio-decode.d.ts +2 -14
  50. package/node_modules/audio-decode/audio-decode.js +4 -92
  51. package/node_modules/audio-decode/meta.js +1 -0
  52. package/node_modules/audio-decode/node_modules/{audio-buffer → @audio/decode}/LICENSE +1 -1
  53. package/node_modules/audio-decode/node_modules/@audio/decode/audio-decode.d.ts +52 -0
  54. package/node_modules/audio-decode/node_modules/@audio/decode/audio-decode.js +242 -0
  55. package/node_modules/audio-decode/node_modules/@audio/decode/meta.js +14 -0
  56. package/node_modules/audio-decode/node_modules/@audio/decode/package.json +114 -0
  57. package/node_modules/audio-decode/node_modules/@audio/decode/readme.md +191 -0
  58. package/node_modules/audio-decode/node_modules/@audio/decode/stream.d.ts +12 -0
  59. package/node_modules/audio-decode/node_modules/@audio/decode/stream.js +1 -0
  60. package/node_modules/audio-decode/node_modules/@audio/decode/test.html +52 -0
  61. package/node_modules/audio-decode/node_modules/@audio/decode-aac/LICENSE +9 -0
  62. package/node_modules/audio-decode/node_modules/@audio/decode-aac/README.md +80 -0
  63. package/node_modules/audio-decode/node_modules/@audio/decode-aac/alac.js +326 -0
  64. package/node_modules/audio-decode/node_modules/@audio/decode-aac/audio.d.ts +15 -0
  65. package/node_modules/audio-decode/node_modules/@audio/decode-aac/audio.js +10 -0
  66. package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.d.ts +24 -0
  67. package/node_modules/audio-decode/node_modules/@audio/decode-aac/decode-aac.js +452 -0
  68. package/node_modules/audio-decode/node_modules/@audio/decode-aac/meta.js +81 -0
  69. package/node_modules/audio-decode/node_modules/@audio/decode-aac/package.json +63 -0
  70. package/node_modules/audio-decode/node_modules/@audio/decode-aac/src/aac.wasm.js +0 -0
  71. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/LICENSE +12 -0
  72. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/LICENSE.liba52 +340 -0
  73. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/README.md +41 -0
  74. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/audio.d.ts +15 -0
  75. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/audio.js +9 -0
  76. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/decode-ac3.d.ts +20 -0
  77. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/decode-ac3.js +131 -0
  78. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/package.json +64 -0
  79. package/node_modules/audio-decode/node_modules/@audio/decode-ac3/src/ac3.wasm.js +0 -0
  80. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/LICENSE +21 -0
  81. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/README.md +46 -0
  82. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/audio.d.ts +15 -0
  83. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/audio.js +10 -0
  84. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/decode-aiff.d.ts +16 -0
  85. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/decode-aiff.js +583 -0
  86. package/node_modules/audio-decode/node_modules/@audio/decode-aiff/package.json +52 -0
  87. package/node_modules/audio-decode/node_modules/@audio/decode-amr/LICENSE +191 -0
  88. package/node_modules/audio-decode/node_modules/@audio/decode-amr/README.md +65 -0
  89. package/node_modules/audio-decode/node_modules/@audio/decode-amr/audio.d.ts +15 -0
  90. package/node_modules/audio-decode/node_modules/@audio/decode-amr/audio.js +10 -0
  91. package/node_modules/audio-decode/node_modules/@audio/decode-amr/decode-amr.d.ts +16 -0
  92. package/node_modules/audio-decode/node_modules/@audio/decode-amr/decode-amr.js +150 -0
  93. package/node_modules/audio-decode/node_modules/@audio/decode-amr/package.json +58 -0
  94. package/node_modules/audio-decode/node_modules/@audio/decode-amr/src/amr.wasm.js +0 -0
  95. package/node_modules/audio-decode/node_modules/@audio/decode-avi/LICENSE +21 -0
  96. package/node_modules/audio-decode/node_modules/@audio/decode-avi/README.md +53 -0
  97. package/node_modules/audio-decode/node_modules/@audio/decode-avi/audio.d.ts +15 -0
  98. package/node_modules/audio-decode/node_modules/@audio/decode-avi/audio.js +9 -0
  99. package/node_modules/audio-decode/node_modules/@audio/decode-avi/decode-avi.d.ts +21 -0
  100. package/node_modules/audio-decode/node_modules/@audio/decode-avi/decode-avi.js +241 -0
  101. package/node_modules/audio-decode/node_modules/@audio/decode-avi/package.json +66 -0
  102. package/node_modules/audio-decode/node_modules/@audio/decode-caf/LICENSE +21 -0
  103. package/node_modules/audio-decode/node_modules/@audio/decode-caf/README.md +48 -0
  104. package/node_modules/audio-decode/node_modules/@audio/decode-caf/audio.d.ts +15 -0
  105. package/node_modules/audio-decode/node_modules/@audio/decode-caf/audio.js +10 -0
  106. package/node_modules/audio-decode/node_modules/@audio/decode-caf/decode-caf.d.ts +16 -0
  107. package/node_modules/audio-decode/node_modules/@audio/decode-caf/decode-caf.js +238 -0
  108. package/node_modules/audio-decode/node_modules/@audio/decode-caf/package.json +53 -0
  109. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/LICENSE +21 -0
  110. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/README.md +73 -0
  111. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/audio.d.ts +21 -0
  112. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/audio.js +15 -0
  113. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/decode-dsd.d.ts +29 -0
  114. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/decode-dsd.js +423 -0
  115. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/meta.js +40 -0
  116. package/node_modules/audio-decode/node_modules/@audio/decode-dsd/package.json +64 -0
  117. package/node_modules/audio-decode/node_modules/@audio/decode-dts/LICENSE +12 -0
  118. package/node_modules/audio-decode/node_modules/@audio/decode-dts/LICENSE.libdca +339 -0
  119. package/node_modules/audio-decode/node_modules/@audio/decode-dts/README.md +41 -0
  120. package/node_modules/audio-decode/node_modules/@audio/decode-dts/audio.d.ts +15 -0
  121. package/node_modules/audio-decode/node_modules/@audio/decode-dts/audio.js +9 -0
  122. package/node_modules/audio-decode/node_modules/@audio/decode-dts/decode-dts.d.ts +20 -0
  123. package/node_modules/audio-decode/node_modules/@audio/decode-dts/decode-dts.js +139 -0
  124. package/node_modules/audio-decode/node_modules/@audio/decode-dts/package.json +64 -0
  125. package/node_modules/audio-decode/node_modules/@audio/decode-dts/src/dts.wasm.js +0 -0
  126. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/LICENSE +12 -0
  127. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/LICENSE.ffmpeg +502 -0
  128. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/README.md +45 -0
  129. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/audio.d.ts +15 -0
  130. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/audio.js +9 -0
  131. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/decode-eac3.d.ts +20 -0
  132. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/decode-eac3.js +124 -0
  133. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/package.json +68 -0
  134. package/node_modules/audio-decode/node_modules/@audio/decode-eac3/src/eac3.wasm.js +0 -0
  135. package/node_modules/audio-decode/node_modules/@audio/decode-flac/LICENSE +25 -0
  136. package/node_modules/audio-decode/node_modules/@audio/decode-flac/README.md +23 -0
  137. package/node_modules/audio-decode/node_modules/@audio/decode-flac/audio.d.ts +15 -0
  138. package/node_modules/audio-decode/node_modules/@audio/decode-flac/audio.js +10 -0
  139. package/node_modules/audio-decode/node_modules/@audio/decode-flac/decode-flac.d.ts +18 -0
  140. package/node_modules/audio-decode/node_modules/@audio/decode-flac/decode-flac.js +3172 -0
  141. package/node_modules/audio-decode/node_modules/@audio/decode-flac/meta.js +115 -0
  142. package/node_modules/audio-decode/node_modules/@audio/decode-flac/package.json +60 -0
  143. package/node_modules/audio-decode/node_modules/@audio/decode-mod/LICENSE +23 -0
  144. package/node_modules/audio-decode/node_modules/@audio/decode-mod/LICENSE.libopenmpt +25 -0
  145. package/node_modules/audio-decode/node_modules/@audio/decode-mod/README.md +86 -0
  146. package/node_modules/audio-decode/node_modules/@audio/decode-mod/audio.d.ts +20 -0
  147. package/node_modules/audio-decode/node_modules/@audio/decode-mod/audio.js +12 -0
  148. package/node_modules/audio-decode/node_modules/@audio/decode-mod/decode-mod.d.ts +58 -0
  149. package/node_modules/audio-decode/node_modules/@audio/decode-mod/decode-mod.js +148 -0
  150. package/node_modules/audio-decode/node_modules/@audio/decode-mod/package.json +68 -0
  151. package/node_modules/audio-decode/node_modules/@audio/decode-mod/src/mod.wasm.js +0 -0
  152. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/LICENSE +25 -0
  153. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/README.md +20 -0
  154. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/audio.d.ts +15 -0
  155. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/audio.js +10 -0
  156. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/decode-mp3.d.ts +16 -0
  157. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/decode-mp3.js +793 -0
  158. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/meta.js +143 -0
  159. package/node_modules/audio-decode/node_modules/@audio/decode-mp3/package.json +60 -0
  160. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/LICENSE +21 -0
  161. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/README.md +58 -0
  162. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/audio.d.ts +15 -0
  163. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/audio.js +9 -0
  164. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/decode-mp4.d.ts +21 -0
  165. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/decode-mp4.js +455 -0
  166. package/node_modules/audio-decode/node_modules/@audio/decode-mp4/package.json +74 -0
  167. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/LICENSE +31 -0
  168. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/LICENSE.libmpcdec +31 -0
  169. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/README.md +60 -0
  170. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/audio.d.ts +15 -0
  171. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/audio.js +9 -0
  172. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/decode-mpc.d.ts +20 -0
  173. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/decode-mpc.js +158 -0
  174. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/package.json +64 -0
  175. package/node_modules/audio-decode/node_modules/@audio/decode-mpc/src/mpc.wasm.js +0 -0
  176. package/node_modules/audio-decode/node_modules/@audio/decode-opus/LICENSE +25 -0
  177. package/node_modules/audio-decode/node_modules/@audio/decode-opus/LICENSE.libopus +44 -0
  178. package/node_modules/audio-decode/node_modules/@audio/decode-opus/README.md +32 -0
  179. package/node_modules/audio-decode/node_modules/@audio/decode-opus/audio.d.ts +15 -0
  180. package/node_modules/audio-decode/node_modules/@audio/decode-opus/audio.js +10 -0
  181. package/node_modules/audio-decode/node_modules/@audio/decode-opus/core.d.ts +33 -0
  182. package/node_modules/audio-decode/node_modules/@audio/decode-opus/core.js +147 -0
  183. package/node_modules/audio-decode/node_modules/@audio/decode-opus/decode-opus.d.ts +18 -0
  184. package/node_modules/audio-decode/node_modules/@audio/decode-opus/decode-opus.js +1 -0
  185. package/node_modules/audio-decode/node_modules/@audio/decode-opus/meta.js +103 -0
  186. package/node_modules/audio-decode/node_modules/@audio/decode-opus/package.json +68 -0
  187. package/node_modules/audio-decode/node_modules/@audio/decode-opus/src/decode-opus.js +2 -0
  188. package/node_modules/audio-decode/node_modules/@audio/decode-opus/src/opus.wasm.js +0 -0
  189. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/LICENSE +25 -0
  190. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/README.md +19 -0
  191. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/audio.d.ts +15 -0
  192. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/audio.js +10 -0
  193. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/decode-qoa.d.ts +16 -0
  194. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/decode-qoa.js +275 -0
  195. package/node_modules/audio-decode/node_modules/@audio/decode-qoa/package.json +56 -0
  196. package/node_modules/audio-decode/node_modules/@audio/decode-tta/LICENSE +21 -0
  197. package/node_modules/audio-decode/node_modules/@audio/decode-tta/LICENSE.ttadec +39 -0
  198. package/node_modules/audio-decode/node_modules/@audio/decode-tta/README.md +58 -0
  199. package/node_modules/audio-decode/node_modules/@audio/decode-tta/audio.d.ts +15 -0
  200. package/node_modules/audio-decode/node_modules/@audio/decode-tta/audio.js +9 -0
  201. package/node_modules/audio-decode/node_modules/@audio/decode-tta/decode-tta.d.ts +17 -0
  202. package/node_modules/audio-decode/node_modules/@audio/decode-tta/decode-tta.js +302 -0
  203. package/node_modules/audio-decode/node_modules/@audio/decode-tta/package.json +58 -0
  204. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/LICENSE +25 -0
  205. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/README.md +33 -0
  206. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/audio.d.ts +15 -0
  207. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/audio.js +10 -0
  208. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/decode-vorbis.d.ts +18 -0
  209. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/decode-vorbis.js +2984 -0
  210. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/meta.js +102 -0
  211. package/node_modules/audio-decode/node_modules/@audio/decode-vorbis/package.json +60 -0
  212. package/node_modules/audio-decode/node_modules/@audio/decode-wav/LICENSE +21 -0
  213. package/node_modules/audio-decode/node_modules/@audio/decode-wav/README.md +23 -0
  214. package/node_modules/audio-decode/node_modules/@audio/decode-wav/audio.d.ts +15 -0
  215. package/node_modules/audio-decode/node_modules/@audio/decode-wav/audio.js +10 -0
  216. package/node_modules/audio-decode/node_modules/@audio/decode-wav/decode-wav.d.ts +8 -0
  217. package/node_modules/audio-decode/node_modules/@audio/decode-wav/decode-wav.js +256 -0
  218. package/node_modules/audio-decode/node_modules/@audio/decode-wav/meta.js +114 -0
  219. package/node_modules/audio-decode/node_modules/@audio/decode-wav/package.json +52 -0
  220. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/LICENSE +29 -0
  221. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/LICENSE.wavpack +25 -0
  222. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/README.md +41 -0
  223. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/audio.d.ts +15 -0
  224. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/audio.js +9 -0
  225. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/decode-wavpack.d.ts +18 -0
  226. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/decode-wavpack.js +140 -0
  227. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/package.json +62 -0
  228. package/node_modules/audio-decode/node_modules/@audio/decode-wavpack/src/wavpack.wasm.js +0 -0
  229. package/node_modules/audio-decode/node_modules/@audio/decode-webm/LICENSE +21 -0
  230. package/node_modules/audio-decode/node_modules/@audio/decode-webm/LICENSE.libopus +44 -0
  231. package/node_modules/audio-decode/node_modules/@audio/decode-webm/README.md +59 -0
  232. package/node_modules/audio-decode/node_modules/@audio/decode-webm/audio.d.ts +15 -0
  233. package/node_modules/audio-decode/node_modules/@audio/decode-webm/audio.js +10 -0
  234. package/node_modules/audio-decode/node_modules/@audio/decode-webm/decode-webm.d.ts +18 -0
  235. package/node_modules/audio-decode/node_modules/@audio/decode-webm/decode-webm.js +141 -0
  236. package/node_modules/audio-decode/node_modules/@audio/decode-webm/package.json +76 -0
  237. package/node_modules/audio-decode/node_modules/@audio/decode-webm/src/opus.wasm.js +0 -0
  238. package/node_modules/audio-decode/node_modules/@audio/decode-wma/LICENSE +12 -0
  239. package/node_modules/audio-decode/node_modules/@audio/decode-wma/README.md +74 -0
  240. package/node_modules/audio-decode/node_modules/@audio/decode-wma/audio.d.ts +15 -0
  241. package/node_modules/audio-decode/node_modules/@audio/decode-wma/audio.js +10 -0
  242. package/node_modules/audio-decode/node_modules/@audio/decode-wma/decode-wma.d.ts +33 -0
  243. package/node_modules/audio-decode/node_modules/@audio/decode-wma/decode-wma.js +516 -0
  244. package/node_modules/audio-decode/node_modules/@audio/decode-wma/package.json +57 -0
  245. package/node_modules/audio-decode/node_modules/@audio/decode-wma/src/wma.wasm.js +0 -0
  246. package/node_modules/audio-decode/package.json +37 -39
  247. package/node_modules/audio-decode/stream.d.ts +2 -0
  248. package/node_modules/audio-decode/stream.js +2 -0
  249. package/node_modules/baileys/lib/Utils/messages-media.js +1 -1
  250. package/node_modules/baileys/node_modules/file-type/package.json +3 -2
  251. package/node_modules/baileys/node_modules/file-type/readme.md +5 -0
  252. package/node_modules/baileys/node_modules/file-type/source/detectors/zip.js +9 -4
  253. package/node_modules/baileys/node_modules/file-type/source/index.js +28 -1
  254. package/node_modules/baileys/node_modules/file-type/source/supported.js +2 -0
  255. package/node_modules/baileys/node_modules/p-timeout/index.js +3 -0
  256. package/node_modules/baileys/node_modules/p-timeout/package.json +1 -1
  257. package/node_modules/baileys/package.json +1 -1
  258. package/node_modules/typebox/build/compile/code.mjs +1 -2
  259. package/node_modules/typebox/build/compile/validator.mjs +5 -1
  260. package/node_modules/typebox/build/format/iri.mjs +16 -9
  261. package/node_modules/typebox/build/guard/emit.mjs +2 -2
  262. package/node_modules/typebox/build/guard/guard.d.mts +7 -5
  263. package/node_modules/typebox/build/guard/guard.mjs +14 -9
  264. package/node_modules/typebox/build/guard/index.mjs +6 -0
  265. package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
  266. package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
  267. package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
  268. package/node_modules/typebox/build/schema/build.mjs +2 -3
  269. package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
  270. package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
  271. package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
  272. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
  273. package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
  274. package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
  275. package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
  276. package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
  277. package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
  278. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
  279. package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
  280. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
  281. package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
  282. package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
  283. package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
  284. package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
  285. package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
  286. package/node_modules/typebox/build/schema/parse.mjs +3 -0
  287. package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
  288. package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
  289. package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
  290. package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
  291. package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
  292. package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
  293. package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
  294. package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
  295. package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
  296. package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
  297. package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
  298. package/node_modules/typebox/package.json +1 -1
  299. package/node_modules/typebox/readme.md +3 -1
  300. package/package.json +6 -6
  301. package/dist/.setup/doctor-BPb-SjdE.mjs +0 -65
  302. package/dist/.setup/group-config-path-BGyzT9Lg.mjs +0 -54
  303. package/dist/.setup/normalize-DdsROMMa.mjs +0 -2
  304. package/dist/.setup/rolldown-runtime-D7D4PA-g.mjs +0 -13
  305. package/dist/.setup/runtime-group-policy-DeSRFXEV.mjs +0 -11
  306. package/dist/.setup/setup-plugin-api-CXfU-7vN.mjs +0 -3
  307. package/dist/.setup/text-runtime-CHl0iPYe.mjs +0 -4
  308. package/node_modules/audio-decode/.eslintrc.json +0 -43
  309. package/node_modules/audio-decode/.github/workflows/test.js.yml +0 -31
  310. package/node_modules/audio-decode/.travis.yml +0 -13
  311. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/README.md +0 -293
  312. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/dist/opus-ml-decoder.min.js +0 -11646
  313. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/dist/opus-ml-decoder.min.js.map +0 -1
  314. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/index.js +0 -8
  315. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/package.json +0 -58
  316. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/EmscriptenWasm.js +0 -0
  317. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/OpusMLDecoder.js +0 -253
  318. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/src/OpusMLDecoderWebWorker.js +0 -17
  319. package/node_modules/audio-decode/node_modules/@wasm-audio-decoders/opus-ml/types.d.ts +0 -77
  320. package/node_modules/audio-decode/node_modules/audio-buffer/.eslintrc.json +0 -44
  321. package/node_modules/audio-decode/node_modules/audio-buffer/.github/workflows/node.js.yml +0 -31
  322. package/node_modules/audio-decode/node_modules/audio-buffer/.travis.yml +0 -7
  323. package/node_modules/audio-decode/node_modules/audio-buffer/index.js +0 -76
  324. package/node_modules/audio-decode/node_modules/audio-buffer/package.json +0 -37
  325. package/node_modules/audio-decode/node_modules/audio-buffer/readme.md +0 -56
  326. package/node_modules/audio-decode/node_modules/node-wav/README.md +0 -35
  327. package/node_modules/audio-decode/node_modules/node-wav/file.wav +0 -0
  328. package/node_modules/audio-decode/node_modules/node-wav/index.js +0 -291
  329. package/node_modules/audio-decode/node_modules/node-wav/package.json +0 -29
  330. package/node_modules/audio-decode/node_modules/node-wav/tests/file1.wav +0 -0
  331. package/node_modules/audio-decode/node_modules/node-wav/tests/test.js +0 -66
  332. package/node_modules/audio-decode/node_modules/node-wav/x.js +0 -12
  333. package/node_modules/audio-decode/node_modules/node-wav/x.json +0 -86702
  334. package/node_modules/audio-decode/node_modules/node-wav/x.js~ +0 -13
  335. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/README.md +0 -320
  336. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.min.js +0 -232
  337. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.min.js.map +0 -1
  338. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.opus-ml.min.js +0 -0
  339. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/dist/ogg-opus-decoder.opus-ml.min.js.map +0 -1
  340. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/index.js +0 -8
  341. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/package.json +0 -74
  342. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/src/OggOpusDecoder.js +0 -226
  343. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/src/OggOpusDecoderWebWorker.js +0 -17
  344. package/node_modules/audio-decode/node_modules/ogg-opus-decoder/types.d.ts +0 -37
  345. package/node_modules/audio-decode/node_modules/opus-decoder/README.md +0 -265
  346. package/node_modules/audio-decode/node_modules/opus-decoder/dist/opus-decoder.min.js +0 -232
  347. package/node_modules/audio-decode/node_modules/opus-decoder/dist/opus-decoder.min.js.map +0 -1
  348. package/node_modules/audio-decode/node_modules/opus-decoder/index.js +0 -8
  349. package/node_modules/audio-decode/node_modules/opus-decoder/package.json +0 -56
  350. package/node_modules/audio-decode/node_modules/opus-decoder/src/EmscriptenWasm.js +0 -0
  351. package/node_modules/audio-decode/node_modules/opus-decoder/src/OpusDecoder.js +0 -239
  352. package/node_modules/audio-decode/node_modules/opus-decoder/src/OpusDecoderWebWorker.js +0 -17
  353. package/node_modules/audio-decode/node_modules/opus-decoder/types.d.ts +0 -74
  354. package/node_modules/audio-decode/readme.md +0 -49
  355. package/node_modules/audio-decode/tea.yaml +0 -6
  356. package/node_modules/audio-decode/test-case.js +0 -11
  357. package/node_modules/audio-decode/test.html +0 -15
  358. package/node_modules/audio-decode/test.js +0 -107
  359. /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";
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";
3
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,36 +27,37 @@ 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";
35
- import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
34
+ import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolvePromptHistoryLimit } from "openclaw/plugin-sdk/number-runtime";
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
- import { DEFAULT_GROUP_HISTORY_LIMIT, buildHistoryContextFromEntries, buildInboundHistoryFromEntries, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
45
44
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
46
- import { fanInChannelIngressLifecycles, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
47
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";
48
47
  import { createInboundDebouncer, resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound-debounce";
48
+ import { fanInChannelIngressLifecycles } from "openclaw/plugin-sdk/channel-ingress-runtime";
49
49
  import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
50
50
  import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
51
51
  import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
52
52
  import { getRuntimeConfig as getRuntimeConfig$1 } from "openclaw/plugin-sdk/runtime-config-snapshot";
53
53
  import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
54
- import { buildMentionRegexes, implicitMentionKindWhen, normalizeMentionText, resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-mention-gating";
55
54
  import { channelReadyPatch, channelStoppedPatch, createTransportActivityStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
56
55
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
57
56
  import { resolveAgentIdentity, resolveIdentityNamePrefix } from "openclaw/plugin-sdk/agent-runtime";
58
57
  import { normalizeGroupActivation, parseActivationCommand } from "openclaw/plugin-sdk/group-activation";
59
58
  import { formatAudioTranscriptForAgent } from "openclaw/plugin-sdk/media-understanding-runtime";
60
59
  import { hasControlCommand, isControlCommandMessage, shouldComputeCommandAuthorized } from "openclaw/plugin-sdk/command-detection";
60
+ import { buildHistoryContextFromEntries, buildInboundHistoryFromEntries, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
61
61
  import { createInternalHookEvent, deriveInboundMessageHookContext, fireAndForgetBoundedHook, toInternalMessageReceivedContext, toPluginMessageContext, toPluginMessageReceivedEvent, triggerInternalHook } from "openclaw/plugin-sdk/hook-runtime";
62
62
  import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
63
63
  import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
@@ -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 resolveStableChannelMessageIngress({
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,116 +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
- resolveNonRetryableFailure: resolveWhatsAppIngressNonRetryableFailure,
365
- deriveLaneKey: (record) => {
366
- try {
367
- return inspectWhatsAppIngressMessage(deserializeWhatsAppDurableInboundMessage(record.payload.message)).laneKey;
368
- } catch {
369
- return record.id;
370
- }
371
- },
372
- ...params.onLog ? { onLog: params.onLog } : {}
373
- },
374
- ...params.abortSignal ? { abortSignal: params.abortSignal } : {},
375
- admissionMode: "while-running",
376
- createStoppedError: () => /* @__PURE__ */ new Error("WhatsApp ingress monitor is stopped."),
377
- ...params.onError ? { onError: params.onError } : {},
378
- ...params.onActivityChange ? { onActivityChange: params.onActivityChange } : {}
379
- });
380
- }
381
- //#endregion
382
262
  //#region extensions/whatsapp/src/inbound/group-metadata-cache.ts
383
263
  const GROUP_META_TTL_MS = 3e5;
384
264
  const WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES = 500;
@@ -393,11 +273,7 @@ function rememberGroupMetadataCacheEntry(cache, jid, entry) {
393
273
  }
394
274
  if (cache.has(jid)) cache.delete(jid);
395
275
  cache.set(jid, entry);
396
- while (cache.size > WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES) {
397
- const oldest = cache.keys().next();
398
- if (oldest.done) break;
399
- cache.delete(oldest.value);
400
- }
276
+ pruneMapToMaxSize(cache, WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES);
401
277
  }
402
278
  function readGroupMetadataCacheEntry(cache, jid) {
403
279
  const entry = cache.get(jid);
@@ -587,6 +463,117 @@ function closeInboundMonitorSocket(sock) {
587
463
  sock.ws?.close?.();
588
464
  }
589
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
590
577
  //#region extensions/whatsapp/src/inbound/ingress-lifecycle.ts
591
578
  const ingressLifecycleKey = Symbol("whatsappIngressLifecycle");
592
579
  function attachWhatsAppIngressLifecycle(message, lifecycle) {
@@ -608,19 +595,25 @@ function createWhatsAppInboundMessageDebouncer(options) {
608
595
  for (const resolve of waiters) resolve();
609
596
  };
610
597
  const buildKey = (msg) => {
598
+ const admission = requireWhatsAppInboundAdmission(msg);
599
+ return `${admission.accountId}:${admission.conversation.id}`;
600
+ };
601
+ const resolveSenderKey = (msg) => {
611
602
  const admission = requireWhatsAppInboundAdmission(msg);
612
603
  const sender = msg.platform.sender;
613
- const senderKey = admission.conversation.kind === "group" ? getPrimaryIdentityId(sender ?? null) ?? msg.platform.senderJid ?? msg.platform.senderE164 ?? msg.platform.senderName ?? admission.sender.id : admission.conversation.id;
614
- return senderKey ? `${admission.accountId}:${admission.conversation.id}:${senderKey}` : null;
604
+ return admission.conversation.kind === "group" ? getPrimaryIdentityId(sender ?? null) ?? msg.platform.senderJid ?? msg.platform.senderE164 ?? msg.platform.senderName ?? admission.sender.id : admission.conversation.id;
615
605
  };
616
606
  const shouldDebounce = (msg) => options.shouldDebounce?.(msg) ?? true;
617
- const trackKey = (key) => {
618
- pendingKeys.set(key, (pendingKeys.get(key) ?? 0) + 1);
607
+ const trackKey = (key, senderKey) => {
608
+ pendingKeys.set(key, {
609
+ count: (pendingKeys.get(key)?.count ?? 0) + 1,
610
+ senderKey
611
+ });
619
612
  };
620
613
  const releaseKey = (entry) => {
621
614
  if (!entry.debounceKey || entry.debounceKeyTracked !== true) return;
622
- const remaining = (pendingKeys.get(entry.debounceKey) ?? 0) - 1;
623
- if (remaining > 0) pendingKeys.set(entry.debounceKey, remaining);
615
+ const pending = pendingKeys.get(entry.debounceKey);
616
+ if (pending && pending.count > 1) pending.count -= 1;
624
617
  else pendingKeys.delete(entry.debounceKey);
625
618
  };
626
619
  const orderEntries = (entries) => entries.toSorted((a, b) => {
@@ -701,14 +694,15 @@ function createWhatsAppInboundMessageDebouncer(options) {
701
694
  debounceMs: options.resolveDebounceMs()
702
695
  };
703
696
  const key = buildKey(message);
704
- if (key) {
705
- message.debounceKey = key;
706
- if (message.debounceMs > 0 && shouldDebounce(message)) {
707
- message.debounceKeyTracked = true;
708
- trackKey(key);
709
- options.onPendingWorkChanged();
710
- notifyWork();
711
- }
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();
712
706
  }
713
707
  await debouncer.enqueue(message);
714
708
  };
@@ -743,11 +737,8 @@ function createWhatsAppInboundMessageDebouncer(options) {
743
737
  }
744
738
  //#endregion
745
739
  //#region extensions/whatsapp/src/inbound/media.ts
746
- function unwrapMessage(message) {
747
- return normalizeMessageContent$1(message);
748
- }
749
740
  async function downloadInboundMedia(msg, sock, maxBytes = 52428800, normalizedMessage) {
750
- const message = normalizedMessage ?? unwrapMessage(msg.message);
741
+ const message = normalizedMessage ?? normalizeMessageContent$1(msg.message);
751
742
  if (!message) return;
752
743
  const mimetype = resolveInboundMediaMimetype(message);
753
744
  const fileName = message.documentMessage?.fileName ?? void 0;
@@ -763,7 +754,7 @@ async function downloadInboundMedia(msg, sock, maxBytes = 52428800, normalizedMe
763
754
  };
764
755
  }
765
756
  async function downloadQuotedInboundMedia(msg, sock, maxBytes = 52428800) {
766
- const message = unwrapMessage(msg.message);
757
+ const message = normalizeMessageContent$1(msg.message);
767
758
  const contextInfo = extractContextInfo(message);
768
759
  if (!contextInfo?.quotedMessage) return;
769
760
  const quotedMessage = contextInfo.quotedMessage;
@@ -1170,12 +1161,9 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1170
1161
  logWhatsAppVerbose$1(options.verbose, `Failed to mark message ${id} read: ${String(err)}`);
1171
1162
  }
1172
1163
  };
1173
- const maybeLogSkippedSelfChatReadReceipt = (inbound, target) => {
1174
- if (target?.id && inbound.access.isSelfChat && options.verbose) logWhatsAppVerbose$1(options.verbose, `Self-chat mode: skipping read receipt for ${target.id}`);
1175
- };
1176
1164
  const maybeMarkNonSelfChatReadReceipt = async (inbound, target) => {
1177
1165
  if (inbound.access.isSelfChat) {
1178
- maybeLogSkippedSelfChatReadReceipt(inbound, target);
1166
+ if (target?.id) logWhatsAppVerbose$1(options.verbose, `Self-chat mode: skipping read receipt for ${target.id}`);
1179
1167
  return;
1180
1168
  }
1181
1169
  await maybeMarkInboundAsRead(target);
@@ -1251,25 +1239,27 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1251
1239
  mentions: groupMentions
1252
1240
  } : void 0;
1253
1241
  const channelStructuredContext = [
1254
- ...enriched.nativeMedia ? [{
1255
- label: "WhatsApp media",
1256
- source: "whatsapp",
1257
- type: "media",
1258
- payload: enriched.nativeMedia
1259
- }] : [],
1260
- ...enriched.contactContext ? [{
1261
- label: "WhatsApp contact",
1262
- source: "whatsapp",
1263
- type: enriched.contactContext.kind,
1264
- payload: enriched.contactContext
1265
- }] : [],
1266
- ...enriched.externalAdReplyContext ? [{
1267
- label: "WhatsApp external ad reply",
1268
- source: "whatsapp",
1269
- type: "external_ad_reply",
1270
- payload: enriched.externalAdReplyContext
1271
- }] : []
1272
- ];
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
+ }] : []);
1273
1263
  const inboundMessage = {
1274
1264
  admission: inbound.access.admission,
1275
1265
  event: {
@@ -1332,25 +1322,29 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1332
1322
  }
1333
1323
  await messageDebouncer.enqueue(inboundMessage);
1334
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
+ });
1335
1335
  const processDurableInboundMessage = async (admission, lifecycle) => {
1336
1336
  const { message: msg, ...context } = admission;
1337
1337
  rememberBaileysMessage(msg.key?.remoteJid, msg.key?.id, msg.message);
1338
1338
  const remoteJid = msg.key?.remoteJid;
1339
1339
  const id = msg.key?.id;
1340
- 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;
1341
1344
  const preparation = durableId ? preparedInboundByDurableId.get(durableId) : void 0;
1342
1345
  if (durableId) preparedInboundByDurableId.delete(durableId);
1343
1346
  if (context.skipRecentOutboundEcho === true) return "completed";
1344
- if (await maybeResolveWhatsAppApprovalReaction({
1345
- cfg: options.loadConfig?.() ?? options.cfg,
1346
- accountId: options.accountId,
1347
- msg,
1348
- selfJid: self.jid,
1349
- selfLid: self.lid,
1350
- resolveInboundJid,
1351
- resolveReactionTargetJids,
1352
- logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
1353
- })) return "completed";
1347
+ if (await resolveApprovalReaction(msg)) return "completed";
1354
1348
  const prepared = await preparation;
1355
1349
  if (prepared === null) return "completed";
1356
1350
  const inbound = prepared ?? await normalizeInboundMessage(msg);
@@ -1405,16 +1399,7 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1405
1399
  const receiveOrder = nextReceiveOrder++;
1406
1400
  let approvalReactionResolved = false;
1407
1401
  try {
1408
- approvalReactionResolved = await maybeResolveWhatsAppApprovalReaction({
1409
- cfg: options.loadConfig?.() ?? options.cfg,
1410
- accountId: options.accountId,
1411
- msg,
1412
- selfJid: self.jid,
1413
- selfLid: self.lid,
1414
- resolveInboundJid,
1415
- resolveReactionTargetJids,
1416
- logVerboseMessage: (message) => logWhatsAppVerbose$1(options.verbose, message)
1417
- });
1402
+ approvalReactionResolved = await resolveApprovalReaction(msg);
1418
1403
  } catch (error) {
1419
1404
  inboundLogger.warn({ error: formatError(error) }, "whatsapp approval reaction resolution failed; admitting reaction for durable replay");
1420
1405
  }
@@ -1424,16 +1409,19 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1424
1409
  const skipRecentOutboundEcho = shouldSkipRecentOutboundEcho(msg);
1425
1410
  const remoteJid = msg.key?.remoteJid;
1426
1411
  const id = msg.key?.id;
1427
- 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;
1428
1416
  let resolvePrepared;
1429
1417
  if (durableId && !preparedInboundByDurableId.has(durableId)) {
1430
1418
  if (preparedInboundByDurableId.size >= 1e3) {
1431
1419
  const oldest = preparedInboundByDurableId.keys().next().value;
1432
1420
  if (oldest !== void 0) preparedInboundByDurableId.delete(oldest);
1433
1421
  }
1434
- preparedInboundByDurableId.set(durableId, new Promise((resolve) => {
1435
- resolvePrepared = resolve;
1436
- }));
1422
+ const prepared = createDeferred();
1423
+ resolvePrepared = prepared.resolve;
1424
+ preparedInboundByDurableId.set(durableId, prepared.promise);
1437
1425
  }
1438
1426
  const finishPreparation = (inbound, keepForDrain = false) => {
1439
1427
  resolvePrepared?.(inbound);
@@ -1483,22 +1471,19 @@ function createWhatsAppMessageDeliveryCoordinator(options) {
1483
1471
  publishPendingWorkState();
1484
1472
  });
1485
1473
  };
1486
- const drainDebouncedInboundMessages = async () => {
1487
- await messageDebouncer.drain();
1488
- };
1489
1474
  const drainInboundBeforeSocketClose = async () => {
1490
1475
  for (;;) {
1491
- await drainDebouncedInboundMessages();
1476
+ await messageDebouncer.drain();
1492
1477
  if (pendingMessageHandlers.size === 0) break;
1493
1478
  const handlers = Array.from(pendingMessageHandlers);
1494
1479
  await Promise.race([Promise.allSettled(handlers), messageDebouncer.waitForWorkOrIdle(handlers, pendingMessageHandlers.size === 0)]);
1495
1480
  if (pendingMessageHandlers.size === 0 && !messageDebouncer.hasPendingWork()) break;
1496
1481
  }
1497
- await drainDebouncedInboundMessages();
1482
+ await messageDebouncer.drain();
1498
1483
  for (;;) {
1499
1484
  await durableInboundMonitor.waitForIdle();
1500
1485
  if (!messageDebouncer.hasPendingWork()) break;
1501
- await drainDebouncedInboundMessages();
1486
+ await messageDebouncer.drain();
1502
1487
  }
1503
1488
  await durableInboundMonitor.stop();
1504
1489
  };
@@ -1564,16 +1549,7 @@ async function createWhatsAppAttachedSocketSession(options) {
1564
1549
  const disconnectRetryPolicy = options.disconnectRetryPolicy ?? DEFAULT_RECONNECT_POLICY;
1565
1550
  const sendRetryMaxAttempts = disconnectRetryPolicy.maxAttempts > 0 ? disconnectRetryPolicy.maxAttempts : DEFAULT_RECONNECT_POLICY.maxAttempts;
1566
1551
  const sendOperationTimeoutMs = resolveWhatsAppSocketOperationTimeoutMs(options.socketTiming.defaultQueryTimeoutMs);
1567
- let onCloseResolve = null;
1568
- const onClose = new Promise((resolve) => {
1569
- onCloseResolve = resolve;
1570
- });
1571
- const resolveClose = (reason) => {
1572
- if (!onCloseResolve) return;
1573
- const resolver = onCloseResolve;
1574
- onCloseResolve = null;
1575
- resolver(reason);
1576
- };
1552
+ const { promise: onClose, resolve: resolveClose } = createDeferred();
1577
1553
  const presence = options.selfChatMode ? "unavailable" : "available";
1578
1554
  try {
1579
1555
  await createWhatsAppSocketOperationTimeoutAdapter(sock, sendOperationTimeoutMs).sendPresenceUpdate(presence);
@@ -1608,14 +1584,14 @@ async function createWhatsAppAttachedSocketSession(options) {
1608
1584
  rememberWhatsAppBaileysCacheEntry(options.recentMessageKeys, `${remoteJid}:${messageId}`, message, BAILEYS_MESSAGE_TTL_MS);
1609
1585
  };
1610
1586
  const rememberOutboundMessage = (remoteJid, result) => {
1611
- const messageId = typeof result === "object" && result && "key" in result ? result.key?.id ?? "" : "";
1587
+ const messageId = result?.key?.id;
1612
1588
  if (!messageId) return;
1613
1589
  rememberRecentOutboundMessage({
1614
1590
  accountId: options.accountId,
1615
1591
  remoteJid,
1616
1592
  messageId
1617
1593
  });
1618
- const message = typeof result === "object" && result && "message" in result ? result.message : void 0;
1594
+ const message = result?.message;
1619
1595
  rememberBaileysMessage(remoteJid, messageId, message);
1620
1596
  cacheInboundMessageMeta(options.accountId, remoteJid, messageId, {
1621
1597
  fromMe: true,
@@ -1705,7 +1681,7 @@ async function createWhatsAppAttachedSocketSession(options) {
1705
1681
  }
1706
1682
  };
1707
1683
  const socketOperations = {
1708
- sendMessage: (jid, content, sendOptions) => sendTrackedMessage(jid, content, sendOptions),
1684
+ sendMessage: sendTrackedMessage,
1709
1685
  sendPresenceUpdate: async (presenceLocal, jid) => {
1710
1686
  const currentSock = getCurrentSock();
1711
1687
  if (!currentSock) throw new Error(RECONNECT_IN_PROGRESS_ERROR);
@@ -1836,7 +1812,7 @@ async function attachWebInboxToSocket(options) {
1836
1812
  appendReplyWindow: options.appendReplyWindow,
1837
1813
  shouldDebounce: options.shouldDebounce,
1838
1814
  onPendingWorkChanged: options.onPendingWorkChanged,
1839
- durableInboundQueue: options.durableInboundQueue ?? createWhatsAppDurableInboundQueue(options.accountId)
1815
+ durableInboundQueue: options.durableInboundQueue
1840
1816
  });
1841
1817
  const sendApi = createWebSendApi({
1842
1818
  sock: socketSession.socketOperations,
@@ -1903,64 +1879,6 @@ const whatsappInboundLog = whatsappLog.child("inbound");
1903
1879
  const whatsappOutboundLog = whatsappLog.child("outbound");
1904
1880
  const whatsappHeartbeatLog = whatsappLog.child("heartbeat");
1905
1881
  //#endregion
1906
- //#region extensions/whatsapp/src/auto-reply/mentions.ts
1907
- function buildMentionConfig(cfg, agentId, options) {
1908
- return {
1909
- mentionRegexes: buildMentionRegexes(cfg, agentId, options),
1910
- allowFrom: cfg.channels?.whatsapp?.allowFrom
1911
- };
1912
- }
1913
- function resolveMentionTargets(msg, authDir) {
1914
- return {
1915
- normalizedMentions: getMentionIdentities(msg, authDir),
1916
- self: getSelfIdentity(msg, authDir)
1917
- };
1918
- }
1919
- function isBotMentionedFromTargets(msg, mentionCfg, targets) {
1920
- const clean = (text) => normalizeMentionText(text);
1921
- const explicitSelfChatOverride = typeof mentionCfg.isSelfChat === "boolean";
1922
- const isGroupConversation = requireWhatsAppInboundAdmission(msg).conversation.kind === "group";
1923
- const isSelfChat = explicitSelfChatOverride ? Boolean(mentionCfg.isSelfChat) : isSelfChatMode(targets.self.e164, mentionCfg.allowFrom) && !isGroupConversation;
1924
- const hasMentions = targets.normalizedMentions.length > 0;
1925
- const hasNativeMentionsOutsideSelfChat = hasMentions && !isSelfChat;
1926
- if (hasNativeMentionsOutsideSelfChat) {
1927
- for (const mention of targets.normalizedMentions) if (identitiesOverlap(targets.self, mention)) return true;
1928
- } else if (hasMentions && isSelfChat) {}
1929
- const bodyClean = clean(msg.payload.body);
1930
- if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) return true;
1931
- if (hasNativeMentionsOutsideSelfChat) return false;
1932
- if (targets.self.e164) {
1933
- const selfDigits = targets.self.e164.replace(/\D/g, "");
1934
- if (selfDigits) {
1935
- if (bodyClean.replace(/[^\d]/g, "").includes(selfDigits)) return true;
1936
- const bodyNoSpace = msg.payload.body.replace(/[\s-]/g, "");
1937
- if (new RegExp(`\\+?${selfDigits}`, "i").test(bodyNoSpace)) return true;
1938
- }
1939
- }
1940
- return false;
1941
- }
1942
- function debugMention(msg, mentionCfg, authDir) {
1943
- const mentionTargets = resolveMentionTargets(msg, authDir);
1944
- return {
1945
- wasMentioned: isBotMentionedFromTargets(msg, mentionCfg, mentionTargets),
1946
- details: {
1947
- from: requireWhatsAppInboundAdmission(msg).conversation.id,
1948
- body: msg.payload.body,
1949
- bodyClean: normalizeMentionText(msg.payload.body),
1950
- mentionedJids: msg.group?.mentions?.jids ?? null,
1951
- normalizedMentionedJids: mentionTargets.normalizedMentions.length ? mentionTargets.normalizedMentions.map((identity) => getComparableIdentityValues(identity)) : null,
1952
- selfJid: msg.platform.self?.jid ?? msg.platform.selfJid ?? null,
1953
- selfLid: msg.platform.self?.lid ?? msg.platform.selfLid ?? null,
1954
- selfE164: msg.platform.self?.e164 ?? msg.platform.selfE164 ?? null,
1955
- resolvedSelf: mentionTargets.self
1956
- }
1957
- };
1958
- }
1959
- function resolveOwnerList(mentionCfg, selfE164) {
1960
- const allowFrom = mentionCfg.allowFrom;
1961
- return (Array.isArray(allowFrom) && allowFrom.length > 0 ? allowFrom : selfE164 ? [selfE164] : []).filter((entry) => Boolean(entry && entry !== "*")).map((entry) => normalizeE164(entry)).filter((entry) => Boolean(entry));
1962
- }
1963
- //#endregion
1964
1882
  //#region extensions/whatsapp/src/auto-reply/monitor-state.ts
1965
1883
  const LIFECYCLE_BY_HEALTH_STATE = {
1966
1884
  starting: "starting",
@@ -2102,6 +2020,76 @@ function formatWhatsAppInboundListeningLog(account) {
2102
2020
  return `Listening for WhatsApp inbound messages (DM + ${explicitGroupCount} configured ${explicitGroupCount === 1 ? "group" : "groups"}).`;
2103
2021
  }
2104
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
2105
2093
  //#region extensions/whatsapp/src/auto-reply/monitor/ack-emoji.ts
2106
2094
  const DEFAULT_WHATSAPP_ACK_REACTION = "👀";
2107
2095
  function resolveWhatsAppAckEmoji(params) {
@@ -2218,13 +2206,7 @@ async function resolveWhatsAppReactionEligibility(params) {
2218
2206
  //#endregion
2219
2207
  //#region extensions/whatsapp/src/auto-reply/monitor/ack-reaction.ts
2220
2208
  async function maybeSendAckReaction(params) {
2221
- const eligibility = await resolveWhatsAppReactionEligibility({
2222
- cfg: params.cfg,
2223
- msg: params.msg,
2224
- agentId: params.agentId,
2225
- sessionKey: params.sessionKey,
2226
- verbose: params.verbose
2227
- });
2209
+ const eligibility = await resolveWhatsAppReactionEligibility(params);
2228
2210
  if (eligibility.status === "disabled") return null;
2229
2211
  const { chatId, messageId, emoji, reactionOptions } = eligibility;
2230
2212
  params.info({
@@ -2247,6 +2229,33 @@ async function maybeSendAckReaction(params) {
2247
2229
  });
2248
2230
  }
2249
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
2250
2259
  //#region extensions/whatsapp/src/auto-reply/monitor/broadcast.ts
2251
2260
  function buildBroadcastRouteKeys(params) {
2252
2261
  const admission = requireWhatsAppInboundAdmission(params.msg);
@@ -2378,11 +2387,8 @@ const groupDropWarned = createDedupeCache({
2378
2387
  ttlMs: 0,
2379
2388
  maxSize: 100
2380
2389
  });
2381
- function shouldWarnForGroupDrop(warnKey) {
2382
- return !groupDropWarned.check(warnKey);
2383
- }
2384
2390
  function isOwnerSender(baseMentionConfig, msg, authDir) {
2385
- const sender = normalizeE164(getSenderIdentity(msg, authDir).e164 ?? "");
2391
+ const sender = normalizeE164$2(getSenderIdentity(msg, authDir).e164 ?? "");
2386
2392
  if (!sender) return false;
2387
2393
  return resolveOwnerList(baseMentionConfig, getSelfIdentity(msg, authDir).e164 ?? void 0).includes(sender);
2388
2394
  }
@@ -2431,11 +2437,12 @@ async function applyGroupGating(params) {
2431
2437
  const conversationGroupPolicy = inboundPolicy.resolveConversationGroupPolicy(conversationId);
2432
2438
  if (conversationGroupPolicy.allowlistEnabled && !conversationGroupPolicy.allowed) {
2433
2439
  const accountId = inboundPolicy.account.accountId;
2434
- if (shouldWarnForGroupDrop(JSON.stringify([
2440
+ const warnKey = JSON.stringify([
2435
2441
  accountId,
2436
2442
  conversationId,
2437
2443
  "group registry"
2438
- ]))) {
2444
+ ]);
2445
+ if (!groupDropWarned.check(warnKey)) {
2439
2446
  const groupsPath = resolveWhatsAppGroupsConfigPath({
2440
2447
  cfg: params.cfg,
2441
2448
  accountId
@@ -2462,17 +2469,11 @@ async function applyGroupGating(params) {
2462
2469
  }),
2463
2470
  allowFrom: inboundPolicy.configuredAllowFrom
2464
2471
  };
2465
- const mentionMsg = params.mentionText !== void 0 ? {
2466
- ...params.msg,
2467
- payload: {
2468
- ...params.msg.payload,
2469
- body: params.mentionText
2470
- }
2471
- } : {
2472
+ const mentionMsg = {
2472
2473
  ...params.msg,
2473
2474
  payload: {
2474
2475
  ...params.msg.payload,
2475
- body: params.msg.payload.commandBody ?? params.msg.payload.body
2476
+ body: params.mentionText ?? params.msg.payload.commandBody ?? params.msg.payload.body
2476
2477
  }
2477
2478
  };
2478
2479
  const commandBody = stripMentionsForCommand(mentionMsg.payload.body, mentionConfig.mentionRegexes, self.e164);
@@ -2496,8 +2497,8 @@ async function applyGroupGating(params) {
2496
2497
  }) !== "always";
2497
2498
  const replyContext = getReplyContext(params.msg, params.authDir);
2498
2499
  const implicitReplyToSelf = params.selfChatMode === true && identitiesOverlap(self, sender);
2499
- const implicitMentionKinds = implicitMentionKindWhen("quoted_bot", !implicitReplyToSelf && identitiesOverlap(self, replyContext?.sender));
2500
- 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)({
2501
2502
  facts: {
2502
2503
  canDetectMention: true,
2503
2504
  wasMentioned,
@@ -2525,7 +2526,7 @@ async function applyGroupGating(params) {
2525
2526
  };
2526
2527
  }
2527
2528
  const accountId = inboundPolicy.account.accountId;
2528
- if (shouldWarnForGroupDrop(JSON.stringify([
2529
+ if (!groupDropWarned.check(JSON.stringify([
2529
2530
  accountId,
2530
2531
  conversationId,
2531
2532
  "no mention"
@@ -2682,15 +2683,12 @@ function isLikelyWhatsAppCryptoError(reason) {
2682
2683
  } catch {
2683
2684
  return Object.prototype.toString.call(value);
2684
2685
  }
2685
- if (typeof value === "number") return String(value);
2686
- if (typeof value === "boolean") return String(value);
2687
- if (typeof value === "bigint") return String(value);
2686
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
2688
2687
  if (typeof value === "symbol") return value.description ?? value.toString();
2689
2688
  if (typeof value === "function") return value.name ? `[function ${value.name}]` : "[function]";
2690
2689
  return Object.prototype.toString.call(value);
2691
2690
  };
2692
- const raw = reason instanceof Error ? `${reason.message}\n${reason.stack ?? ""}` : formatReason(reason);
2693
- const haystack = normalizeLowercaseStringOrEmpty(raw);
2691
+ const haystack = normalizeLowercaseStringOrEmpty(formatReason(reason));
2694
2692
  if (!(haystack.includes("unsupported state or unable to authenticate data") || haystack.includes("bad mac"))) return false;
2695
2693
  return haystack.includes("baileys") || haystack.includes("noise-handler") || haystack.includes("aesdecryptgcm");
2696
2694
  }
@@ -2920,7 +2918,6 @@ async function deliverWebReplyInActivityScope(params) {
2920
2918
  return;
2921
2919
  }
2922
2920
  const fallbackText = [caption ?? "", "⚠️ Media failed."].filter(Boolean).join("\n");
2923
- if (!fallbackText) return;
2924
2921
  whatsappOutboundLog.warn(`Media skipped; sent text-only to ${conversationId}`);
2925
2922
  rememberSendResult(await sendWithRetry(() => transport.reply(fallbackText, getQuote()), "media:fallback-text", "text"));
2926
2923
  }
@@ -3055,9 +3052,6 @@ function normalizeErrForLog(err) {
3055
3052
  };
3056
3053
  return err;
3057
3054
  }
3058
- function whatsAppReplyDeliveryVisibility(visibleReplySent) {
3059
- return { visibleReplySent };
3060
- }
3061
3055
  function createWhatsAppChannelDeliveryResult(params) {
3062
3056
  const messageIds = listMessageReceiptPlatformIds(params.delivery.receipt);
3063
3057
  return {
@@ -3144,18 +3138,13 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
3144
3138
  };
3145
3139
  return {
3146
3140
  defer(pending) {
3147
- let resolveFinalization;
3148
- let rejectFinalization;
3149
- const finalization = new Promise((resolve, reject) => {
3150
- resolveFinalization = resolve;
3151
- rejectFinalization = reject;
3152
- });
3141
+ const finalization = createDeferred();
3153
3142
  pendingMediaOnlyPayloads.push({
3154
3143
  ...pending,
3155
- resolveFinalization,
3156
- rejectFinalization
3144
+ resolveFinalization: finalization.resolve,
3145
+ rejectFinalization: finalization.reject
3157
3146
  });
3158
- return finalization;
3147
+ return finalization.promise;
3159
3148
  },
3160
3149
  flushNonDuplicateMedia: (mediaUrls) => flushWhere((pending) => !hasWhatsAppMediaUrlOverlap(pending.mediaUrls, mediaUrls)),
3161
3150
  supersedeMedia(mediaUrl) {
@@ -3175,7 +3164,7 @@ function createWhatsAppMediaOnlyReplyCoalescer(params) {
3175
3164
  };
3176
3165
  }
3177
3166
  if (pending.mediaUrls.size === 0) {
3178
- pending.resolveFinalization(whatsAppReplyDeliveryVisibility(false));
3167
+ pending.resolveFinalization({ visibleReplySent: false });
3179
3168
  continue;
3180
3169
  }
3181
3170
  retained.push(pending);
@@ -3366,7 +3355,7 @@ function createWhatsAppReplyPlan(params) {
3366
3355
  };
3367
3356
  const deliverNormalizedPayload = async (normalizedDeliveryPayload, info, options) => {
3368
3357
  const reply = resolveSendableOutboundReplyParts(normalizedDeliveryPayload);
3369
- if (!reply.hasMedia && !reply.text.trim()) return whatsAppReplyDeliveryVisibility(false);
3358
+ if (!reply.hasMedia && !reply.text.trim()) return { visibleReplySent: false };
3370
3359
  let delivery;
3371
3360
  try {
3372
3361
  delivery = await params.deliverReply({
@@ -3427,7 +3416,7 @@ function createWhatsAppReplyPlan(params) {
3427
3416
  onSettled: async () => {
3428
3417
  const flushResult = await mediaOnlyCoalescer.flushAll();
3429
3418
  logWhatsAppMediaOnlyFlushResult(flushResult);
3430
- return whatsAppReplyDeliveryVisibility(didSendReply || flushResult.delivered > 0);
3419
+ return { visibleReplySent: didSendReply || flushResult.delivered > 0 };
3431
3420
  },
3432
3421
  onReplyStart: params.transport.sendComposing
3433
3422
  },
@@ -3475,7 +3464,7 @@ function createWhatsAppReplyPlan(params) {
3475
3464
  deliver: async (payload, info) => {
3476
3465
  const normalizedDeliveryPayload = payload;
3477
3466
  const reply = resolveSendableOutboundReplyParts(normalizedDeliveryPayload);
3478
- if (!reply.hasMedia && !reply.text.trim()) return whatsAppReplyDeliveryVisibility(false);
3467
+ if (!reply.hasMedia && !reply.text.trim()) return { visibleReplySent: false };
3479
3468
  if (!reply.hasMedia) return await deliverNormalizedPayload(normalizedDeliveryPayload, info, { recordDelivery: false });
3480
3469
  const mediaUrls = new Set(normalizedDeliveryPayload.mediaUrls);
3481
3470
  if (shouldDeferWhatsAppMediaOnlyPayload({
@@ -3536,20 +3525,11 @@ function createWhatsAppReplyPlan(params) {
3536
3525
  finalize: (dispatchResult) => {
3537
3526
  const didQueueVisibleReply = hasVisibleInboundReplyDispatch(dispatchResult);
3538
3527
  const didDeliverVisibleReply = didSendReply || dispatchResult.observedReplyDelivery === true;
3539
- if (!didQueueVisibleReply && !didDeliverVisibleReply) {
3540
- if (statusReactionController) finalizeWhatsAppStatusReaction({
3541
- controller: statusReactionController,
3542
- outcome: "error"
3543
- });
3544
- if (params.shouldClearGroupHistory) params.groupHistories.set(params.groupHistoryKey, []);
3545
- logVerbose$1("Skipping auto-reply: silent token or no text/media returned from resolver");
3546
- return false;
3547
- }
3548
3528
  if (statusReactionController) finalizeWhatsAppStatusReaction({
3549
3529
  controller: statusReactionController,
3550
3530
  outcome: readAgentRunTerminalOutcome(dispatchResult) === "failed" || !didDeliverVisibleReply ? "error" : "done"
3551
3531
  });
3552
- 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");
3553
3533
  return didDeliverVisibleReply;
3554
3534
  }
3555
3535
  };
@@ -3565,15 +3545,12 @@ function formatReplyTarget(replyTo) {
3565
3545
  if (!replyTo?.body) return null;
3566
3546
  return `[Replying to ${replyTo.sender?.label ?? replyTo.sender?.e164 ?? "unknown sender"}${replyTo.id ? ` id:${replyTo.id}` : ""}]\n${replyTo.body}\n[/Replying]`;
3567
3547
  }
3568
- function formatReplyContext(msg) {
3569
- return formatReplyTarget(getReplyContext(msg));
3570
- }
3571
3548
  function buildInboundLine(params) {
3572
3549
  const { msg, previousTimestamp, envelope } = params;
3573
3550
  const admission = requireWhatsAppInboundAdmission(msg);
3574
3551
  const conversationId = admission.conversation.id;
3575
3552
  const conversationKind = admission.conversation.kind;
3576
- const replyContext = params.visibleReplyTo === void 0 ? formatReplyContext(msg) : formatReplyTarget(params.visibleReplyTo);
3553
+ const replyContext = formatReplyTarget(params.visibleReplyTo === void 0 ? getReplyContext(msg) : params.visibleReplyTo);
3577
3554
  const baseLine = `${msg.payload.body}${replyContext ? `\n\n${replyContext}` : ""}`;
3578
3555
  const sender = getSenderIdentity(msg);
3579
3556
  return formatInboundEnvelope({
@@ -3597,13 +3574,7 @@ function buildInboundLine(params) {
3597
3574
  async function createWhatsAppStatusReactionController(params) {
3598
3575
  if (!params.msg.event.id) return null;
3599
3576
  if ((params.cfg.messages?.statusReactions)?.enabled !== true) return null;
3600
- const eligibility = await resolveWhatsAppReactionEligibility({
3601
- cfg: params.cfg,
3602
- msg: params.msg,
3603
- agentId: params.agentId,
3604
- sessionKey: params.sessionKey,
3605
- verbose: params.verbose
3606
- });
3577
+ const eligibility = await resolveWhatsAppReactionEligibility(params);
3607
3578
  if (eligibility.status === "disabled") return null;
3608
3579
  const { chatId, messageId, emoji: initialEmoji, reactionOptions } = eligibility;
3609
3580
  return createStatusReactionController({
@@ -3630,39 +3601,37 @@ const WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS = {
3630
3601
  maxQueue: 128,
3631
3602
  timeoutMs: 2e3
3632
3603
  };
3633
- function readWhatsAppMessageReceivedHookOptIn(value) {
3634
- if (!value || typeof value !== "object") return;
3635
- const pluginHooks = value.pluginHooks;
3636
- if (pluginHooks?.messageReceived === void 0) return;
3637
- 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
+ };
3638
3623
  }
3639
3624
  function shouldEmitWhatsAppMessageReceivedHooks(params) {
3640
3625
  const channelConfig = params.cfg.channels?.whatsapp;
3641
- 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;
3642
3627
  }
3643
- function emitWhatsAppMessageReceivedHooks(params) {
3628
+ function emitWhatsAppMessageReceivedHooksIfEnabled(params) {
3629
+ if (!shouldEmitWhatsAppMessageReceivedHooks(params)) return;
3644
3630
  const canonical = deriveInboundMessageHookContext(params.ctx);
3645
3631
  const hookRunner = getGlobalHookRunner();
3646
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);
3647
3633
  fireAndForgetBoundedHook(() => triggerInternalHook(createInternalHookEvent("message", "received", params.sessionKey, toInternalMessageReceivedContext(canonical))), "whatsapp: message_received internal hook failed", void 0, WHATSAPP_MESSAGE_RECEIVED_HOOK_LIMITS);
3648
3634
  }
3649
- function emitWhatsAppMessageReceivedHooksIfEnabled(params) {
3650
- if (!shouldEmitWhatsAppMessageReceivedHooks({
3651
- cfg: params.cfg,
3652
- accountId: params.accountId
3653
- })) return;
3654
- emitWhatsAppMessageReceivedHooks({
3655
- ctx: params.ctx,
3656
- sessionKey: params.sessionKey
3657
- });
3658
- }
3659
- function resolvePinnedMainDmRecipient(params) {
3660
- return resolvePinnedMainDmOwnerFromAllowlist({
3661
- dmScope: params.cfg.session?.dmScope,
3662
- allowFrom: params.allowFrom,
3663
- normalizeEntry: (entry) => normalizeE164(entry)
3664
- });
3665
- }
3666
3635
  async function processMessage(params) {
3667
3636
  const admission = requireWhatsAppInboundAdmission(params.msg);
3668
3637
  if (admission.ingress.admission !== "dispatch" && admission.ingress.admission !== "observe") return false;
@@ -3686,26 +3655,8 @@ async function processMessage(params) {
3686
3655
  sessionKey: params.route.sessionKey
3687
3656
  });
3688
3657
  let audioTranscript = params.preflightAudioTranscript ?? void 0;
3689
- const hasAudioBody = (params.msg.payload.media?.kind === "audio" || params.msg.payload.media?.type?.startsWith("audio/") === true) && !params.msg.payload.body.trim();
3690
- if (params.preflightAudioTranscript === void 0 && hasAudioBody && params.msg.payload.media?.path) try {
3691
- const { transcribeFirstAudio } = await import("./audio-preflight.runtime-C_glQhZY.mjs");
3692
- audioTranscript = await transcribeFirstAudio({
3693
- ctx: {
3694
- media: [{
3695
- path: params.msg.payload.media.path,
3696
- contentType: params.msg.payload.media.type,
3697
- kind: params.msg.payload.media.kind ?? void 0
3698
- }],
3699
- From: conversationId,
3700
- To: params.msg.platform.recipientJid,
3701
- Provider: "whatsapp",
3702
- Surface: "whatsapp",
3703
- OriginatingChannel: "whatsapp",
3704
- OriginatingTo: conversationId,
3705
- AccountId: params.route.accountId
3706
- },
3707
- cfg: params.cfg
3708
- });
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);
3709
3660
  } catch {
3710
3661
  if (shouldLogVerbose$1()) logVerbose$1("whatsapp: audio preflight transcription failed, keeping structured audio");
3711
3662
  }
@@ -3729,7 +3680,6 @@ async function processMessage(params) {
3729
3680
  envelope: envelopeOptions,
3730
3681
  visibleReplyTo
3731
3682
  });
3732
- let shouldClearGroupHistory = false;
3733
3683
  const visibleGroupHistory = conversationKind === "group" ? resolveVisibleWhatsAppGroupHistory({
3734
3684
  history: params.groupHistory ?? params.groupHistories.get(params.groupHistoryKey) ?? [],
3735
3685
  mode: contextVisibilityMode,
@@ -3763,7 +3713,6 @@ async function processMessage(params) {
3763
3713
  }
3764
3714
  });
3765
3715
  }
3766
- shouldClearGroupHistory = !(params.suppressGroupHistoryClear ?? false);
3767
3716
  }
3768
3717
  const statusReactionController = params.statusReactionController ?? (params.cfg.messages?.statusReactions?.enabled === true && !params.ackAlreadySent ? await createWhatsAppStatusReactionController({
3769
3718
  cfg: params.cfg,
@@ -3793,16 +3742,15 @@ async function processMessage(params) {
3793
3742
  mediaType: params.msg.payload.media?.type ?? null,
3794
3743
  mediaPath: params.msg.payload.media?.path ?? null
3795
3744
  }, "inbound web message");
3796
- const fromDisplay = conversationId;
3797
3745
  const kindLabel = params.msg.payload.media?.type ? `, ${params.msg.payload.media?.type}` : "";
3798
- 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)`);
3799
3747
  if (shouldLogVerbose$1()) whatsappInboundLog.debug(`Inbound body: ${elide(combinedBody, 400)}`);
3800
3748
  const sender = getSenderIdentity(params.msg);
3801
3749
  const commandBody = params.msg.payload.commandBody ?? params.msg.payload.body;
3802
3750
  const dmRouteTarget = resolveWhatsAppDmRouteTarget({
3803
3751
  msg: params.msg,
3804
3752
  senderE164: sender.e164 ?? void 0,
3805
- normalizeE164
3753
+ normalizeE164: normalizeE164$1
3806
3754
  });
3807
3755
  const shouldCheckCommandAuth = shouldComputeCommandAuthorized(commandBody, params.cfg);
3808
3756
  const isTextCommand = isControlCommandMessage(commandBody, params.cfg);
@@ -3860,6 +3808,8 @@ async function processMessage(params) {
3860
3808
  visibleReplyTo: visibleReplyTo ?? void 0,
3861
3809
  suppressMessageReceivedHooks: true
3862
3810
  });
3811
+ const turnAdmission = mapWhatsAppIngressToTurnAdmission(inbound.channelIngress?.ingress ?? admission.ingress);
3812
+ const shouldClearGroupHistory = conversationKind === "group" && params.suppressGroupHistoryClear !== true;
3863
3813
  const transport = buildWhatsAppInboundTransportContext(params.msg);
3864
3814
  const ingressLifecycle = resolveWhatsAppIngressLifecycle(params.msg);
3865
3815
  const turnAdoptionLifecycle = ingressLifecycle ? bindIngressLifecycleToReplyOptions(ingressLifecycle).turnAdoptionLifecycle : void 0;
@@ -3869,9 +3819,10 @@ async function processMessage(params) {
3869
3819
  accountId: params.route.accountId,
3870
3820
  sessionKey: params.route.sessionKey
3871
3821
  });
3872
- const pinnedMainDmRecipient = resolvePinnedMainDmRecipient({
3873
- cfg: params.cfg,
3874
- allowFrom: inboundPolicy.configuredAllowFrom
3822
+ const pinnedMainDmRecipient = resolvePinnedMainDmOwnerFromAllowlist({
3823
+ dmScope: params.cfg.session?.dmScope,
3824
+ allowFrom: inboundPolicy.configuredAllowFrom,
3825
+ normalizeEntry: normalizeE164$1
3875
3826
  });
3876
3827
  updateWhatsAppMainLastRoute({
3877
3828
  backgroundTasks: params.backgroundTasks,
@@ -3891,25 +3842,9 @@ async function processMessage(params) {
3891
3842
  ...turnAdoptionLifecycle ? { turnAdoptionLifecycle } : {},
3892
3843
  adapter: {
3893
3844
  ingest: () => turnInput,
3894
- preflight: () => {
3895
- const reason = admission.ingress.reasonCode;
3896
- if (admission.ingress.admission === "dispatch") return { admission: {
3897
- kind: "dispatch",
3898
- reason
3899
- } };
3900
- if (admission.ingress.admission === "observe") return { admission: {
3901
- kind: "observeOnly",
3902
- reason
3903
- } };
3904
- if (admission.ingress.admission === "skip") return { admission: {
3905
- kind: "handled",
3906
- reason
3907
- } };
3908
- return { admission: {
3909
- kind: "drop",
3910
- reason,
3911
- recordHistory: false
3912
- } };
3845
+ preflight: () => ({ admission: turnAdmission }),
3846
+ onFinalize: (result) => {
3847
+ if (result.dispatched && turnAdmission.kind === "dispatch" && shouldClearGroupHistory) params.groupHistories.set(params.groupHistoryKey, []);
3913
3848
  },
3914
3849
  resolveTurn: () => {
3915
3850
  const { finalize, ...replyPlan } = createWhatsAppReplyPlan({
@@ -3917,8 +3852,6 @@ async function processMessage(params) {
3917
3852
  connectionId: params.connectionId,
3918
3853
  context: ctxPayload,
3919
3854
  deliverReply: deliverWebReply,
3920
- groupHistories: params.groupHistories,
3921
- groupHistoryKey: params.groupHistoryKey,
3922
3855
  maxMediaBytes: params.maxMediaBytes,
3923
3856
  maxMediaTextChunkLimit: params.maxMediaTextChunkLimit,
3924
3857
  inbound,
@@ -3930,7 +3863,6 @@ async function processMessage(params) {
3930
3863
  },
3931
3864
  replyResolver: params.replyResolver,
3932
3865
  route: params.route,
3933
- shouldClearGroupHistory,
3934
3866
  statusReactionController,
3935
3867
  transport,
3936
3868
  turnAdoptionLifecycle
@@ -3981,7 +3913,6 @@ async function processMessage(params) {
3981
3913
  //#endregion
3982
3914
  //#region extensions/whatsapp/src/auto-reply/monitor/on-message.ts
3983
3915
  function createWebOnMessageHandler(params) {
3984
- const hasExplicitlyPassedInboundAccess = (msg) => msg.admission.ingress.decision === "allow";
3985
3916
  const withDirectSenderPeer = (msg, peerId) => {
3986
3917
  if (requireWhatsAppInboundAdmission(msg).conversation.kind === "group" || msg.platform.sender?.e164 || msg.platform.senderE164 || !peerId.startsWith("+")) return msg;
3987
3918
  const normalized = normalizeE164(peerId);
@@ -3999,7 +3930,7 @@ function createWebOnMessageHandler(params) {
3999
3930
  };
4000
3931
  };
4001
3932
  const processForRoute = async (cfg, msg, route, groupHistoryKey, opts) => {
4002
- const processParams = {
3933
+ return processMessage({
4003
3934
  cfg,
4004
3935
  msg,
4005
3936
  route,
@@ -4014,18 +3945,12 @@ function createWebOnMessageHandler(params) {
4014
3945
  replyLogger: params.replyLogger,
4015
3946
  backgroundTasks: params.backgroundTasks,
4016
3947
  buildContext: params.buildContext,
4017
- dispatchReplyFromConfig: params.dispatchReplyFromConfig
4018
- };
4019
- if (opts?.groupHistory !== void 0) processParams.groupHistory = opts.groupHistory;
4020
- if (opts?.suppressGroupHistoryClear !== void 0) processParams.suppressGroupHistoryClear = opts.suppressGroupHistoryClear;
4021
- if (opts?.preflightAudioTranscript !== void 0) processParams.preflightAudioTranscript = opts.preflightAudioTranscript;
4022
- if (opts?.ackAlreadySent === true) processParams.ackAlreadySent = true;
4023
- if (opts?.ackReaction !== void 0) processParams.ackReaction = opts.ackReaction;
4024
- if (opts?.statusReactionController !== void 0) processParams.statusReactionController = opts.statusReactionController;
4025
- return processMessage(processParams);
3948
+ dispatchReplyFromConfig: params.dispatchReplyFromConfig,
3949
+ ...opts
3950
+ });
4026
3951
  };
4027
3952
  return async (normalizedMsg) => {
4028
- const canRunDirectEarlyAudioPreflight = hasExplicitlyPassedInboundAccess(normalizedMsg);
3953
+ const canRunDirectEarlyAudioPreflight = normalizedMsg.admission.ingress.decision === "allow";
4029
3954
  const cfg = params.loadConfig?.() ?? params.cfg;
4030
3955
  const peerId = resolvePeerId(normalizedMsg);
4031
3956
  const msg = withDirectSenderPeer(normalizedMsg, peerId);
@@ -4065,7 +3990,7 @@ function createWebOnMessageHandler(params) {
4065
3990
  peerId
4066
3991
  }) : route.sessionKey;
4067
3992
  let preflightAudioTranscript;
4068
- const hasAudioBody = (msg.payload.media?.kind === "audio" || msg.payload.media?.type?.startsWith("audio/") === true) && !msg.payload.body.trim();
3993
+ const hasAudioBody = hasWhatsAppAudioBody(msg);
4069
3994
  const canRunEarlyAudioPreflight = conversationKind === "group" || canRunDirectEarlyAudioPreflight;
4070
3995
  let ackAlreadySent = false;
4071
3996
  let ackReaction = null;
@@ -4088,24 +4013,7 @@ function createWebOnMessageHandler(params) {
4088
4013
  const transcribeAudioOnce = async () => {
4089
4014
  if (preflightAudioTranscript !== void 0 || !hasAudioBody || !msg.payload.media?.path) return;
4090
4015
  try {
4091
- const { transcribeFirstAudio } = await import("./audio-preflight.runtime-C_glQhZY.mjs");
4092
- preflightAudioTranscript = await transcribeFirstAudio({
4093
- ctx: {
4094
- media: [{
4095
- path: msg.payload.media.path,
4096
- contentType: msg.payload.media.type,
4097
- kind: msg.payload.media.kind ?? void 0
4098
- }],
4099
- From: conversationId,
4100
- To: msg.platform.recipientJid,
4101
- Provider: "whatsapp",
4102
- Surface: "whatsapp",
4103
- OriginatingChannel: "whatsapp",
4104
- OriginatingTo: conversationId,
4105
- AccountId: route.accountId
4106
- },
4107
- cfg
4108
- }) ?? null;
4016
+ preflightAudioTranscript = await transcribeWhatsAppAudioMessage(cfg, msg, route.accountId) ?? null;
4109
4017
  } catch {
4110
4018
  preflightAudioTranscript = null;
4111
4019
  }
@@ -4165,10 +4073,9 @@ function createWebOnMessageHandler(params) {
4165
4073
  warn: params.replyLogger.warn.bind(params.replyLogger)
4166
4074
  });
4167
4075
  recordAcceptedConfiguredGroupRoute = recordGroupRoute;
4168
- let gating = await applyGroupGating({
4076
+ const gatingParams = {
4169
4077
  cfg,
4170
4078
  msg,
4171
- deferMissingMention: hasAudioBody && Boolean(msg.payload.media?.path),
4172
4079
  groupHistoryKey,
4173
4080
  agentId: route.agentId,
4174
4081
  sessionKey: route.sessionKey,
@@ -4181,25 +4088,16 @@ function createWebOnMessageHandler(params) {
4181
4088
  groupMemberNames: params.groupMemberNames,
4182
4089
  logVerbose,
4183
4090
  replyLogger: params.replyLogger
4091
+ };
4092
+ let gating = await applyGroupGating({
4093
+ ...gatingParams,
4094
+ deferMissingMention: hasAudioBody && Boolean(msg.payload.media?.path)
4184
4095
  });
4185
4096
  if (!gating.shouldProcess && "needsMentionText" in gating && gating.needsMentionText === true) {
4186
4097
  await runAudioPreflightOnce();
4187
4098
  gating = await applyGroupGating({
4188
- cfg,
4189
- msg,
4190
- ...typeof preflightAudioTranscript === "string" ? { mentionText: preflightAudioTranscript } : {},
4191
- groupHistoryKey,
4192
- agentId: route.agentId,
4193
- sessionKey: route.sessionKey,
4194
- baseMentionConfig,
4195
- providerMentionPatterns: account.mentionPatterns,
4196
- authDir: account.authDir,
4197
- selfChatMode: account.selfChatMode,
4198
- groupHistories: params.groupHistories,
4199
- groupHistoryLimit: params.groupHistoryLimit,
4200
- groupMemberNames: params.groupMemberNames,
4201
- logVerbose,
4202
- replyLogger: params.replyLogger
4099
+ ...gatingParams,
4100
+ ...typeof preflightAudioTranscript === "string" ? { mentionText: preflightAudioTranscript } : {}
4203
4101
  });
4204
4102
  }
4205
4103
  if (!gating.shouldProcess) {
@@ -4322,8 +4220,7 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4322
4220
  const heartbeatSeconds = resolveHeartbeatSeconds(cfg, tuning.heartbeatSeconds);
4323
4221
  const reconnectPolicy = resolveReconnectPolicy(cfg, tuning.reconnect);
4324
4222
  const socketTiming = resolveWhatsAppSocketTiming(tuning.socketTiming);
4325
- const baseMentionConfig = buildMentionConfig(cfg);
4326
- const groupHistoryLimit = account.historyLimit ?? cfg.channels?.whatsapp?.historyLimit ?? cfg.messages?.groupChat?.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT;
4223
+ const groupHistoryLimit = resolvePromptHistoryLimit(account.historyLimit ?? cfg.channels?.whatsapp?.historyLimit ?? cfg.messages?.groupChat?.historyLimit);
4327
4224
  const groupHistories = /* @__PURE__ */ new Map();
4328
4225
  const groupMemberNames = /* @__PURE__ */ new Map();
4329
4226
  const groupMetadataCache = /* @__PURE__ */ new Map();
@@ -4392,8 +4289,6 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4392
4289
  backgroundTasks: connectionLocal.backgroundTasks,
4393
4290
  replyResolver: activeReplyResolver,
4394
4291
  replyLogger,
4395
- baseMentionConfig,
4396
- account,
4397
4292
  buildContext: pluginChannelRuntime?.inbound.buildContext,
4398
4293
  dispatchReplyFromConfig: pluginChannelRuntime?.reply?.dispatchReplyFromConfig
4399
4294
  });
@@ -4573,38 +4468,25 @@ async function monitorWebChannel(verbose, listenerFactory = attachWebInboxToSock
4573
4468
  });
4574
4469
  enqueueSystemEvent(`WhatsApp gateway connected${selfE164 ? ` as ${selfE164}` : ""}.`, { sessionKey: connectRoute.sessionKey });
4575
4470
  const normalizedAccountId = normalizeReconnectAccountId(account.accountId);
4576
- drainPendingDeliveries({
4577
- drainKey: `whatsapp:${normalizedAccountId}`,
4578
- logLabel: "WhatsApp reconnect drain",
4579
- cfg,
4580
- log: reconnectLogger,
4581
- selectEntry: (entry) => ({
4582
- match: entry.channel === "whatsapp" && normalizeReconnectAccountId(entry.accountId) === normalizedAccountId,
4583
- bypassBackoff: isNoListenerReconnectError(entry.lastError)
4584
- })
4585
- }).catch((err) => {
4586
- reconnectLogger.warn({
4587
- connectionId: connection.connectionId,
4588
- error: String(err)
4589
- }, "reconnect drain failed");
4590
- });
4591
- const periodicDrainInterval = setInterval(() => {
4471
+ const drainDeliveries = (mode) => {
4592
4472
  drainPendingDeliveries({
4593
4473
  drainKey: `whatsapp:${normalizedAccountId}`,
4594
- logLabel: "WhatsApp periodic drain",
4474
+ logLabel: `WhatsApp ${mode} drain`,
4595
4475
  cfg,
4596
4476
  log: reconnectLogger,
4597
4477
  selectEntry: (entry) => ({
4598
4478
  match: entry.channel === "whatsapp" && normalizeReconnectAccountId(entry.accountId) === normalizedAccountId,
4599
- bypassBackoff: false
4479
+ bypassBackoff: mode === "reconnect" && isNoListenerReconnectError(entry.lastError)
4600
4480
  })
4601
4481
  }).catch((err) => {
4602
4482
  reconnectLogger.warn({
4603
4483
  connectionId: connection.connectionId,
4604
4484
  error: String(err)
4605
- }, "periodic drain failed");
4485
+ }, `${mode} drain failed`);
4606
4486
  });
4607
- }, 3e4);
4487
+ };
4488
+ drainDeliveries("reconnect");
4489
+ const periodicDrainInterval = setInterval(() => drainDeliveries("periodic"), 3e4);
4608
4490
  const inboundPolicy = resolveWhatsAppInboundPolicy({
4609
4491
  cfg,
4610
4492
  accountId: account.accountId,