@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,15 +1,37 @@
1
1
  import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
2
2
  import { loadConfig } from "../../config/config.js";
3
- import { callGateway, randomIdempotencyKey } from "../../gateway/call.js";
3
+ import { callGatewayLeastPrivilege, randomIdempotencyKey } from "../../gateway/call.js";
4
4
  import { normalizePollInput } from "../../polls.js";
5
5
  import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, } from "../../utils/message-channel.js";
6
6
  import { resolveMessageChannelSelection } from "./channel-selection.js";
7
7
  import { deliverOutboundPayloads, } from "./deliver.js";
8
8
  import { normalizeReplyPayloadsForDelivery } from "./payloads.js";
9
9
  import { resolveOutboundTarget } from "./targets.js";
10
+ async function resolveRequiredChannel(params) {
11
+ const channel = params.channel?.trim()
12
+ ? normalizeChannelId(params.channel)
13
+ : (await resolveMessageChannelSelection({ cfg: params.cfg })).channel;
14
+ if (!channel) {
15
+ throw new Error(`Unknown channel: ${params.channel}`);
16
+ }
17
+ return channel;
18
+ }
19
+ function resolveRequiredPlugin(channel) {
20
+ const plugin = getChannelPlugin(channel);
21
+ if (!plugin) {
22
+ throw new Error(`Unknown channel: ${channel}`);
23
+ }
24
+ return plugin;
25
+ }
10
26
  function resolveGatewayOptions(opts) {
27
+ // Security: backend callers (tools/agents) must not accept user-controlled gateway URLs.
28
+ // Use config-derived gateway target only.
29
+ const url = opts?.mode === GATEWAY_CLIENT_MODES.BACKEND ||
30
+ opts?.clientName === GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT
31
+ ? undefined
32
+ : opts?.url;
11
33
  return {
12
- url: opts?.url,
34
+ url,
13
35
  token: opts?.token,
14
36
  timeoutMs: typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
15
37
  ? Math.max(1, Math.floor(opts.timeoutMs))
@@ -19,18 +41,23 @@ function resolveGatewayOptions(opts) {
19
41
  mode: opts?.mode ?? GATEWAY_CLIENT_MODES.CLI,
20
42
  };
21
43
  }
44
+ async function callMessageGateway(params) {
45
+ const gateway = resolveGatewayOptions(params.gateway);
46
+ return await callGatewayLeastPrivilege({
47
+ url: gateway.url,
48
+ token: gateway.token,
49
+ method: params.method,
50
+ params: params.params,
51
+ timeoutMs: gateway.timeoutMs,
52
+ clientName: gateway.clientName,
53
+ clientDisplayName: gateway.clientDisplayName,
54
+ mode: gateway.mode,
55
+ });
56
+ }
22
57
  export async function sendMessage(params) {
23
58
  const cfg = params.cfg ?? loadConfig();
24
- const channel = params.channel?.trim()
25
- ? normalizeChannelId(params.channel)
26
- : (await resolveMessageChannelSelection({ cfg })).channel;
27
- if (!channel) {
28
- throw new Error(`Unknown channel: ${params.channel}`);
29
- }
30
- const plugin = getChannelPlugin(channel);
31
- if (!plugin) {
32
- throw new Error(`Unknown channel: ${channel}`);
33
- }
59
+ const channel = await resolveRequiredChannel({ cfg, channel: params.channel });
60
+ const plugin = resolveRequiredPlugin(channel);
34
61
  const deliveryMode = plugin.outbound?.deliveryMode ?? "direct";
35
62
  const normalizedPayloads = normalizeReplyPayloadsForDelivery([
36
63
  {
@@ -64,18 +91,23 @@ export async function sendMessage(params) {
64
91
  accountId: params.accountId,
65
92
  mode: "explicit",
66
93
  });
67
- if (!resolvedTarget.ok)
94
+ if (!resolvedTarget.ok) {
68
95
  throw resolvedTarget.error;
96
+ }
69
97
  const results = await deliverOutboundPayloads({
70
98
  cfg,
71
99
  channel: outboundChannel,
72
100
  to: resolvedTarget.to,
101
+ agentId: params.agentId,
73
102
  accountId: params.accountId,
74
103
  payloads: normalizedPayloads,
104
+ replyToId: params.replyToId,
105
+ threadId: params.threadId,
75
106
  gifPlayback: params.gifPlayback,
76
107
  deps: params.deps,
77
108
  bestEffort: params.bestEffort,
78
109
  abortSignal: params.abortSignal,
110
+ silent: params.silent,
79
111
  mirror: params.mirror
80
112
  ? {
81
113
  ...params.mirror,
@@ -93,10 +125,8 @@ export async function sendMessage(params) {
93
125
  result: results.at(-1),
94
126
  };
95
127
  }
96
- const gateway = resolveGatewayOptions(params.gateway);
97
- const result = await callGateway({
98
- url: gateway.url,
99
- token: gateway.token,
128
+ const result = await callMessageGateway({
129
+ gateway: params.gateway,
100
130
  method: "send",
101
131
  params: {
102
132
  to: params.to,
@@ -109,10 +139,6 @@ export async function sendMessage(params) {
109
139
  sessionKey: params.mirror?.sessionKey,
110
140
  idempotencyKey: params.idempotencyKey ?? randomIdempotencyKey(),
111
141
  },
112
- timeoutMs: gateway.timeoutMs,
113
- clientName: gateway.clientName,
114
- clientDisplayName: gateway.clientDisplayName,
115
- mode: gateway.mode,
116
142
  });
117
143
  return {
118
144
  channel,
@@ -125,19 +151,15 @@ export async function sendMessage(params) {
125
151
  }
126
152
  export async function sendPoll(params) {
127
153
  const cfg = params.cfg ?? loadConfig();
128
- const channel = params.channel?.trim()
129
- ? normalizeChannelId(params.channel)
130
- : (await resolveMessageChannelSelection({ cfg })).channel;
131
- if (!channel) {
132
- throw new Error(`Unknown channel: ${params.channel}`);
133
- }
154
+ const channel = await resolveRequiredChannel({ cfg, channel: params.channel });
134
155
  const pollInput = {
135
156
  question: params.question,
136
157
  options: params.options,
137
158
  maxSelections: params.maxSelections,
159
+ durationSeconds: params.durationSeconds,
138
160
  durationHours: params.durationHours,
139
161
  };
140
- const plugin = getChannelPlugin(channel);
162
+ const plugin = resolveRequiredPlugin(channel);
141
163
  const outbound = plugin?.outbound;
142
164
  if (!outbound?.sendPoll) {
143
165
  throw new Error(`Unsupported poll channel: ${channel}`);
@@ -152,29 +174,29 @@ export async function sendPoll(params) {
152
174
  question: normalized.question,
153
175
  options: normalized.options,
154
176
  maxSelections: normalized.maxSelections,
177
+ durationSeconds: normalized.durationSeconds ?? null,
155
178
  durationHours: normalized.durationHours ?? null,
156
179
  via: "gateway",
157
180
  dryRun: true,
158
181
  };
159
182
  }
160
- const gateway = resolveGatewayOptions(params.gateway);
161
- const result = await callGateway({
162
- url: gateway.url,
163
- token: gateway.token,
183
+ const result = await callMessageGateway({
184
+ gateway: params.gateway,
164
185
  method: "poll",
165
186
  params: {
166
187
  to: params.to,
167
188
  question: normalized.question,
168
189
  options: normalized.options,
169
190
  maxSelections: normalized.maxSelections,
191
+ durationSeconds: normalized.durationSeconds,
170
192
  durationHours: normalized.durationHours,
193
+ threadId: params.threadId,
194
+ silent: params.silent,
195
+ isAnonymous: params.isAnonymous,
171
196
  channel,
197
+ accountId: params.accountId,
172
198
  idempotencyKey: params.idempotencyKey ?? randomIdempotencyKey(),
173
199
  },
174
- timeoutMs: gateway.timeoutMs,
175
- clientName: gateway.clientName,
176
- clientDisplayName: gateway.clientDisplayName,
177
- mode: gateway.mode,
178
200
  });
179
201
  return {
180
202
  channel,
@@ -182,6 +204,7 @@ export async function sendPoll(params) {
182
204
  question: normalized.question,
183
205
  options: normalized.options,
184
206
  maxSelections: normalized.maxSelections,
207
+ durationSeconds: normalized.durationSeconds ?? null,
185
208
  durationHours: normalized.durationHours ?? null,
186
209
  via: "gateway",
187
210
  result,
@@ -1,5 +1,5 @@
1
+ import { getChannelMessageAdapter, } from "./channel-adapters.js";
1
2
  import { normalizeTargetForProvider } from "./target-normalization.js";
2
- import { getChannelMessageAdapter } from "./channel-adapters.js";
3
3
  import { formatTargetDisplay, lookupDirectoryDisplay } from "./target-resolver.js";
4
4
  const CONTEXT_GUARDED_ACTIONS = new Set([
5
5
  "send",
@@ -21,42 +21,52 @@ const CONTEXT_MARKER_ACTIONS = new Set([
21
21
  "sticker",
22
22
  ]);
23
23
  function resolveContextGuardTarget(action, params) {
24
- if (!CONTEXT_GUARDED_ACTIONS.has(action))
24
+ if (!CONTEXT_GUARDED_ACTIONS.has(action)) {
25
25
  return undefined;
26
+ }
26
27
  if (action === "thread-reply" || action === "thread-create") {
27
- if (typeof params.channelId === "string")
28
+ if (typeof params.channelId === "string") {
28
29
  return params.channelId;
29
- if (typeof params.to === "string")
30
+ }
31
+ if (typeof params.to === "string") {
30
32
  return params.to;
33
+ }
31
34
  return undefined;
32
35
  }
33
- if (typeof params.to === "string")
36
+ if (typeof params.to === "string") {
34
37
  return params.to;
35
- if (typeof params.channelId === "string")
38
+ }
39
+ if (typeof params.channelId === "string") {
36
40
  return params.channelId;
41
+ }
37
42
  return undefined;
38
43
  }
39
44
  function normalizeTarget(channel, raw) {
40
- return normalizeTargetForProvider(channel, raw) ?? raw.trim().toLowerCase();
45
+ return normalizeTargetForProvider(channel, raw) ?? raw.trim();
41
46
  }
42
47
  function isCrossContextTarget(params) {
43
48
  const currentTarget = params.toolContext?.currentChannelId?.trim();
44
- if (!currentTarget)
49
+ if (!currentTarget) {
45
50
  return false;
51
+ }
46
52
  const normalizedTarget = normalizeTarget(params.channel, params.target);
47
53
  const normalizedCurrent = normalizeTarget(params.channel, currentTarget);
48
- if (!normalizedTarget || !normalizedCurrent)
54
+ if (!normalizedTarget || !normalizedCurrent) {
49
55
  return false;
56
+ }
50
57
  return normalizedTarget !== normalizedCurrent;
51
58
  }
52
59
  export function enforceCrossContextPolicy(params) {
53
60
  const currentTarget = params.toolContext?.currentChannelId?.trim();
54
- if (!currentTarget)
61
+ if (!currentTarget) {
55
62
  return;
56
- if (!CONTEXT_GUARDED_ACTIONS.has(params.action))
63
+ }
64
+ if (!CONTEXT_GUARDED_ACTIONS.has(params.action)) {
57
65
  return;
58
- if (params.cfg.tools?.message?.allowCrossContextSend)
66
+ }
67
+ if (params.cfg.tools?.message?.allowCrossContextSend) {
59
68
  return;
69
+ }
60
70
  const currentProvider = params.toolContext?.currentChannelProvider;
61
71
  const allowWithinProvider = params.cfg.tools?.message?.crossContext?.allowWithinProvider !== false;
62
72
  const allowAcrossProviders = params.cfg.tools?.message?.crossContext?.allowAcrossProviders === true;
@@ -66,27 +76,33 @@ export function enforceCrossContextPolicy(params) {
66
76
  }
67
77
  return;
68
78
  }
69
- if (allowWithinProvider)
79
+ if (allowWithinProvider) {
70
80
  return;
81
+ }
71
82
  const target = resolveContextGuardTarget(params.action, params.args);
72
- if (!target)
83
+ if (!target) {
73
84
  return;
85
+ }
74
86
  if (!isCrossContextTarget({ channel: params.channel, target, toolContext: params.toolContext })) {
75
87
  return;
76
88
  }
77
89
  throw new Error(`Cross-context messaging denied: action=${params.action} target="${target}" while bound to "${currentTarget}" (channel=${params.channel}).`);
78
90
  }
79
91
  export async function buildCrossContextDecoration(params) {
80
- if (!params.toolContext?.currentChannelId)
92
+ if (!params.toolContext?.currentChannelId) {
81
93
  return null;
94
+ }
82
95
  // Skip decoration for direct tool sends (agent composing, not forwarding)
83
- if (params.toolContext.skipCrossContextDecoration)
96
+ if (params.toolContext.skipCrossContextDecoration) {
84
97
  return null;
85
- if (!isCrossContextTarget(params))
98
+ }
99
+ if (!isCrossContextTarget(params)) {
86
100
  return null;
101
+ }
87
102
  const markerConfig = params.cfg.tools?.message?.crossContext?.marker;
88
- if (markerConfig?.enabled === false)
103
+ if (markerConfig?.enabled === false) {
89
104
  return null;
105
+ }
90
106
  const currentName = (await lookupDirectoryDisplay({
91
107
  cfg: params.cfg,
92
108
  channel: params.channel,
@@ -104,19 +120,30 @@ export async function buildCrossContextDecoration(params) {
104
120
  const prefix = prefixTemplate.replaceAll("{channel}", originLabel);
105
121
  const suffix = suffixTemplate.replaceAll("{channel}", originLabel);
106
122
  const adapter = getChannelMessageAdapter(params.channel);
107
- const embeds = adapter.supportsEmbeds
108
- ? (adapter.buildCrossContextEmbeds?.(originLabel) ?? undefined)
123
+ const componentsBuilder = adapter.supportsComponentsV2
124
+ ? adapter.buildCrossContextComponents
125
+ ? (message) => adapter.buildCrossContextComponents({
126
+ originLabel,
127
+ message,
128
+ cfg: params.cfg,
129
+ accountId: params.accountId ?? undefined,
130
+ })
131
+ : undefined
109
132
  : undefined;
110
- return { prefix, suffix, embeds };
133
+ return { prefix, suffix, componentsBuilder };
111
134
  }
112
135
  export function shouldApplyCrossContextMarker(action) {
113
136
  return CONTEXT_MARKER_ACTIONS.has(action);
114
137
  }
115
138
  export function applyCrossContextDecoration(params) {
116
- const useEmbeds = params.preferEmbeds && params.decoration.embeds?.length;
117
- if (useEmbeds) {
118
- return { message: params.message, embeds: params.decoration.embeds, usedEmbeds: true };
139
+ const useComponents = params.preferComponents && params.decoration.componentsBuilder;
140
+ if (useComponents) {
141
+ return {
142
+ message: params.message,
143
+ componentsBuilder: params.decoration.componentsBuilder,
144
+ usedComponents: true,
145
+ };
119
146
  }
120
147
  const message = `${params.decoration.prefix}${params.message}${params.decoration.suffix}`;
121
- return { message, usedEmbeds: false };
148
+ return { message, usedComponents: false };
122
149
  }
@@ -1,75 +1,68 @@
1
1
  import { dispatchChannelMessageAction } from "../../channels/plugins/message-actions.js";
2
2
  import { appendAssistantMessageToSessionTranscript } from "../../config/sessions.js";
3
+ import { throwIfAborted } from "./abort.js";
3
4
  import { sendMessage, sendPoll } from "./message.js";
4
- function extractToolPayload(result) {
5
- if (result.details !== undefined)
6
- return result.details;
7
- const textBlock = Array.isArray(result.content)
8
- ? result.content.find((block) => block &&
9
- typeof block === "object" &&
10
- block.type === "text" &&
11
- typeof block.text === "string")
12
- : undefined;
13
- const text = textBlock?.text;
14
- if (text) {
15
- try {
16
- return JSON.parse(text);
17
- }
18
- catch {
19
- return text;
20
- }
5
+ import { extractToolPayload } from "./tool-payload.js";
6
+ async function tryHandleWithPluginAction(params) {
7
+ if (params.ctx.dryRun) {
8
+ return null;
21
9
  }
22
- return result.content ?? result;
23
- }
24
- function throwIfAborted(abortSignal) {
25
- if (abortSignal?.aborted) {
26
- const err = new Error("Message send aborted");
27
- err.name = "AbortError";
28
- throw err;
10
+ const handled = await dispatchChannelMessageAction({
11
+ channel: params.ctx.channel,
12
+ action: params.action,
13
+ cfg: params.ctx.cfg,
14
+ params: params.ctx.params,
15
+ accountId: params.ctx.accountId ?? undefined,
16
+ gateway: params.ctx.gateway,
17
+ toolContext: params.ctx.toolContext,
18
+ dryRun: params.ctx.dryRun,
19
+ });
20
+ if (!handled) {
21
+ return null;
29
22
  }
23
+ await params.onHandled?.();
24
+ return {
25
+ handledBy: "plugin",
26
+ payload: extractToolPayload(handled),
27
+ toolResult: handled,
28
+ };
30
29
  }
31
30
  export async function executeSendAction(params) {
32
31
  throwIfAborted(params.ctx.abortSignal);
33
- if (!params.ctx.dryRun) {
34
- const handled = await dispatchChannelMessageAction({
35
- channel: params.ctx.channel,
36
- action: "send",
37
- cfg: params.ctx.cfg,
38
- params: params.ctx.params,
39
- accountId: params.ctx.accountId ?? undefined,
40
- gateway: params.ctx.gateway,
41
- toolContext: params.ctx.toolContext,
42
- dryRun: params.ctx.dryRun,
43
- });
44
- if (handled) {
45
- if (params.ctx.mirror) {
46
- const mirrorText = params.ctx.mirror.text ?? params.message;
47
- const mirrorMediaUrls = params.ctx.mirror.mediaUrls ??
48
- params.mediaUrls ??
49
- (params.mediaUrl ? [params.mediaUrl] : undefined);
50
- await appendAssistantMessageToSessionTranscript({
51
- agentId: params.ctx.mirror.agentId,
52
- sessionKey: params.ctx.mirror.sessionKey,
53
- text: mirrorText,
54
- mediaUrls: mirrorMediaUrls,
55
- });
32
+ const pluginHandled = await tryHandleWithPluginAction({
33
+ ctx: params.ctx,
34
+ action: "send",
35
+ onHandled: async () => {
36
+ if (!params.ctx.mirror) {
37
+ return;
56
38
  }
57
- return {
58
- handledBy: "plugin",
59
- payload: extractToolPayload(handled),
60
- toolResult: handled,
61
- };
62
- }
39
+ const mirrorText = params.ctx.mirror.text ?? params.message;
40
+ const mirrorMediaUrls = params.ctx.mirror.mediaUrls ??
41
+ params.mediaUrls ??
42
+ (params.mediaUrl ? [params.mediaUrl] : undefined);
43
+ await appendAssistantMessageToSessionTranscript({
44
+ agentId: params.ctx.mirror.agentId,
45
+ sessionKey: params.ctx.mirror.sessionKey,
46
+ text: mirrorText,
47
+ mediaUrls: mirrorMediaUrls,
48
+ });
49
+ },
50
+ });
51
+ if (pluginHandled) {
52
+ return pluginHandled;
63
53
  }
64
54
  throwIfAborted(params.ctx.abortSignal);
65
55
  const result = await sendMessage({
66
56
  cfg: params.ctx.cfg,
67
57
  to: params.to,
68
58
  content: params.message,
59
+ agentId: params.ctx.agentId,
69
60
  mediaUrl: params.mediaUrl || undefined,
70
61
  mediaUrls: params.mediaUrls,
71
62
  channel: params.ctx.channel || undefined,
72
63
  accountId: params.ctx.accountId ?? undefined,
64
+ replyToId: params.replyToId,
65
+ threadId: params.threadId,
73
66
  gifPlayback: params.gifPlayback,
74
67
  dryRun: params.ctx.dryRun,
75
68
  bestEffort: params.bestEffort ?? undefined,
@@ -77,6 +70,7 @@ export async function executeSendAction(params) {
77
70
  gateway: params.ctx.gateway,
78
71
  mirror: params.ctx.mirror,
79
72
  abortSignal: params.ctx.abortSignal,
73
+ silent: params.ctx.silent,
80
74
  });
81
75
  return {
82
76
  handledBy: "core",
@@ -85,24 +79,12 @@ export async function executeSendAction(params) {
85
79
  };
86
80
  }
87
81
  export async function executePollAction(params) {
88
- if (!params.ctx.dryRun) {
89
- const handled = await dispatchChannelMessageAction({
90
- channel: params.ctx.channel,
91
- action: "poll",
92
- cfg: params.ctx.cfg,
93
- params: params.ctx.params,
94
- accountId: params.ctx.accountId ?? undefined,
95
- gateway: params.ctx.gateway,
96
- toolContext: params.ctx.toolContext,
97
- dryRun: params.ctx.dryRun,
98
- });
99
- if (handled) {
100
- return {
101
- handledBy: "plugin",
102
- payload: extractToolPayload(handled),
103
- toolResult: handled,
104
- };
105
- }
82
+ const pluginHandled = await tryHandleWithPluginAction({
83
+ ctx: params.ctx,
84
+ action: "poll",
85
+ });
86
+ if (pluginHandled) {
87
+ return pluginHandled;
106
88
  }
107
89
  const result = await sendPoll({
108
90
  cfg: params.ctx.cfg,
@@ -110,8 +92,13 @@ export async function executePollAction(params) {
110
92
  question: params.question,
111
93
  options: params.options,
112
94
  maxSelections: params.maxSelections,
95
+ durationSeconds: params.durationSeconds ?? undefined,
113
96
  durationHours: params.durationHours ?? undefined,
114
97
  channel: params.ctx.channel,
98
+ accountId: params.ctx.accountId ?? undefined,
99
+ threadId: params.threadId ?? undefined,
100
+ silent: params.ctx.silent ?? undefined,
101
+ isAnonymous: params.isAnonymous ?? undefined,
115
102
  dryRun: params.ctx.dryRun,
116
103
  gateway: params.ctx.gateway,
117
104
  });
@@ -4,14 +4,17 @@ function mergeMediaUrls(...lists) {
4
4
  const seen = new Set();
5
5
  const merged = [];
6
6
  for (const list of lists) {
7
- if (!list)
7
+ if (!list) {
8
8
  continue;
9
+ }
9
10
  for (const entry of list) {
10
11
  const trimmed = entry?.trim();
11
- if (!trimmed)
12
+ if (!trimmed) {
12
13
  continue;
13
- if (seen.has(trimmed))
14
+ }
15
+ if (seen.has(trimmed)) {
14
16
  continue;
17
+ }
15
18
  seen.add(trimmed);
16
19
  merged.push(trimmed);
17
20
  }
@@ -36,10 +39,12 @@ export function normalizeReplyPayloadsForDelivery(payloads) {
36
39
  replyToCurrent: payload.replyToCurrent || parsed.replyToCurrent,
37
40
  audioAsVoice: Boolean(payload.audioAsVoice || parsed.audioAsVoice),
38
41
  };
39
- if (parsed.isSilent && mergedMedia.length === 0)
42
+ if (parsed.isSilent && mergedMedia.length === 0) {
40
43
  return [];
41
- if (!isRenderablePayload(next))
44
+ }
45
+ if (!isRenderablePayload(next)) {
42
46
  return [];
47
+ }
43
48
  return [next];
44
49
  });
45
50
  }
@@ -70,9 +75,11 @@ export function normalizeOutboundPayloadsForJson(payloads) {
70
75
  }
71
76
  export function formatOutboundPayloadLog(payload) {
72
77
  const lines = [];
73
- if (payload.text)
78
+ if (payload.text) {
74
79
  lines.push(payload.text.trimEnd());
75
- for (const url of payload.mediaUrls)
80
+ }
81
+ for (const url of payload.mediaUrls) {
76
82
  lines.push(`MEDIA:${url}`);
83
+ }
77
84
  return lines.join("\n");
78
85
  }
@@ -0,0 +1,123 @@
1
+ import { normalizeAccountId } from "../../routing/session-key.js";
2
+ function normalizeConversationRef(ref) {
3
+ return {
4
+ channel: ref.channel.trim().toLowerCase(),
5
+ accountId: normalizeAccountId(ref.accountId),
6
+ conversationId: ref.conversationId.trim(),
7
+ parentConversationId: ref.parentConversationId?.trim() || undefined,
8
+ };
9
+ }
10
+ function toAdapterKey(params) {
11
+ return `${params.channel.trim().toLowerCase()}:${normalizeAccountId(params.accountId)}`;
12
+ }
13
+ const ADAPTERS_BY_CHANNEL_ACCOUNT = new Map();
14
+ export function registerSessionBindingAdapter(adapter) {
15
+ const key = toAdapterKey({
16
+ channel: adapter.channel,
17
+ accountId: adapter.accountId,
18
+ });
19
+ ADAPTERS_BY_CHANNEL_ACCOUNT.set(key, {
20
+ ...adapter,
21
+ channel: adapter.channel.trim().toLowerCase(),
22
+ accountId: normalizeAccountId(adapter.accountId),
23
+ });
24
+ }
25
+ export function unregisterSessionBindingAdapter(params) {
26
+ ADAPTERS_BY_CHANNEL_ACCOUNT.delete(toAdapterKey(params));
27
+ }
28
+ function resolveAdapterForConversation(ref) {
29
+ const normalized = normalizeConversationRef(ref);
30
+ const key = toAdapterKey({
31
+ channel: normalized.channel,
32
+ accountId: normalized.accountId,
33
+ });
34
+ return ADAPTERS_BY_CHANNEL_ACCOUNT.get(key) ?? null;
35
+ }
36
+ function dedupeBindings(records) {
37
+ const byId = new Map();
38
+ for (const record of records) {
39
+ if (!record?.bindingId) {
40
+ continue;
41
+ }
42
+ byId.set(record.bindingId, record);
43
+ }
44
+ return [...byId.values()];
45
+ }
46
+ function createDefaultSessionBindingService() {
47
+ return {
48
+ bind: async (input) => {
49
+ const normalizedConversation = normalizeConversationRef(input.conversation);
50
+ const adapter = resolveAdapterForConversation(normalizedConversation);
51
+ if (!adapter?.bind) {
52
+ throw new Error(`Session binding adapter unavailable for ${normalizedConversation.channel}:${normalizedConversation.accountId}`);
53
+ }
54
+ const bound = await adapter.bind({
55
+ ...input,
56
+ conversation: normalizedConversation,
57
+ });
58
+ if (!bound) {
59
+ throw new Error("Session binding adapter failed to bind target conversation");
60
+ }
61
+ return bound;
62
+ },
63
+ listBySession: (targetSessionKey) => {
64
+ const key = targetSessionKey.trim();
65
+ if (!key) {
66
+ return [];
67
+ }
68
+ const results = [];
69
+ for (const adapter of ADAPTERS_BY_CHANNEL_ACCOUNT.values()) {
70
+ const entries = adapter.listBySession(key);
71
+ if (entries.length > 0) {
72
+ results.push(...entries);
73
+ }
74
+ }
75
+ return dedupeBindings(results);
76
+ },
77
+ resolveByConversation: (ref) => {
78
+ const normalized = normalizeConversationRef(ref);
79
+ if (!normalized.channel || !normalized.conversationId) {
80
+ return null;
81
+ }
82
+ const adapter = resolveAdapterForConversation(normalized);
83
+ if (!adapter) {
84
+ return null;
85
+ }
86
+ return adapter.resolveByConversation(normalized);
87
+ },
88
+ touch: (bindingId, at) => {
89
+ const normalizedBindingId = bindingId.trim();
90
+ if (!normalizedBindingId) {
91
+ return;
92
+ }
93
+ for (const adapter of ADAPTERS_BY_CHANNEL_ACCOUNT.values()) {
94
+ adapter.touch?.(normalizedBindingId, at);
95
+ }
96
+ },
97
+ unbind: async (input) => {
98
+ const removed = [];
99
+ for (const adapter of ADAPTERS_BY_CHANNEL_ACCOUNT.values()) {
100
+ if (!adapter.unbind) {
101
+ continue;
102
+ }
103
+ const entries = await adapter.unbind(input);
104
+ if (entries.length > 0) {
105
+ removed.push(...entries);
106
+ }
107
+ }
108
+ return dedupeBindings(removed);
109
+ },
110
+ };
111
+ }
112
+ const DEFAULT_SESSION_BINDING_SERVICE = createDefaultSessionBindingService();
113
+ export function getSessionBindingService() {
114
+ return DEFAULT_SESSION_BINDING_SERVICE;
115
+ }
116
+ export const __testing = {
117
+ resetSessionBindingAdaptersForTests() {
118
+ ADAPTERS_BY_CHANNEL_ACCOUNT.clear();
119
+ },
120
+ getRegisteredAdapterKeys() {
121
+ return [...ADAPTERS_BY_CHANNEL_ACCOUNT.keys()];
122
+ },
123
+ };