@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
@@ -2,13 +2,16 @@ import { logVerbose } from "../../globals.js";
2
2
  import { getLastTtsAttempt, getTtsMaxLength, getTtsProvider, isSummarizationEnabled, isTtsEnabled, isTtsProviderConfigured, resolveTtsApiKey, resolveTtsConfig, resolveTtsPrefsPath, setLastTtsAttempt, setSummarizationEnabled, setTtsEnabled, setTtsMaxLength, setTtsProvider, textToSpeech, } from "../../tts/tts.js";
3
3
  function parseTtsCommand(normalized) {
4
4
  // Accept `/tts` and `/tts <action> [args]` as a single control surface.
5
- if (normalized === "/tts")
5
+ if (normalized === "/tts") {
6
6
  return { action: "status", args: "" };
7
- if (!normalized.startsWith("/tts "))
7
+ }
8
+ if (!normalized.startsWith("/tts ")) {
8
9
  return null;
10
+ }
9
11
  const rest = normalized.slice(5).trim();
10
- if (!rest)
12
+ if (!rest) {
11
13
  return { action: "status", args: "" };
14
+ }
12
15
  const [action, ...tail] = rest.split(/\s+/);
13
16
  return { action: action.toLowerCase(), args: tail.join(" ").trim() };
14
17
  }
@@ -39,11 +42,13 @@ function ttsUsage() {
39
42
  };
40
43
  }
41
44
  export const handleTtsCommands = async (params, allowTextCommands) => {
42
- if (!allowTextCommands)
45
+ if (!allowTextCommands) {
43
46
  return null;
47
+ }
44
48
  const parsed = parseTtsCommand(params.command.commandBodyNormalized);
45
- if (!parsed)
49
+ if (!parsed) {
46
50
  return null;
51
+ }
47
52
  if (!params.command.isAuthorizedSender) {
48
53
  logVerbose(`Ignoring TTS command from unauthorized sender: ${params.command.senderId || "<unknown>"}`);
49
54
  return { shouldContinue: false };
@@ -1,7 +1,8 @@
1
1
  export function parseConfigValue(raw) {
2
2
  const trimmed = raw.trim();
3
- if (!trimmed)
3
+ if (!trimmed) {
4
4
  return { error: "Missing value." };
5
+ }
5
6
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
6
7
  try {
7
8
  return { value: JSON.parse(trimmed) };
@@ -10,16 +11,20 @@ export function parseConfigValue(raw) {
10
11
  return { error: `Invalid JSON: ${String(err)}` };
11
12
  }
12
13
  }
13
- if (trimmed === "true")
14
+ if (trimmed === "true") {
14
15
  return { value: true };
15
- if (trimmed === "false")
16
+ }
17
+ if (trimmed === "false") {
16
18
  return { value: false };
17
- if (trimmed === "null")
19
+ }
20
+ if (trimmed === "null") {
18
21
  return { value: null };
22
+ }
19
23
  if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
20
24
  const num = Number(trimmed);
21
- if (Number.isFinite(num))
25
+ if (Number.isFinite(num)) {
22
26
  return { value: num };
27
+ }
23
28
  }
24
29
  if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
25
30
  (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
@@ -20,12 +20,15 @@ const PROVIDER_RANK = new Map(MODEL_PICK_PROVIDER_PREFERENCE.map((provider, idx)
20
20
  function compareProvidersForPicker(a, b) {
21
21
  const pa = PROVIDER_RANK.get(a);
22
22
  const pb = PROVIDER_RANK.get(b);
23
- if (pa !== undefined && pb !== undefined)
23
+ if (pa !== undefined && pb !== undefined) {
24
24
  return pa - pb;
25
- if (pa !== undefined)
25
+ }
26
+ if (pa !== undefined) {
26
27
  return -1;
27
- if (pb !== undefined)
28
+ }
29
+ if (pb !== undefined) {
28
30
  return 1;
31
+ }
29
32
  return a.localeCompare(b);
30
33
  }
31
34
  export function buildModelPickerItems(catalog) {
@@ -34,19 +37,22 @@ export function buildModelPickerItems(catalog) {
34
37
  for (const entry of catalog) {
35
38
  const provider = normalizeProviderId(entry.provider);
36
39
  const model = entry.id?.trim();
37
- if (!provider || !model)
40
+ if (!provider || !model) {
38
41
  continue;
42
+ }
39
43
  const key = `${provider}/${model}`;
40
- if (seen.has(key))
44
+ if (seen.has(key)) {
41
45
  continue;
46
+ }
42
47
  seen.add(key);
43
48
  out.push({ model, provider });
44
49
  }
45
50
  // Sort by provider preference first, then by model name
46
51
  out.sort((a, b) => {
47
52
  const providerOrder = compareProvidersForPicker(a.provider, b.provider);
48
- if (providerOrder !== 0)
53
+ if (providerOrder !== 0) {
49
54
  return providerOrder;
55
+ }
50
56
  return a.model.toLowerCase().localeCompare(b.model.toLowerCase());
51
57
  });
52
58
  return out;
@@ -7,7 +7,7 @@ import { enqueueSystemEvent } from "../../infra/system-events.js";
7
7
  import { applyVerboseOverride } from "../../sessions/level-overrides.js";
8
8
  import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js";
9
9
  import { resolveProfileOverride } from "./directive-handling.auth.js";
10
- import { formatElevatedEvent, formatReasoningEvent } from "./directive-handling.shared.js";
10
+ import { enqueueModeSwitchEvents } from "./directive-handling.shared.js";
11
11
  export async function persistInlineDirectives(params) {
12
12
  const { directives, cfg, sessionEntry, sessionStore, sessionKey, storePath, elevatedEnabled, elevatedAllowed, defaultProvider, defaultModel, aliasIndex, allowedModelKeys, initialModelLabel, formatModelSwitchEvent, agentCfg, } = params;
13
13
  let { provider, model } = params;
@@ -27,12 +27,7 @@ export async function persistInlineDirectives(params) {
27
27
  let reasoningChanged = directives.hasReasoningDirective && directives.reasoningLevel !== undefined;
28
28
  let updated = false;
29
29
  if (directives.hasThinkDirective && directives.thinkLevel) {
30
- if (directives.thinkLevel === "off") {
31
- delete sessionEntry.thinkingLevel;
32
- }
33
- else {
34
- sessionEntry.thinkingLevel = directives.thinkLevel;
35
- }
30
+ sessionEntry.thinkingLevel = directives.thinkLevel;
36
31
  updated = true;
37
32
  }
38
33
  if (directives.hasVerboseDirective && directives.verboseLevel) {
@@ -144,20 +139,13 @@ export async function persistInlineDirectives(params) {
144
139
  store[sessionKey] = sessionEntry;
145
140
  });
146
141
  }
147
- if (elevatedChanged) {
148
- const nextElevated = (sessionEntry.elevatedLevel ?? "off");
149
- enqueueSystemEvent(formatElevatedEvent(nextElevated), {
150
- sessionKey,
151
- contextKey: "mode:elevated",
152
- });
153
- }
154
- if (reasoningChanged) {
155
- const nextReasoning = (sessionEntry.reasoningLevel ?? "off");
156
- enqueueSystemEvent(formatReasoningEvent(nextReasoning), {
157
- sessionKey,
158
- contextKey: "mode:reasoning",
159
- });
160
- }
142
+ enqueueModeSwitchEvents({
143
+ enqueueSystemEvent,
144
+ sessionEntry,
145
+ sessionKey,
146
+ elevatedChanged,
147
+ reasoningChanged,
148
+ });
161
149
  }
162
150
  }
163
151
  return {
@@ -1,10 +1,12 @@
1
1
  import { formatCliCommand } from "../../cli/command-format.js";
2
2
  export const SYSTEM_MARK = "⚙️";
3
3
  export const formatDirectiveAck = (text) => {
4
- if (!text)
4
+ if (!text) {
5
5
  return text;
6
- if (text.startsWith(SYSTEM_MARK))
6
+ }
7
+ if (text.startsWith(SYSTEM_MARK)) {
7
8
  return text;
9
+ }
8
10
  return `${SYSTEM_MARK} ${text}`;
9
11
  };
10
12
  export const formatOptionsLine = (options) => `Options: ${options}.`;
@@ -20,12 +22,30 @@ export const formatElevatedEvent = (level) => {
20
22
  return "Elevated OFF — exec stays in sandbox.";
21
23
  };
22
24
  export const formatReasoningEvent = (level) => {
23
- if (level === "stream")
25
+ if (level === "stream") {
24
26
  return "Reasoning STREAM — emit live <think>.";
25
- if (level === "on")
27
+ }
28
+ if (level === "on") {
26
29
  return "Reasoning ON — include <think>.";
30
+ }
27
31
  return "Reasoning OFF — hide <think>.";
28
32
  };
33
+ export function enqueueModeSwitchEvents(params) {
34
+ if (params.elevatedChanged) {
35
+ const nextElevated = (params.sessionEntry.elevatedLevel ?? "off");
36
+ params.enqueueSystemEvent(formatElevatedEvent(nextElevated), {
37
+ sessionKey: params.sessionKey,
38
+ contextKey: "mode:elevated",
39
+ });
40
+ }
41
+ if (params.reasoningChanged) {
42
+ const nextReasoning = (params.sessionEntry.reasoningLevel ?? "off");
43
+ params.enqueueSystemEvent(formatReasoningEvent(nextReasoning), {
44
+ sessionKey: params.sessionKey,
45
+ contextKey: "mode:reasoning",
46
+ });
47
+ }
48
+ }
29
49
  export function formatElevatedUnavailableText(params) {
30
50
  const lines = [];
31
51
  lines.push(`elevated is not available right now (runtime=${params.runtimeSandboxed ? "sandboxed" : "direct"}).`);
@@ -111,6 +111,7 @@ export function createFollowupRunner(params) {
111
111
  senderName: queued.run.senderName,
112
112
  senderUsername: queued.run.senderUsername,
113
113
  senderE164: queued.run.senderE164,
114
+ senderIsOwner: queued.run.senderIsOwner,
114
115
  sessionFile: queued.run.sessionFile,
115
116
  workspaceDir: queued.run.workspaceDir,
116
117
  config: queued.run.config,
@@ -1,3 +1,19 @@
1
+ const CLEARED_EXEC_FIELDS = {
2
+ hasExecDirective: false,
3
+ execHost: undefined,
4
+ execSecurity: undefined,
5
+ execAsk: undefined,
6
+ execNode: undefined,
7
+ rawExecHost: undefined,
8
+ rawExecSecurity: undefined,
9
+ rawExecAsk: undefined,
10
+ rawExecNode: undefined,
11
+ hasExecOptions: false,
12
+ invalidExecHost: false,
13
+ invalidExecSecurity: false,
14
+ invalidExecAsk: false,
15
+ invalidExecNode: false,
16
+ };
1
17
  export function clearInlineDirectives(cleaned) {
2
18
  return {
3
19
  cleaned,
@@ -13,20 +29,7 @@ export function clearInlineDirectives(cleaned) {
13
29
  hasElevatedDirective: false,
14
30
  elevatedLevel: undefined,
15
31
  rawElevatedLevel: undefined,
16
- hasExecDirective: false,
17
- execHost: undefined,
18
- execSecurity: undefined,
19
- execAsk: undefined,
20
- execNode: undefined,
21
- rawExecHost: undefined,
22
- rawExecSecurity: undefined,
23
- rawExecAsk: undefined,
24
- rawExecNode: undefined,
25
- hasExecOptions: false,
26
- invalidExecHost: false,
27
- invalidExecSecurity: false,
28
- invalidExecAsk: false,
29
- invalidExecNode: false,
32
+ ...CLEARED_EXEC_FIELDS,
30
33
  hasStatusDirective: false,
31
34
  hasModelDirective: false,
32
35
  rawModelDirective: undefined,
@@ -43,3 +46,9 @@ export function clearInlineDirectives(cleaned) {
43
46
  hasQueueOptions: false,
44
47
  };
45
48
  }
49
+ export function clearExecInlineDirectives(directives) {
50
+ return {
51
+ ...directives,
52
+ ...CLEARED_EXEC_FIELDS,
53
+ };
54
+ }
@@ -5,7 +5,7 @@ import { resolveBlockStreamingChunking } from "./block-streaming.js";
5
5
  import { buildCommandContext } from "./commands.js";
6
6
  import { parseInlineDirectives } from "./directive-handling.js";
7
7
  import { applyInlineDirectiveOverrides } from "./get-reply-directives-apply.js";
8
- import { clearInlineDirectives } from "./get-reply-directives-utils.js";
8
+ import { clearExecInlineDirectives, clearInlineDirectives } from "./get-reply-directives-utils.js";
9
9
  import { defaultGroupActivation, resolveGroupRequireMention } from "./groups.js";
10
10
  import { CURRENT_MESSAGE_MARKER, stripMentions, stripStructuralPrefixes } from "./mentions.js";
11
11
  import { createModelSelectionState, resolveContextTokens } from "./model-selection.js";
@@ -17,12 +17,13 @@ function resolveExecOverrides(params) {
17
17
  params.sessionEntry?.execSecurity;
18
18
  const ask = params.directives.execAsk ?? params.sessionEntry?.execAsk;
19
19
  const node = params.directives.execNode ?? params.sessionEntry?.execNode;
20
- if (!host && !security && !ask && !node)
20
+ if (!host && !security && !ask && !node) {
21
21
  return undefined;
22
+ }
22
23
  return { host, security, ask, node };
23
24
  }
24
25
  export async function resolveReplyDirectives(params) {
25
- const { ctx, cfg, agentId, agentCfg, agentDir, workspaceDir, sessionCtx, sessionEntry, sessionStore, sessionKey, storePath, sessionScope, groupResolution, isGroup, triggerBodyNormalized, commandAuthorized, defaultProvider, defaultModel, provider: initialProvider, model: initialModel, typing, opts, skillFilter, } = params;
26
+ const { ctx, cfg, agentId, agentCfg, agentDir, workspaceDir, sessionCtx, sessionEntry, sessionStore, sessionKey, storePath, sessionScope, groupResolution, isGroup, triggerBodyNormalized, commandAuthorized, defaultProvider, defaultModel, provider: initialProvider, model: initialModel, hasResolvedHeartbeatModelOverride, typing, opts, skillFilter, } = params;
26
27
  let provider = initialProvider;
27
28
  let model = initialModel;
28
29
  // Prefer CommandBody/RawBody (clean message without structural context) for directive parsing.
@@ -53,22 +54,24 @@ export async function resolveReplyDirectives(params) {
53
54
  surface: command.surface,
54
55
  commandSource: ctx.CommandSource,
55
56
  });
56
- const shouldResolveSkillCommands = allowTextCommands && command.commandBodyNormalized.includes("/");
57
- const skillCommands = shouldResolveSkillCommands
57
+ const reservedCommands = new Set(listChatCommands().flatMap((cmd) => cmd.textAliases.map((a) => a.replace(/^\//, "").toLowerCase())));
58
+ const rawAliases = Object.values(cfg.agents?.defaults?.models ?? {})
59
+ .map((entry) => entry.alias?.trim())
60
+ .filter((alias) => Boolean(alias))
61
+ .filter((alias) => !reservedCommands.has(alias.toLowerCase()));
62
+ // Only load workspace skill commands when we actually need them to filter aliases.
63
+ // This avoids scanning skills for messages that only use inline directives like /think:/verbose:.
64
+ const skillCommands = allowTextCommands && rawAliases.length > 0
58
65
  ? listSkillCommandsForWorkspace({
59
66
  workspaceDir,
60
67
  cfg,
61
68
  skillFilter,
62
69
  })
63
70
  : [];
64
- const reservedCommands = new Set(listChatCommands().flatMap((cmd) => cmd.textAliases.map((a) => a.replace(/^\//, "").toLowerCase())));
65
71
  for (const command of skillCommands) {
66
72
  reservedCommands.add(command.name.toLowerCase());
67
73
  }
68
- const configuredAliases = Object.values(cfg.agents?.defaults?.models ?? {})
69
- .map((entry) => entry.alias?.trim())
70
- .filter((alias) => Boolean(alias))
71
- .filter((alias) => !reservedCommands.has(alias.toLowerCase()));
74
+ const configuredAliases = rawAliases.filter((alias) => !reservedCommands.has(alias.toLowerCase()));
72
75
  const allowStatusDirective = allowTextCommands && command.isAuthorizedSender;
73
76
  let parsedDirectives = parseInlineDirectives(commandText, {
74
77
  modelAliases: configuredAliases,
@@ -93,23 +96,7 @@ export async function resolveReplyDirectives(params) {
93
96
  }
94
97
  if (isGroup && ctx.WasMentioned !== true && parsedDirectives.hasExecDirective) {
95
98
  if (parsedDirectives.execSecurity !== "deny") {
96
- parsedDirectives = {
97
- ...parsedDirectives,
98
- hasExecDirective: false,
99
- execHost: undefined,
100
- execSecurity: undefined,
101
- execAsk: undefined,
102
- execNode: undefined,
103
- rawExecHost: undefined,
104
- rawExecSecurity: undefined,
105
- rawExecAsk: undefined,
106
- rawExecNode: undefined,
107
- hasExecOptions: false,
108
- invalidExecHost: false,
109
- invalidExecSecurity: false,
110
- invalidExecAsk: false,
111
- invalidExecNode: false,
112
- };
99
+ parsedDirectives = clearExecInlineDirectives(parsedDirectives);
113
100
  }
114
101
  }
115
102
  const hasInlineDirective = parsedDirectives.hasThinkDirective ||
@@ -151,8 +138,9 @@ export async function resolveReplyDirectives(params) {
151
138
  };
152
139
  const existingBody = sessionCtx.BodyStripped ?? sessionCtx.Body ?? "";
153
140
  let cleanedBody = (() => {
154
- if (!existingBody)
141
+ if (!existingBody) {
155
142
  return parsedDirectives.cleaned;
143
+ }
156
144
  if (!sessionCtx.CommandBody && !sessionCtx.RawBody) {
157
145
  return parseInlineDirectives(existingBody, {
158
146
  modelAliases: configuredAliases,
@@ -253,6 +241,7 @@ export async function resolveReplyDirectives(params) {
253
241
  provider,
254
242
  model,
255
243
  hasModelDirective: directives.hasModelDirective,
244
+ hasResolvedHeartbeatModelOverride,
256
245
  });
257
246
  provider = modelState.provider;
258
247
  model = modelState.model;
@@ -136,6 +136,7 @@ export async function handleInlineActions(params) {
136
136
  command,
137
137
  sessionEntry,
138
138
  sessionKey,
139
+ parentSessionKey: ctx.ParentSessionKey,
139
140
  sessionScope,
140
141
  provider,
141
142
  model,
@@ -1,24 +1,49 @@
1
- import { resolveAgentDir, resolveAgentWorkspaceDir, resolveSessionAgentId, } from "../../agents/agent-scope.js";
1
+ import { resolveAgentDir, resolveAgentWorkspaceDir, resolveSessionAgentId, resolveAgentSkillsFilter, } from "../../agents/agent-scope.js";
2
2
  import { resolveModelRefFromString } from "../../agents/model-selection.js";
3
3
  import { resolveAgentTimeoutMs } from "../../agents/timeout.js";
4
4
  import { DEFAULT_AGENT_WORKSPACE_DIR, ensureAgentWorkspace } from "../../agents/workspace.js";
5
+ import { resolveChannelModelOverride } from "../../channels/model-overrides.js";
5
6
  import { loadConfig } from "../../config/config.js";
7
+ import { applyLinkUnderstanding } from "../../link-understanding/apply.js";
8
+ import { applyMediaUnderstanding } from "../../media-understanding/apply.js";
6
9
  import { defaultRuntime } from "../../runtime.js";
7
10
  import { resolveCommandAuthorization } from "../command-auth.js";
8
11
  import { SILENT_REPLY_TOKEN } from "../tokens.js";
9
- import { applyMediaUnderstanding } from "../../media-understanding/apply.js";
10
- import { applyLinkUnderstanding } from "../../link-understanding/apply.js";
11
12
  import { resolveDefaultModel } from "./directive-handling.js";
12
13
  import { resolveReplyDirectives } from "./get-reply-directives.js";
13
14
  import { handleInlineActions } from "./get-reply-inline-actions.js";
14
15
  import { runPreparedReply } from "./get-reply-run.js";
15
16
  import { finalizeInboundContext } from "./inbound-context.js";
16
- import { initSessionState } from "./session.js";
17
17
  import { applyResetModelOverride } from "./session-reset-model.js";
18
+ import { initSessionState } from "./session.js";
18
19
  import { stageSandboxMedia } from "./stage-sandbox-media.js";
19
20
  import { createTypingController } from "./typing.js";
21
+ function mergeSkillFilters(channelFilter, agentFilter) {
22
+ const normalize = (list) => {
23
+ if (!Array.isArray(list)) {
24
+ return undefined;
25
+ }
26
+ return list.map((entry) => String(entry).trim()).filter(Boolean);
27
+ };
28
+ const channel = normalize(channelFilter);
29
+ const agent = normalize(agentFilter);
30
+ if (!channel && !agent) {
31
+ return undefined;
32
+ }
33
+ if (!channel) {
34
+ return agent;
35
+ }
36
+ if (!agent) {
37
+ return channel;
38
+ }
39
+ if (channel.length === 0 || agent.length === 0) {
40
+ return [];
41
+ }
42
+ const agentSet = new Set(agent);
43
+ return channel.filter((name) => agentSet.has(name));
44
+ }
20
45
  export async function getReplyFromConfig(ctx, opts, configOverride) {
21
- const isFastTestEnv = process.env.POOLBOT_TEST_FAST === "1" || process.env.CLAWDBOT_TEST_FAST === "1";
46
+ const isFastTestEnv = process.env.POOLBOT_TEST_FAST === "1";
22
47
  const cfg = configOverride ?? loadConfig();
23
48
  const targetSessionKey = ctx.CommandSource === "native" ? ctx.CommandTargetSessionKey?.trim() : undefined;
24
49
  const agentSessionKey = targetSessionKey || ctx.SessionKey;
@@ -26,6 +51,8 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
26
51
  sessionKey: agentSessionKey,
27
52
  config: cfg,
28
53
  });
54
+ const mergedSkillFilter = mergeSkillFilters(opts?.skillFilter, resolveAgentSkillsFilter(cfg, agentId));
55
+ const resolvedOpts = mergedSkillFilter !== undefined ? { ...opts, skillFilter: mergedSkillFilter } : opts;
29
56
  const agentCfg = cfg.agents?.defaults;
30
57
  const sessionCfg = cfg.session;
31
58
  const { defaultProvider, defaultModel, aliasIndex } = resolveDefaultModel({
@@ -34,8 +61,11 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
34
61
  });
35
62
  let provider = defaultProvider;
36
63
  let model = defaultModel;
64
+ let hasResolvedHeartbeatModelOverride = false;
37
65
  if (opts?.isHeartbeat) {
38
- const heartbeatRaw = agentCfg?.heartbeat?.model?.trim() ?? "";
66
+ // Prefer the resolved per-agent heartbeat model passed from the heartbeat runner,
67
+ // fall back to the global defaults heartbeat model for backward compatibility.
68
+ const heartbeatRaw = opts.heartbeatModelOverride?.trim() ?? agentCfg?.heartbeat?.model?.trim() ?? "";
39
69
  const heartbeatRef = heartbeatRaw
40
70
  ? resolveModelRefFromString({
41
71
  raw: heartbeatRaw,
@@ -46,6 +76,7 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
46
76
  if (heartbeatRef) {
47
77
  provider = heartbeatRef.ref.provider;
48
78
  model = heartbeatRef.ref.model;
79
+ hasResolvedHeartbeatModelOverride = true;
49
80
  }
50
81
  }
51
82
  const workspaceDirRaw = resolveAgentWorkspaceDir(cfg, agentId) ?? DEFAULT_AGENT_WORKSPACE_DIR;
@@ -55,11 +86,12 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
55
86
  });
56
87
  const workspaceDir = workspace.dir;
57
88
  const agentDir = resolveAgentDir(cfg, agentId);
58
- const timeoutMs = resolveAgentTimeoutMs({ cfg });
89
+ const timeoutMs = resolveAgentTimeoutMs({ cfg, overrideSeconds: opts?.timeoutOverrideSeconds });
59
90
  const configuredTypingSeconds = agentCfg?.typingIntervalSeconds ?? sessionCfg?.typingIntervalSeconds;
60
91
  const typingIntervalSeconds = typeof configuredTypingSeconds === "number" ? configuredTypingSeconds : 6;
61
92
  const typing = createTypingController({
62
93
  onReplyStart: opts?.onReplyStart,
94
+ onCleanup: opts?.onTypingCleanup,
63
95
  typingIntervalSeconds,
64
96
  silentToken: SILENT_REPLY_TOKEN,
65
97
  log: defaultRuntime.log,
@@ -104,6 +136,32 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
104
136
  defaultModel,
105
137
  aliasIndex,
106
138
  });
139
+ const channelModelOverride = resolveChannelModelOverride({
140
+ cfg,
141
+ channel: groupResolution?.channel ??
142
+ sessionEntry.channel ??
143
+ sessionEntry.origin?.provider ??
144
+ (typeof finalized.OriginatingChannel === "string"
145
+ ? finalized.OriginatingChannel
146
+ : undefined) ??
147
+ finalized.Provider,
148
+ groupId: groupResolution?.id ?? sessionEntry.groupId,
149
+ groupChannel: sessionEntry.groupChannel ?? sessionCtx.GroupChannel ?? finalized.GroupChannel,
150
+ groupSubject: sessionEntry.subject ?? sessionCtx.GroupSubject ?? finalized.GroupSubject,
151
+ parentSessionKey: sessionCtx.ParentSessionKey,
152
+ });
153
+ const hasSessionModelOverride = Boolean(sessionEntry.modelOverride?.trim() || sessionEntry.providerOverride?.trim());
154
+ if (!hasResolvedHeartbeatModelOverride && !hasSessionModelOverride && channelModelOverride) {
155
+ const resolved = resolveModelRefFromString({
156
+ raw: channelModelOverride.model,
157
+ defaultProvider,
158
+ aliasIndex,
159
+ });
160
+ if (resolved) {
161
+ provider = resolved.ref.provider;
162
+ model = resolved.ref.model;
163
+ }
164
+ }
107
165
  const directiveResult = await resolveReplyDirectives({
108
166
  ctx: finalized,
109
167
  cfg,
@@ -126,9 +184,10 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
126
184
  aliasIndex,
127
185
  provider,
128
186
  model,
187
+ hasResolvedHeartbeatModelOverride,
129
188
  typing,
130
- opts,
131
- skillFilter: opts?.skillFilter,
189
+ opts: resolvedOpts,
190
+ skillFilter: mergedSkillFilter,
132
191
  });
133
192
  if (directiveResult.kind === "reply") {
134
193
  return directiveResult.reply;
@@ -150,7 +209,7 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
150
209
  sessionScope,
151
210
  workspaceDir,
152
211
  isGroup,
153
- opts,
212
+ opts: resolvedOpts,
154
213
  typing,
155
214
  allowTextCommands,
156
215
  inlineStatusRequested,
@@ -172,7 +231,7 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
172
231
  contextTokens,
173
232
  directiveAck,
174
233
  abortedLastRun,
175
- skillFilter: opts?.skillFilter,
234
+ skillFilter: mergedSkillFilter,
176
235
  });
177
236
  if (inlineActionResult.kind === "reply") {
178
237
  return inlineActionResult.reply;
@@ -216,7 +275,7 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
216
275
  perMessageQueueMode,
217
276
  perMessageQueueOptions,
218
277
  typing,
219
- opts,
278
+ opts: resolvedOpts,
220
279
  defaultProvider,
221
280
  defaultModel,
222
281
  timeoutMs,