@poolzin/pool-bot 2026.2.24 → 2026.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (646) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/acp/client.js +207 -18
  3. package/dist/acp/event-mapper.js +87 -22
  4. package/dist/acp/meta.js +12 -6
  5. package/dist/acp/secret-file.js +22 -0
  6. package/dist/agents/agent-paths.js +8 -9
  7. package/dist/agents/agent-scope.js +17 -5
  8. package/dist/agents/auth-profiles/oauth.js +148 -64
  9. package/dist/agents/auth-profiles/session-override.js +13 -7
  10. package/dist/agents/bash-process-registry.test-helpers.js +29 -0
  11. package/dist/agents/bash-tools.exec-approval-request.js +20 -0
  12. package/dist/agents/bash-tools.exec-host-gateway.js +240 -0
  13. package/dist/agents/bash-tools.exec-host-node.js +235 -0
  14. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  15. package/dist/agents/bash-tools.exec-types.js +1 -0
  16. package/dist/agents/bash-tools.process.js +224 -218
  17. package/dist/agents/bedrock-discovery.js +3 -1
  18. package/dist/agents/byteplus-models.js +97 -0
  19. package/dist/agents/chutes-oauth.js +1 -0
  20. package/dist/agents/cli-runner/helpers.js +4 -0
  21. package/dist/agents/compaction.js +41 -14
  22. package/dist/agents/content-blocks.js +16 -0
  23. package/dist/agents/doubao-models.js +121 -0
  24. package/dist/agents/failover-error.js +2 -0
  25. package/dist/agents/huggingface-models.js +5 -3
  26. package/dist/agents/live-model-filter.js +5 -0
  27. package/dist/agents/minimax-vlm.js +10 -8
  28. package/dist/agents/model-auth.js +6 -0
  29. package/dist/agents/model-catalog.js +3 -1
  30. package/dist/agents/model-fallback.js +96 -101
  31. package/dist/agents/model-selection.js +7 -1
  32. package/dist/agents/models-config.providers.js +364 -165
  33. package/dist/agents/ollama-stream.js +117 -4
  34. package/dist/agents/opencode-zen-models.js +22 -11
  35. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  36. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  37. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  38. package/dist/agents/pi-embedded-helpers.js +1 -1
  39. package/dist/agents/pi-embedded-payloads.js +1 -0
  40. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  41. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  42. package/dist/agents/pi-embedded-runner/google.js +20 -8
  43. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  44. package/dist/agents/pi-embedded-runner/run.js +71 -12
  45. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +34 -0
  46. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  47. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  48. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  49. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  50. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  51. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  52. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  53. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  54. package/dist/agents/pi-embedded-subscribe.js +9 -4
  55. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  56. package/dist/agents/pi-embedded-utils.js +3 -0
  57. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  58. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  59. package/dist/agents/pi-settings.js +40 -0
  60. package/dist/agents/pi-tools.policy.js +2 -1
  61. package/dist/agents/provider/config-loader.js +1 -1
  62. package/dist/agents/sandbox/browser.js +170 -33
  63. package/dist/agents/sandbox/config-hash.js +14 -27
  64. package/dist/agents/sandbox/config.js +21 -2
  65. package/dist/agents/sandbox/constants.js +2 -0
  66. package/dist/agents/sandbox/docker.js +16 -2
  67. package/dist/agents/sandbox/novnc-auth.js +62 -0
  68. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  69. package/dist/agents/sandbox/shared.js +10 -6
  70. package/dist/agents/sandbox-paths.js +24 -11
  71. package/dist/agents/schema/clean-for-gemini.js +132 -85
  72. package/dist/agents/session-slug.js +10 -5
  73. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  74. package/dist/agents/session-tool-result-guard.js +3 -1
  75. package/dist/agents/session-transcript-repair.js +40 -6
  76. package/dist/agents/skills/bundled-dir.js +19 -5
  77. package/dist/agents/skills/env-overrides.js +124 -43
  78. package/dist/agents/skills/frontmatter.js +6 -6
  79. package/dist/agents/skills/plugin-skills.js +14 -7
  80. package/dist/agents/skills/workspace.js +1 -0
  81. package/dist/agents/skills.test-helpers.js +13 -0
  82. package/dist/agents/stable-stringify.js +12 -0
  83. package/dist/agents/subagent-announce.js +251 -49
  84. package/dist/agents/subagent-lifecycle-events.js +19 -0
  85. package/dist/agents/subagent-registry-cleanup.js +31 -0
  86. package/dist/agents/subagent-registry-completion.js +68 -0
  87. package/dist/agents/subagent-registry-queries.js +117 -0
  88. package/dist/agents/subagent-registry-state.js +46 -0
  89. package/dist/agents/subagent-registry.js +252 -221
  90. package/dist/agents/subagent-registry.mocks.shared.js +12 -0
  91. package/dist/agents/subagent-registry.store.js +1 -0
  92. package/dist/agents/subagent-registry.types.js +1 -0
  93. package/dist/agents/subagent-spawn.js +195 -7
  94. package/dist/agents/system-prompt.js +22 -6
  95. package/dist/agents/test-helpers/assistant-message-fixtures.js +29 -0
  96. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  97. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  98. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +27 -0
  99. package/dist/agents/timeout.js +18 -6
  100. package/dist/agents/tool-call-id.js +1 -1
  101. package/dist/agents/tool-display-common.js +162 -29
  102. package/dist/agents/tool-images.js +82 -9
  103. package/dist/agents/tool-policy-shared.js +108 -0
  104. package/dist/agents/tool-policy.js +51 -26
  105. package/dist/agents/tools/browser-tool.js +160 -54
  106. package/dist/agents/tools/canvas-tool.js +27 -1
  107. package/dist/agents/tools/common.js +45 -0
  108. package/dist/agents/tools/cron-tool.test-helpers.js +12 -0
  109. package/dist/agents/tools/discord-actions-guild.js +4 -1
  110. package/dist/agents/tools/discord-actions-moderation-shared.js +27 -0
  111. package/dist/agents/tools/gateway-tool.js +3 -1
  112. package/dist/agents/tools/image-tool.js +214 -99
  113. package/dist/agents/tools/nodes-utils.js +1 -10
  114. package/dist/agents/tools/sessions-history-tool.js +140 -108
  115. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  116. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  117. package/dist/agents/tools/subagents-tool.js +2 -1
  118. package/dist/agents/tools/whatsapp-actions.js +10 -2
  119. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  120. package/dist/agents/transcript-policy.js +22 -8
  121. package/dist/agents/venice-models.js +11 -3
  122. package/dist/agents/workspace.js +222 -46
  123. package/dist/auto-reply/commands-registry.data.js +51 -0
  124. package/dist/auto-reply/commands-registry.js +19 -21
  125. package/dist/auto-reply/fallback-state.js +114 -0
  126. package/dist/auto-reply/group-activation.js +10 -5
  127. package/dist/auto-reply/inbound-debounce.js +10 -5
  128. package/dist/auto-reply/model-runtime.js +68 -0
  129. package/dist/auto-reply/reply/abort.js +1 -1
  130. package/dist/auto-reply/reply/agent-runner-execution.js +40 -5
  131. package/dist/auto-reply/reply/agent-runner.js +165 -39
  132. package/dist/auto-reply/reply/bash-command.js +41 -39
  133. package/dist/auto-reply/reply/command-gates.js +25 -0
  134. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  135. package/dist/auto-reply/reply/commands-bash.js +6 -5
  136. package/dist/auto-reply/reply/commands-config.js +30 -28
  137. package/dist/auto-reply/reply/commands-core.js +2 -1
  138. package/dist/auto-reply/reply/commands-info.js +1 -0
  139. package/dist/auto-reply/reply/commands-models.js +65 -14
  140. package/dist/auto-reply/reply/commands-session.js +237 -82
  141. package/dist/auto-reply/reply/commands-setunset-standard.js +13 -0
  142. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  143. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  144. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  145. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  146. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  147. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  148. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  149. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  150. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  151. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  152. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  153. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  154. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  155. package/dist/auto-reply/reply/commands-tts.js +10 -5
  156. package/dist/auto-reply/reply/config-value.js +10 -5
  157. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  158. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  159. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  160. package/dist/auto-reply/reply/followup-runner.js +1 -0
  161. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  162. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  163. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  164. package/dist/auto-reply/reply/get-reply.js +71 -12
  165. package/dist/auto-reply/reply/model-selection.js +80 -39
  166. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  167. package/dist/auto-reply/reply/queue/state.js +13 -12
  168. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  169. package/dist/auto-reply/reply/reply-reference.js +9 -8
  170. package/dist/auto-reply/reply/route-reply.js +15 -8
  171. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  172. package/dist/auto-reply/reply/session.js +22 -6
  173. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  174. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  175. package/dist/auto-reply/reply/typing.js +46 -21
  176. package/dist/auto-reply/send-policy.js +14 -7
  177. package/dist/auto-reply/status.js +140 -16
  178. package/dist/auto-reply/templating.js +10 -5
  179. package/dist/auto-reply/thinking.js +7 -16
  180. package/dist/auto-reply/tokens.js +21 -5
  181. package/dist/browser/bridge-server.js +36 -20
  182. package/dist/browser/cdp.helpers.js +7 -14
  183. package/dist/browser/cdp.js +35 -15
  184. package/dist/browser/chrome.profile-decoration.js +7 -4
  185. package/dist/browser/config.js +30 -0
  186. package/dist/browser/extension-relay-auth.js +55 -0
  187. package/dist/browser/extension-relay.js +74 -29
  188. package/dist/browser/navigation-guard.js +39 -0
  189. package/dist/browser/paths.js +77 -0
  190. package/dist/browser/profiles.js +13 -8
  191. package/dist/browser/pw-ai-module.js +10 -5
  192. package/dist/browser/pw-session.js +76 -39
  193. package/dist/browser/pw-tools-core.interactions.js +14 -7
  194. package/dist/browser/pw-tools-core.state.js +12 -6
  195. package/dist/browser/routes/agent.act.js +431 -424
  196. package/dist/browser/routes/agent.shared.js +47 -3
  197. package/dist/browser/routes/agent.snapshot.js +122 -116
  198. package/dist/browser/routes/agent.storage.js +303 -297
  199. package/dist/browser/routes/tabs.js +154 -100
  200. package/dist/browser/server-context.js +7 -0
  201. package/dist/browser/server-lifecycle.js +37 -0
  202. package/dist/build-info.json +3 -3
  203. package/dist/channels/allow-from.js +26 -0
  204. package/dist/channels/allowlists/resolve-utils.js +43 -19
  205. package/dist/channels/channel-config.js +14 -7
  206. package/dist/channels/draft-stream-loop.js +7 -0
  207. package/dist/channels/model-overrides.js +82 -0
  208. package/dist/channels/plugins/account-action-gate.js +13 -0
  209. package/dist/channels/plugins/message-actions.js +10 -0
  210. package/dist/channels/plugins/normalize/imessage.js +14 -7
  211. package/dist/channels/plugins/normalize/slack.js +10 -5
  212. package/dist/channels/plugins/normalize/telegram.js +14 -7
  213. package/dist/channels/plugins/outbound/discord.js +80 -8
  214. package/dist/channels/plugins/outbound/signal.js +11 -11
  215. package/dist/channels/plugins/setup-helpers.js +10 -5
  216. package/dist/channels/sender-label.js +14 -7
  217. package/dist/channels/session.js +4 -2
  218. package/dist/channels/status-reactions.js +297 -0
  219. package/dist/channels/telegram/api.js +18 -0
  220. package/dist/cli/argv.js +84 -21
  221. package/dist/cli/banner.js +3 -2
  222. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  223. package/dist/cli/cli-name.js +11 -11
  224. package/dist/cli/cli-utils.js +13 -3
  225. package/dist/cli/command-format.js +1 -1
  226. package/dist/cli/config-cli.js +1 -1
  227. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  228. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  229. package/dist/cli/daemon-cli/restart-health.js +126 -0
  230. package/dist/cli/daemon-cli/status.gather.js +9 -13
  231. package/dist/cli/daemon-cli/status.print.js +2 -10
  232. package/dist/cli/deps.js +27 -22
  233. package/dist/cli/exec-approvals-cli.js +92 -124
  234. package/dist/cli/gateway-cli/run-loop.js +23 -5
  235. package/dist/cli/memory-cli.js +158 -61
  236. package/dist/cli/node-cli/register.js +14 -5
  237. package/dist/cli/nodes-cli/register.push.js +63 -0
  238. package/dist/cli/nodes-media-utils.js +26 -0
  239. package/dist/cli/outbound-send-deps.js +2 -9
  240. package/dist/cli/outbound-send-mapping.js +11 -0
  241. package/dist/cli/pairing-cli.js +40 -14
  242. package/dist/cli/plugins-cli.js +250 -73
  243. package/dist/cli/ports.js +11 -10
  244. package/dist/cli/program/build-program.js +3 -1
  245. package/dist/cli/program/command-registry.js +214 -136
  246. package/dist/cli/program/command-tree.js +16 -0
  247. package/dist/cli/program/help.js +43 -12
  248. package/dist/cli/program/preaction.js +13 -9
  249. package/dist/cli/program/register.configure.js +3 -18
  250. package/dist/cli/program/register.maintenance.js +2 -2
  251. package/dist/cli/program/register.onboard.js +2 -0
  252. package/dist/cli/program/register.status-health-sessions.js +16 -17
  253. package/dist/cli/program/register.subclis.js +93 -52
  254. package/dist/cli/route.js +12 -8
  255. package/dist/cli/system-cli.js +36 -46
  256. package/dist/cli/test-runtime-capture.js +24 -0
  257. package/dist/cli/update-cli/shared.js +22 -9
  258. package/dist/cli/update-cli/update-command.js +89 -14
  259. package/dist/cli/update-cli/wizard.js +6 -12
  260. package/dist/commands/agent/run-context.js +18 -5
  261. package/dist/commands/agent/session-store.js +17 -4
  262. package/dist/commands/agent.js +185 -89
  263. package/dist/commands/agents.bindings.js +14 -7
  264. package/dist/commands/agents.commands.add.js +13 -9
  265. package/dist/commands/agents.commands.identity.js +12 -6
  266. package/dist/commands/agents.commands.list.js +11 -6
  267. package/dist/commands/agents.config.js +8 -10
  268. package/dist/commands/agents.providers.js +12 -6
  269. package/dist/commands/auth-choice-options.js +103 -75
  270. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  271. package/dist/commands/auth-choice.apply.js +4 -0
  272. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  273. package/dist/commands/auth-choice.apply.openai.js +3 -1
  274. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  275. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  276. package/dist/commands/channels/remove.js +13 -6
  277. package/dist/commands/channels/shared.js +4 -14
  278. package/dist/commands/channels.mock-harness.js +23 -0
  279. package/dist/commands/configure.commands.js +14 -0
  280. package/dist/commands/configure.gateway.js +2 -4
  281. package/dist/commands/configure.js +1 -1
  282. package/dist/commands/configure.shared.js +11 -0
  283. package/dist/commands/daemon-install-helpers.js +2 -2
  284. package/dist/commands/daemon-install-runtime-warning.js +11 -0
  285. package/dist/commands/dashboard.js +12 -10
  286. package/dist/commands/docs.js +14 -8
  287. package/dist/commands/doctor-config-flow.js +11 -9
  288. package/dist/commands/doctor-legacy-config.js +281 -0
  289. package/dist/commands/doctor-state-integrity.js +99 -23
  290. package/dist/commands/doctor-update.js +12 -9
  291. package/dist/commands/models/list.list-command.js +7 -5
  292. package/dist/commands/models/set-image.js +2 -21
  293. package/dist/commands/node-daemon-install-helpers.js +10 -8
  294. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  295. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  296. package/dist/commands/onboard-auth.credentials.js +90 -13
  297. package/dist/commands/onboard-auth.js +1 -1
  298. package/dist/commands/onboard-auth.models.js +6 -5
  299. package/dist/commands/onboard-hooks.js +1 -1
  300. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  301. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  302. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  303. package/dist/commands/onboard-remote.js +14 -7
  304. package/dist/commands/onboard.js +11 -13
  305. package/dist/commands/sandbox-display.js +6 -5
  306. package/dist/commands/sessions.test-helpers.js +61 -0
  307. package/dist/commands/status-all/diagnosis.js +14 -10
  308. package/dist/commands/status-all/format.js +1 -0
  309. package/dist/commands/status.gateway-probe.js +1 -16
  310. package/dist/commands/systemd-linger.js +12 -6
  311. package/dist/config/agent-limits.js +2 -0
  312. package/dist/config/commands.js +32 -15
  313. package/dist/config/config-paths.js +9 -11
  314. package/dist/config/config.js +1 -1
  315. package/dist/config/defaults.js +22 -2
  316. package/dist/config/discord-preview-streaming.js +104 -0
  317. package/dist/config/env-substitution.js +62 -34
  318. package/dist/config/env-vars.js +45 -7
  319. package/dist/config/includes.js +4 -0
  320. package/dist/config/io.js +656 -171
  321. package/dist/config/legacy.migrations.part-1.js +189 -78
  322. package/dist/config/legacy.shared.js +3 -1
  323. package/dist/config/merge-patch.js +54 -4
  324. package/dist/config/prototype-keys.js +4 -0
  325. package/dist/config/redact-snapshot.js +404 -76
  326. package/dist/config/schema.help.js +44 -7
  327. package/dist/config/schema.js +58 -570
  328. package/dist/config/schema.labels.js +38 -6
  329. package/dist/config/sessions/delivery-info.js +10 -3
  330. package/dist/config/sessions/main-session.js +10 -5
  331. package/dist/config/sessions/session-file.js +33 -0
  332. package/dist/config/sessions/session-key.js +10 -5
  333. package/dist/config/sessions/store.js +1 -1
  334. package/dist/config/sessions.js +1 -0
  335. package/dist/config/validation.js +140 -85
  336. package/dist/config/zod-schema.agent-runtime.js +11 -0
  337. package/dist/config/zod-schema.hooks.js +40 -11
  338. package/dist/config/zod-schema.installs.js +20 -0
  339. package/dist/config/zod-schema.js +156 -20
  340. package/dist/config/zod-schema.providers-core.js +78 -4
  341. package/dist/config/zod-schema.providers.js +6 -1
  342. package/dist/config/zod-schema.session.js +41 -2
  343. package/dist/cron/run-log.js +3 -0
  344. package/dist/cron/schedule.js +21 -10
  345. package/dist/cron/service/ops.js +35 -21
  346. package/dist/cron/service/timer.js +116 -16
  347. package/dist/cron/stagger.js +3 -1
  348. package/dist/daemon/cmd-argv.js +21 -0
  349. package/dist/daemon/cmd-set.js +58 -0
  350. package/dist/daemon/service-types.js +1 -0
  351. package/dist/discord/api.js +12 -6
  352. package/dist/discord/draft-chunking.js +22 -0
  353. package/dist/discord/draft-stream.js +124 -0
  354. package/dist/discord/monitor/agent-components.js +1 -1
  355. package/dist/discord/monitor/commands.js +5 -0
  356. package/dist/discord/monitor/exec-approvals.js +357 -162
  357. package/dist/discord/monitor/gateway-plugin.js +2 -1
  358. package/dist/discord/monitor/listeners.js +37 -27
  359. package/dist/discord/monitor/message-handler.js +4 -1
  360. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  361. package/dist/discord/monitor/message-handler.process.js +246 -217
  362. package/dist/discord/monitor/message-utils.js +143 -6
  363. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  364. package/dist/discord/monitor/model-picker.js +651 -0
  365. package/dist/discord/monitor/native-command.js +573 -16
  366. package/dist/discord/monitor/provider.allowlist.js +223 -0
  367. package/dist/discord/monitor/provider.js +275 -347
  368. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  369. package/dist/discord/monitor/reply-delivery.js +123 -16
  370. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  371. package/dist/discord/monitor/thread-bindings.js +4 -0
  372. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  373. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  374. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  375. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  376. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  377. package/dist/discord/resolve-users.js +33 -21
  378. package/dist/discord/send.channels.js +15 -0
  379. package/dist/discord/send.js +3 -2
  380. package/dist/discord/send.outbound.js +82 -26
  381. package/dist/discord/send.permissions.js +83 -30
  382. package/dist/discord/send.reactions.js +8 -4
  383. package/dist/discord/token.js +10 -5
  384. package/dist/discord/voice/command.js +263 -0
  385. package/dist/discord/voice/manager.js +531 -0
  386. package/dist/gateway/auth.js +72 -13
  387. package/dist/gateway/call.js +152 -83
  388. package/dist/gateway/canvas-capability.js +75 -0
  389. package/dist/gateway/client.js +28 -4
  390. package/dist/gateway/config-reload.js +3 -4
  391. package/dist/gateway/control-plane-audit.js +28 -0
  392. package/dist/gateway/control-plane-rate-limit.js +53 -0
  393. package/dist/gateway/control-ui.js +219 -96
  394. package/dist/gateway/events.js +1 -0
  395. package/dist/gateway/hooks-mapping.js +88 -38
  396. package/dist/gateway/hooks.js +109 -54
  397. package/dist/gateway/http-auth-helpers.js +3 -2
  398. package/dist/gateway/http-common.js +22 -0
  399. package/dist/gateway/http-endpoint-helpers.js +1 -0
  400. package/dist/gateway/method-scopes.js +169 -0
  401. package/dist/gateway/net.js +74 -9
  402. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  403. package/dist/gateway/node-registry.js +10 -5
  404. package/dist/gateway/openai-http.js +1 -0
  405. package/dist/gateway/openresponses-http.js +121 -110
  406. package/dist/gateway/origin-check.js +1 -18
  407. package/dist/gateway/probe-auth.js +2 -0
  408. package/dist/gateway/protocol/index.js +4 -2
  409. package/dist/gateway/protocol/schema/cron.js +1 -0
  410. package/dist/gateway/protocol/schema/devices.js +1 -0
  411. package/dist/gateway/protocol/schema/protocol-schemas.js +4 -1
  412. package/dist/gateway/protocol/schema/push.js +18 -0
  413. package/dist/gateway/protocol/schema/sessions.js +6 -0
  414. package/dist/gateway/protocol/schema.js +1 -0
  415. package/dist/gateway/role-policy.js +17 -0
  416. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  417. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  418. package/dist/gateway/server-chat.js +83 -25
  419. package/dist/gateway/server-constants.js +10 -9
  420. package/dist/gateway/server-cron.js +1 -0
  421. package/dist/gateway/server-http.js +247 -54
  422. package/dist/gateway/server-maintenance.js +20 -5
  423. package/dist/gateway/server-methods/agent.js +162 -24
  424. package/dist/gateway/server-methods/chat.js +465 -130
  425. package/dist/gateway/server-methods/config.js +193 -152
  426. package/dist/gateway/server-methods/devices.js +17 -3
  427. package/dist/gateway/server-methods/models.js +11 -1
  428. package/dist/gateway/server-methods/nodes.helpers.js +12 -0
  429. package/dist/gateway/server-methods/nodes.js +251 -69
  430. package/dist/gateway/server-methods/push.js +53 -0
  431. package/dist/gateway/server-methods/sessions.js +64 -8
  432. package/dist/gateway/server-methods/usage.js +162 -75
  433. package/dist/gateway/server-node-events.js +29 -0
  434. package/dist/gateway/server-reload-handlers.js +2 -3
  435. package/dist/gateway/server-runtime-config.js +39 -13
  436. package/dist/gateway/server-runtime-state.js +2 -0
  437. package/dist/gateway/server-startup-memory.js +17 -11
  438. package/dist/gateway/server-ws-runtime.js +1 -0
  439. package/dist/gateway/server.impl.js +296 -139
  440. package/dist/gateway/session-preview.test-helpers.js +11 -0
  441. package/dist/gateway/session-utils.fs.js +32 -34
  442. package/dist/gateway/sessions-resolve.js +17 -5
  443. package/dist/gateway/startup-auth.js +126 -0
  444. package/dist/gateway/test-helpers.agent-results.js +15 -0
  445. package/dist/gateway/test-helpers.mocks.js +37 -14
  446. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  447. package/dist/gateway/test-helpers.server.js +161 -77
  448. package/dist/gateway/tools-invoke-http.js +21 -10
  449. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  450. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  451. package/dist/hooks/bundled/session-memory/handler.js +170 -38
  452. package/dist/hooks/frontmatter.js +6 -6
  453. package/dist/hooks/gmail-watcher-lifecycle.js +23 -0
  454. package/dist/hooks/gmail-watcher.js +11 -6
  455. package/dist/hooks/internal-hooks.js +11 -1
  456. package/dist/hooks/llm-slug-generator.js +4 -1
  457. package/dist/hooks/workspace.js +47 -17
  458. package/dist/imessage/accounts.js +9 -20
  459. package/dist/imessage/monitor/inbound-processing.js +2 -1
  460. package/dist/infra/archive-path.js +49 -0
  461. package/dist/infra/archive.js +174 -73
  462. package/dist/infra/control-ui-assets.js +14 -6
  463. package/dist/infra/device-pairing.js +204 -144
  464. package/dist/infra/env.js +10 -5
  465. package/dist/infra/exec-approvals-allowlist.js +141 -70
  466. package/dist/infra/exec-approvals-analysis.js +78 -20
  467. package/dist/infra/exec-approvals.js +5 -17
  468. package/dist/infra/exec-safe-bin-policy.js +277 -0
  469. package/dist/infra/fixed-window-rate-limit.js +33 -0
  470. package/dist/infra/fs-safe.js +71 -39
  471. package/dist/infra/gateway-lock.js +6 -2
  472. package/dist/infra/git-root.js +61 -0
  473. package/dist/infra/heartbeat-active-hours.js +2 -2
  474. package/dist/infra/heartbeat-reason.js +40 -0
  475. package/dist/infra/heartbeat-runner.js +72 -32
  476. package/dist/infra/heartbeat-wake.js +6 -12
  477. package/dist/infra/host-env-security-policy.json +19 -0
  478. package/dist/infra/host-env-security.js +66 -0
  479. package/dist/infra/install-source-utils.js +91 -7
  480. package/dist/infra/net/ssrf.js +131 -38
  481. package/dist/infra/node-pairing.js +50 -105
  482. package/dist/infra/npm-integrity.js +45 -0
  483. package/dist/infra/npm-pack-install.js +40 -0
  484. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  485. package/dist/infra/outbound/channel-adapters.js +20 -7
  486. package/dist/infra/outbound/channel-selection.js +12 -6
  487. package/dist/infra/outbound/envelope.js +1 -1
  488. package/dist/infra/outbound/format.js +12 -6
  489. package/dist/infra/outbound/message-action-runner.js +107 -327
  490. package/dist/infra/outbound/message.js +59 -36
  491. package/dist/infra/outbound/outbound-policy.js +52 -25
  492. package/dist/infra/outbound/outbound-send-service.js +58 -71
  493. package/dist/infra/outbound/payloads.js +14 -7
  494. package/dist/infra/outbound/session-binding-service.js +123 -0
  495. package/dist/infra/pairing-files.js +10 -0
  496. package/dist/infra/path-guards.js +25 -0
  497. package/dist/infra/plain-object.js +9 -0
  498. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  499. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  500. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  501. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  502. package/dist/infra/push-apns.js +365 -0
  503. package/dist/infra/restart-sentinel.js +16 -1
  504. package/dist/infra/restart.js +229 -26
  505. package/dist/infra/retry-policy.js +4 -2
  506. package/dist/infra/retry.js +9 -5
  507. package/dist/infra/scp-host.js +54 -0
  508. package/dist/infra/session-cost-usage.js +107 -59
  509. package/dist/infra/session-maintenance-warning.js +3 -1
  510. package/dist/infra/shell-env.js +98 -34
  511. package/dist/infra/ssh-config.js +12 -6
  512. package/dist/infra/system-run-command.js +49 -4
  513. package/dist/infra/update-channels.js +10 -5
  514. package/dist/infra/update-startup.js +86 -9
  515. package/dist/line/accounts.js +5 -7
  516. package/dist/line/bot-access.js +8 -20
  517. package/dist/line/bot-handlers.js +3 -1
  518. package/dist/link-understanding/detect.js +15 -7
  519. package/dist/media/constants.js +15 -6
  520. package/dist/media/image-ops.js +7 -0
  521. package/dist/media/inbound-path-policy.js +114 -0
  522. package/dist/media/input-files.js +16 -0
  523. package/dist/media/local-roots.js +3 -2
  524. package/dist/media-understanding/apply.js +4 -1
  525. package/dist/media-understanding/concurrency.js +8 -20
  526. package/dist/memory/backend-config.js +45 -6
  527. package/dist/memory/embeddings.js +10 -4
  528. package/dist/memory/fs-utils.js +23 -0
  529. package/dist/memory/manager-search.js +12 -6
  530. package/dist/memory/manager-sync-ops.js +12 -2
  531. package/dist/memory/qmd-manager.js +466 -53
  532. package/dist/memory/query-expansion.js +167 -3
  533. package/dist/memory/status-format.js +10 -5
  534. package/dist/memory/sync-memory-files.js +1 -1
  535. package/dist/memory/test-manager.js +8 -0
  536. package/dist/node-host/invoke-system-run.js +281 -0
  537. package/dist/node-host/invoke.js +55 -337
  538. package/dist/pairing/pairing-store.js +22 -0
  539. package/dist/plugin-sdk/allow-from.js +1 -1
  540. package/dist/plugin-sdk/command-auth.js +3 -1
  541. package/dist/plugin-sdk/index.js +6 -3
  542. package/dist/plugin-sdk/temp-path.js +47 -0
  543. package/dist/plugin-sdk/webhook-targets.js +32 -0
  544. package/dist/plugins/bundled-dir.js +9 -6
  545. package/dist/plugins/discovery.js +217 -23
  546. package/dist/plugins/hook-runner-global.js +16 -0
  547. package/dist/plugins/hooks.js +50 -0
  548. package/dist/plugins/install.js +28 -16
  549. package/dist/plugins/loader.js +192 -26
  550. package/dist/plugins/logger.js +8 -0
  551. package/dist/plugins/manifest-registry.js +3 -0
  552. package/dist/plugins/path-safety.js +34 -0
  553. package/dist/plugins/registry.js +5 -2
  554. package/dist/plugins/runtime/index.js +271 -206
  555. package/dist/plugins/runtime.js +3 -17
  556. package/dist/plugins/update.js +78 -12
  557. package/dist/process/spawn-utils.js +14 -7
  558. package/dist/providers/github-copilot-models.js +4 -1
  559. package/dist/providers/github-copilot-token.js +11 -6
  560. package/dist/providers/qwen-portal-oauth.js +14 -6
  561. package/dist/routing/account-id.js +30 -0
  562. package/dist/routing/resolve-route.js +3 -7
  563. package/dist/routing/session-key.js +2 -16
  564. package/dist/security/audit-channel.js +100 -20
  565. package/dist/security/audit-extra.async.js +505 -179
  566. package/dist/security/audit-extra.js +12 -2
  567. package/dist/security/audit-extra.sync.js +421 -35
  568. package/dist/security/audit-fs.js +31 -13
  569. package/dist/security/audit.js +180 -370
  570. package/dist/security/dm-policy-shared.js +68 -0
  571. package/dist/security/external-content.js +46 -14
  572. package/dist/security/fix.js +49 -85
  573. package/dist/security/scan-paths.js +20 -0
  574. package/dist/security/secret-equal.js +3 -7
  575. package/dist/security/windows-acl.js +30 -15
  576. package/dist/shared/entry-status.js +6 -0
  577. package/dist/shared/frontmatter.js +5 -5
  578. package/dist/shared/node-list-parse.js +13 -0
  579. package/dist/shared/node-match.js +11 -4
  580. package/dist/shared/operator-scope-compat.js +42 -0
  581. package/dist/shared/text-chunking.js +29 -0
  582. package/dist/signal/accounts.js +7 -20
  583. package/dist/signal/monitor/event-handler.js +3 -1
  584. package/dist/slack/accounts.js +6 -19
  585. package/dist/slack/actions.js +11 -3
  586. package/dist/slack/blocks.test-helpers.js +31 -0
  587. package/dist/slack/monitor/auth.js +1 -1
  588. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  589. package/dist/slack/monitor/mrkdwn.js +8 -0
  590. package/dist/slack/monitor/replies.js +15 -7
  591. package/dist/slack/monitor/slash.js +22 -13
  592. package/dist/slack/resolve-channels.js +10 -5
  593. package/dist/slack/send.js +102 -12
  594. package/dist/slack/stream-mode.js +10 -0
  595. package/dist/slack/streaming.js +4 -2
  596. package/dist/telegram/accounts.js +19 -14
  597. package/dist/telegram/bot/helpers.js +3 -5
  598. package/dist/telegram/bot-access.js +35 -36
  599. package/dist/telegram/bot-handlers.js +120 -148
  600. package/dist/telegram/bot-message-context.js +68 -9
  601. package/dist/telegram/bot-message-dispatch.js +477 -210
  602. package/dist/telegram/bot-native-commands.js +16 -0
  603. package/dist/telegram/draft-stream.js +44 -8
  604. package/dist/telegram/inline-buttons.js +5 -15
  605. package/dist/telegram/monitor.js +11 -7
  606. package/dist/telegram/network-config.js +19 -7
  607. package/dist/telegram/reasoning-lane-coordinator.js +128 -0
  608. package/dist/telegram/send.js +3 -2
  609. package/dist/telegram/sent-message-cache.js +5 -6
  610. package/dist/telegram/status-reaction-variants.js +208 -0
  611. package/dist/telegram/sticker-cache.js +11 -9
  612. package/dist/terminal/prompt-select-styled.js +9 -0
  613. package/dist/terminal/theme.js +12 -12
  614. package/dist/test-utils/command-runner.js +6 -0
  615. package/dist/test-utils/internal-hook-event-payload.js +10 -0
  616. package/dist/test-utils/model-auth-mock.js +12 -0
  617. package/dist/test-utils/provider-usage-fetch.js +14 -0
  618. package/dist/test-utils/temp-home.js +33 -0
  619. package/dist/tts/tts.js +80 -567
  620. package/dist/tui/components/chat-log.js +50 -8
  621. package/dist/tui/theme/theme.js +10 -12
  622. package/dist/tui/tui-command-handlers.js +36 -27
  623. package/dist/tui/tui-event-handlers.js +122 -32
  624. package/dist/tui/tui-local-shell.js +16 -6
  625. package/dist/tui/tui.js +236 -48
  626. package/dist/utils/account-id.js +2 -4
  627. package/dist/utils/boolean.js +10 -5
  628. package/dist/utils/directive-tags.js +11 -0
  629. package/dist/utils/mask-api-key.js +10 -0
  630. package/dist/utils/queue-helpers.js +67 -12
  631. package/dist/utils/run-with-concurrency.js +39 -0
  632. package/dist/web/auto-reply/deliver-reply.js +8 -4
  633. package/dist/web/auto-reply/mentions.js +10 -5
  634. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  635. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  636. package/dist/web/inbound/access-control.js +5 -2
  637. package/dist/web/login-qr.js +12 -6
  638. package/dist/web/media.js +126 -15
  639. package/docs/tools/slash-commands.md +5 -1
  640. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  641. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  642. package/extensions/feishu/src/external-keys.ts +19 -0
  643. package/extensions/lobster/src/windows-spawn.ts +193 -0
  644. package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
  645. package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
  646. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
1
  import crypto from "node:crypto";
2
2
  import { formatThinkingLevels, normalizeThinkLevel } from "../auto-reply/thinking.js";
3
+ import { DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "../config/agent-limits.js";
3
4
  import { loadConfig } from "../config/config.js";
4
5
  import { callGateway } from "../gateway/call.js";
6
+ import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
5
7
  import { normalizeAgentId, parseAgentSessionKey } from "../routing/session-key.js";
6
8
  import { normalizeDeliveryContext } from "../utils/delivery-context.js";
7
9
  import { resolveAgentConfig } from "./agent-scope.js";
@@ -12,7 +14,9 @@ import { getSubagentDepthFromSessionStore } from "./subagent-depth.js";
12
14
  import { countActiveRunsForSession, registerSubagentRun } from "./subagent-registry.js";
13
15
  import { readStringParam } from "./tools/common.js";
14
16
  import { resolveDisplaySessionKey, resolveInternalSessionKey, resolveMainSessionAlias, } from "./tools/sessions-helpers.js";
15
- export const SUBAGENT_SPAWN_ACCEPTED_NOTE = "auto-announces on completion, do not poll/sleep. The response will be sent back as an agent message.";
17
+ export const SUBAGENT_SPAWN_MODES = ["run", "session"];
18
+ export const SUBAGENT_SPAWN_ACCEPTED_NOTE = "auto-announces on completion, do not poll/sleep. The response will be sent back as an user message.";
19
+ export const SUBAGENT_SPAWN_SESSION_ACCEPTED_NOTE = "thread-bound session stays active after this task; continue in-thread for follow-ups.";
16
20
  export function splitModelRef(ref) {
17
21
  if (!ref) {
18
22
  return { provider: undefined, model: undefined };
@@ -27,23 +31,99 @@ export function splitModelRef(ref) {
27
31
  }
28
32
  return { provider: undefined, model: trimmed };
29
33
  }
34
+ function resolveSpawnMode(params) {
35
+ if (params.requestedMode === "run" || params.requestedMode === "session") {
36
+ return params.requestedMode;
37
+ }
38
+ // Thread-bound spawns should default to persistent sessions.
39
+ return params.threadRequested ? "session" : "run";
40
+ }
41
+ function summarizeError(err) {
42
+ if (err instanceof Error) {
43
+ return err.message;
44
+ }
45
+ if (typeof err === "string") {
46
+ return err;
47
+ }
48
+ return "error";
49
+ }
50
+ async function ensureThreadBindingForSubagentSpawn(params) {
51
+ const hookRunner = params.hookRunner;
52
+ if (!hookRunner?.hasHooks("subagent_spawning")) {
53
+ return {
54
+ status: "error",
55
+ error: "thread=true is unavailable because no channel plugin registered subagent_spawning hooks.",
56
+ };
57
+ }
58
+ try {
59
+ const result = await hookRunner.runSubagentSpawning({
60
+ childSessionKey: params.childSessionKey,
61
+ agentId: params.agentId,
62
+ label: params.label,
63
+ mode: params.mode,
64
+ requester: params.requester,
65
+ threadRequested: true,
66
+ }, {
67
+ childSessionKey: params.childSessionKey,
68
+ requesterSessionKey: params.requesterSessionKey,
69
+ });
70
+ if (result?.status === "error") {
71
+ const error = result.error.trim();
72
+ return {
73
+ status: "error",
74
+ error: error || "Failed to prepare thread binding for this subagent session.",
75
+ };
76
+ }
77
+ if (result?.status !== "ok" || !result.threadBindingReady) {
78
+ return {
79
+ status: "error",
80
+ error: "Unable to create or bind a thread for this subagent session. Session mode is unavailable for this target.",
81
+ };
82
+ }
83
+ return { status: "ok" };
84
+ }
85
+ catch (err) {
86
+ return {
87
+ status: "error",
88
+ error: `Thread bind failed: ${summarizeError(err)}`,
89
+ };
90
+ }
91
+ }
30
92
  export async function spawnSubagentDirect(params, ctx) {
31
93
  const task = params.task;
32
94
  const label = params.label?.trim() || "";
33
95
  const requestedAgentId = params.agentId;
34
96
  const modelOverride = params.model;
35
97
  const thinkingOverrideRaw = params.thinking;
36
- const cleanup = params.cleanup === "keep" || params.cleanup === "delete" ? params.cleanup : "keep";
98
+ const requestThreadBinding = params.thread === true;
99
+ const spawnMode = resolveSpawnMode({
100
+ requestedMode: params.mode,
101
+ threadRequested: requestThreadBinding,
102
+ });
103
+ if (spawnMode === "session" && !requestThreadBinding) {
104
+ return {
105
+ status: "error",
106
+ error: 'mode="session" requires thread=true so the subagent can stay bound to a thread.',
107
+ };
108
+ }
109
+ const cleanup = spawnMode === "session"
110
+ ? "keep"
111
+ : params.cleanup === "keep" || params.cleanup === "delete"
112
+ ? params.cleanup
113
+ : "keep";
114
+ const expectsCompletionMessage = params.expectsCompletionMessage !== false;
37
115
  const requesterOrigin = normalizeDeliveryContext({
38
116
  channel: ctx.agentChannel,
39
117
  accountId: ctx.agentAccountId,
40
118
  to: ctx.agentTo,
41
119
  threadId: ctx.agentThreadId,
42
120
  });
121
+ const hookRunner = getGlobalHookRunner();
43
122
  const runTimeoutSeconds = typeof params.runTimeoutSeconds === "number" && Number.isFinite(params.runTimeoutSeconds)
44
123
  ? Math.max(0, Math.floor(params.runTimeoutSeconds))
45
124
  : 0;
46
125
  let modelApplied = false;
126
+ let threadBindingReady = false;
47
127
  const cfg = loadConfig();
48
128
  const { mainKey, alias } = resolveMainSessionAlias(cfg);
49
129
  const requesterSessionKey = ctx.agentSessionKey;
@@ -60,7 +140,7 @@ export async function spawnSubagentDirect(params, ctx) {
60
140
  mainKey,
61
141
  });
62
142
  const callerDepth = getSubagentDepthFromSessionStore(requesterInternalKey, { cfg });
63
- const maxSpawnDepth = cfg.agents?.defaults?.subagents?.maxSpawnDepth ?? 1;
143
+ const maxSpawnDepth = cfg.agents?.defaults?.subagents?.maxSpawnDepth ?? DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH;
64
144
  if (callerDepth >= maxSpawnDepth) {
65
145
  return {
66
146
  status: "forbidden",
@@ -170,6 +250,40 @@ export async function spawnSubagentDirect(params, ctx) {
170
250
  };
171
251
  }
172
252
  }
253
+ if (requestThreadBinding) {
254
+ const bindResult = await ensureThreadBindingForSubagentSpawn({
255
+ hookRunner,
256
+ childSessionKey,
257
+ agentId: targetAgentId,
258
+ label: label || undefined,
259
+ mode: spawnMode,
260
+ requesterSessionKey: requesterInternalKey,
261
+ requester: {
262
+ channel: requesterOrigin?.channel,
263
+ accountId: requesterOrigin?.accountId,
264
+ to: requesterOrigin?.to,
265
+ threadId: requesterOrigin?.threadId,
266
+ },
267
+ });
268
+ if (bindResult.status === "error") {
269
+ try {
270
+ await callGateway({
271
+ method: "sessions.delete",
272
+ params: { key: childSessionKey, emitLifecycleHooks: false },
273
+ timeoutMs: 10_000,
274
+ });
275
+ }
276
+ catch {
277
+ // Best-effort cleanup only.
278
+ }
279
+ return {
280
+ status: "error",
281
+ error: bindResult.error,
282
+ childSessionKey,
283
+ };
284
+ }
285
+ threadBindingReady = true;
286
+ }
173
287
  const childSystemPrompt = buildSubagentSystemPrompt({
174
288
  requesterSessionKey,
175
289
  requesterOrigin,
@@ -181,8 +295,13 @@ export async function spawnSubagentDirect(params, ctx) {
181
295
  });
182
296
  const childTaskMessage = [
183
297
  `[Subagent Context] You are running as a subagent (depth ${childDepth}/${maxSpawnDepth}). Results auto-announce to your requester; do not busy-poll for status.`,
298
+ spawnMode === "session"
299
+ ? "[Subagent Context] This subagent session is persistent and remains available for thread follow-up messages."
300
+ : undefined,
184
301
  `[Subagent Task]: ${task}`,
185
- ].join("\n\n");
302
+ ]
303
+ .filter((line) => Boolean(line))
304
+ .join("\n\n");
186
305
  const childIdem = crypto.randomUUID();
187
306
  let childRunId = childIdem;
188
307
  try {
@@ -214,7 +333,49 @@ export async function spawnSubagentDirect(params, ctx) {
214
333
  }
215
334
  }
216
335
  catch (err) {
217
- const messageText = err instanceof Error ? err.message : typeof err === "string" ? err : "error";
336
+ if (threadBindingReady) {
337
+ const hasEndedHook = hookRunner?.hasHooks("subagent_ended") === true;
338
+ let endedHookEmitted = false;
339
+ if (hasEndedHook) {
340
+ try {
341
+ await hookRunner?.runSubagentEnded({
342
+ targetSessionKey: childSessionKey,
343
+ targetKind: "subagent",
344
+ reason: "spawn-failed",
345
+ sendFarewell: true,
346
+ accountId: requesterOrigin?.accountId,
347
+ runId: childRunId,
348
+ outcome: "error",
349
+ error: "Session failed to start",
350
+ }, {
351
+ runId: childRunId,
352
+ childSessionKey,
353
+ requesterSessionKey: requesterInternalKey,
354
+ });
355
+ endedHookEmitted = true;
356
+ }
357
+ catch {
358
+ // Spawn should still return an actionable error even if cleanup hooks fail.
359
+ }
360
+ }
361
+ // Always delete the provisional child session after a failed spawn attempt.
362
+ // If we already emitted subagent_ended above, suppress a duplicate lifecycle hook.
363
+ try {
364
+ await callGateway({
365
+ method: "sessions.delete",
366
+ params: {
367
+ key: childSessionKey,
368
+ deleteTranscript: true,
369
+ emitLifecycleHooks: !endedHookEmitted,
370
+ },
371
+ timeoutMs: 10_000,
372
+ });
373
+ }
374
+ catch {
375
+ // Best-effort only.
376
+ }
377
+ }
378
+ const messageText = summarizeError(err);
218
379
  return {
219
380
  status: "error",
220
381
  error: messageText,
@@ -233,13 +394,40 @@ export async function spawnSubagentDirect(params, ctx) {
233
394
  label: label || undefined,
234
395
  model: resolvedModel,
235
396
  runTimeoutSeconds,
236
- expectsCompletionMessage: params.expectsCompletionMessage === true,
397
+ expectsCompletionMessage,
398
+ spawnMode,
237
399
  });
400
+ if (hookRunner?.hasHooks("subagent_spawned")) {
401
+ try {
402
+ await hookRunner.runSubagentSpawned({
403
+ runId: childRunId,
404
+ childSessionKey,
405
+ agentId: targetAgentId,
406
+ label: label || undefined,
407
+ requester: {
408
+ channel: requesterOrigin?.channel,
409
+ accountId: requesterOrigin?.accountId,
410
+ to: requesterOrigin?.to,
411
+ threadId: requesterOrigin?.threadId,
412
+ },
413
+ threadRequested: requestThreadBinding,
414
+ mode: spawnMode,
415
+ }, {
416
+ runId: childRunId,
417
+ childSessionKey,
418
+ requesterSessionKey: requesterInternalKey,
419
+ });
420
+ }
421
+ catch {
422
+ // Spawn should still return accepted if spawn lifecycle hooks fail.
423
+ }
424
+ }
238
425
  return {
239
426
  status: "accepted",
240
427
  childSessionKey,
241
428
  runId: childRunId,
242
- note: SUBAGENT_SPAWN_ACCEPTED_NOTE,
429
+ mode: spawnMode,
430
+ note: spawnMode === "session" ? SUBAGENT_SPAWN_SESSION_ACCEPTED_NOTE : SUBAGENT_SPAWN_ACCEPTED_NOTE,
243
431
  modelApplied: resolvedModel ? modelApplied : undefined,
244
432
  };
245
433
  }
@@ -1,3 +1,4 @@
1
+ import { createHmac, createHash } from "node:crypto";
1
2
  import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
2
3
  import { listDeliverableMessageChannels } from "../utils/message-channel.js";
3
4
  import { sanitizeForPromptLiteral } from "./sanitize-for-prompt.js";
@@ -44,7 +45,24 @@ function buildUserIdentitySection(ownerLine, isMinimal) {
44
45
  if (!ownerLine || isMinimal) {
45
46
  return [];
46
47
  }
47
- return ["## User Identity", ownerLine, ""];
48
+ return ["## Authorized Senders", ownerLine, ""];
49
+ }
50
+ function formatOwnerDisplayId(ownerId, ownerDisplaySecret) {
51
+ const hasSecret = ownerDisplaySecret?.trim();
52
+ const digest = hasSecret
53
+ ? createHmac("sha256", hasSecret).update(ownerId).digest("hex")
54
+ : createHash("sha256").update(ownerId).digest("hex");
55
+ return digest.slice(0, 12);
56
+ }
57
+ function buildOwnerIdentityLine(ownerNumbers, ownerDisplay, ownerDisplaySecret) {
58
+ const normalized = ownerNumbers.map((value) => value.trim()).filter(Boolean);
59
+ if (normalized.length === 0) {
60
+ return undefined;
61
+ }
62
+ const displayOwnerNumbers = ownerDisplay === "hash"
63
+ ? normalized.map((ownerId) => formatOwnerDisplayId(ownerId, ownerDisplaySecret))
64
+ : normalized;
65
+ return `Authorized senders: ${displayOwnerNumbers.join(", ")}. These senders are allowlisted; do not assume they are the owner.`;
48
66
  }
49
67
  function buildTimeSection(params) {
50
68
  if (!params.userTimezone) {
@@ -118,7 +136,7 @@ function buildDocsSection(params) {
118
136
  return [
119
137
  "## Documentation",
120
138
  `Pool Bot docs: ${docsPath}`,
121
- "Mirror: https://docs.poolbot.dev",
139
+ "Mirror: https://docs.molt.bot",
122
140
  "Source: https://github.com/poolbot/poolbot",
123
141
  "Community: https://discord.com/invite/clawd",
124
142
  "Find new skills: https://clawhub.com",
@@ -220,10 +238,8 @@ export function buildAgentSystemPrompt(params) {
220
238
  const execToolName = resolveToolName("exec");
221
239
  const processToolName = resolveToolName("process");
222
240
  const extraSystemPrompt = params.extraSystemPrompt?.trim();
223
- const ownerNumbers = (params.ownerNumbers ?? []).map((value) => value.trim()).filter(Boolean);
224
- const ownerLine = ownerNumbers.length > 0
225
- ? `Owner numbers: ${ownerNumbers.join(", ")}. Treat messages from these numbers as the user.`
226
- : undefined;
241
+ const ownerDisplay = params.ownerDisplay === "hash" ? "hash" : "raw";
242
+ const ownerLine = buildOwnerIdentityLine(params.ownerNumbers ?? [], ownerDisplay, params.ownerDisplaySecret);
227
243
  const reasoningHint = params.reasoningTagHint
228
244
  ? [
229
245
  "ALL internal reasoning MUST be inside <think>...</think>.",
@@ -0,0 +1,29 @@
1
+ const ZERO_USAGE = {
2
+ input: 0,
3
+ output: 0,
4
+ cacheRead: 0,
5
+ cacheWrite: 0,
6
+ totalTokens: 0,
7
+ cost: {
8
+ input: 0,
9
+ output: 0,
10
+ cacheRead: 0,
11
+ cacheWrite: 0,
12
+ total: 0,
13
+ },
14
+ };
15
+ export function makeAssistantMessageFixture(overrides = {}) {
16
+ const errorText = typeof overrides.errorMessage === "string" ? overrides.errorMessage : "error";
17
+ return {
18
+ role: "assistant",
19
+ api: "openai-responses",
20
+ provider: "openai",
21
+ model: "test-model",
22
+ usage: ZERO_USAGE,
23
+ timestamp: 0,
24
+ stopReason: "error",
25
+ errorMessage: errorText,
26
+ content: [{ type: "text", text: errorText }],
27
+ ...overrides,
28
+ };
29
+ }
@@ -1,18 +1 @@
1
- import { vi } from "vitest";
2
- const stubTool = (name) => ({
3
- name,
4
- description: `${name} stub`,
5
- parameters: { type: "object", properties: {} },
6
- execute: vi.fn(),
7
- });
8
- vi.mock("../tools/image-tool.js", () => ({
9
- createImageTool: () => stubTool("image"),
10
- }));
11
- vi.mock("../tools/web-tools.js", () => ({
12
- createWebSearchTool: () => null,
13
- createWebFetchTool: () => null,
14
- }));
15
- vi.mock("../../plugins/tools.js", () => ({
16
- resolvePluginTools: () => [],
17
- getPluginToolMeta: () => undefined,
18
- }));
1
+ import "./fast-tool-stubs.js";
@@ -1,24 +1,8 @@
1
1
  import { vi } from "vitest";
2
- const stubTool = (name) => ({
3
- name,
4
- description: `${name} stub`,
5
- parameters: { type: "object", properties: {} },
6
- execute: vi.fn(),
7
- });
2
+ import { stubTool } from "./fast-tool-stubs.js";
8
3
  vi.mock("../tools/browser-tool.js", () => ({
9
4
  createBrowserTool: () => stubTool("browser"),
10
5
  }));
11
6
  vi.mock("../tools/canvas-tool.js", () => ({
12
7
  createCanvasTool: () => stubTool("canvas"),
13
8
  }));
14
- vi.mock("../tools/image-tool.js", () => ({
15
- createImageTool: () => stubTool("image"),
16
- }));
17
- vi.mock("../tools/web-tools.js", () => ({
18
- createWebSearchTool: () => null,
19
- createWebFetchTool: () => null,
20
- }));
21
- vi.mock("../../plugins/tools.js", () => ({
22
- resolvePluginTools: () => [],
23
- getPluginToolMeta: () => undefined,
24
- }));
@@ -0,0 +1,27 @@
1
+ export function createPiToolsSandboxContext(params) {
2
+ const workspaceDir = params.workspaceDir;
3
+ return {
4
+ enabled: true,
5
+ sessionKey: params.sessionKey ?? "sandbox:test",
6
+ workspaceDir,
7
+ agentWorkspaceDir: params.agentWorkspaceDir ?? workspaceDir,
8
+ workspaceAccess: params.workspaceAccess ?? "rw",
9
+ containerName: params.containerName ?? "poolbot-sbx-test",
10
+ containerWorkdir: params.containerWorkdir ?? "/workspace",
11
+ fsBridge: params.fsBridge,
12
+ docker: {
13
+ image: "poolbot-sandbox:bookworm-slim",
14
+ containerPrefix: "poolbot-sbx-",
15
+ workdir: "/workspace",
16
+ readOnlyRoot: true,
17
+ tmpfs: [],
18
+ network: "none",
19
+ user: "1000:1000",
20
+ capDrop: ["ALL"],
21
+ env: { LANG: "C.UTF-8" },
22
+ ...params.dockerOverrides,
23
+ },
24
+ tools: params.tools ?? { allow: [], deny: [] },
25
+ browserAllowHostControl: params.browserAllowHostControl ?? false,
26
+ };
27
+ }
@@ -1,4 +1,5 @@
1
1
  const DEFAULT_AGENT_TIMEOUT_SECONDS = 600;
2
+ const MAX_SAFE_TIMEOUT_MS = 2_147_000_000;
2
3
  const normalizeNumber = (value) => typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : undefined;
3
4
  export function resolveAgentTimeoutSeconds(cfg) {
4
5
  const raw = normalizeNumber(cfg?.agents?.defaults?.timeoutSeconds);
@@ -7,18 +8,29 @@ export function resolveAgentTimeoutSeconds(cfg) {
7
8
  }
8
9
  export function resolveAgentTimeoutMs(opts) {
9
10
  const minMs = Math.max(normalizeNumber(opts.minMs) ?? 1, 1);
10
- const defaultMs = resolveAgentTimeoutSeconds(opts.cfg) * 1000;
11
+ const clampTimeoutMs = (valueMs) => Math.min(Math.max(valueMs, minMs), MAX_SAFE_TIMEOUT_MS);
12
+ const defaultMs = clampTimeoutMs(resolveAgentTimeoutSeconds(opts.cfg) * 1000);
13
+ // Use the maximum timer-safe timeout to represent "no timeout" when explicitly set to 0.
14
+ const NO_TIMEOUT_MS = MAX_SAFE_TIMEOUT_MS;
11
15
  const overrideMs = normalizeNumber(opts.overrideMs);
12
16
  if (overrideMs !== undefined) {
13
- if (overrideMs <= 0)
17
+ if (overrideMs === 0) {
18
+ return NO_TIMEOUT_MS;
19
+ }
20
+ if (overrideMs < 0) {
14
21
  return defaultMs;
15
- return Math.max(overrideMs, minMs);
22
+ }
23
+ return clampTimeoutMs(overrideMs);
16
24
  }
17
25
  const overrideSeconds = normalizeNumber(opts.overrideSeconds);
18
26
  if (overrideSeconds !== undefined) {
19
- if (overrideSeconds <= 0)
27
+ if (overrideSeconds === 0) {
28
+ return NO_TIMEOUT_MS;
29
+ }
30
+ if (overrideSeconds < 0) {
20
31
  return defaultMs;
21
- return Math.max(overrideSeconds * 1000, minMs);
32
+ }
33
+ return clampTimeoutMs(overrideSeconds * 1000);
22
34
  }
23
- return Math.max(defaultMs, minMs);
35
+ return defaultMs;
24
36
  }
@@ -73,7 +73,7 @@ export function isValidCloudCodeAssistToolId(id, mode = "strict") {
73
73
  return /^[a-zA-Z0-9]+$/.test(id);
74
74
  }
75
75
  function shortHash(text, length = 8) {
76
- return createHash("sha1").update(text).digest("hex").slice(0, length);
76
+ return createHash("sha256").update(text).digest("hex").slice(0, length);
77
77
  }
78
78
  function makeUniqueToolId(params) {
79
79
  if (params.mode === "strict9") {