@poolzin/pool-bot 2026.2.25 → 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 (506) hide show
  1. package/dist/acp/event-mapper.js +87 -22
  2. package/dist/acp/meta.js +12 -6
  3. package/dist/agents/agent-paths.js +8 -9
  4. package/dist/agents/agent-scope.js +7 -5
  5. package/dist/agents/auth-profiles/oauth.js +148 -64
  6. package/dist/agents/auth-profiles/session-override.js +13 -7
  7. package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
  8. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  9. package/dist/agents/bedrock-discovery.js +3 -1
  10. package/dist/agents/byteplus-models.js +97 -0
  11. package/dist/agents/chutes-oauth.js +1 -0
  12. package/dist/agents/cli-runner/helpers.js +4 -0
  13. package/dist/agents/compaction.js +41 -14
  14. package/dist/agents/doubao-models.js +121 -0
  15. package/dist/agents/failover-error.js +2 -0
  16. package/dist/agents/huggingface-models.js +5 -3
  17. package/dist/agents/live-model-filter.js +5 -0
  18. package/dist/agents/minimax-vlm.js +10 -8
  19. package/dist/agents/model-auth.js +6 -0
  20. package/dist/agents/model-catalog.js +3 -1
  21. package/dist/agents/model-selection.js +7 -1
  22. package/dist/agents/models-config.providers.js +93 -11
  23. package/dist/agents/ollama-stream.js +117 -4
  24. package/dist/agents/opencode-zen-models.js +22 -11
  25. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  26. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  27. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  28. package/dist/agents/pi-embedded-helpers.js +1 -1
  29. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  30. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  31. package/dist/agents/pi-embedded-runner/google.js +20 -8
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  33. package/dist/agents/pi-embedded-runner/run.js +71 -12
  34. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  35. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  36. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  37. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  38. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  39. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  40. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  41. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  42. package/dist/agents/pi-embedded-subscribe.js +9 -4
  43. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  44. package/dist/agents/pi-embedded-utils.js +3 -0
  45. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  46. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  47. package/dist/agents/pi-settings.js +40 -0
  48. package/dist/agents/pi-tools.policy.js +2 -1
  49. package/dist/agents/provider/config-loader.js +1 -1
  50. package/dist/agents/sandbox/browser.js +170 -33
  51. package/dist/agents/sandbox/config-hash.js +14 -27
  52. package/dist/agents/sandbox/config.js +21 -2
  53. package/dist/agents/sandbox/constants.js +2 -0
  54. package/dist/agents/sandbox/docker.js +16 -2
  55. package/dist/agents/sandbox/novnc-auth.js +62 -0
  56. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  57. package/dist/agents/sandbox/shared.js +10 -6
  58. package/dist/agents/sandbox-paths.js +24 -11
  59. package/dist/agents/schema/clean-for-gemini.js +132 -85
  60. package/dist/agents/session-slug.js +10 -5
  61. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  62. package/dist/agents/session-tool-result-guard.js +3 -1
  63. package/dist/agents/session-transcript-repair.js +40 -6
  64. package/dist/agents/skills/bundled-dir.js +19 -5
  65. package/dist/agents/skills/env-overrides.js +124 -43
  66. package/dist/agents/skills/frontmatter.js +6 -6
  67. package/dist/agents/skills/plugin-skills.js +14 -7
  68. package/dist/agents/skills/workspace.js +1 -0
  69. package/dist/agents/subagent-announce.js +251 -49
  70. package/dist/agents/subagent-lifecycle-events.js +19 -0
  71. package/dist/agents/subagent-registry-cleanup.js +31 -0
  72. package/dist/agents/subagent-registry-completion.js +68 -0
  73. package/dist/agents/subagent-registry-queries.js +117 -0
  74. package/dist/agents/subagent-registry-state.js +46 -0
  75. package/dist/agents/subagent-registry.js +252 -221
  76. package/dist/agents/subagent-registry.store.js +1 -0
  77. package/dist/agents/subagent-registry.types.js +1 -0
  78. package/dist/agents/subagent-spawn.js +195 -7
  79. package/dist/agents/system-prompt.js +22 -6
  80. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  81. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  82. package/dist/agents/timeout.js +18 -6
  83. package/dist/agents/tool-call-id.js +1 -1
  84. package/dist/agents/tool-display-common.js +162 -29
  85. package/dist/agents/tool-images.js +82 -9
  86. package/dist/agents/tool-policy.js +51 -26
  87. package/dist/agents/tools/browser-tool.js +2 -2
  88. package/dist/agents/tools/canvas-tool.js +27 -1
  89. package/dist/agents/tools/common.js +45 -0
  90. package/dist/agents/tools/discord-actions-guild.js +4 -1
  91. package/dist/agents/tools/gateway-tool.js +3 -1
  92. package/dist/agents/tools/nodes-utils.js +1 -10
  93. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  94. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  95. package/dist/agents/tools/subagents-tool.js +2 -1
  96. package/dist/agents/tools/whatsapp-actions.js +10 -2
  97. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  98. package/dist/agents/transcript-policy.js +22 -8
  99. package/dist/agents/venice-models.js +11 -3
  100. package/dist/auto-reply/commands-registry.data.js +51 -0
  101. package/dist/auto-reply/commands-registry.js +4 -3
  102. package/dist/auto-reply/group-activation.js +10 -5
  103. package/dist/auto-reply/inbound-debounce.js +10 -5
  104. package/dist/auto-reply/reply/abort.js +1 -1
  105. package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
  106. package/dist/auto-reply/reply/bash-command.js +41 -39
  107. package/dist/auto-reply/reply/command-gates.js +25 -0
  108. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  109. package/dist/auto-reply/reply/commands-bash.js +6 -5
  110. package/dist/auto-reply/reply/commands-config.js +30 -28
  111. package/dist/auto-reply/reply/commands-core.js +2 -1
  112. package/dist/auto-reply/reply/commands-info.js +1 -0
  113. package/dist/auto-reply/reply/commands-models.js +65 -14
  114. package/dist/auto-reply/reply/commands-session.js +237 -82
  115. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  116. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  117. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  118. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  119. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  120. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  121. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  122. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  123. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  124. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  125. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  126. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  127. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  128. package/dist/auto-reply/reply/commands-tts.js +10 -5
  129. package/dist/auto-reply/reply/config-value.js +10 -5
  130. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  131. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  132. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  133. package/dist/auto-reply/reply/followup-runner.js +1 -0
  134. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  135. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  136. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  137. package/dist/auto-reply/reply/get-reply.js +71 -12
  138. package/dist/auto-reply/reply/model-selection.js +80 -39
  139. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  140. package/dist/auto-reply/reply/queue/state.js +13 -12
  141. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  142. package/dist/auto-reply/reply/reply-reference.js +9 -8
  143. package/dist/auto-reply/reply/route-reply.js +15 -8
  144. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  145. package/dist/auto-reply/reply/session.js +22 -6
  146. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  147. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  148. package/dist/auto-reply/reply/typing.js +46 -21
  149. package/dist/auto-reply/send-policy.js +14 -7
  150. package/dist/auto-reply/status.js +140 -16
  151. package/dist/auto-reply/templating.js +10 -5
  152. package/dist/auto-reply/thinking.js +7 -16
  153. package/dist/auto-reply/tokens.js +21 -5
  154. package/dist/browser/bridge-server.js +36 -20
  155. package/dist/browser/cdp.helpers.js +7 -14
  156. package/dist/browser/cdp.js +35 -15
  157. package/dist/browser/chrome.profile-decoration.js +7 -4
  158. package/dist/browser/config.js +4 -0
  159. package/dist/browser/extension-relay-auth.js +55 -0
  160. package/dist/browser/extension-relay.js +74 -29
  161. package/dist/browser/navigation-guard.js +9 -1
  162. package/dist/browser/paths.js +77 -0
  163. package/dist/browser/profiles.js +13 -8
  164. package/dist/browser/pw-ai-module.js +10 -5
  165. package/dist/browser/pw-session.js +76 -39
  166. package/dist/browser/pw-tools-core.interactions.js +14 -7
  167. package/dist/browser/pw-tools-core.state.js +12 -6
  168. package/dist/browser/routes/agent.act.js +2 -2
  169. package/dist/browser/server-context.js +7 -0
  170. package/dist/build-info.json +3 -3
  171. package/dist/channels/allow-from.js +2 -1
  172. package/dist/channels/allowlists/resolve-utils.js +43 -19
  173. package/dist/channels/channel-config.js +14 -7
  174. package/dist/channels/draft-stream-loop.js +7 -0
  175. package/dist/channels/model-overrides.js +82 -0
  176. package/dist/channels/plugins/normalize/imessage.js +14 -7
  177. package/dist/channels/plugins/normalize/slack.js +10 -5
  178. package/dist/channels/plugins/normalize/telegram.js +14 -7
  179. package/dist/channels/plugins/outbound/discord.js +80 -8
  180. package/dist/channels/plugins/outbound/signal.js +11 -11
  181. package/dist/channels/plugins/setup-helpers.js +10 -5
  182. package/dist/channels/sender-label.js +14 -7
  183. package/dist/channels/session.js +4 -2
  184. package/dist/channels/status-reactions.js +297 -0
  185. package/dist/cli/banner.js +1 -1
  186. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  187. package/dist/cli/cli-name.js +11 -11
  188. package/dist/cli/cli-utils.js +13 -3
  189. package/dist/cli/command-format.js +1 -1
  190. package/dist/cli/config-cli.js +1 -1
  191. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  192. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  193. package/dist/cli/daemon-cli/restart-health.js +126 -0
  194. package/dist/cli/daemon-cli/status.gather.js +9 -13
  195. package/dist/cli/daemon-cli/status.print.js +2 -10
  196. package/dist/cli/deps.js +27 -22
  197. package/dist/cli/gateway-cli/run-loop.js +23 -5
  198. package/dist/cli/node-cli/register.js +14 -5
  199. package/dist/cli/nodes-media-utils.js +7 -2
  200. package/dist/cli/outbound-send-deps.js +2 -9
  201. package/dist/cli/outbound-send-mapping.js +11 -0
  202. package/dist/cli/pairing-cli.js +40 -14
  203. package/dist/cli/plugins-cli.js +34 -41
  204. package/dist/cli/ports.js +11 -10
  205. package/dist/cli/program/command-registry.js +2 -11
  206. package/dist/cli/program/command-tree.js +16 -0
  207. package/dist/cli/program/preaction.js +13 -9
  208. package/dist/cli/program/register.configure.js +3 -18
  209. package/dist/cli/program/register.maintenance.js +2 -2
  210. package/dist/cli/program/register.onboard.js +2 -0
  211. package/dist/cli/program/register.status-health-sessions.js +16 -17
  212. package/dist/cli/program/register.subclis.js +93 -52
  213. package/dist/cli/route.js +11 -7
  214. package/dist/cli/system-cli.js +36 -46
  215. package/dist/cli/update-cli/shared.js +22 -9
  216. package/dist/cli/update-cli/update-command.js +89 -14
  217. package/dist/cli/update-cli/wizard.js +6 -12
  218. package/dist/commands/agent/run-context.js +18 -5
  219. package/dist/commands/agent/session-store.js +17 -4
  220. package/dist/commands/agent.js +22 -2
  221. package/dist/commands/agents.bindings.js +14 -7
  222. package/dist/commands/agents.commands.add.js +13 -9
  223. package/dist/commands/agents.commands.identity.js +12 -6
  224. package/dist/commands/agents.commands.list.js +11 -6
  225. package/dist/commands/agents.config.js +8 -10
  226. package/dist/commands/agents.providers.js +12 -6
  227. package/dist/commands/auth-choice-options.js +103 -75
  228. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  229. package/dist/commands/auth-choice.apply.js +4 -0
  230. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  231. package/dist/commands/auth-choice.apply.openai.js +3 -1
  232. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  233. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  234. package/dist/commands/channels/remove.js +13 -6
  235. package/dist/commands/channels/shared.js +4 -14
  236. package/dist/commands/configure.commands.js +14 -0
  237. package/dist/commands/configure.gateway.js +2 -4
  238. package/dist/commands/configure.js +1 -1
  239. package/dist/commands/configure.shared.js +11 -0
  240. package/dist/commands/daemon-install-helpers.js +2 -2
  241. package/dist/commands/dashboard.js +12 -10
  242. package/dist/commands/docs.js +14 -8
  243. package/dist/commands/doctor-config-flow.js +11 -9
  244. package/dist/commands/doctor-legacy-config.js +281 -0
  245. package/dist/commands/doctor-state-integrity.js +99 -23
  246. package/dist/commands/doctor-update.js +12 -9
  247. package/dist/commands/models/list.list-command.js +7 -5
  248. package/dist/commands/models/set-image.js +2 -21
  249. package/dist/commands/node-daemon-install-helpers.js +10 -8
  250. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  251. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  252. package/dist/commands/onboard-auth.credentials.js +90 -13
  253. package/dist/commands/onboard-auth.js +1 -1
  254. package/dist/commands/onboard-auth.models.js +6 -5
  255. package/dist/commands/onboard-hooks.js +1 -1
  256. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  257. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  258. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  259. package/dist/commands/onboard-remote.js +14 -7
  260. package/dist/commands/onboard.js +11 -13
  261. package/dist/commands/sandbox-display.js +6 -5
  262. package/dist/commands/status-all/diagnosis.js +14 -10
  263. package/dist/commands/status-all/format.js +1 -0
  264. package/dist/commands/status.gateway-probe.js +1 -16
  265. package/dist/commands/systemd-linger.js +12 -6
  266. package/dist/config/agent-limits.js +2 -0
  267. package/dist/config/commands.js +30 -16
  268. package/dist/config/config-paths.js +9 -11
  269. package/dist/config/defaults.js +22 -2
  270. package/dist/config/discord-preview-streaming.js +104 -0
  271. package/dist/config/env-vars.js +37 -8
  272. package/dist/config/includes.js +4 -0
  273. package/dist/config/io.js +97 -12
  274. package/dist/config/legacy.migrations.part-1.js +189 -78
  275. package/dist/config/legacy.shared.js +3 -1
  276. package/dist/config/merge-patch.js +4 -0
  277. package/dist/config/prototype-keys.js +4 -0
  278. package/dist/config/schema.help.js +44 -7
  279. package/dist/config/schema.labels.js +38 -6
  280. package/dist/config/sessions/delivery-info.js +10 -3
  281. package/dist/config/sessions/main-session.js +10 -5
  282. package/dist/config/sessions/session-file.js +33 -0
  283. package/dist/config/sessions/session-key.js +10 -5
  284. package/dist/config/sessions/store.js +1 -1
  285. package/dist/config/sessions.js +1 -0
  286. package/dist/config/zod-schema.agent-runtime.js +11 -0
  287. package/dist/config/zod-schema.js +148 -13
  288. package/dist/config/zod-schema.providers-core.js +78 -4
  289. package/dist/config/zod-schema.providers.js +6 -1
  290. package/dist/config/zod-schema.session.js +41 -2
  291. package/dist/cron/run-log.js +3 -0
  292. package/dist/cron/schedule.js +21 -10
  293. package/dist/cron/service/ops.js +35 -21
  294. package/dist/cron/service/timer.js +116 -16
  295. package/dist/cron/stagger.js +3 -1
  296. package/dist/discord/api.js +12 -6
  297. package/dist/discord/draft-chunking.js +22 -0
  298. package/dist/discord/draft-stream.js +124 -0
  299. package/dist/discord/monitor/agent-components.js +1 -1
  300. package/dist/discord/monitor/commands.js +5 -0
  301. package/dist/discord/monitor/gateway-plugin.js +2 -1
  302. package/dist/discord/monitor/listeners.js +37 -27
  303. package/dist/discord/monitor/message-handler.js +4 -1
  304. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  305. package/dist/discord/monitor/message-handler.process.js +246 -217
  306. package/dist/discord/monitor/message-utils.js +143 -6
  307. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  308. package/dist/discord/monitor/model-picker.js +651 -0
  309. package/dist/discord/monitor/native-command.js +573 -16
  310. package/dist/discord/monitor/provider.allowlist.js +223 -0
  311. package/dist/discord/monitor/provider.js +275 -347
  312. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  313. package/dist/discord/monitor/reply-delivery.js +123 -16
  314. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  315. package/dist/discord/monitor/thread-bindings.js +4 -0
  316. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  317. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  318. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  319. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  320. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  321. package/dist/discord/resolve-users.js +33 -21
  322. package/dist/discord/send.channels.js +15 -0
  323. package/dist/discord/send.js +3 -2
  324. package/dist/discord/send.outbound.js +82 -26
  325. package/dist/discord/send.permissions.js +83 -30
  326. package/dist/discord/send.reactions.js +8 -4
  327. package/dist/discord/token.js +10 -5
  328. package/dist/discord/voice/command.js +263 -0
  329. package/dist/discord/voice/manager.js +531 -0
  330. package/dist/gateway/auth.js +34 -10
  331. package/dist/gateway/call.js +4 -16
  332. package/dist/gateway/client.js +28 -4
  333. package/dist/gateway/config-reload.js +3 -4
  334. package/dist/gateway/control-ui.js +219 -96
  335. package/dist/gateway/hooks-mapping.js +88 -38
  336. package/dist/gateway/http-auth-helpers.js +3 -2
  337. package/dist/gateway/http-endpoint-helpers.js +1 -0
  338. package/dist/gateway/net.js +54 -12
  339. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  340. package/dist/gateway/node-registry.js +10 -5
  341. package/dist/gateway/openai-http.js +1 -0
  342. package/dist/gateway/openresponses-http.js +1 -0
  343. package/dist/gateway/origin-check.js +1 -18
  344. package/dist/gateway/protocol/index.js +4 -3
  345. package/dist/gateway/protocol/schema/cron.js +1 -0
  346. package/dist/gateway/protocol/schema/devices.js +1 -0
  347. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
  348. package/dist/gateway/protocol/schema/sessions.js +6 -0
  349. package/dist/gateway/role-policy.js +17 -0
  350. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  351. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  352. package/dist/gateway/server-chat.js +83 -25
  353. package/dist/gateway/server-constants.js +10 -9
  354. package/dist/gateway/server-cron.js +1 -0
  355. package/dist/gateway/server-http.js +16 -7
  356. package/dist/gateway/server-maintenance.js +20 -5
  357. package/dist/gateway/server-methods/chat.js +10 -6
  358. package/dist/gateway/server-methods/config.js +12 -14
  359. package/dist/gateway/server-methods/devices.js +17 -3
  360. package/dist/gateway/server-methods/models.js +11 -1
  361. package/dist/gateway/server-methods/sessions.js +64 -8
  362. package/dist/gateway/server-methods/usage.js +162 -75
  363. package/dist/gateway/server-node-events.js +29 -0
  364. package/dist/gateway/server-runtime-config.js +34 -13
  365. package/dist/gateway/server-startup-memory.js +17 -11
  366. package/dist/gateway/session-utils.fs.js +32 -34
  367. package/dist/gateway/sessions-resolve.js +17 -5
  368. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  369. package/dist/gateway/tools-invoke-http.js +21 -10
  370. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  371. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  372. package/dist/hooks/bundled/session-memory/handler.js +6 -5
  373. package/dist/hooks/frontmatter.js +6 -6
  374. package/dist/hooks/gmail-watcher.js +11 -6
  375. package/dist/hooks/internal-hooks.js +11 -1
  376. package/dist/hooks/llm-slug-generator.js +4 -1
  377. package/dist/hooks/workspace.js +47 -17
  378. package/dist/imessage/accounts.js +9 -20
  379. package/dist/imessage/monitor/inbound-processing.js +2 -1
  380. package/dist/infra/archive.js +174 -73
  381. package/dist/infra/control-ui-assets.js +14 -6
  382. package/dist/infra/device-pairing.js +108 -29
  383. package/dist/infra/env.js +10 -5
  384. package/dist/infra/exec-approvals-allowlist.js +122 -0
  385. package/dist/infra/exec-approvals-analysis.js +34 -3
  386. package/dist/infra/exec-approvals.js +5 -17
  387. package/dist/infra/exec-safe-bin-policy.js +53 -45
  388. package/dist/infra/fs-safe.js +71 -39
  389. package/dist/infra/gateway-lock.js +6 -2
  390. package/dist/infra/heartbeat-wake.js +6 -12
  391. package/dist/infra/host-env-security-policy.json +19 -0
  392. package/dist/infra/host-env-security.js +66 -0
  393. package/dist/infra/net/ssrf.js +131 -38
  394. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  395. package/dist/infra/outbound/channel-selection.js +12 -6
  396. package/dist/infra/outbound/envelope.js +1 -1
  397. package/dist/infra/outbound/format.js +12 -6
  398. package/dist/infra/outbound/payloads.js +14 -7
  399. package/dist/infra/outbound/session-binding-service.js +123 -0
  400. package/dist/infra/path-guards.js +25 -0
  401. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  402. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  403. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  404. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  405. package/dist/infra/retry-policy.js +4 -2
  406. package/dist/infra/retry.js +9 -5
  407. package/dist/infra/session-cost-usage.js +107 -59
  408. package/dist/infra/session-maintenance-warning.js +3 -1
  409. package/dist/infra/shell-env.js +98 -34
  410. package/dist/infra/ssh-config.js +12 -6
  411. package/dist/infra/system-run-command.js +49 -4
  412. package/dist/infra/update-channels.js +10 -5
  413. package/dist/line/accounts.js +5 -7
  414. package/dist/line/bot-access.js +8 -20
  415. package/dist/line/bot-handlers.js +3 -1
  416. package/dist/link-understanding/detect.js +15 -7
  417. package/dist/media/constants.js +15 -6
  418. package/dist/media/image-ops.js +7 -0
  419. package/dist/media/local-roots.js +3 -2
  420. package/dist/media-understanding/apply.js +4 -1
  421. package/dist/media-understanding/concurrency.js +8 -20
  422. package/dist/memory/backend-config.js +45 -6
  423. package/dist/memory/embeddings.js +10 -4
  424. package/dist/memory/fs-utils.js +23 -0
  425. package/dist/memory/manager-search.js +12 -6
  426. package/dist/memory/manager-sync-ops.js +12 -2
  427. package/dist/memory/qmd-manager.js +466 -53
  428. package/dist/memory/query-expansion.js +167 -3
  429. package/dist/memory/status-format.js +10 -5
  430. package/dist/memory/sync-memory-files.js +1 -1
  431. package/dist/node-host/invoke-system-run.js +281 -0
  432. package/dist/node-host/invoke.js +55 -337
  433. package/dist/pairing/pairing-store.js +22 -0
  434. package/dist/plugin-sdk/allow-from.js +1 -1
  435. package/dist/plugin-sdk/command-auth.js +3 -1
  436. package/dist/plugin-sdk/index.js +6 -3
  437. package/dist/plugin-sdk/webhook-targets.js +32 -0
  438. package/dist/plugins/bundled-dir.js +9 -6
  439. package/dist/plugins/hooks.js +50 -0
  440. package/dist/plugins/install.js +28 -16
  441. package/dist/plugins/runtime.js +3 -17
  442. package/dist/plugins/update.js +78 -12
  443. package/dist/process/spawn-utils.js +14 -7
  444. package/dist/providers/github-copilot-token.js +11 -6
  445. package/dist/providers/qwen-portal-oauth.js +14 -6
  446. package/dist/routing/account-id.js +30 -0
  447. package/dist/routing/resolve-route.js +3 -7
  448. package/dist/routing/session-key.js +2 -16
  449. package/dist/security/audit-channel.js +93 -2
  450. package/dist/security/audit-extra.async.js +159 -5
  451. package/dist/security/audit-extra.js +1 -1
  452. package/dist/security/audit-extra.sync.js +85 -6
  453. package/dist/security/audit.js +40 -4
  454. package/dist/security/dm-policy-shared.js +44 -0
  455. package/dist/security/external-content.js +26 -6
  456. package/dist/shared/entry-status.js +6 -0
  457. package/dist/shared/frontmatter.js +5 -5
  458. package/dist/shared/node-match.js +11 -4
  459. package/dist/shared/operator-scope-compat.js +8 -3
  460. package/dist/signal/accounts.js +7 -20
  461. package/dist/signal/monitor/event-handler.js +3 -1
  462. package/dist/slack/accounts.js +6 -19
  463. package/dist/slack/actions.js +11 -3
  464. package/dist/slack/monitor/auth.js +1 -1
  465. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  466. package/dist/slack/monitor/replies.js +15 -7
  467. package/dist/slack/monitor/slash.js +22 -13
  468. package/dist/slack/resolve-channels.js +10 -5
  469. package/dist/slack/send.js +102 -12
  470. package/dist/slack/stream-mode.js +10 -0
  471. package/dist/slack/streaming.js +4 -2
  472. package/dist/telegram/accounts.js +19 -14
  473. package/dist/telegram/bot/helpers.js +3 -5
  474. package/dist/telegram/bot-access.js +35 -36
  475. package/dist/telegram/bot-handlers.js +120 -148
  476. package/dist/telegram/bot-message-context.js +68 -9
  477. package/dist/telegram/bot-message-dispatch.js +155 -90
  478. package/dist/telegram/bot-native-commands.js +16 -0
  479. package/dist/telegram/draft-stream.js +14 -1
  480. package/dist/telegram/inline-buttons.js +5 -15
  481. package/dist/telegram/monitor.js +11 -7
  482. package/dist/telegram/network-config.js +19 -7
  483. package/dist/telegram/send.js +3 -2
  484. package/dist/telegram/sent-message-cache.js +5 -6
  485. package/dist/telegram/status-reaction-variants.js +208 -0
  486. package/dist/telegram/sticker-cache.js +11 -9
  487. package/dist/terminal/theme.js +12 -12
  488. package/dist/tts/tts.js +80 -567
  489. package/dist/tui/components/chat-log.js +41 -8
  490. package/dist/tui/theme/theme.js +10 -12
  491. package/dist/tui/tui-local-shell.js +16 -6
  492. package/dist/tui/tui.js +58 -6
  493. package/dist/utils/account-id.js +2 -4
  494. package/dist/utils/boolean.js +10 -5
  495. package/dist/utils/directive-tags.js +11 -0
  496. package/dist/utils/queue-helpers.js +67 -12
  497. package/dist/web/auto-reply/deliver-reply.js +8 -4
  498. package/dist/web/auto-reply/mentions.js +10 -5
  499. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  500. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  501. package/dist/web/inbound/access-control.js +5 -2
  502. package/dist/web/login-qr.js +12 -6
  503. package/dist/web/media.js +123 -16
  504. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  505. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  506. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { sendReactionWhatsApp } from "../../web/outbound.js";
2
2
  import { createActionGate, jsonResult, readReactionParams, readStringParam } from "./common.js";
3
+ import { resolveAuthorizedWhatsAppOutboundTarget } from "./whatsapp-target-auth.js";
3
4
  export async function handleWhatsAppAction(params, cfg) {
4
5
  const action = readStringParam(params, "action", { required: true });
5
6
  const isActionEnabled = createActionGate(cfg.channels?.whatsapp?.actions);
@@ -16,12 +17,19 @@ export async function handleWhatsAppAction(params, cfg) {
16
17
  const accountId = readStringParam(params, "accountId");
17
18
  const fromMeRaw = params.fromMe;
18
19
  const fromMe = typeof fromMeRaw === "boolean" ? fromMeRaw : undefined;
20
+ // Resolve account + allowFrom via shared account logic so auth and routing stay aligned.
21
+ const resolved = resolveAuthorizedWhatsAppOutboundTarget({
22
+ cfg,
23
+ chatJid,
24
+ accountId,
25
+ actionLabel: "reaction",
26
+ });
19
27
  const resolvedEmoji = remove ? "" : emoji;
20
- await sendReactionWhatsApp(chatJid, messageId, resolvedEmoji, {
28
+ await sendReactionWhatsApp(resolved.to, messageId, resolvedEmoji, {
21
29
  verbose: false,
22
30
  fromMe,
23
31
  participant: participant ?? undefined,
24
- accountId: accountId ?? undefined,
32
+ accountId: resolved.accountId,
25
33
  });
26
34
  if (!remove && !isEmpty) {
27
35
  return jsonResult({ ok: true, added: emoji });
@@ -0,0 +1,18 @@
1
+ import { resolveWhatsAppAccount } from "../../web/accounts.js";
2
+ import { resolveWhatsAppOutboundTarget } from "../../whatsapp/resolve-outbound-target.js";
3
+ import { ToolAuthorizationError } from "./common.js";
4
+ export function resolveAuthorizedWhatsAppOutboundTarget(params) {
5
+ const account = resolveWhatsAppAccount({
6
+ cfg: params.cfg,
7
+ accountId: params.accountId,
8
+ });
9
+ const resolution = resolveWhatsAppOutboundTarget({
10
+ to: params.chatJid,
11
+ allowFrom: account.allowFrom ?? [],
12
+ mode: "implicit",
13
+ });
14
+ if (!resolution.ok) {
15
+ throw new ToolAuthorizationError(`WhatsApp ${params.actionLabel} blocked: chatJid "${params.chatJid}" is not in the configured allowFrom list for account "${account.accountId}".`);
16
+ }
17
+ return { to: resolution.to, accountId: account.accountId };
18
+ }
@@ -1,5 +1,5 @@
1
- import { isAntigravityClaude, isGoogleModelApi } from "./pi-embedded-helpers/google.js";
2
1
  import { normalizeProviderId } from "./model-selection.js";
2
+ import { isAntigravityClaude, isGoogleModelApi } from "./pi-embedded-helpers/google.js";
3
3
  const MISTRAL_MODEL_HINTS = [
4
4
  "mistral",
5
5
  "mixtral",
@@ -17,28 +17,34 @@ const OPENAI_MODEL_APIS = new Set([
17
17
  ]);
18
18
  const OPENAI_PROVIDERS = new Set(["openai", "openai-codex"]);
19
19
  function isOpenAiApi(modelApi) {
20
- if (!modelApi)
20
+ if (!modelApi) {
21
21
  return false;
22
+ }
22
23
  return OPENAI_MODEL_APIS.has(modelApi);
23
24
  }
24
25
  function isOpenAiProvider(provider) {
25
- if (!provider)
26
+ if (!provider) {
26
27
  return false;
28
+ }
27
29
  return OPENAI_PROVIDERS.has(normalizeProviderId(provider));
28
30
  }
29
31
  function isAnthropicApi(modelApi, provider) {
30
- if (modelApi === "anthropic-messages")
32
+ if (modelApi === "anthropic-messages") {
31
33
  return true;
34
+ }
32
35
  const normalized = normalizeProviderId(provider ?? "");
33
- return normalized === "anthropic" || normalized === "minimax";
36
+ // MiniMax now uses openai-completions API, not anthropic-messages
37
+ return normalized === "anthropic";
34
38
  }
35
39
  function isMistralModel(params) {
36
40
  const provider = normalizeProviderId(params.provider ?? "");
37
- if (provider === "mistral")
41
+ if (provider === "mistral") {
38
42
  return true;
43
+ }
39
44
  const modelId = (params.modelId ?? "").toLowerCase();
40
- if (!modelId)
45
+ if (!modelId) {
41
46
  return false;
47
+ }
42
48
  return MISTRAL_MODEL_HINTS.some((hint) => modelId.includes(hint));
43
49
  }
44
50
  export function resolveTranscriptPolicy(params) {
@@ -55,8 +61,13 @@ export function resolveTranscriptPolicy(params) {
55
61
  provider,
56
62
  modelId,
57
63
  });
64
+ const isCopilotClaude = provider === "github-copilot" && modelId.toLowerCase().includes("claude");
65
+ // GitHub Copilot's Claude endpoints can reject persisted `thinking` blocks with
66
+ // non-binary/non-base64 signatures (e.g. thinkingSignature: "reasoning_text").
67
+ // Drop these blocks at send-time to keep sessions usable.
68
+ const dropThinkingBlocks = isCopilotClaude;
58
69
  const needsNonImageSanitize = isGoogle || isAnthropic || isMistral || isOpenRouterGemini;
59
- const sanitizeToolCallIds = isGoogle || isMistral;
70
+ const sanitizeToolCallIds = isGoogle || isMistral || isAnthropic;
60
71
  const toolCallIdMode = isMistral
61
72
  ? "strict9"
62
73
  : sanitizeToolCallIds
@@ -67,6 +78,7 @@ export function resolveTranscriptPolicy(params) {
67
78
  ? { allowBase64Only: true, includeCamelCase: true }
68
79
  : undefined;
69
80
  const normalizeAntigravityThinkingBlocks = isAntigravityClaudeModel;
81
+ const sanitizeThinkingSignatures = isAntigravityClaudeModel;
70
82
  return {
71
83
  sanitizeMode: isOpenAi ? "images-only" : needsNonImageSanitize ? "full" : "images-only",
72
84
  sanitizeToolCallIds: !isOpenAi && sanitizeToolCallIds,
@@ -75,6 +87,8 @@ export function resolveTranscriptPolicy(params) {
75
87
  preserveSignatures: isAntigravityClaudeModel,
76
88
  sanitizeThoughtSignatures: isOpenAi ? undefined : sanitizeThoughtSignatures,
77
89
  normalizeAntigravityThinkingBlocks,
90
+ sanitizeThinkingSignatures,
91
+ dropThinkingBlocks,
78
92
  applyGoogleTurnOrdering: !isOpenAi && isGoogle,
79
93
  validateGeminiTurns: !isOpenAi && isGoogle,
80
94
  validateAnthropicTurns: !isOpenAi && isAnthropic,
@@ -1,3 +1,5 @@
1
+ import { createSubsystemLogger } from "../logging/subsystem.js";
2
+ const log = createSubsystemLogger("venice-models");
1
3
  export const VENICE_BASE_URL = "https://api.venice.ai/api/v1";
2
4
  export const VENICE_DEFAULT_MODEL_ID = "llama-3.3-70b";
3
5
  export const VENICE_DEFAULT_MODEL_REF = `venice/${VENICE_DEFAULT_MODEL_ID}`;
@@ -282,6 +284,11 @@ export function buildVeniceModelDefinition(entry) {
282
284
  cost: VENICE_DEFAULT_COST,
283
285
  contextWindow: entry.contextWindow,
284
286
  maxTokens: entry.maxTokens,
287
+ // Avoid usage-only streaming chunks that can break OpenAI-compatible parsers.
288
+ // See: https://github.com/openclaw/openclaw/issues/15819
289
+ compat: {
290
+ supportsUsageInStreaming: false,
291
+ },
285
292
  };
286
293
  }
287
294
  /**
@@ -298,12 +305,12 @@ export async function discoverVeniceModels() {
298
305
  signal: AbortSignal.timeout(5000),
299
306
  });
300
307
  if (!response.ok) {
301
- console.warn(`[venice-models] Failed to discover models: HTTP ${response.status}, using static catalog`);
308
+ log.warn(`Failed to discover models: HTTP ${response.status}, using static catalog`);
302
309
  return VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition);
303
310
  }
304
311
  const data = (await response.json());
305
312
  if (!Array.isArray(data.data) || data.data.length === 0) {
306
- console.warn("[venice-models] No models found from API, using static catalog");
313
+ log.warn("No models found from API, using static catalog");
307
314
  return VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition);
308
315
  }
309
316
  // Merge discovered models with catalog metadata
@@ -330,13 +337,14 @@ export async function discoverVeniceModels() {
330
337
  cost: VENICE_DEFAULT_COST,
331
338
  contextWindow: apiModel.model_spec.availableContextTokens || 128000,
332
339
  maxTokens: 8192,
340
+ compat: { supportsUsageInStreaming: false },
333
341
  });
334
342
  }
335
343
  }
336
344
  return models.length > 0 ? models : VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition);
337
345
  }
338
346
  catch (error) {
339
- console.warn(`[venice-models] Discovery failed: ${String(error)}, using static catalog`);
347
+ log.warn(`Discovery failed: ${String(error)}, using static catalog`);
340
348
  return VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition);
341
349
  }
342
350
  }
@@ -231,6 +231,28 @@ function buildChatCommands() {
231
231
  textAlias: "/whoami",
232
232
  category: "status",
233
233
  }),
234
+ defineChatCommand({
235
+ key: "session",
236
+ nativeName: "session",
237
+ description: "Manage session-level settings (for example /session ttl).",
238
+ textAlias: "/session",
239
+ category: "session",
240
+ args: [
241
+ {
242
+ name: "action",
243
+ description: "ttl",
244
+ type: "string",
245
+ choices: ["ttl"],
246
+ },
247
+ {
248
+ name: "value",
249
+ description: "Duration (24h, 90m) or off",
250
+ type: "string",
251
+ captureRemaining: true,
252
+ },
253
+ ],
254
+ argsMenu: "auto",
255
+ }),
234
256
  defineChatCommand({
235
257
  key: "subagents",
236
258
  nativeName: "subagents",
@@ -258,6 +280,35 @@ function buildChatCommands() {
258
280
  ],
259
281
  argsMenu: "auto",
260
282
  }),
283
+ defineChatCommand({
284
+ key: "focus",
285
+ nativeName: "focus",
286
+ description: "Bind this Discord thread (or a new one) to a session target.",
287
+ textAlias: "/focus",
288
+ category: "management",
289
+ args: [
290
+ {
291
+ name: "target",
292
+ description: "Subagent label/index or session key/id/label",
293
+ type: "string",
294
+ captureRemaining: true,
295
+ },
296
+ ],
297
+ }),
298
+ defineChatCommand({
299
+ key: "unfocus",
300
+ nativeName: "unfocus",
301
+ description: "Remove the current Discord thread binding.",
302
+ textAlias: "/unfocus",
303
+ category: "management",
304
+ }),
305
+ defineChatCommand({
306
+ key: "agents",
307
+ nativeName: "agents",
308
+ description: "List thread-bound agents for this session.",
309
+ textAlias: "/agents",
310
+ category: "management",
311
+ }),
261
312
  defineChatCommand({
262
313
  key: "kill",
263
314
  nativeName: "kill",
@@ -1,5 +1,6 @@
1
1
  import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
2
2
  import { resolveConfiguredModelRef } from "../agents/model-selection.js";
3
+ import { isCommandFlagEnabled } from "../config/commands.js";
3
4
  import { escapeRegExp } from "../utils.js";
4
5
  import { getChatCommands, getNativeCommandSurfaces } from "./commands-registry.data.js";
5
6
  let cachedTextAliasMap = null;
@@ -51,11 +52,11 @@ export function listChatCommands(params) {
51
52
  }
52
53
  export function isCommandEnabled(cfg, commandKey) {
53
54
  if (commandKey === "config")
54
- return cfg.commands?.config === true;
55
+ return isCommandFlagEnabled(cfg, "config");
55
56
  if (commandKey === "debug")
56
- return cfg.commands?.debug === true;
57
+ return isCommandFlagEnabled(cfg, "debug");
57
58
  if (commandKey === "bash")
58
- return cfg.commands?.bash === true;
59
+ return isCommandFlagEnabled(cfg, "bash");
59
60
  return true;
60
61
  }
61
62
  export function listChatCommandsForConfig(cfg, params) {
@@ -1,22 +1,27 @@
1
1
  import { normalizeCommandBody } from "./commands-registry.js";
2
2
  export function normalizeGroupActivation(raw) {
3
3
  const value = raw?.trim().toLowerCase();
4
- if (value === "mention")
4
+ if (value === "mention") {
5
5
  return "mention";
6
- if (value === "always")
6
+ }
7
+ if (value === "always") {
7
8
  return "always";
9
+ }
8
10
  return undefined;
9
11
  }
10
12
  export function parseActivationCommand(raw) {
11
- if (!raw)
13
+ if (!raw) {
12
14
  return { hasCommand: false };
15
+ }
13
16
  const trimmed = raw.trim();
14
- if (!trimmed)
17
+ if (!trimmed) {
15
18
  return { hasCommand: false };
19
+ }
16
20
  const normalized = normalizeCommandBody(trimmed);
17
21
  const match = normalized.match(/^\/activation(?:\s+([a-zA-Z]+))?\s*$/i);
18
- if (!match)
22
+ if (!match) {
19
23
  return { hasCommand: false };
24
+ }
20
25
  const mode = normalizeGroupActivation(match[1]);
21
26
  return { hasCommand: true, mode };
22
27
  }
@@ -1,11 +1,13 @@
1
1
  const resolveMs = (value) => {
2
- if (typeof value !== "number" || !Number.isFinite(value))
2
+ if (typeof value !== "number" || !Number.isFinite(value)) {
3
3
  return undefined;
4
+ }
4
5
  return Math.max(0, Math.trunc(value));
5
6
  };
6
7
  const resolveChannelOverride = (params) => {
7
- if (!params.byChannel)
8
+ if (!params.byChannel) {
8
9
  return undefined;
10
+ }
9
11
  return resolveMs(params.byChannel[params.channel]);
10
12
  };
11
13
  export function resolveInboundDebounceMs(params) {
@@ -27,8 +29,9 @@ export function createInboundDebouncer(params) {
27
29
  clearTimeout(buffer.timeout);
28
30
  buffer.timeout = null;
29
31
  }
30
- if (buffer.items.length === 0)
32
+ if (buffer.items.length === 0) {
31
33
  return;
34
+ }
32
35
  try {
33
36
  await params.onFlush(buffer.items);
34
37
  }
@@ -38,13 +41,15 @@ export function createInboundDebouncer(params) {
38
41
  };
39
42
  const flushKey = async (key) => {
40
43
  const buffer = buffers.get(key);
41
- if (!buffer)
44
+ if (!buffer) {
42
45
  return;
46
+ }
43
47
  await flushBuffer(key, buffer);
44
48
  };
45
49
  const scheduleFlush = (key, buffer) => {
46
- if (buffer.timeout)
50
+ if (buffer.timeout) {
47
51
  clearTimeout(buffer.timeout);
52
+ }
48
53
  buffer.timeout = setTimeout(() => {
49
54
  void flushBuffer(key, buffer);
50
55
  }, debounceMs);
@@ -79,7 +79,7 @@ export function formatAbortReplyText(stoppedSubagents) {
79
79
  const label = stoppedSubagents === 1 ? "sub-agent" : "sub-agents";
80
80
  return `⚙️ Agent was aborted. Stopped ${stoppedSubagents} ${label}.`;
81
81
  }
82
- function resolveSessionEntryForKey(store, sessionKey) {
82
+ export function resolveSessionEntryForKey(store, sessionKey) {
83
83
  if (!store || !sessionKey) {
84
84
  return {};
85
85
  }
@@ -13,7 +13,7 @@ import { emitAgentEvent, registerAgentRunContext } from "../../infra/agent-event
13
13
  import { defaultRuntime } from "../../runtime.js";
14
14
  import { isMarkdownCapableMessageChannel, resolveMessageChannel, } from "../../utils/message-channel.js";
15
15
  import { stripHeartbeatToken } from "../heartbeat.js";
16
- import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js";
16
+ import { isSilentReplyPrefixText, isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js";
17
17
  import { buildThreadingToolContext, resolveEnforceFinalTag } from "./agent-runner-utils.js";
18
18
  import { createBlockReplyPayloadKey } from "./block-reply-pipeline.js";
19
19
  import { parseReplyDirectives } from "./reply-directives.js";
@@ -74,6 +74,9 @@ export async function runAgentTurnWithFallback(params) {
74
74
  return { text: sanitized, skip: false };
75
75
  };
76
76
  const handlePartialForTyping = async (payload) => {
77
+ if (isSilentReplyPrefixText(payload.text, SILENT_REPLY_TOKEN)) {
78
+ return undefined;
79
+ }
77
80
  const { text, skip } = normalizeStreamingText(payload);
78
81
  if (skip || !text)
79
82
  return undefined;
@@ -3,9 +3,11 @@ import { getFinishedSession, getSession, markExited } from "../../agents/bash-pr
3
3
  import { createExecTool } from "../../agents/bash-tools.js";
4
4
  import { resolveSandboxRuntimeStatus } from "../../agents/sandbox.js";
5
5
  import { killProcessTree } from "../../agents/shell-utils.js";
6
- import { formatCliCommand } from "../../cli/command-format.js";
6
+ import { isCommandFlagEnabled } from "../../config/commands.js";
7
7
  import { logVerbose } from "../../globals.js";
8
8
  import { clampInt } from "../../utils.js";
9
+ import { buildDisabledCommandReply } from "./command-gates.js";
10
+ import { formatElevatedUnavailableMessage } from "./elevated-unavailable.js";
9
11
  import { stripMentions, stripStructuralPrefixes } from "./mentions.js";
10
12
  const CHAT_BASH_SCOPE_KEY = "chat:bash";
11
13
  const DEFAULT_FOREGROUND_MS = 2000;
@@ -13,20 +15,23 @@ const MAX_FOREGROUND_MS = 30_000;
13
15
  let activeJob = null;
14
16
  function resolveForegroundMs(cfg) {
15
17
  const raw = cfg.commands?.bashForegroundMs;
16
- if (typeof raw !== "number" || Number.isNaN(raw))
18
+ if (typeof raw !== "number" || Number.isNaN(raw)) {
17
19
  return DEFAULT_FOREGROUND_MS;
20
+ }
18
21
  return clampInt(raw, 0, MAX_FOREGROUND_MS);
19
22
  }
20
23
  function formatSessionSnippet(sessionId) {
21
24
  const trimmed = sessionId.trim();
22
- if (trimmed.length <= 12)
25
+ if (trimmed.length <= 12) {
23
26
  return trimmed;
27
+ }
24
28
  return `${trimmed.slice(0, 8)}…`;
25
29
  }
26
30
  function formatOutputBlock(text) {
27
31
  const trimmed = text.trim();
28
- if (!trimmed)
32
+ if (!trimmed) {
29
33
  return "(no output)";
34
+ }
30
35
  return `\`\`\`txt\n${trimmed}\n\`\`\``;
31
36
  }
32
37
  function parseBashRequest(raw) {
@@ -34,8 +39,9 @@ function parseBashRequest(raw) {
34
39
  let restSource = "";
35
40
  if (trimmed.toLowerCase().startsWith("/bash")) {
36
41
  const match = trimmed.match(/^\/bash(?:\s*:\s*|\s+|$)([\s\S]*)$/i);
37
- if (!match)
42
+ if (!match) {
38
43
  return null;
44
+ }
39
45
  restSource = match[1] ?? "";
40
46
  }
41
47
  else if (trimmed.startsWith("!")) {
@@ -48,8 +54,9 @@ function parseBashRequest(raw) {
48
54
  return null;
49
55
  }
50
56
  const rest = restSource.trimStart();
51
- if (!rest)
57
+ if (!rest) {
52
58
  return { action: "help" };
59
+ }
53
60
  const tokenMatch = rest.match(/^(\S+)(?:\s+([\s\S]+))?$/);
54
61
  const token = tokenMatch?.[1]?.trim() ?? "";
55
62
  const remainder = tokenMatch?.[2]?.trim() ?? "";
@@ -74,21 +81,26 @@ function resolveRawCommandBody(params) {
74
81
  }
75
82
  function getScopedSession(sessionId) {
76
83
  const running = getSession(sessionId);
77
- if (running && running.scopeKey === CHAT_BASH_SCOPE_KEY)
84
+ if (running && running.scopeKey === CHAT_BASH_SCOPE_KEY) {
78
85
  return { running };
86
+ }
79
87
  const finished = getFinishedSession(sessionId);
80
- if (finished && finished.scopeKey === CHAT_BASH_SCOPE_KEY)
88
+ if (finished && finished.scopeKey === CHAT_BASH_SCOPE_KEY) {
81
89
  return { finished };
90
+ }
82
91
  return {};
83
92
  }
84
93
  function ensureActiveJobState() {
85
- if (!activeJob)
94
+ if (!activeJob) {
86
95
  return null;
87
- if (activeJob.state === "starting")
96
+ }
97
+ if (activeJob.state === "starting") {
88
98
  return activeJob;
99
+ }
89
100
  const { running, finished } = getScopedSession(activeJob.sessionId);
90
- if (running)
101
+ if (running) {
91
102
  return activeJob;
103
+ }
92
104
  if (finished) {
93
105
  activeJob = null;
94
106
  return null;
@@ -97,16 +109,20 @@ function ensureActiveJobState() {
97
109
  return null;
98
110
  }
99
111
  function attachActiveWatcher(sessionId) {
100
- if (!activeJob || activeJob.state !== "running")
112
+ if (!activeJob || activeJob.state !== "running") {
101
113
  return;
102
- if (activeJob.sessionId !== sessionId)
114
+ }
115
+ if (activeJob.sessionId !== sessionId) {
103
116
  return;
104
- if (activeJob.watcherAttached)
117
+ }
118
+ if (activeJob.watcherAttached) {
105
119
  return;
120
+ }
106
121
  const { running } = getScopedSession(sessionId);
107
122
  const child = running?.child;
108
- if (!child)
123
+ if (!child) {
109
124
  return;
125
+ }
110
126
  activeJob.watcherAttached = true;
111
127
  child.once("close", () => {
112
128
  if (activeJob?.state === "running" && activeJob.sessionId === sessionId) {
@@ -125,30 +141,13 @@ function buildUsageReply() {
125
141
  ].join("\n"),
126
142
  };
127
143
  }
128
- function formatElevatedUnavailableMessage(params) {
129
- const lines = [];
130
- lines.push(`elevated is not available right now (runtime=${params.runtimeSandboxed ? "sandboxed" : "direct"}).`);
131
- if (params.failures.length > 0) {
132
- lines.push(`Failing gates: ${params.failures.map((f) => `${f.gate} (${f.key})`).join(", ")}`);
133
- }
134
- else {
135
- lines.push("Failing gates: enabled (tools.elevated.enabled / agents.list[].tools.elevated.enabled), allowFrom (tools.elevated.allowFrom.<provider>).");
136
- }
137
- lines.push("Fix-it keys:");
138
- lines.push("- tools.elevated.enabled");
139
- lines.push("- tools.elevated.allowFrom.<provider>");
140
- lines.push("- agents.list[].tools.elevated.enabled");
141
- lines.push("- agents.list[].tools.elevated.allowFrom.<provider>");
142
- if (params.sessionKey) {
143
- lines.push(`See: ${formatCliCommand(`poolbot sandbox explain --session ${params.sessionKey}`)}`);
144
- }
145
- return lines.join("\n");
146
- }
147
144
  export async function handleBashChatCommand(params) {
148
- if (params.cfg.commands?.bash !== true) {
149
- return {
150
- text: "⚠️ bash is disabled. Set commands.bash=true to enable. Docs: https://docs.molt.bot/tools/slash-commands#config",
151
- };
145
+ if (!isCommandFlagEnabled(params.cfg, "bash")) {
146
+ return buildDisabledCommandReply({
147
+ label: "bash",
148
+ configKey: "bash",
149
+ docsUrl: "https://docs.molt.bot/tools/slash-commands#config",
150
+ });
152
151
  }
153
152
  const agentId = params.agentId ??
154
153
  resolveSessionAgentId({
@@ -262,8 +261,9 @@ export async function handleBashChatCommand(params) {
262
261
  };
263
262
  }
264
263
  const commandText = request.command.trim();
265
- if (!commandText)
264
+ if (!commandText) {
266
265
  return buildUsageReply();
266
+ }
267
267
  activeJob = {
268
268
  state: "starting",
269
269
  startedAt: Date.now(),
@@ -274,12 +274,14 @@ export async function handleBashChatCommand(params) {
274
274
  const shouldBackgroundImmediately = foregroundMs <= 0;
275
275
  const timeoutSec = params.cfg.tools?.exec?.timeoutSec;
276
276
  const notifyOnExit = params.cfg.tools?.exec?.notifyOnExit;
277
+ const notifyOnExitEmptySuccess = params.cfg.tools?.exec?.notifyOnExitEmptySuccess;
277
278
  const execTool = createExecTool({
278
279
  scopeKey: CHAT_BASH_SCOPE_KEY,
279
280
  allowBackground: true,
280
281
  timeoutSec,
281
282
  sessionKey: params.sessionKey,
282
283
  notifyOnExit,
284
+ notifyOnExitEmptySuccess,
283
285
  elevated: {
284
286
  enabled: params.elevated.enabled,
285
287
  allowed: params.elevated.allowed,
@@ -0,0 +1,25 @@
1
+ import { isCommandFlagEnabled } from "../../config/commands.js";
2
+ import { logVerbose } from "../../globals.js";
3
+ export function rejectUnauthorizedCommand(params, commandLabel) {
4
+ if (params.command.isAuthorizedSender) {
5
+ return null;
6
+ }
7
+ logVerbose(`Ignoring ${commandLabel} from unauthorized sender: ${params.command.senderId || "<unknown>"}`);
8
+ return { shouldContinue: false };
9
+ }
10
+ export function buildDisabledCommandReply(params) {
11
+ const disabledVerb = params.disabledVerb ?? "is";
12
+ const docsSuffix = params.docsUrl ? ` Docs: ${params.docsUrl}` : "";
13
+ return {
14
+ text: `⚠️ ${params.label} ${disabledVerb} disabled. Set commands.${params.configKey}=true to enable.${docsSuffix}`,
15
+ };
16
+ }
17
+ export function requireCommandFlagEnabled(cfg, params) {
18
+ if (isCommandFlagEnabled(cfg, params.configKey)) {
19
+ return null;
20
+ }
21
+ return {
22
+ shouldContinue: false,
23
+ reply: buildDisabledCommandReply(params),
24
+ };
25
+ }