@poolzin/pool-bot 2026.2.24 → 2026.2.26

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 (646) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/acp/client.js +207 -18
  3. package/dist/acp/event-mapper.js +87 -22
  4. package/dist/acp/meta.js +12 -6
  5. package/dist/acp/secret-file.js +22 -0
  6. package/dist/agents/agent-paths.js +8 -9
  7. package/dist/agents/agent-scope.js +17 -5
  8. package/dist/agents/auth-profiles/oauth.js +148 -64
  9. package/dist/agents/auth-profiles/session-override.js +13 -7
  10. package/dist/agents/bash-process-registry.test-helpers.js +29 -0
  11. package/dist/agents/bash-tools.exec-approval-request.js +20 -0
  12. package/dist/agents/bash-tools.exec-host-gateway.js +240 -0
  13. package/dist/agents/bash-tools.exec-host-node.js +235 -0
  14. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  15. package/dist/agents/bash-tools.exec-types.js +1 -0
  16. package/dist/agents/bash-tools.process.js +224 -218
  17. package/dist/agents/bedrock-discovery.js +3 -1
  18. package/dist/agents/byteplus-models.js +97 -0
  19. package/dist/agents/chutes-oauth.js +1 -0
  20. package/dist/agents/cli-runner/helpers.js +4 -0
  21. package/dist/agents/compaction.js +41 -14
  22. package/dist/agents/content-blocks.js +16 -0
  23. package/dist/agents/doubao-models.js +121 -0
  24. package/dist/agents/failover-error.js +2 -0
  25. package/dist/agents/huggingface-models.js +5 -3
  26. package/dist/agents/live-model-filter.js +5 -0
  27. package/dist/agents/minimax-vlm.js +10 -8
  28. package/dist/agents/model-auth.js +6 -0
  29. package/dist/agents/model-catalog.js +3 -1
  30. package/dist/agents/model-fallback.js +96 -101
  31. package/dist/agents/model-selection.js +7 -1
  32. package/dist/agents/models-config.providers.js +364 -165
  33. package/dist/agents/ollama-stream.js +117 -4
  34. package/dist/agents/opencode-zen-models.js +22 -11
  35. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  36. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  37. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  38. package/dist/agents/pi-embedded-helpers.js +1 -1
  39. package/dist/agents/pi-embedded-payloads.js +1 -0
  40. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  41. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  42. package/dist/agents/pi-embedded-runner/google.js +20 -8
  43. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  44. package/dist/agents/pi-embedded-runner/run.js +71 -12
  45. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +34 -0
  46. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  47. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  48. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  49. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  50. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  51. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  52. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  53. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  54. package/dist/agents/pi-embedded-subscribe.js +9 -4
  55. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  56. package/dist/agents/pi-embedded-utils.js +3 -0
  57. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  58. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  59. package/dist/agents/pi-settings.js +40 -0
  60. package/dist/agents/pi-tools.policy.js +2 -1
  61. package/dist/agents/provider/config-loader.js +1 -1
  62. package/dist/agents/sandbox/browser.js +170 -33
  63. package/dist/agents/sandbox/config-hash.js +14 -27
  64. package/dist/agents/sandbox/config.js +21 -2
  65. package/dist/agents/sandbox/constants.js +2 -0
  66. package/dist/agents/sandbox/docker.js +16 -2
  67. package/dist/agents/sandbox/novnc-auth.js +62 -0
  68. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  69. package/dist/agents/sandbox/shared.js +10 -6
  70. package/dist/agents/sandbox-paths.js +24 -11
  71. package/dist/agents/schema/clean-for-gemini.js +132 -85
  72. package/dist/agents/session-slug.js +10 -5
  73. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  74. package/dist/agents/session-tool-result-guard.js +3 -1
  75. package/dist/agents/session-transcript-repair.js +40 -6
  76. package/dist/agents/skills/bundled-dir.js +19 -5
  77. package/dist/agents/skills/env-overrides.js +124 -43
  78. package/dist/agents/skills/frontmatter.js +6 -6
  79. package/dist/agents/skills/plugin-skills.js +14 -7
  80. package/dist/agents/skills/workspace.js +1 -0
  81. package/dist/agents/skills.test-helpers.js +13 -0
  82. package/dist/agents/stable-stringify.js +12 -0
  83. package/dist/agents/subagent-announce.js +251 -49
  84. package/dist/agents/subagent-lifecycle-events.js +19 -0
  85. package/dist/agents/subagent-registry-cleanup.js +31 -0
  86. package/dist/agents/subagent-registry-completion.js +68 -0
  87. package/dist/agents/subagent-registry-queries.js +117 -0
  88. package/dist/agents/subagent-registry-state.js +46 -0
  89. package/dist/agents/subagent-registry.js +252 -221
  90. package/dist/agents/subagent-registry.mocks.shared.js +12 -0
  91. package/dist/agents/subagent-registry.store.js +1 -0
  92. package/dist/agents/subagent-registry.types.js +1 -0
  93. package/dist/agents/subagent-spawn.js +195 -7
  94. package/dist/agents/system-prompt.js +22 -6
  95. package/dist/agents/test-helpers/assistant-message-fixtures.js +29 -0
  96. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  97. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  98. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +27 -0
  99. package/dist/agents/timeout.js +18 -6
  100. package/dist/agents/tool-call-id.js +1 -1
  101. package/dist/agents/tool-display-common.js +162 -29
  102. package/dist/agents/tool-images.js +82 -9
  103. package/dist/agents/tool-policy-shared.js +108 -0
  104. package/dist/agents/tool-policy.js +51 -26
  105. package/dist/agents/tools/browser-tool.js +160 -54
  106. package/dist/agents/tools/canvas-tool.js +27 -1
  107. package/dist/agents/tools/common.js +45 -0
  108. package/dist/agents/tools/cron-tool.test-helpers.js +12 -0
  109. package/dist/agents/tools/discord-actions-guild.js +4 -1
  110. package/dist/agents/tools/discord-actions-moderation-shared.js +27 -0
  111. package/dist/agents/tools/gateway-tool.js +3 -1
  112. package/dist/agents/tools/image-tool.js +214 -99
  113. package/dist/agents/tools/nodes-utils.js +1 -10
  114. package/dist/agents/tools/sessions-history-tool.js +140 -108
  115. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  116. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  117. package/dist/agents/tools/subagents-tool.js +2 -1
  118. package/dist/agents/tools/whatsapp-actions.js +10 -2
  119. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  120. package/dist/agents/transcript-policy.js +22 -8
  121. package/dist/agents/venice-models.js +11 -3
  122. package/dist/agents/workspace.js +222 -46
  123. package/dist/auto-reply/commands-registry.data.js +51 -0
  124. package/dist/auto-reply/commands-registry.js +19 -21
  125. package/dist/auto-reply/fallback-state.js +114 -0
  126. package/dist/auto-reply/group-activation.js +10 -5
  127. package/dist/auto-reply/inbound-debounce.js +10 -5
  128. package/dist/auto-reply/model-runtime.js +68 -0
  129. package/dist/auto-reply/reply/abort.js +1 -1
  130. package/dist/auto-reply/reply/agent-runner-execution.js +40 -5
  131. package/dist/auto-reply/reply/agent-runner.js +165 -39
  132. package/dist/auto-reply/reply/bash-command.js +41 -39
  133. package/dist/auto-reply/reply/command-gates.js +25 -0
  134. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  135. package/dist/auto-reply/reply/commands-bash.js +6 -5
  136. package/dist/auto-reply/reply/commands-config.js +30 -28
  137. package/dist/auto-reply/reply/commands-core.js +2 -1
  138. package/dist/auto-reply/reply/commands-info.js +1 -0
  139. package/dist/auto-reply/reply/commands-models.js +65 -14
  140. package/dist/auto-reply/reply/commands-session.js +237 -82
  141. package/dist/auto-reply/reply/commands-setunset-standard.js +13 -0
  142. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  143. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  144. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  145. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  146. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  147. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  148. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  149. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  150. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  151. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  152. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  153. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  154. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  155. package/dist/auto-reply/reply/commands-tts.js +10 -5
  156. package/dist/auto-reply/reply/config-value.js +10 -5
  157. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  158. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  159. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  160. package/dist/auto-reply/reply/followup-runner.js +1 -0
  161. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  162. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  163. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  164. package/dist/auto-reply/reply/get-reply.js +71 -12
  165. package/dist/auto-reply/reply/model-selection.js +80 -39
  166. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  167. package/dist/auto-reply/reply/queue/state.js +13 -12
  168. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  169. package/dist/auto-reply/reply/reply-reference.js +9 -8
  170. package/dist/auto-reply/reply/route-reply.js +15 -8
  171. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  172. package/dist/auto-reply/reply/session.js +22 -6
  173. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  174. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  175. package/dist/auto-reply/reply/typing.js +46 -21
  176. package/dist/auto-reply/send-policy.js +14 -7
  177. package/dist/auto-reply/status.js +140 -16
  178. package/dist/auto-reply/templating.js +10 -5
  179. package/dist/auto-reply/thinking.js +7 -16
  180. package/dist/auto-reply/tokens.js +21 -5
  181. package/dist/browser/bridge-server.js +36 -20
  182. package/dist/browser/cdp.helpers.js +7 -14
  183. package/dist/browser/cdp.js +35 -15
  184. package/dist/browser/chrome.profile-decoration.js +7 -4
  185. package/dist/browser/config.js +30 -0
  186. package/dist/browser/extension-relay-auth.js +55 -0
  187. package/dist/browser/extension-relay.js +74 -29
  188. package/dist/browser/navigation-guard.js +39 -0
  189. package/dist/browser/paths.js +77 -0
  190. package/dist/browser/profiles.js +13 -8
  191. package/dist/browser/pw-ai-module.js +10 -5
  192. package/dist/browser/pw-session.js +76 -39
  193. package/dist/browser/pw-tools-core.interactions.js +14 -7
  194. package/dist/browser/pw-tools-core.state.js +12 -6
  195. package/dist/browser/routes/agent.act.js +431 -424
  196. package/dist/browser/routes/agent.shared.js +47 -3
  197. package/dist/browser/routes/agent.snapshot.js +122 -116
  198. package/dist/browser/routes/agent.storage.js +303 -297
  199. package/dist/browser/routes/tabs.js +154 -100
  200. package/dist/browser/server-context.js +7 -0
  201. package/dist/browser/server-lifecycle.js +37 -0
  202. package/dist/build-info.json +3 -3
  203. package/dist/channels/allow-from.js +26 -0
  204. package/dist/channels/allowlists/resolve-utils.js +43 -19
  205. package/dist/channels/channel-config.js +14 -7
  206. package/dist/channels/draft-stream-loop.js +7 -0
  207. package/dist/channels/model-overrides.js +82 -0
  208. package/dist/channels/plugins/account-action-gate.js +13 -0
  209. package/dist/channels/plugins/message-actions.js +10 -0
  210. package/dist/channels/plugins/normalize/imessage.js +14 -7
  211. package/dist/channels/plugins/normalize/slack.js +10 -5
  212. package/dist/channels/plugins/normalize/telegram.js +14 -7
  213. package/dist/channels/plugins/outbound/discord.js +80 -8
  214. package/dist/channels/plugins/outbound/signal.js +11 -11
  215. package/dist/channels/plugins/setup-helpers.js +10 -5
  216. package/dist/channels/sender-label.js +14 -7
  217. package/dist/channels/session.js +4 -2
  218. package/dist/channels/status-reactions.js +297 -0
  219. package/dist/channels/telegram/api.js +18 -0
  220. package/dist/cli/argv.js +84 -21
  221. package/dist/cli/banner.js +3 -2
  222. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  223. package/dist/cli/cli-name.js +11 -11
  224. package/dist/cli/cli-utils.js +13 -3
  225. package/dist/cli/command-format.js +1 -1
  226. package/dist/cli/config-cli.js +1 -1
  227. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  228. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  229. package/dist/cli/daemon-cli/restart-health.js +126 -0
  230. package/dist/cli/daemon-cli/status.gather.js +9 -13
  231. package/dist/cli/daemon-cli/status.print.js +2 -10
  232. package/dist/cli/deps.js +27 -22
  233. package/dist/cli/exec-approvals-cli.js +92 -124
  234. package/dist/cli/gateway-cli/run-loop.js +23 -5
  235. package/dist/cli/memory-cli.js +158 -61
  236. package/dist/cli/node-cli/register.js +14 -5
  237. package/dist/cli/nodes-cli/register.push.js +63 -0
  238. package/dist/cli/nodes-media-utils.js +26 -0
  239. package/dist/cli/outbound-send-deps.js +2 -9
  240. package/dist/cli/outbound-send-mapping.js +11 -0
  241. package/dist/cli/pairing-cli.js +40 -14
  242. package/dist/cli/plugins-cli.js +250 -73
  243. package/dist/cli/ports.js +11 -10
  244. package/dist/cli/program/build-program.js +3 -1
  245. package/dist/cli/program/command-registry.js +214 -136
  246. package/dist/cli/program/command-tree.js +16 -0
  247. package/dist/cli/program/help.js +43 -12
  248. package/dist/cli/program/preaction.js +13 -9
  249. package/dist/cli/program/register.configure.js +3 -18
  250. package/dist/cli/program/register.maintenance.js +2 -2
  251. package/dist/cli/program/register.onboard.js +2 -0
  252. package/dist/cli/program/register.status-health-sessions.js +16 -17
  253. package/dist/cli/program/register.subclis.js +93 -52
  254. package/dist/cli/route.js +12 -8
  255. package/dist/cli/system-cli.js +36 -46
  256. package/dist/cli/test-runtime-capture.js +24 -0
  257. package/dist/cli/update-cli/shared.js +22 -9
  258. package/dist/cli/update-cli/update-command.js +89 -14
  259. package/dist/cli/update-cli/wizard.js +6 -12
  260. package/dist/commands/agent/run-context.js +18 -5
  261. package/dist/commands/agent/session-store.js +17 -4
  262. package/dist/commands/agent.js +185 -89
  263. package/dist/commands/agents.bindings.js +14 -7
  264. package/dist/commands/agents.commands.add.js +13 -9
  265. package/dist/commands/agents.commands.identity.js +12 -6
  266. package/dist/commands/agents.commands.list.js +11 -6
  267. package/dist/commands/agents.config.js +8 -10
  268. package/dist/commands/agents.providers.js +12 -6
  269. package/dist/commands/auth-choice-options.js +103 -75
  270. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  271. package/dist/commands/auth-choice.apply.js +4 -0
  272. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  273. package/dist/commands/auth-choice.apply.openai.js +3 -1
  274. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  275. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  276. package/dist/commands/channels/remove.js +13 -6
  277. package/dist/commands/channels/shared.js +4 -14
  278. package/dist/commands/channels.mock-harness.js +23 -0
  279. package/dist/commands/configure.commands.js +14 -0
  280. package/dist/commands/configure.gateway.js +2 -4
  281. package/dist/commands/configure.js +1 -1
  282. package/dist/commands/configure.shared.js +11 -0
  283. package/dist/commands/daemon-install-helpers.js +2 -2
  284. package/dist/commands/daemon-install-runtime-warning.js +11 -0
  285. package/dist/commands/dashboard.js +12 -10
  286. package/dist/commands/docs.js +14 -8
  287. package/dist/commands/doctor-config-flow.js +11 -9
  288. package/dist/commands/doctor-legacy-config.js +281 -0
  289. package/dist/commands/doctor-state-integrity.js +99 -23
  290. package/dist/commands/doctor-update.js +12 -9
  291. package/dist/commands/models/list.list-command.js +7 -5
  292. package/dist/commands/models/set-image.js +2 -21
  293. package/dist/commands/node-daemon-install-helpers.js +10 -8
  294. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  295. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  296. package/dist/commands/onboard-auth.credentials.js +90 -13
  297. package/dist/commands/onboard-auth.js +1 -1
  298. package/dist/commands/onboard-auth.models.js +6 -5
  299. package/dist/commands/onboard-hooks.js +1 -1
  300. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  301. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  302. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  303. package/dist/commands/onboard-remote.js +14 -7
  304. package/dist/commands/onboard.js +11 -13
  305. package/dist/commands/sandbox-display.js +6 -5
  306. package/dist/commands/sessions.test-helpers.js +61 -0
  307. package/dist/commands/status-all/diagnosis.js +14 -10
  308. package/dist/commands/status-all/format.js +1 -0
  309. package/dist/commands/status.gateway-probe.js +1 -16
  310. package/dist/commands/systemd-linger.js +12 -6
  311. package/dist/config/agent-limits.js +2 -0
  312. package/dist/config/commands.js +32 -15
  313. package/dist/config/config-paths.js +9 -11
  314. package/dist/config/config.js +1 -1
  315. package/dist/config/defaults.js +22 -2
  316. package/dist/config/discord-preview-streaming.js +104 -0
  317. package/dist/config/env-substitution.js +62 -34
  318. package/dist/config/env-vars.js +45 -7
  319. package/dist/config/includes.js +4 -0
  320. package/dist/config/io.js +656 -171
  321. package/dist/config/legacy.migrations.part-1.js +189 -78
  322. package/dist/config/legacy.shared.js +3 -1
  323. package/dist/config/merge-patch.js +54 -4
  324. package/dist/config/prototype-keys.js +4 -0
  325. package/dist/config/redact-snapshot.js +404 -76
  326. package/dist/config/schema.help.js +44 -7
  327. package/dist/config/schema.js +58 -570
  328. package/dist/config/schema.labels.js +38 -6
  329. package/dist/config/sessions/delivery-info.js +10 -3
  330. package/dist/config/sessions/main-session.js +10 -5
  331. package/dist/config/sessions/session-file.js +33 -0
  332. package/dist/config/sessions/session-key.js +10 -5
  333. package/dist/config/sessions/store.js +1 -1
  334. package/dist/config/sessions.js +1 -0
  335. package/dist/config/validation.js +140 -85
  336. package/dist/config/zod-schema.agent-runtime.js +11 -0
  337. package/dist/config/zod-schema.hooks.js +40 -11
  338. package/dist/config/zod-schema.installs.js +20 -0
  339. package/dist/config/zod-schema.js +156 -20
  340. package/dist/config/zod-schema.providers-core.js +78 -4
  341. package/dist/config/zod-schema.providers.js +6 -1
  342. package/dist/config/zod-schema.session.js +41 -2
  343. package/dist/cron/run-log.js +3 -0
  344. package/dist/cron/schedule.js +21 -10
  345. package/dist/cron/service/ops.js +35 -21
  346. package/dist/cron/service/timer.js +116 -16
  347. package/dist/cron/stagger.js +3 -1
  348. package/dist/daemon/cmd-argv.js +21 -0
  349. package/dist/daemon/cmd-set.js +58 -0
  350. package/dist/daemon/service-types.js +1 -0
  351. package/dist/discord/api.js +12 -6
  352. package/dist/discord/draft-chunking.js +22 -0
  353. package/dist/discord/draft-stream.js +124 -0
  354. package/dist/discord/monitor/agent-components.js +1 -1
  355. package/dist/discord/monitor/commands.js +5 -0
  356. package/dist/discord/monitor/exec-approvals.js +357 -162
  357. package/dist/discord/monitor/gateway-plugin.js +2 -1
  358. package/dist/discord/monitor/listeners.js +37 -27
  359. package/dist/discord/monitor/message-handler.js +4 -1
  360. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  361. package/dist/discord/monitor/message-handler.process.js +246 -217
  362. package/dist/discord/monitor/message-utils.js +143 -6
  363. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  364. package/dist/discord/monitor/model-picker.js +651 -0
  365. package/dist/discord/monitor/native-command.js +573 -16
  366. package/dist/discord/monitor/provider.allowlist.js +223 -0
  367. package/dist/discord/monitor/provider.js +275 -347
  368. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  369. package/dist/discord/monitor/reply-delivery.js +123 -16
  370. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  371. package/dist/discord/monitor/thread-bindings.js +4 -0
  372. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  373. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  374. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  375. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  376. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  377. package/dist/discord/resolve-users.js +33 -21
  378. package/dist/discord/send.channels.js +15 -0
  379. package/dist/discord/send.js +3 -2
  380. package/dist/discord/send.outbound.js +82 -26
  381. package/dist/discord/send.permissions.js +83 -30
  382. package/dist/discord/send.reactions.js +8 -4
  383. package/dist/discord/token.js +10 -5
  384. package/dist/discord/voice/command.js +263 -0
  385. package/dist/discord/voice/manager.js +531 -0
  386. package/dist/gateway/auth.js +72 -13
  387. package/dist/gateway/call.js +152 -83
  388. package/dist/gateway/canvas-capability.js +75 -0
  389. package/dist/gateway/client.js +28 -4
  390. package/dist/gateway/config-reload.js +3 -4
  391. package/dist/gateway/control-plane-audit.js +28 -0
  392. package/dist/gateway/control-plane-rate-limit.js +53 -0
  393. package/dist/gateway/control-ui.js +219 -96
  394. package/dist/gateway/events.js +1 -0
  395. package/dist/gateway/hooks-mapping.js +88 -38
  396. package/dist/gateway/hooks.js +109 -54
  397. package/dist/gateway/http-auth-helpers.js +3 -2
  398. package/dist/gateway/http-common.js +22 -0
  399. package/dist/gateway/http-endpoint-helpers.js +1 -0
  400. package/dist/gateway/method-scopes.js +169 -0
  401. package/dist/gateway/net.js +74 -9
  402. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  403. package/dist/gateway/node-registry.js +10 -5
  404. package/dist/gateway/openai-http.js +1 -0
  405. package/dist/gateway/openresponses-http.js +121 -110
  406. package/dist/gateway/origin-check.js +1 -18
  407. package/dist/gateway/probe-auth.js +2 -0
  408. package/dist/gateway/protocol/index.js +4 -2
  409. package/dist/gateway/protocol/schema/cron.js +1 -0
  410. package/dist/gateway/protocol/schema/devices.js +1 -0
  411. package/dist/gateway/protocol/schema/protocol-schemas.js +4 -1
  412. package/dist/gateway/protocol/schema/push.js +18 -0
  413. package/dist/gateway/protocol/schema/sessions.js +6 -0
  414. package/dist/gateway/protocol/schema.js +1 -0
  415. package/dist/gateway/role-policy.js +17 -0
  416. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  417. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  418. package/dist/gateway/server-chat.js +83 -25
  419. package/dist/gateway/server-constants.js +10 -9
  420. package/dist/gateway/server-cron.js +1 -0
  421. package/dist/gateway/server-http.js +247 -54
  422. package/dist/gateway/server-maintenance.js +20 -5
  423. package/dist/gateway/server-methods/agent.js +162 -24
  424. package/dist/gateway/server-methods/chat.js +465 -130
  425. package/dist/gateway/server-methods/config.js +193 -152
  426. package/dist/gateway/server-methods/devices.js +17 -3
  427. package/dist/gateway/server-methods/models.js +11 -1
  428. package/dist/gateway/server-methods/nodes.helpers.js +12 -0
  429. package/dist/gateway/server-methods/nodes.js +251 -69
  430. package/dist/gateway/server-methods/push.js +53 -0
  431. package/dist/gateway/server-methods/sessions.js +64 -8
  432. package/dist/gateway/server-methods/usage.js +162 -75
  433. package/dist/gateway/server-node-events.js +29 -0
  434. package/dist/gateway/server-reload-handlers.js +2 -3
  435. package/dist/gateway/server-runtime-config.js +39 -13
  436. package/dist/gateway/server-runtime-state.js +2 -0
  437. package/dist/gateway/server-startup-memory.js +17 -11
  438. package/dist/gateway/server-ws-runtime.js +1 -0
  439. package/dist/gateway/server.impl.js +296 -139
  440. package/dist/gateway/session-preview.test-helpers.js +11 -0
  441. package/dist/gateway/session-utils.fs.js +32 -34
  442. package/dist/gateway/sessions-resolve.js +17 -5
  443. package/dist/gateway/startup-auth.js +126 -0
  444. package/dist/gateway/test-helpers.agent-results.js +15 -0
  445. package/dist/gateway/test-helpers.mocks.js +37 -14
  446. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  447. package/dist/gateway/test-helpers.server.js +161 -77
  448. package/dist/gateway/tools-invoke-http.js +21 -10
  449. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  450. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  451. package/dist/hooks/bundled/session-memory/handler.js +170 -38
  452. package/dist/hooks/frontmatter.js +6 -6
  453. package/dist/hooks/gmail-watcher-lifecycle.js +23 -0
  454. package/dist/hooks/gmail-watcher.js +11 -6
  455. package/dist/hooks/internal-hooks.js +11 -1
  456. package/dist/hooks/llm-slug-generator.js +4 -1
  457. package/dist/hooks/workspace.js +47 -17
  458. package/dist/imessage/accounts.js +9 -20
  459. package/dist/imessage/monitor/inbound-processing.js +2 -1
  460. package/dist/infra/archive-path.js +49 -0
  461. package/dist/infra/archive.js +174 -73
  462. package/dist/infra/control-ui-assets.js +14 -6
  463. package/dist/infra/device-pairing.js +204 -144
  464. package/dist/infra/env.js +10 -5
  465. package/dist/infra/exec-approvals-allowlist.js +141 -70
  466. package/dist/infra/exec-approvals-analysis.js +78 -20
  467. package/dist/infra/exec-approvals.js +5 -17
  468. package/dist/infra/exec-safe-bin-policy.js +277 -0
  469. package/dist/infra/fixed-window-rate-limit.js +33 -0
  470. package/dist/infra/fs-safe.js +71 -39
  471. package/dist/infra/gateway-lock.js +6 -2
  472. package/dist/infra/git-root.js +61 -0
  473. package/dist/infra/heartbeat-active-hours.js +2 -2
  474. package/dist/infra/heartbeat-reason.js +40 -0
  475. package/dist/infra/heartbeat-runner.js +72 -32
  476. package/dist/infra/heartbeat-wake.js +6 -12
  477. package/dist/infra/host-env-security-policy.json +19 -0
  478. package/dist/infra/host-env-security.js +66 -0
  479. package/dist/infra/install-source-utils.js +91 -7
  480. package/dist/infra/net/ssrf.js +131 -38
  481. package/dist/infra/node-pairing.js +50 -105
  482. package/dist/infra/npm-integrity.js +45 -0
  483. package/dist/infra/npm-pack-install.js +40 -0
  484. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  485. package/dist/infra/outbound/channel-adapters.js +20 -7
  486. package/dist/infra/outbound/channel-selection.js +12 -6
  487. package/dist/infra/outbound/envelope.js +1 -1
  488. package/dist/infra/outbound/format.js +12 -6
  489. package/dist/infra/outbound/message-action-runner.js +107 -327
  490. package/dist/infra/outbound/message.js +59 -36
  491. package/dist/infra/outbound/outbound-policy.js +52 -25
  492. package/dist/infra/outbound/outbound-send-service.js +58 -71
  493. package/dist/infra/outbound/payloads.js +14 -7
  494. package/dist/infra/outbound/session-binding-service.js +123 -0
  495. package/dist/infra/pairing-files.js +10 -0
  496. package/dist/infra/path-guards.js +25 -0
  497. package/dist/infra/plain-object.js +9 -0
  498. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  499. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  500. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  501. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  502. package/dist/infra/push-apns.js +365 -0
  503. package/dist/infra/restart-sentinel.js +16 -1
  504. package/dist/infra/restart.js +229 -26
  505. package/dist/infra/retry-policy.js +4 -2
  506. package/dist/infra/retry.js +9 -5
  507. package/dist/infra/scp-host.js +54 -0
  508. package/dist/infra/session-cost-usage.js +107 -59
  509. package/dist/infra/session-maintenance-warning.js +3 -1
  510. package/dist/infra/shell-env.js +98 -34
  511. package/dist/infra/ssh-config.js +12 -6
  512. package/dist/infra/system-run-command.js +49 -4
  513. package/dist/infra/update-channels.js +10 -5
  514. package/dist/infra/update-startup.js +86 -9
  515. package/dist/line/accounts.js +5 -7
  516. package/dist/line/bot-access.js +8 -20
  517. package/dist/line/bot-handlers.js +3 -1
  518. package/dist/link-understanding/detect.js +15 -7
  519. package/dist/media/constants.js +15 -6
  520. package/dist/media/image-ops.js +7 -0
  521. package/dist/media/inbound-path-policy.js +114 -0
  522. package/dist/media/input-files.js +16 -0
  523. package/dist/media/local-roots.js +3 -2
  524. package/dist/media-understanding/apply.js +4 -1
  525. package/dist/media-understanding/concurrency.js +8 -20
  526. package/dist/memory/backend-config.js +45 -6
  527. package/dist/memory/embeddings.js +10 -4
  528. package/dist/memory/fs-utils.js +23 -0
  529. package/dist/memory/manager-search.js +12 -6
  530. package/dist/memory/manager-sync-ops.js +12 -2
  531. package/dist/memory/qmd-manager.js +466 -53
  532. package/dist/memory/query-expansion.js +167 -3
  533. package/dist/memory/status-format.js +10 -5
  534. package/dist/memory/sync-memory-files.js +1 -1
  535. package/dist/memory/test-manager.js +8 -0
  536. package/dist/node-host/invoke-system-run.js +281 -0
  537. package/dist/node-host/invoke.js +55 -337
  538. package/dist/pairing/pairing-store.js +22 -0
  539. package/dist/plugin-sdk/allow-from.js +1 -1
  540. package/dist/plugin-sdk/command-auth.js +3 -1
  541. package/dist/plugin-sdk/index.js +6 -3
  542. package/dist/plugin-sdk/temp-path.js +47 -0
  543. package/dist/plugin-sdk/webhook-targets.js +32 -0
  544. package/dist/plugins/bundled-dir.js +9 -6
  545. package/dist/plugins/discovery.js +217 -23
  546. package/dist/plugins/hook-runner-global.js +16 -0
  547. package/dist/plugins/hooks.js +50 -0
  548. package/dist/plugins/install.js +28 -16
  549. package/dist/plugins/loader.js +192 -26
  550. package/dist/plugins/logger.js +8 -0
  551. package/dist/plugins/manifest-registry.js +3 -0
  552. package/dist/plugins/path-safety.js +34 -0
  553. package/dist/plugins/registry.js +5 -2
  554. package/dist/plugins/runtime/index.js +271 -206
  555. package/dist/plugins/runtime.js +3 -17
  556. package/dist/plugins/update.js +78 -12
  557. package/dist/process/spawn-utils.js +14 -7
  558. package/dist/providers/github-copilot-models.js +4 -1
  559. package/dist/providers/github-copilot-token.js +11 -6
  560. package/dist/providers/qwen-portal-oauth.js +14 -6
  561. package/dist/routing/account-id.js +30 -0
  562. package/dist/routing/resolve-route.js +3 -7
  563. package/dist/routing/session-key.js +2 -16
  564. package/dist/security/audit-channel.js +100 -20
  565. package/dist/security/audit-extra.async.js +505 -179
  566. package/dist/security/audit-extra.js +12 -2
  567. package/dist/security/audit-extra.sync.js +421 -35
  568. package/dist/security/audit-fs.js +31 -13
  569. package/dist/security/audit.js +180 -370
  570. package/dist/security/dm-policy-shared.js +68 -0
  571. package/dist/security/external-content.js +46 -14
  572. package/dist/security/fix.js +49 -85
  573. package/dist/security/scan-paths.js +20 -0
  574. package/dist/security/secret-equal.js +3 -7
  575. package/dist/security/windows-acl.js +30 -15
  576. package/dist/shared/entry-status.js +6 -0
  577. package/dist/shared/frontmatter.js +5 -5
  578. package/dist/shared/node-list-parse.js +13 -0
  579. package/dist/shared/node-match.js +11 -4
  580. package/dist/shared/operator-scope-compat.js +42 -0
  581. package/dist/shared/text-chunking.js +29 -0
  582. package/dist/signal/accounts.js +7 -20
  583. package/dist/signal/monitor/event-handler.js +3 -1
  584. package/dist/slack/accounts.js +6 -19
  585. package/dist/slack/actions.js +11 -3
  586. package/dist/slack/blocks.test-helpers.js +31 -0
  587. package/dist/slack/monitor/auth.js +1 -1
  588. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  589. package/dist/slack/monitor/mrkdwn.js +8 -0
  590. package/dist/slack/monitor/replies.js +15 -7
  591. package/dist/slack/monitor/slash.js +22 -13
  592. package/dist/slack/resolve-channels.js +10 -5
  593. package/dist/slack/send.js +102 -12
  594. package/dist/slack/stream-mode.js +10 -0
  595. package/dist/slack/streaming.js +4 -2
  596. package/dist/telegram/accounts.js +19 -14
  597. package/dist/telegram/bot/helpers.js +3 -5
  598. package/dist/telegram/bot-access.js +35 -36
  599. package/dist/telegram/bot-handlers.js +120 -148
  600. package/dist/telegram/bot-message-context.js +68 -9
  601. package/dist/telegram/bot-message-dispatch.js +477 -210
  602. package/dist/telegram/bot-native-commands.js +16 -0
  603. package/dist/telegram/draft-stream.js +44 -8
  604. package/dist/telegram/inline-buttons.js +5 -15
  605. package/dist/telegram/monitor.js +11 -7
  606. package/dist/telegram/network-config.js +19 -7
  607. package/dist/telegram/reasoning-lane-coordinator.js +128 -0
  608. package/dist/telegram/send.js +3 -2
  609. package/dist/telegram/sent-message-cache.js +5 -6
  610. package/dist/telegram/status-reaction-variants.js +208 -0
  611. package/dist/telegram/sticker-cache.js +11 -9
  612. package/dist/terminal/prompt-select-styled.js +9 -0
  613. package/dist/terminal/theme.js +12 -12
  614. package/dist/test-utils/command-runner.js +6 -0
  615. package/dist/test-utils/internal-hook-event-payload.js +10 -0
  616. package/dist/test-utils/model-auth-mock.js +12 -0
  617. package/dist/test-utils/provider-usage-fetch.js +14 -0
  618. package/dist/test-utils/temp-home.js +33 -0
  619. package/dist/tts/tts.js +80 -567
  620. package/dist/tui/components/chat-log.js +50 -8
  621. package/dist/tui/theme/theme.js +10 -12
  622. package/dist/tui/tui-command-handlers.js +36 -27
  623. package/dist/tui/tui-event-handlers.js +122 -32
  624. package/dist/tui/tui-local-shell.js +16 -6
  625. package/dist/tui/tui.js +236 -48
  626. package/dist/utils/account-id.js +2 -4
  627. package/dist/utils/boolean.js +10 -5
  628. package/dist/utils/directive-tags.js +11 -0
  629. package/dist/utils/mask-api-key.js +10 -0
  630. package/dist/utils/queue-helpers.js +67 -12
  631. package/dist/utils/run-with-concurrency.js +39 -0
  632. package/dist/web/auto-reply/deliver-reply.js +8 -4
  633. package/dist/web/auto-reply/mentions.js +10 -5
  634. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  635. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  636. package/dist/web/inbound/access-control.js +5 -2
  637. package/dist/web/login-qr.js +12 -6
  638. package/dist/web/media.js +126 -15
  639. package/docs/tools/slash-commands.md +5 -1
  640. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  641. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  642. package/extensions/feishu/src/external-keys.ts +19 -0
  643. package/extensions/lobster/src/windows-spawn.ts +193 -0
  644. package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
  645. package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
  646. package/package.json +1 -1
@@ -1,6 +1,34 @@
1
+ export function clearQueueSummaryState(state) {
2
+ state.droppedCount = 0;
3
+ state.summaryLines = [];
4
+ }
5
+ export function previewQueueSummaryPrompt(params) {
6
+ return buildQueueSummaryPrompt({
7
+ state: {
8
+ dropPolicy: params.state.dropPolicy,
9
+ droppedCount: params.state.droppedCount,
10
+ summaryLines: [...params.state.summaryLines],
11
+ },
12
+ noun: params.noun,
13
+ title: params.title,
14
+ });
15
+ }
16
+ export function applyQueueRuntimeSettings(params) {
17
+ params.target.mode = params.settings.mode;
18
+ params.target.debounceMs =
19
+ typeof params.settings.debounceMs === "number"
20
+ ? Math.max(0, params.settings.debounceMs)
21
+ : params.target.debounceMs;
22
+ params.target.cap =
23
+ typeof params.settings.cap === "number" && params.settings.cap > 0
24
+ ? Math.floor(params.settings.cap)
25
+ : params.target.cap;
26
+ params.target.dropPolicy = params.settings.dropPolicy ?? params.target.dropPolicy;
27
+ }
1
28
  export function elideQueueText(text, limit = 140) {
2
- if (text.length <= limit)
29
+ if (text.length <= limit) {
3
30
  return text;
31
+ }
4
32
  return `${text.slice(0, Math.max(0, limit - 1)).trimEnd()}…`;
5
33
  }
6
34
  export function buildQueueSummaryLine(text, limit = 160) {
@@ -8,16 +36,19 @@ export function buildQueueSummaryLine(text, limit = 160) {
8
36
  return elideQueueText(cleaned, limit);
9
37
  }
10
38
  export function shouldSkipQueueItem(params) {
11
- if (!params.dedupe)
39
+ if (!params.dedupe) {
12
40
  return false;
41
+ }
13
42
  return params.dedupe(params.item, params.items);
14
43
  }
15
44
  export function applyQueueDropPolicy(params) {
16
45
  const cap = params.queue.cap;
17
- if (cap <= 0 || params.queue.items.length < cap)
46
+ if (cap <= 0 || params.queue.items.length < cap) {
18
47
  return true;
19
- if (params.queue.dropPolicy === "new")
48
+ }
49
+ if (params.queue.dropPolicy === "new") {
20
50
  return false;
51
+ }
21
52
  const dropCount = params.queue.items.length - cap + 1;
22
53
  const dropped = params.queue.items.splice(0, dropCount);
23
54
  if (params.queue.dropPolicy === "summarize") {
@@ -26,15 +57,17 @@ export function applyQueueDropPolicy(params) {
26
57
  params.queue.summaryLines.push(buildQueueSummaryLine(params.summarize(item)));
27
58
  }
28
59
  const limit = Math.max(0, params.summaryLimit ?? cap);
29
- while (params.queue.summaryLines.length > limit)
60
+ while (params.queue.summaryLines.length > limit) {
30
61
  params.queue.summaryLines.shift();
62
+ }
31
63
  }
32
64
  return true;
33
65
  }
34
66
  export function waitForQueueDebounce(queue) {
35
67
  const debounceMs = Math.max(0, queue.debounceMs);
36
- if (debounceMs <= 0)
68
+ if (debounceMs <= 0) {
37
69
  return Promise.resolve();
70
+ }
38
71
  return new Promise((resolve) => {
39
72
  const check = () => {
40
73
  const since = Date.now() - queue.lastEnqueuedAt;
@@ -47,6 +80,25 @@ export function waitForQueueDebounce(queue) {
47
80
  check();
48
81
  });
49
82
  }
83
+ export async function drainNextQueueItem(items, run) {
84
+ const next = items[0];
85
+ if (!next) {
86
+ return false;
87
+ }
88
+ await run(next);
89
+ items.shift();
90
+ return true;
91
+ }
92
+ export async function drainCollectItemIfNeeded(params) {
93
+ if (!params.forceIndividualCollect && !params.isCrossChannel) {
94
+ return "skipped";
95
+ }
96
+ if (params.isCrossChannel) {
97
+ params.setForceIndividualCollect?.(true);
98
+ }
99
+ const drained = await drainNextQueueItem(params.items, params.run);
100
+ return drained ? "drained" : "empty";
101
+ }
50
102
  export function buildQueueSummaryPrompt(params) {
51
103
  if (params.state.dropPolicy !== "summarize" || params.state.droppedCount <= 0) {
52
104
  return undefined;
@@ -61,14 +113,14 @@ export function buildQueueSummaryPrompt(params) {
61
113
  lines.push(`- ${line}`);
62
114
  }
63
115
  }
64
- params.state.droppedCount = 0;
65
- params.state.summaryLines = [];
116
+ clearQueueSummaryState(params.state);
66
117
  return lines.join("\n");
67
118
  }
68
119
  export function buildCollectPrompt(params) {
69
120
  const blocks = [params.title];
70
- if (params.summary)
121
+ if (params.summary) {
71
122
  blocks.push(params.summary);
123
+ }
72
124
  params.items.forEach((item, idx) => {
73
125
  blocks.push(params.renderItem(item, idx));
74
126
  });
@@ -79,17 +131,20 @@ export function hasCrossChannelItems(items, resolveKey) {
79
131
  let hasUnkeyed = false;
80
132
  for (const item of items) {
81
133
  const resolved = resolveKey(item);
82
- if (resolved.cross)
134
+ if (resolved.cross) {
83
135
  return true;
136
+ }
84
137
  if (!resolved.key) {
85
138
  hasUnkeyed = true;
86
139
  continue;
87
140
  }
88
141
  keys.add(resolved.key);
89
142
  }
90
- if (keys.size === 0)
143
+ if (keys.size === 0) {
91
144
  return false;
92
- if (hasUnkeyed)
145
+ }
146
+ if (hasUnkeyed) {
93
147
  return true;
148
+ }
94
149
  return keys.size > 1;
95
150
  }
@@ -0,0 +1,39 @@
1
+ export async function runTasksWithConcurrency(params) {
2
+ const { tasks, limit, onTaskError } = params;
3
+ const errorMode = params.errorMode ?? "continue";
4
+ if (tasks.length === 0) {
5
+ return { results: [], firstError: undefined, hasError: false };
6
+ }
7
+ const resolvedLimit = Math.max(1, Math.min(limit, tasks.length));
8
+ const results = Array.from({ length: tasks.length });
9
+ let next = 0;
10
+ let firstError = undefined;
11
+ let hasError = false;
12
+ const workers = Array.from({ length: resolvedLimit }, async () => {
13
+ while (true) {
14
+ if (errorMode === "stop" && hasError) {
15
+ return;
16
+ }
17
+ const index = next;
18
+ next += 1;
19
+ if (index >= tasks.length) {
20
+ return;
21
+ }
22
+ try {
23
+ results[index] = await tasks[index]();
24
+ }
25
+ catch (error) {
26
+ if (!hasError) {
27
+ firstError = error;
28
+ hasError = true;
29
+ }
30
+ onTaskError?.(error, index);
31
+ if (errorMode === "stop") {
32
+ return;
33
+ }
34
+ }
35
+ }
36
+ });
37
+ await Promise.allSettled(workers);
38
+ return { results, firstError, hasError };
39
+ }
@@ -1,6 +1,8 @@
1
1
  import { chunkMarkdownTextWithMode } from "../../auto-reply/chunk.js";
2
- import { convertMarkdownTables } from "../../markdown/tables.js";
3
2
  import { logVerbose, shouldLogVerbose } from "../../globals.js";
3
+ import { convertMarkdownTables } from "../../markdown/tables.js";
4
+ import { markdownToWhatsApp } from "../../markdown/whatsapp.js";
5
+ import { sleep } from "../../utils.js";
4
6
  import { loadWebMedia } from "../media.js";
5
7
  import { newConnectionId } from "../reconnect.js";
6
8
  import { formatError } from "../session.js";
@@ -11,14 +13,13 @@ export async function deliverWebReply(params) {
11
13
  const replyStarted = Date.now();
12
14
  const tableMode = params.tableMode ?? "code";
13
15
  const chunkMode = params.chunkMode ?? "length";
14
- const convertedText = convertMarkdownTables(replyResult.text || "", tableMode);
16
+ const convertedText = markdownToWhatsApp(convertMarkdownTables(replyResult.text || "", tableMode));
15
17
  const textChunks = chunkMarkdownTextWithMode(convertedText, textLimit, chunkMode);
16
18
  const mediaList = replyResult.mediaUrls?.length
17
19
  ? replyResult.mediaUrls
18
20
  : replyResult.mediaUrl
19
21
  ? [replyResult.mediaUrl]
20
22
  : [];
21
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
22
23
  const sendWithRetry = async (fn, label, maxAttempts = 3) => {
23
24
  let lastErr;
24
25
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
@@ -69,7 +70,10 @@ export async function deliverWebReply(params) {
69
70
  for (const [index, mediaUrl] of mediaList.entries()) {
70
71
  const caption = index === 0 ? remainingText.shift() || undefined : undefined;
71
72
  try {
72
- const media = await loadWebMedia(mediaUrl, maxMediaBytes);
73
+ const media = await loadWebMedia(mediaUrl, {
74
+ maxBytes: maxMediaBytes,
75
+ localRoots: params.mediaLocalRoots,
76
+ });
73
77
  if (shouldLogVerbose()) {
74
78
  logVerbose(`Web auto-reply media size: ${(media.buffer.length / (1024 * 1024)).toFixed(2)}MB`);
75
79
  logVerbose(`Web auto-reply media source: ${mediaUrl} (kind ${media.kind})`);
@@ -20,12 +20,14 @@ export function isBotMentionedFromTargets(msg, mentionCfg, targets) {
20
20
  const isSelfChat = isSelfChatMode(targets.selfE164, mentionCfg.allowFrom);
21
21
  const hasMentions = (msg.mentionedJids?.length ?? 0) > 0;
22
22
  if (hasMentions && !isSelfChat) {
23
- if (targets.selfE164 && targets.normalizedMentions.includes(targets.selfE164))
23
+ if (targets.selfE164 && targets.normalizedMentions.includes(targets.selfE164)) {
24
24
  return true;
25
+ }
25
26
  if (targets.selfJid) {
26
27
  // Some mentions use the bare JID; match on E.164 to be safe.
27
- if (targets.normalizedMentions.includes(targets.selfJid))
28
+ if (targets.normalizedMentions.includes(targets.selfJid)) {
28
29
  return true;
30
+ }
29
31
  }
30
32
  // If the message explicitly mentions someone else, do not fall back to regex matches.
31
33
  return false;
@@ -34,19 +36,22 @@ export function isBotMentionedFromTargets(msg, mentionCfg, targets) {
34
36
  // Self-chat mode: ignore WhatsApp @mention JIDs, otherwise @mentioning the owner in group chats triggers the bot.
35
37
  }
36
38
  const bodyClean = clean(msg.body);
37
- if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean)))
39
+ if (mentionCfg.mentionRegexes.some((re) => re.test(bodyClean))) {
38
40
  return true;
41
+ }
39
42
  // Fallback: detect body containing our own number (with or without +, spacing)
40
43
  if (targets.selfE164) {
41
44
  const selfDigits = targets.selfE164.replace(/\D/g, "");
42
45
  if (selfDigits) {
43
46
  const bodyDigits = bodyClean.replace(/[^\d]/g, "");
44
- if (bodyDigits.includes(selfDigits))
47
+ if (bodyDigits.includes(selfDigits)) {
45
48
  return true;
49
+ }
46
50
  const bodyNoSpace = msg.body.replace(/[\s-]/g, "");
47
51
  const pattern = new RegExp(`\\+?${selfDigits}`, "i");
48
- if (pattern.test(bodyNoSpace))
52
+ if (pattern.test(bodyNoSpace)) {
49
53
  return true;
54
+ }
50
55
  }
51
56
  }
52
57
  return false;
@@ -1,11 +1,13 @@
1
1
  import { normalizeE164 } from "../../../utils.js";
2
2
  export function noteGroupMember(groupMemberNames, conversationId, e164, name) {
3
- if (!e164 || !name)
3
+ if (!e164 || !name) {
4
4
  return;
5
+ }
5
6
  const normalized = normalizeE164(e164);
6
7
  const key = normalized ?? e164;
7
- if (!key)
8
+ if (!key) {
8
9
  return;
10
+ }
9
11
  let roster = groupMemberNames.get(conversationId);
10
12
  if (!roster) {
11
13
  roster = new Map();
@@ -19,11 +21,13 @@ export function formatGroupMembers(params) {
19
21
  const ordered = [];
20
22
  if (participants?.length) {
21
23
  for (const entry of participants) {
22
- if (!entry)
24
+ if (!entry) {
23
25
  continue;
26
+ }
24
27
  const normalized = normalizeE164(entry) ?? entry;
25
- if (!normalized || seen.has(normalized))
28
+ if (!normalized || seen.has(normalized)) {
26
29
  continue;
30
+ }
27
31
  seen.add(normalized);
28
32
  ordered.push(normalized);
29
33
  }
@@ -31,19 +35,22 @@ export function formatGroupMembers(params) {
31
35
  if (roster) {
32
36
  for (const entry of roster.keys()) {
33
37
  const normalized = normalizeE164(entry) ?? entry;
34
- if (!normalized || seen.has(normalized))
38
+ if (!normalized || seen.has(normalized)) {
35
39
  continue;
40
+ }
36
41
  seen.add(normalized);
37
42
  ordered.push(normalized);
38
43
  }
39
44
  }
40
45
  if (ordered.length === 0 && fallbackE164) {
41
46
  const normalized = normalizeE164(fallbackE164) ?? fallbackE164;
42
- if (normalized)
47
+ if (normalized) {
43
48
  ordered.push(normalized);
49
+ }
44
50
  }
45
- if (ordered.length === 0)
51
+ if (ordered.length === 0) {
46
52
  return undefined;
53
+ }
47
54
  return ordered
48
55
  .map((entry) => {
49
56
  const name = roster?.get(entry);
@@ -1,17 +1,19 @@
1
1
  import { resolveIdentityNamePrefix } from "../../../agents/identity.js";
2
2
  import { resolveChunkMode, resolveTextChunkLimit } from "../../../auto-reply/chunk.js";
3
+ import { shouldComputeCommandAuthorized } from "../../../auto-reply/command-detection.js";
3
4
  import { formatInboundEnvelope, resolveEnvelopeFormatOptions, } from "../../../auto-reply/envelope.js";
4
5
  import { buildHistoryContextFromEntries, } from "../../../auto-reply/reply/history.js";
5
- import { dispatchReplyWithBufferedBlockDispatcher } from "../../../auto-reply/reply/provider-dispatcher.js";
6
- import { shouldComputeCommandAuthorized } from "../../../auto-reply/command-detection.js";
7
6
  import { finalizeInboundContext } from "../../../auto-reply/reply/inbound-context.js";
7
+ import { dispatchReplyWithBufferedBlockDispatcher } from "../../../auto-reply/reply/provider-dispatcher.js";
8
8
  import { toLocationContext } from "../../../channels/location.js";
9
- import { createReplyPrefixContext } from "../../../channels/reply-prefix.js";
10
- import { readSessionUpdatedAt, recordSessionMetaFromInbound, resolveStorePath, } from "../../../config/sessions.js";
9
+ import { createReplyPrefixOptions } from "../../../channels/reply-prefix.js";
11
10
  import { resolveMarkdownTableMode } from "../../../config/markdown-tables.js";
11
+ import { readSessionUpdatedAt, recordSessionMetaFromInbound, resolveStorePath, } from "../../../config/sessions.js";
12
12
  import { logVerbose, shouldLogVerbose } from "../../../globals.js";
13
+ import { getAgentScopedMediaLocalRoots } from "../../../media/local-roots.js";
13
14
  import { readChannelAllowFromStore } from "../../../pairing/pairing-store.js";
14
15
  import { jidToE164, normalizeE164 } from "../../../utils.js";
16
+ import { resolveWhatsAppAccount } from "../../accounts.js";
15
17
  import { newConnectionId } from "../../reconnect.js";
16
18
  import { formatError } from "../../session.js";
17
19
  import { deliverWebReply } from "../deliver-reply.js";
@@ -31,31 +33,39 @@ function normalizeAllowFromE164(values) {
31
33
  }
32
34
  async function resolveWhatsAppCommandAuthorized(params) {
33
35
  const useAccessGroups = params.cfg.commands?.useAccessGroups !== false;
34
- if (!useAccessGroups)
36
+ if (!useAccessGroups) {
35
37
  return true;
38
+ }
36
39
  const isGroup = params.msg.chatType === "group";
37
40
  const senderE164 = normalizeE164(isGroup ? (params.msg.senderE164 ?? "") : (params.msg.senderE164 ?? params.msg.from ?? ""));
38
- if (!senderE164)
41
+ if (!senderE164) {
39
42
  return false;
40
- const configuredAllowFrom = params.cfg.channels?.whatsapp?.allowFrom ?? [];
41
- const configuredGroupAllowFrom = params.cfg.channels?.whatsapp?.groupAllowFrom ??
42
- (configuredAllowFrom.length > 0 ? configuredAllowFrom : undefined);
43
+ }
44
+ const account = resolveWhatsAppAccount({ cfg: params.cfg, accountId: params.msg.accountId });
45
+ const dmPolicy = account.dmPolicy ?? "pairing";
46
+ const configuredAllowFrom = account.allowFrom ?? [];
47
+ const configuredGroupAllowFrom = account.groupAllowFrom ?? (configuredAllowFrom.length > 0 ? configuredAllowFrom : undefined);
43
48
  if (isGroup) {
44
- if (!configuredGroupAllowFrom || configuredGroupAllowFrom.length === 0)
49
+ if (!configuredGroupAllowFrom || configuredGroupAllowFrom.length === 0) {
45
50
  return false;
46
- if (configuredGroupAllowFrom.some((v) => String(v).trim() === "*"))
51
+ }
52
+ if (configuredGroupAllowFrom.some((v) => String(v).trim() === "*")) {
47
53
  return true;
54
+ }
48
55
  return normalizeAllowFromE164(configuredGroupAllowFrom).includes(senderE164);
49
56
  }
50
- const storeAllowFrom = await readChannelAllowFromStore("whatsapp").catch(() => []);
57
+ const storeAllowFrom = dmPolicy === "allowlist"
58
+ ? []
59
+ : await readChannelAllowFromStore("whatsapp", process.env, params.msg.accountId).catch(() => []);
51
60
  const combinedAllowFrom = Array.from(new Set([...(configuredAllowFrom ?? []), ...storeAllowFrom]));
52
61
  const allowFrom = combinedAllowFrom.length > 0
53
62
  ? combinedAllowFrom
54
63
  : params.msg.selfE164
55
64
  ? [params.msg.selfE164]
56
65
  : [];
57
- if (allowFrom.some((v) => String(v).trim() === "*"))
66
+ if (allowFrom.some((v) => String(v).trim() === "*")) {
58
67
  return true;
68
+ }
59
69
  return normalizeAllowFromE164(allowFrom).includes(senderE164);
60
70
  }
61
71
  export async function processMessage(params) {
@@ -83,21 +93,17 @@ export async function processMessage(params) {
83
93
  sender: m.sender,
84
94
  body: m.body,
85
95
  timestamp: m.timestamp,
86
- messageId: m.id,
87
96
  }));
88
97
  combinedBody = buildHistoryContextFromEntries({
89
98
  entries: historyEntries,
90
99
  currentMessage: combinedBody,
91
100
  excludeLast: false,
92
101
  formatEntry: (entry) => {
93
- const bodyWithId = entry.messageId
94
- ? `${entry.body}\n[message_id: ${entry.messageId}]`
95
- : entry.body;
96
102
  return formatInboundEnvelope({
97
103
  channel: "WhatsApp",
98
104
  from: conversationId,
99
105
  timestamp: entry.timestamp,
100
- body: bodyWithId,
106
+ body: entry.body,
101
107
  chatType: "group",
102
108
  senderLabel: entry.sender,
103
109
  envelope: envelopeOptions,
@@ -147,11 +153,13 @@ export async function processMessage(params) {
147
153
  }
148
154
  const dmRouteTarget = params.msg.chatType !== "group"
149
155
  ? (() => {
150
- if (params.msg.senderE164)
156
+ if (params.msg.senderE164) {
151
157
  return normalizeE164(params.msg.senderE164);
158
+ }
152
159
  // In direct chats, `msg.from` is already the canonical conversation id.
153
- if (params.msg.from.includes("@"))
160
+ if (params.msg.from.includes("@")) {
154
161
  return jidToE164(params.msg.from);
162
+ }
155
163
  return normalizeE164(params.msg.from);
156
164
  })()
157
165
  : undefined;
@@ -162,25 +170,37 @@ export async function processMessage(params) {
162
170
  channel: "whatsapp",
163
171
  accountId: params.route.accountId,
164
172
  });
173
+ const mediaLocalRoots = getAgentScopedMediaLocalRoots(params.cfg, params.route.agentId);
165
174
  let didLogHeartbeatStrip = false;
166
175
  let didSendReply = false;
167
176
  const commandAuthorized = shouldComputeCommandAuthorized(params.msg.body, params.cfg)
168
177
  ? await resolveWhatsAppCommandAuthorized({ cfg: params.cfg, msg: params.msg })
169
178
  : undefined;
170
179
  const configuredResponsePrefix = params.cfg.messages?.responsePrefix;
171
- const prefixContext = createReplyPrefixContext({
180
+ const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
172
181
  cfg: params.cfg,
173
182
  agentId: params.route.agentId,
183
+ channel: "whatsapp",
184
+ accountId: params.route.accountId,
174
185
  });
175
186
  const isSelfChat = params.msg.chatType !== "group" &&
176
187
  Boolean(params.msg.selfE164) &&
177
188
  normalizeE164(params.msg.from) === normalizeE164(params.msg.selfE164 ?? "");
178
- const responsePrefix = prefixContext.responsePrefix ??
189
+ const responsePrefix = prefixOptions.responsePrefix ??
179
190
  (configuredResponsePrefix === undefined && isSelfChat
180
191
  ? (resolveIdentityNamePrefix(params.cfg, params.route.agentId) ?? "[poolbot]")
181
192
  : undefined);
193
+ const inboundHistory = params.msg.chatType === "group"
194
+ ? (params.groupHistory ?? params.groupHistories.get(params.groupHistoryKey) ?? []).map((entry) => ({
195
+ sender: entry.sender,
196
+ body: entry.body,
197
+ timestamp: entry.timestamp,
198
+ }))
199
+ : undefined;
182
200
  const ctxPayload = finalizeInboundContext({
183
201
  Body: combinedBody,
202
+ BodyForAgent: params.msg.body,
203
+ InboundHistory: inboundHistory,
184
204
  RawBody: params.msg.body,
185
205
  CommandBody: params.msg.body,
186
206
  From: params.msg.from,
@@ -243,8 +263,8 @@ export async function processMessage(params) {
243
263
  cfg: params.cfg,
244
264
  replyResolver: params.replyResolver,
245
265
  dispatcherOptions: {
266
+ ...prefixOptions,
246
267
  responsePrefix,
247
- responsePrefixContextProvider: prefixContext.responsePrefixContextProvider,
248
268
  onHeartbeatStrip: () => {
249
269
  if (!didLogHeartbeatStrip) {
250
270
  didLogHeartbeatStrip = true;
@@ -255,6 +275,7 @@ export async function processMessage(params) {
255
275
  await deliverWebReply({
256
276
  replyResult: payload,
257
277
  msg: params.msg,
278
+ mediaLocalRoots,
258
279
  maxMediaBytes: params.maxMediaBytes,
259
280
  textLimit,
260
281
  chunkMode,
@@ -299,7 +320,7 @@ export async function processMessage(params) {
299
320
  disableBlockStreaming: typeof params.cfg.channels?.whatsapp?.blockStreaming === "boolean"
300
321
  ? !params.cfg.channels.whatsapp.blockStreaming
301
322
  : undefined,
302
- onModelSelected: prefixContext.onModelSelected,
323
+ onModelSelected,
303
324
  },
304
325
  });
305
326
  if (!queuedFinal) {
@@ -11,9 +11,11 @@ export async function checkInboundAccessControl(params) {
11
11
  cfg,
12
12
  accountId: params.accountId,
13
13
  });
14
- const dmPolicy = cfg.channels?.whatsapp?.dmPolicy ?? "pairing";
14
+ const dmPolicy = account.dmPolicy ?? "pairing";
15
15
  const configuredAllowFrom = account.allowFrom;
16
- const storeAllowFrom = await readChannelAllowFromStore("whatsapp").catch(() => []);
16
+ const storeAllowFrom = dmPolicy === "allowlist"
17
+ ? []
18
+ : await readChannelAllowFromStore("whatsapp", process.env, account.accountId).catch(() => []);
17
19
  // Without user config, default to self-only DM access so the owner can talk to themselves.
18
20
  const combinedAllowFrom = Array.from(new Set([...(configuredAllowFrom ?? []), ...storeAllowFrom]));
19
21
  const defaultAllowFrom = combinedAllowFrom.length === 0 && params.selfE164 ? [params.selfE164] : undefined;
@@ -107,6 +109,7 @@ export async function checkInboundAccessControl(params) {
107
109
  const { code, created } = await upsertChannelPairingRequest({
108
110
  channel: "whatsapp",
109
111
  id: candidate,
112
+ accountId: account.accountId,
110
113
  meta: { name: (params.pushName ?? "").trim() || undefined },
111
114
  });
112
115
  if (created) {
@@ -34,20 +34,23 @@ function attachLoginWaiter(accountId, login) {
34
34
  login.waitPromise = waitForWaConnection(login.sock)
35
35
  .then(() => {
36
36
  const current = activeLogins.get(accountId);
37
- if (current?.id === login.id)
37
+ if (current?.id === login.id) {
38
38
  current.connected = true;
39
+ }
39
40
  })
40
41
  .catch((err) => {
41
42
  const current = activeLogins.get(accountId);
42
- if (current?.id !== login.id)
43
+ if (current?.id !== login.id) {
43
44
  return;
45
+ }
44
46
  current.error = formatError(err);
45
47
  current.errorStatus = getStatusCode(err);
46
48
  });
47
49
  }
48
50
  async function restartLoginSocket(login, runtime) {
49
- if (login.restartAttempted)
51
+ if (login.restartAttempted) {
50
52
  return false;
53
+ }
51
54
  login.restartAttempted = true;
52
55
  runtime.log(info("WhatsApp asked for a restart after pairing (code 515); retrying connection once…"));
53
56
  closeSocket(login.sock);
@@ -103,12 +106,14 @@ export async function startWebLoginWithQr(opts = {}) {
103
106
  sock = await createWaSocket(false, Boolean(opts.verbose), {
104
107
  authDir: account.authDir,
105
108
  onQr: (qr) => {
106
- if (pendingQr)
109
+ if (pendingQr) {
107
110
  return;
111
+ }
108
112
  pendingQr = qr;
109
113
  const current = activeLogins.get(account.accountId);
110
- if (current && !current.qr)
114
+ if (current && !current.qr) {
111
115
  current.qr = qr;
116
+ }
112
117
  clearTimeout(qrTimer);
113
118
  runtime.log(info("WhatsApp QR received."));
114
119
  resolveQr?.(qr);
@@ -135,8 +140,9 @@ export async function startWebLoginWithQr(opts = {}) {
135
140
  verbose: Boolean(opts.verbose),
136
141
  };
137
142
  activeLogins.set(account.accountId, login);
138
- if (pendingQr && !login.qr)
143
+ if (pendingQr && !login.qr) {
139
144
  login.qr = pendingQr;
145
+ }
140
146
  attachLoginWaiter(account.accountId, login);
141
147
  let qr;
142
148
  try {