@poolzin/pool-bot 2026.2.25 → 2026.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/dist/acp/event-mapper.js +87 -22
  2. package/dist/acp/meta.js +12 -6
  3. package/dist/agents/agent-paths.js +8 -9
  4. package/dist/agents/agent-scope.js +7 -5
  5. package/dist/agents/auth-profiles/oauth.js +148 -64
  6. package/dist/agents/auth-profiles/session-override.js +13 -7
  7. package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
  8. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  9. package/dist/agents/bedrock-discovery.js +3 -1
  10. package/dist/agents/byteplus-models.js +97 -0
  11. package/dist/agents/chutes-oauth.js +1 -0
  12. package/dist/agents/cli-runner/helpers.js +4 -0
  13. package/dist/agents/compaction.js +41 -14
  14. package/dist/agents/doubao-models.js +121 -0
  15. package/dist/agents/failover-error.js +2 -0
  16. package/dist/agents/huggingface-models.js +5 -3
  17. package/dist/agents/live-model-filter.js +5 -0
  18. package/dist/agents/minimax-vlm.js +10 -8
  19. package/dist/agents/model-auth.js +6 -0
  20. package/dist/agents/model-catalog.js +3 -1
  21. package/dist/agents/model-selection.js +7 -1
  22. package/dist/agents/models-config.providers.js +93 -11
  23. package/dist/agents/ollama-stream.js +117 -4
  24. package/dist/agents/opencode-zen-models.js +22 -11
  25. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  26. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  27. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  28. package/dist/agents/pi-embedded-helpers.js +1 -1
  29. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  30. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  31. package/dist/agents/pi-embedded-runner/google.js +20 -8
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  33. package/dist/agents/pi-embedded-runner/run.js +71 -12
  34. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  35. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  36. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  37. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  38. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  39. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  40. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  41. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  42. package/dist/agents/pi-embedded-subscribe.js +9 -4
  43. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  44. package/dist/agents/pi-embedded-utils.js +3 -0
  45. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  46. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  47. package/dist/agents/pi-settings.js +40 -0
  48. package/dist/agents/pi-tools.policy.js +2 -1
  49. package/dist/agents/provider/config-loader.js +1 -1
  50. package/dist/agents/sandbox/browser.js +170 -33
  51. package/dist/agents/sandbox/config-hash.js +14 -27
  52. package/dist/agents/sandbox/config.js +21 -2
  53. package/dist/agents/sandbox/constants.js +2 -0
  54. package/dist/agents/sandbox/docker.js +16 -2
  55. package/dist/agents/sandbox/novnc-auth.js +62 -0
  56. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  57. package/dist/agents/sandbox/shared.js +10 -6
  58. package/dist/agents/sandbox-paths.js +24 -11
  59. package/dist/agents/schema/clean-for-gemini.js +132 -85
  60. package/dist/agents/session-slug.js +10 -5
  61. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  62. package/dist/agents/session-tool-result-guard.js +3 -1
  63. package/dist/agents/session-transcript-repair.js +40 -6
  64. package/dist/agents/skills/bundled-dir.js +19 -5
  65. package/dist/agents/skills/env-overrides.js +124 -43
  66. package/dist/agents/skills/frontmatter.js +6 -6
  67. package/dist/agents/skills/plugin-skills.js +14 -7
  68. package/dist/agents/skills/workspace.js +1 -0
  69. package/dist/agents/subagent-announce.js +251 -49
  70. package/dist/agents/subagent-lifecycle-events.js +19 -0
  71. package/dist/agents/subagent-registry-cleanup.js +31 -0
  72. package/dist/agents/subagent-registry-completion.js +68 -0
  73. package/dist/agents/subagent-registry-queries.js +117 -0
  74. package/dist/agents/subagent-registry-state.js +46 -0
  75. package/dist/agents/subagent-registry.js +252 -221
  76. package/dist/agents/subagent-registry.store.js +1 -0
  77. package/dist/agents/subagent-registry.types.js +1 -0
  78. package/dist/agents/subagent-spawn.js +195 -7
  79. package/dist/agents/system-prompt.js +22 -6
  80. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  81. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  82. package/dist/agents/timeout.js +18 -6
  83. package/dist/agents/tool-call-id.js +1 -1
  84. package/dist/agents/tool-display-common.js +162 -29
  85. package/dist/agents/tool-images.js +82 -9
  86. package/dist/agents/tool-policy.js +51 -26
  87. package/dist/agents/tools/browser-tool.js +2 -2
  88. package/dist/agents/tools/canvas-tool.js +27 -1
  89. package/dist/agents/tools/common.js +45 -0
  90. package/dist/agents/tools/discord-actions-guild.js +4 -1
  91. package/dist/agents/tools/gateway-tool.js +3 -1
  92. package/dist/agents/tools/nodes-utils.js +1 -10
  93. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  94. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  95. package/dist/agents/tools/subagents-tool.js +2 -1
  96. package/dist/agents/tools/whatsapp-actions.js +10 -2
  97. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  98. package/dist/agents/transcript-policy.js +22 -8
  99. package/dist/agents/venice-models.js +11 -3
  100. package/dist/auto-reply/commands-registry.data.js +51 -0
  101. package/dist/auto-reply/commands-registry.js +4 -3
  102. package/dist/auto-reply/group-activation.js +10 -5
  103. package/dist/auto-reply/inbound-debounce.js +10 -5
  104. package/dist/auto-reply/reply/abort.js +1 -1
  105. package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
  106. package/dist/auto-reply/reply/bash-command.js +41 -39
  107. package/dist/auto-reply/reply/command-gates.js +25 -0
  108. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  109. package/dist/auto-reply/reply/commands-bash.js +6 -5
  110. package/dist/auto-reply/reply/commands-config.js +30 -28
  111. package/dist/auto-reply/reply/commands-core.js +2 -1
  112. package/dist/auto-reply/reply/commands-info.js +1 -0
  113. package/dist/auto-reply/reply/commands-models.js +65 -14
  114. package/dist/auto-reply/reply/commands-session.js +237 -82
  115. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  116. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  117. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  118. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  119. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  120. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  121. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  122. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  123. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  124. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  125. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  126. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  127. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  128. package/dist/auto-reply/reply/commands-tts.js +10 -5
  129. package/dist/auto-reply/reply/config-value.js +10 -5
  130. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  131. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  132. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  133. package/dist/auto-reply/reply/followup-runner.js +1 -0
  134. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  135. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  136. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  137. package/dist/auto-reply/reply/get-reply.js +71 -12
  138. package/dist/auto-reply/reply/model-selection.js +80 -39
  139. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  140. package/dist/auto-reply/reply/queue/state.js +13 -12
  141. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  142. package/dist/auto-reply/reply/reply-reference.js +9 -8
  143. package/dist/auto-reply/reply/route-reply.js +15 -8
  144. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  145. package/dist/auto-reply/reply/session.js +22 -6
  146. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  147. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  148. package/dist/auto-reply/reply/typing.js +46 -21
  149. package/dist/auto-reply/send-policy.js +14 -7
  150. package/dist/auto-reply/status.js +140 -16
  151. package/dist/auto-reply/templating.js +10 -5
  152. package/dist/auto-reply/thinking.js +7 -16
  153. package/dist/auto-reply/tokens.js +21 -5
  154. package/dist/browser/bridge-server.js +36 -20
  155. package/dist/browser/cdp.helpers.js +7 -14
  156. package/dist/browser/cdp.js +35 -15
  157. package/dist/browser/chrome.profile-decoration.js +7 -4
  158. package/dist/browser/config.js +4 -0
  159. package/dist/browser/extension-relay-auth.js +55 -0
  160. package/dist/browser/extension-relay.js +74 -29
  161. package/dist/browser/navigation-guard.js +9 -1
  162. package/dist/browser/paths.js +77 -0
  163. package/dist/browser/profiles.js +13 -8
  164. package/dist/browser/pw-ai-module.js +10 -5
  165. package/dist/browser/pw-session.js +76 -39
  166. package/dist/browser/pw-tools-core.interactions.js +14 -7
  167. package/dist/browser/pw-tools-core.state.js +12 -6
  168. package/dist/browser/routes/agent.act.js +2 -2
  169. package/dist/browser/server-context.js +7 -0
  170. package/dist/build-info.json +3 -3
  171. package/dist/channels/allow-from.js +2 -1
  172. package/dist/channels/allowlists/resolve-utils.js +43 -19
  173. package/dist/channels/channel-config.js +14 -7
  174. package/dist/channels/draft-stream-loop.js +7 -0
  175. package/dist/channels/model-overrides.js +82 -0
  176. package/dist/channels/plugins/normalize/imessage.js +14 -7
  177. package/dist/channels/plugins/normalize/slack.js +10 -5
  178. package/dist/channels/plugins/normalize/telegram.js +14 -7
  179. package/dist/channels/plugins/outbound/discord.js +80 -8
  180. package/dist/channels/plugins/outbound/signal.js +11 -11
  181. package/dist/channels/plugins/setup-helpers.js +10 -5
  182. package/dist/channels/sender-label.js +14 -7
  183. package/dist/channels/session.js +4 -2
  184. package/dist/channels/status-reactions.js +297 -0
  185. package/dist/cli/banner.js +1 -1
  186. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  187. package/dist/cli/cli-name.js +11 -11
  188. package/dist/cli/cli-utils.js +13 -3
  189. package/dist/cli/command-format.js +1 -1
  190. package/dist/cli/config-cli.js +1 -1
  191. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  192. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  193. package/dist/cli/daemon-cli/restart-health.js +126 -0
  194. package/dist/cli/daemon-cli/status.gather.js +9 -13
  195. package/dist/cli/daemon-cli/status.print.js +2 -10
  196. package/dist/cli/deps.js +27 -22
  197. package/dist/cli/gateway-cli/run-loop.js +23 -5
  198. package/dist/cli/node-cli/register.js +14 -5
  199. package/dist/cli/nodes-media-utils.js +7 -2
  200. package/dist/cli/outbound-send-deps.js +2 -9
  201. package/dist/cli/outbound-send-mapping.js +11 -0
  202. package/dist/cli/pairing-cli.js +40 -14
  203. package/dist/cli/plugins-cli.js +34 -41
  204. package/dist/cli/ports.js +11 -10
  205. package/dist/cli/program/command-registry.js +2 -11
  206. package/dist/cli/program/command-tree.js +16 -0
  207. package/dist/cli/program/preaction.js +13 -9
  208. package/dist/cli/program/register.configure.js +3 -18
  209. package/dist/cli/program/register.maintenance.js +2 -2
  210. package/dist/cli/program/register.onboard.js +2 -0
  211. package/dist/cli/program/register.status-health-sessions.js +16 -17
  212. package/dist/cli/program/register.subclis.js +93 -52
  213. package/dist/cli/route.js +11 -7
  214. package/dist/cli/system-cli.js +36 -46
  215. package/dist/cli/update-cli/shared.js +22 -9
  216. package/dist/cli/update-cli/update-command.js +89 -14
  217. package/dist/cli/update-cli/wizard.js +6 -12
  218. package/dist/commands/agent/run-context.js +18 -5
  219. package/dist/commands/agent/session-store.js +17 -4
  220. package/dist/commands/agent.js +22 -2
  221. package/dist/commands/agents.bindings.js +14 -7
  222. package/dist/commands/agents.commands.add.js +13 -9
  223. package/dist/commands/agents.commands.identity.js +12 -6
  224. package/dist/commands/agents.commands.list.js +11 -6
  225. package/dist/commands/agents.config.js +8 -10
  226. package/dist/commands/agents.providers.js +12 -6
  227. package/dist/commands/auth-choice-options.js +103 -75
  228. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  229. package/dist/commands/auth-choice.apply.js +4 -0
  230. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  231. package/dist/commands/auth-choice.apply.openai.js +3 -1
  232. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  233. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  234. package/dist/commands/channels/remove.js +13 -6
  235. package/dist/commands/channels/shared.js +4 -14
  236. package/dist/commands/configure.commands.js +14 -0
  237. package/dist/commands/configure.gateway.js +2 -4
  238. package/dist/commands/configure.js +1 -1
  239. package/dist/commands/configure.shared.js +11 -0
  240. package/dist/commands/daemon-install-helpers.js +2 -2
  241. package/dist/commands/dashboard.js +12 -10
  242. package/dist/commands/docs.js +14 -8
  243. package/dist/commands/doctor-config-flow.js +11 -9
  244. package/dist/commands/doctor-legacy-config.js +281 -0
  245. package/dist/commands/doctor-state-integrity.js +99 -23
  246. package/dist/commands/doctor-update.js +12 -9
  247. package/dist/commands/models/list.list-command.js +7 -5
  248. package/dist/commands/models/set-image.js +2 -21
  249. package/dist/commands/node-daemon-install-helpers.js +10 -8
  250. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  251. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  252. package/dist/commands/onboard-auth.credentials.js +90 -13
  253. package/dist/commands/onboard-auth.js +1 -1
  254. package/dist/commands/onboard-auth.models.js +6 -5
  255. package/dist/commands/onboard-hooks.js +1 -1
  256. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  257. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  258. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  259. package/dist/commands/onboard-remote.js +14 -7
  260. package/dist/commands/onboard.js +11 -13
  261. package/dist/commands/sandbox-display.js +6 -5
  262. package/dist/commands/status-all/diagnosis.js +14 -10
  263. package/dist/commands/status-all/format.js +1 -0
  264. package/dist/commands/status.gateway-probe.js +1 -16
  265. package/dist/commands/systemd-linger.js +12 -6
  266. package/dist/config/agent-limits.js +2 -0
  267. package/dist/config/commands.js +30 -16
  268. package/dist/config/config-paths.js +9 -11
  269. package/dist/config/defaults.js +22 -2
  270. package/dist/config/discord-preview-streaming.js +104 -0
  271. package/dist/config/env-vars.js +37 -8
  272. package/dist/config/includes.js +4 -0
  273. package/dist/config/io.js +97 -12
  274. package/dist/config/legacy.migrations.part-1.js +189 -78
  275. package/dist/config/legacy.shared.js +3 -1
  276. package/dist/config/merge-patch.js +4 -0
  277. package/dist/config/prototype-keys.js +4 -0
  278. package/dist/config/schema.help.js +44 -7
  279. package/dist/config/schema.labels.js +38 -6
  280. package/dist/config/sessions/delivery-info.js +10 -3
  281. package/dist/config/sessions/main-session.js +10 -5
  282. package/dist/config/sessions/session-file.js +33 -0
  283. package/dist/config/sessions/session-key.js +10 -5
  284. package/dist/config/sessions/store.js +1 -1
  285. package/dist/config/sessions.js +1 -0
  286. package/dist/config/zod-schema.agent-runtime.js +11 -0
  287. package/dist/config/zod-schema.js +148 -13
  288. package/dist/config/zod-schema.providers-core.js +78 -4
  289. package/dist/config/zod-schema.providers.js +6 -1
  290. package/dist/config/zod-schema.session.js +41 -2
  291. package/dist/cron/run-log.js +3 -0
  292. package/dist/cron/schedule.js +21 -10
  293. package/dist/cron/service/ops.js +35 -21
  294. package/dist/cron/service/timer.js +116 -16
  295. package/dist/cron/stagger.js +3 -1
  296. package/dist/discord/api.js +12 -6
  297. package/dist/discord/draft-chunking.js +22 -0
  298. package/dist/discord/draft-stream.js +124 -0
  299. package/dist/discord/monitor/agent-components.js +1 -1
  300. package/dist/discord/monitor/commands.js +5 -0
  301. package/dist/discord/monitor/gateway-plugin.js +2 -1
  302. package/dist/discord/monitor/listeners.js +37 -27
  303. package/dist/discord/monitor/message-handler.js +4 -1
  304. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  305. package/dist/discord/monitor/message-handler.process.js +246 -217
  306. package/dist/discord/monitor/message-utils.js +143 -6
  307. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  308. package/dist/discord/monitor/model-picker.js +651 -0
  309. package/dist/discord/monitor/native-command.js +573 -16
  310. package/dist/discord/monitor/provider.allowlist.js +223 -0
  311. package/dist/discord/monitor/provider.js +275 -347
  312. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  313. package/dist/discord/monitor/reply-delivery.js +123 -16
  314. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  315. package/dist/discord/monitor/thread-bindings.js +4 -0
  316. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  317. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  318. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  319. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  320. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  321. package/dist/discord/resolve-users.js +33 -21
  322. package/dist/discord/send.channels.js +15 -0
  323. package/dist/discord/send.js +3 -2
  324. package/dist/discord/send.outbound.js +82 -26
  325. package/dist/discord/send.permissions.js +83 -30
  326. package/dist/discord/send.reactions.js +8 -4
  327. package/dist/discord/token.js +10 -5
  328. package/dist/discord/voice/command.js +263 -0
  329. package/dist/discord/voice/manager.js +531 -0
  330. package/dist/gateway/auth.js +34 -10
  331. package/dist/gateway/call.js +4 -16
  332. package/dist/gateway/client.js +28 -4
  333. package/dist/gateway/config-reload.js +3 -4
  334. package/dist/gateway/control-ui.js +219 -96
  335. package/dist/gateway/hooks-mapping.js +88 -38
  336. package/dist/gateway/http-auth-helpers.js +3 -2
  337. package/dist/gateway/http-endpoint-helpers.js +1 -0
  338. package/dist/gateway/net.js +54 -12
  339. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  340. package/dist/gateway/node-registry.js +10 -5
  341. package/dist/gateway/openai-http.js +1 -0
  342. package/dist/gateway/openresponses-http.js +1 -0
  343. package/dist/gateway/origin-check.js +1 -18
  344. package/dist/gateway/protocol/index.js +4 -3
  345. package/dist/gateway/protocol/schema/cron.js +1 -0
  346. package/dist/gateway/protocol/schema/devices.js +1 -0
  347. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
  348. package/dist/gateway/protocol/schema/sessions.js +6 -0
  349. package/dist/gateway/role-policy.js +17 -0
  350. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  351. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  352. package/dist/gateway/server-chat.js +83 -25
  353. package/dist/gateway/server-constants.js +10 -9
  354. package/dist/gateway/server-cron.js +1 -0
  355. package/dist/gateway/server-http.js +16 -7
  356. package/dist/gateway/server-maintenance.js +20 -5
  357. package/dist/gateway/server-methods/chat.js +10 -6
  358. package/dist/gateway/server-methods/config.js +12 -14
  359. package/dist/gateway/server-methods/devices.js +17 -3
  360. package/dist/gateway/server-methods/models.js +11 -1
  361. package/dist/gateway/server-methods/sessions.js +64 -8
  362. package/dist/gateway/server-methods/usage.js +162 -75
  363. package/dist/gateway/server-node-events.js +29 -0
  364. package/dist/gateway/server-runtime-config.js +34 -13
  365. package/dist/gateway/server-startup-memory.js +17 -11
  366. package/dist/gateway/session-utils.fs.js +32 -34
  367. package/dist/gateway/sessions-resolve.js +17 -5
  368. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  369. package/dist/gateway/tools-invoke-http.js +21 -10
  370. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  371. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  372. package/dist/hooks/bundled/session-memory/handler.js +6 -5
  373. package/dist/hooks/frontmatter.js +6 -6
  374. package/dist/hooks/gmail-watcher.js +11 -6
  375. package/dist/hooks/internal-hooks.js +11 -1
  376. package/dist/hooks/llm-slug-generator.js +4 -1
  377. package/dist/hooks/workspace.js +47 -17
  378. package/dist/imessage/accounts.js +9 -20
  379. package/dist/imessage/monitor/inbound-processing.js +2 -1
  380. package/dist/infra/archive.js +174 -73
  381. package/dist/infra/control-ui-assets.js +14 -6
  382. package/dist/infra/device-pairing.js +108 -29
  383. package/dist/infra/env.js +10 -5
  384. package/dist/infra/exec-approvals-allowlist.js +122 -0
  385. package/dist/infra/exec-approvals-analysis.js +34 -3
  386. package/dist/infra/exec-approvals.js +5 -17
  387. package/dist/infra/exec-safe-bin-policy.js +53 -45
  388. package/dist/infra/fs-safe.js +71 -39
  389. package/dist/infra/gateway-lock.js +6 -2
  390. package/dist/infra/heartbeat-wake.js +6 -12
  391. package/dist/infra/host-env-security-policy.json +19 -0
  392. package/dist/infra/host-env-security.js +66 -0
  393. package/dist/infra/net/ssrf.js +131 -38
  394. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  395. package/dist/infra/outbound/channel-selection.js +12 -6
  396. package/dist/infra/outbound/envelope.js +1 -1
  397. package/dist/infra/outbound/format.js +12 -6
  398. package/dist/infra/outbound/payloads.js +14 -7
  399. package/dist/infra/outbound/session-binding-service.js +123 -0
  400. package/dist/infra/path-guards.js +25 -0
  401. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  402. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  403. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  404. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  405. package/dist/infra/retry-policy.js +4 -2
  406. package/dist/infra/retry.js +9 -5
  407. package/dist/infra/session-cost-usage.js +107 -59
  408. package/dist/infra/session-maintenance-warning.js +3 -1
  409. package/dist/infra/shell-env.js +98 -34
  410. package/dist/infra/ssh-config.js +12 -6
  411. package/dist/infra/system-run-command.js +49 -4
  412. package/dist/infra/update-channels.js +10 -5
  413. package/dist/line/accounts.js +5 -7
  414. package/dist/line/bot-access.js +8 -20
  415. package/dist/line/bot-handlers.js +3 -1
  416. package/dist/link-understanding/detect.js +15 -7
  417. package/dist/media/constants.js +15 -6
  418. package/dist/media/image-ops.js +7 -0
  419. package/dist/media/local-roots.js +3 -2
  420. package/dist/media-understanding/apply.js +4 -1
  421. package/dist/media-understanding/concurrency.js +8 -20
  422. package/dist/memory/backend-config.js +45 -6
  423. package/dist/memory/embeddings.js +10 -4
  424. package/dist/memory/fs-utils.js +23 -0
  425. package/dist/memory/manager-search.js +12 -6
  426. package/dist/memory/manager-sync-ops.js +12 -2
  427. package/dist/memory/qmd-manager.js +466 -53
  428. package/dist/memory/query-expansion.js +167 -3
  429. package/dist/memory/status-format.js +10 -5
  430. package/dist/memory/sync-memory-files.js +1 -1
  431. package/dist/node-host/invoke-system-run.js +281 -0
  432. package/dist/node-host/invoke.js +55 -337
  433. package/dist/pairing/pairing-store.js +22 -0
  434. package/dist/plugin-sdk/allow-from.js +1 -1
  435. package/dist/plugin-sdk/command-auth.js +3 -1
  436. package/dist/plugin-sdk/index.js +6 -3
  437. package/dist/plugin-sdk/webhook-targets.js +32 -0
  438. package/dist/plugins/bundled-dir.js +9 -6
  439. package/dist/plugins/hooks.js +50 -0
  440. package/dist/plugins/install.js +28 -16
  441. package/dist/plugins/runtime.js +3 -17
  442. package/dist/plugins/update.js +78 -12
  443. package/dist/process/spawn-utils.js +14 -7
  444. package/dist/providers/github-copilot-token.js +11 -6
  445. package/dist/providers/qwen-portal-oauth.js +14 -6
  446. package/dist/routing/account-id.js +30 -0
  447. package/dist/routing/resolve-route.js +3 -7
  448. package/dist/routing/session-key.js +2 -16
  449. package/dist/security/audit-channel.js +93 -2
  450. package/dist/security/audit-extra.async.js +159 -5
  451. package/dist/security/audit-extra.js +1 -1
  452. package/dist/security/audit-extra.sync.js +85 -6
  453. package/dist/security/audit.js +40 -4
  454. package/dist/security/dm-policy-shared.js +44 -0
  455. package/dist/security/external-content.js +26 -6
  456. package/dist/shared/entry-status.js +6 -0
  457. package/dist/shared/frontmatter.js +5 -5
  458. package/dist/shared/node-match.js +11 -4
  459. package/dist/shared/operator-scope-compat.js +8 -3
  460. package/dist/signal/accounts.js +7 -20
  461. package/dist/signal/monitor/event-handler.js +3 -1
  462. package/dist/slack/accounts.js +6 -19
  463. package/dist/slack/actions.js +11 -3
  464. package/dist/slack/monitor/auth.js +1 -1
  465. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  466. package/dist/slack/monitor/replies.js +15 -7
  467. package/dist/slack/monitor/slash.js +22 -13
  468. package/dist/slack/resolve-channels.js +10 -5
  469. package/dist/slack/send.js +102 -12
  470. package/dist/slack/stream-mode.js +10 -0
  471. package/dist/slack/streaming.js +4 -2
  472. package/dist/telegram/accounts.js +19 -14
  473. package/dist/telegram/bot/helpers.js +3 -5
  474. package/dist/telegram/bot-access.js +35 -36
  475. package/dist/telegram/bot-handlers.js +120 -148
  476. package/dist/telegram/bot-message-context.js +68 -9
  477. package/dist/telegram/bot-message-dispatch.js +155 -90
  478. package/dist/telegram/bot-native-commands.js +16 -0
  479. package/dist/telegram/draft-stream.js +14 -1
  480. package/dist/telegram/inline-buttons.js +5 -15
  481. package/dist/telegram/monitor.js +11 -7
  482. package/dist/telegram/network-config.js +19 -7
  483. package/dist/telegram/send.js +3 -2
  484. package/dist/telegram/sent-message-cache.js +5 -6
  485. package/dist/telegram/status-reaction-variants.js +208 -0
  486. package/dist/telegram/sticker-cache.js +11 -9
  487. package/dist/terminal/theme.js +12 -12
  488. package/dist/tts/tts.js +80 -567
  489. package/dist/tui/components/chat-log.js +41 -8
  490. package/dist/tui/theme/theme.js +10 -12
  491. package/dist/tui/tui-local-shell.js +16 -6
  492. package/dist/tui/tui.js +58 -6
  493. package/dist/utils/account-id.js +2 -4
  494. package/dist/utils/boolean.js +10 -5
  495. package/dist/utils/directive-tags.js +11 -0
  496. package/dist/utils/queue-helpers.js +67 -12
  497. package/dist/web/auto-reply/deliver-reply.js +8 -4
  498. package/dist/web/auto-reply/mentions.js +10 -5
  499. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  500. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  501. package/dist/web/inbound/access-control.js +5 -2
  502. package/dist/web/login-qr.js +12 -6
  503. package/dist/web/media.js +123 -16
  504. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  505. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  506. package/package.json +1 -1
@@ -1,201 +1,23 @@
1
- import crypto from "node:crypto";
2
- import { AGENT_LANE_SUBAGENT } from "../../agents/lanes.js";
3
- import { abortEmbeddedPiRun } from "../../agents/pi-embedded.js";
4
- import { clearSubagentRunSteerRestart, listSubagentRunsForRequester, markSubagentRunTerminated, markSubagentRunForSteerRestart, replaceSubagentRunAfterSteer, } from "../../agents/subagent-registry.js";
5
- import { spawnSubagentDirect } from "../../agents/subagent-spawn.js";
6
- import { extractAssistantText, resolveInternalSessionKey, resolveMainSessionAlias, sanitizeTextContent, stripToolMessages, } from "../../agents/tools/sessions-helpers.js";
7
- import { loadSessionStore, resolveStorePath, updateSessionStore, } from "../../config/sessions.js";
8
- import { callGateway } from "../../gateway/call.js";
1
+ import { listSubagentRunsForRequester } from "../../agents/subagent-registry.js";
9
2
  import { logVerbose } from "../../globals.js";
10
- import { formatTimeAgo } from "../../infra/format-time/format-relative.js";
11
- import { parseAgentSessionKey } from "../../routing/session-key.js";
12
- import { extractTextFromChatContent } from "../../shared/chat-content.js";
13
- import { formatDurationCompact, formatTokenUsageDisplay, truncateLine, } from "../../shared/subagents-format.js";
14
- import { INTERNAL_MESSAGE_CHANNEL } from "../../utils/message-channel.js";
15
- import { stopSubagentsForRequester } from "./abort.js";
16
- import { clearSessionQueues } from "./queue.js";
17
- import { formatRunLabel, formatRunStatus, sortSubagentRuns } from "./subagents-utils.js";
18
- const COMMAND = "/subagents";
19
- const COMMAND_KILL = "/kill";
20
- const COMMAND_STEER = "/steer";
21
- const COMMAND_TELL = "/tell";
22
- const ACTIONS = new Set(["list", "kill", "log", "send", "steer", "info", "spawn", "help"]);
23
- const RECENT_WINDOW_MINUTES = 30;
24
- const SUBAGENT_TASK_PREVIEW_MAX = 110;
25
- const STEER_ABORT_SETTLE_TIMEOUT_MS = 5_000;
26
- function compactLine(value) {
27
- return value.replace(/\s+/g, " ").trim();
28
- }
29
- function formatTaskPreview(value) {
30
- return truncateLine(compactLine(value), SUBAGENT_TASK_PREVIEW_MAX);
31
- }
32
- function resolveModelDisplay(entry, fallbackModel) {
33
- const model = typeof entry?.model === "string" ? entry.model.trim() : "";
34
- const provider = typeof entry?.modelProvider === "string" ? entry.modelProvider.trim() : "";
35
- let combined = model.includes("/") ? model : model && provider ? `${provider}/${model}` : model;
36
- if (!combined) {
37
- // Fall back to override fields which are populated at spawn time,
38
- // before the first run completes and writes model/modelProvider.
39
- const overrideModel = typeof entry?.modelOverride === "string" ? entry.modelOverride.trim() : "";
40
- const overrideProvider = typeof entry?.providerOverride === "string" ? entry.providerOverride.trim() : "";
41
- combined = overrideModel.includes("/")
42
- ? overrideModel
43
- : overrideModel && overrideProvider
44
- ? `${overrideProvider}/${overrideModel}`
45
- : overrideModel;
46
- }
47
- if (!combined) {
48
- combined = fallbackModel?.trim() || "";
49
- }
50
- if (!combined) {
51
- return "model n/a";
52
- }
53
- const slash = combined.lastIndexOf("/");
54
- if (slash >= 0 && slash < combined.length - 1) {
55
- return combined.slice(slash + 1);
56
- }
57
- return combined;
58
- }
59
- function resolveDisplayStatus(entry) {
60
- const status = formatRunStatus(entry);
61
- return status === "error" ? "failed" : status;
62
- }
63
- function formatTimestamp(valueMs) {
64
- if (!valueMs || !Number.isFinite(valueMs) || valueMs <= 0) {
65
- return "n/a";
66
- }
67
- return new Date(valueMs).toISOString();
68
- }
69
- function formatTimestampWithAge(valueMs) {
70
- if (!valueMs || !Number.isFinite(valueMs) || valueMs <= 0) {
71
- return "n/a";
72
- }
73
- return `${formatTimestamp(valueMs)} (${formatTimeAgo(Date.now() - valueMs, { fallback: "n/a" })})`;
74
- }
75
- function resolveRequesterSessionKey(params, opts) {
76
- const commandTarget = params.ctx.CommandTargetSessionKey?.trim();
77
- const commandSession = params.sessionKey?.trim();
78
- const raw = opts?.preferCommandTarget
79
- ? commandTarget || commandSession
80
- : commandSession || commandTarget;
81
- if (!raw) {
82
- return undefined;
83
- }
84
- const { mainKey, alias } = resolveMainSessionAlias(params.cfg);
85
- return resolveInternalSessionKey({ key: raw, alias, mainKey });
86
- }
87
- function resolveSubagentTarget(runs, token) {
88
- const trimmed = token?.trim();
89
- if (!trimmed) {
90
- return { error: "Missing subagent id." };
91
- }
92
- if (trimmed === "last") {
93
- const sorted = sortSubagentRuns(runs);
94
- return { entry: sorted[0] };
95
- }
96
- const sorted = sortSubagentRuns(runs);
97
- const recentCutoff = Date.now() - RECENT_WINDOW_MINUTES * 60_000;
98
- const numericOrder = [
99
- ...sorted.filter((entry) => !entry.endedAt),
100
- ...sorted.filter((entry) => !!entry.endedAt && (entry.endedAt ?? 0) >= recentCutoff),
101
- ];
102
- if (/^\d+$/.test(trimmed)) {
103
- const idx = Number.parseInt(trimmed, 10);
104
- if (!Number.isFinite(idx) || idx <= 0 || idx > numericOrder.length) {
105
- return { error: `Invalid subagent index: ${trimmed}` };
106
- }
107
- return { entry: numericOrder[idx - 1] };
108
- }
109
- if (trimmed.includes(":")) {
110
- const match = runs.find((entry) => entry.childSessionKey === trimmed);
111
- return match ? { entry: match } : { error: `Unknown subagent session: ${trimmed}` };
112
- }
113
- const lowered = trimmed.toLowerCase();
114
- const byLabel = runs.filter((entry) => formatRunLabel(entry).toLowerCase() === lowered);
115
- if (byLabel.length === 1) {
116
- return { entry: byLabel[0] };
117
- }
118
- if (byLabel.length > 1) {
119
- return { error: `Ambiguous subagent label: ${trimmed}` };
120
- }
121
- const byLabelPrefix = runs.filter((entry) => formatRunLabel(entry).toLowerCase().startsWith(lowered));
122
- if (byLabelPrefix.length === 1) {
123
- return { entry: byLabelPrefix[0] };
124
- }
125
- if (byLabelPrefix.length > 1) {
126
- return { error: `Ambiguous subagent label prefix: ${trimmed}` };
127
- }
128
- const byRunId = runs.filter((entry) => entry.runId.startsWith(trimmed));
129
- if (byRunId.length === 1) {
130
- return { entry: byRunId[0] };
131
- }
132
- if (byRunId.length > 1) {
133
- return { error: `Ambiguous run id prefix: ${trimmed}` };
134
- }
135
- return { error: `Unknown subagent id: ${trimmed}` };
136
- }
137
- function buildSubagentsHelp() {
138
- return [
139
- "Subagents",
140
- "Usage:",
141
- "- /subagents list",
142
- "- /subagents kill <id|#|all>",
143
- "- /subagents log <id|#> [limit] [tools]",
144
- "- /subagents info <id|#>",
145
- "- /subagents send <id|#> <message>",
146
- "- /subagents steer <id|#> <message>",
147
- "- /subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]",
148
- "- /kill <id|#|all>",
149
- "- /steer <id|#> <message>",
150
- "- /tell <id|#> <message>",
151
- "",
152
- "Ids: use the list index (#), runId/session prefix, label, or full session key.",
153
- ].join("\n");
154
- }
155
- export function extractMessageText(message) {
156
- const role = typeof message.role === "string" ? message.role : "";
157
- const shouldSanitize = role === "assistant";
158
- const text = extractTextFromChatContent(message.content, {
159
- sanitizeText: shouldSanitize ? sanitizeTextContent : undefined,
160
- });
161
- return text ? { role, text } : null;
162
- }
163
- function formatLogLines(messages) {
164
- const lines = [];
165
- for (const msg of messages) {
166
- const extracted = extractMessageText(msg);
167
- if (!extracted) {
168
- continue;
169
- }
170
- const label = extracted.role === "assistant" ? "Assistant" : "User";
171
- lines.push(`${label}: ${extracted.text}`);
172
- }
173
- return lines;
174
- }
175
- function loadSubagentSessionEntry(params, childKey, storeCache) {
176
- const parsed = parseAgentSessionKey(childKey);
177
- const storePath = resolveStorePath(params.cfg.session?.store, { agentId: parsed?.agentId });
178
- let store = storeCache?.get(storePath);
179
- if (!store) {
180
- store = loadSessionStore(storePath);
181
- storeCache?.set(storePath, store);
182
- }
183
- return { storePath, store, entry: store[childKey] };
184
- }
3
+ import { handleSubagentsAgentsAction } from "./commands-subagents/action-agents.js";
4
+ import { handleSubagentsFocusAction } from "./commands-subagents/action-focus.js";
5
+ import { handleSubagentsHelpAction } from "./commands-subagents/action-help.js";
6
+ import { handleSubagentsInfoAction } from "./commands-subagents/action-info.js";
7
+ import { handleSubagentsKillAction } from "./commands-subagents/action-kill.js";
8
+ import { handleSubagentsListAction } from "./commands-subagents/action-list.js";
9
+ import { handleSubagentsLogAction } from "./commands-subagents/action-log.js";
10
+ import { handleSubagentsSendAction } from "./commands-subagents/action-send.js";
11
+ import { handleSubagentsSpawnAction } from "./commands-subagents/action-spawn.js";
12
+ import { handleSubagentsUnfocusAction } from "./commands-subagents/action-unfocus.js";
13
+ import { extractMessageText, resolveHandledPrefix, resolveRequesterSessionKey, resolveSubagentsAction, stopWithText, } from "./commands-subagents/shared.js";
14
+ export { extractMessageText };
185
15
  export const handleSubagentsCommand = async (params, allowTextCommands) => {
186
16
  if (!allowTextCommands) {
187
17
  return null;
188
18
  }
189
19
  const normalized = params.command.commandBodyNormalized;
190
- const handledPrefix = normalized.startsWith(COMMAND)
191
- ? COMMAND
192
- : normalized.startsWith(COMMAND_KILL)
193
- ? COMMAND_KILL
194
- : normalized.startsWith(COMMAND_STEER)
195
- ? COMMAND_STEER
196
- : normalized.startsWith(COMMAND_TELL)
197
- ? COMMAND_TELL
198
- : null;
20
+ const handledPrefix = resolveHandledPrefix(normalized);
199
21
  if (!handledPrefix) {
200
22
  return null;
201
23
  }
@@ -205,405 +27,47 @@ export const handleSubagentsCommand = async (params, allowTextCommands) => {
205
27
  }
206
28
  const rest = normalized.slice(handledPrefix.length).trim();
207
29
  const restTokens = rest.split(/\s+/).filter(Boolean);
208
- let action = "list";
209
- if (handledPrefix === COMMAND) {
210
- const [actionRaw] = restTokens;
211
- action = actionRaw?.toLowerCase() || "list";
212
- if (!ACTIONS.has(action)) {
213
- return { shouldContinue: false, reply: { text: buildSubagentsHelp() } };
214
- }
215
- restTokens.splice(0, 1);
216
- }
217
- else if (handledPrefix === COMMAND_KILL) {
218
- action = "kill";
219
- }
220
- else {
221
- action = "steer";
30
+ const action = resolveSubagentsAction({ handledPrefix, restTokens });
31
+ if (!action) {
32
+ return handleSubagentsHelpAction();
222
33
  }
223
34
  const requesterKey = resolveRequesterSessionKey(params, {
224
35
  preferCommandTarget: action === "spawn",
225
36
  });
226
37
  if (!requesterKey) {
227
- return { shouldContinue: false, reply: { text: "⚠️ Missing session key." } };
228
- }
229
- const runs = listSubagentRunsForRequester(requesterKey);
230
- if (action === "help") {
231
- return { shouldContinue: false, reply: { text: buildSubagentsHelp() } };
232
- }
233
- if (action === "list") {
234
- const sorted = sortSubagentRuns(runs);
235
- const now = Date.now();
236
- const recentCutoff = now - RECENT_WINDOW_MINUTES * 60_000;
237
- const storeCache = new Map();
238
- let index = 1;
239
- const activeLines = sorted
240
- .filter((entry) => !entry.endedAt)
241
- .map((entry) => {
242
- const { entry: sessionEntry } = loadSubagentSessionEntry(params, entry.childSessionKey, storeCache);
243
- const usageText = formatTokenUsageDisplay(sessionEntry);
244
- const label = truncateLine(formatRunLabel(entry, { maxLength: 48 }), 48);
245
- const task = formatTaskPreview(entry.task);
246
- const runtime = formatDurationCompact(now - (entry.startedAt ?? entry.createdAt));
247
- const status = resolveDisplayStatus(entry);
248
- const line = `${index}. ${label} (${resolveModelDisplay(sessionEntry, entry.model)}, ${runtime}${usageText ? `, ${usageText}` : ""}) ${status}${task.toLowerCase() !== label.toLowerCase() ? ` - ${task}` : ""}`;
249
- index += 1;
250
- return line;
251
- });
252
- const recentLines = sorted
253
- .filter((entry) => !!entry.endedAt && (entry.endedAt ?? 0) >= recentCutoff)
254
- .map((entry) => {
255
- const { entry: sessionEntry } = loadSubagentSessionEntry(params, entry.childSessionKey, storeCache);
256
- const usageText = formatTokenUsageDisplay(sessionEntry);
257
- const label = truncateLine(formatRunLabel(entry, { maxLength: 48 }), 48);
258
- const task = formatTaskPreview(entry.task);
259
- const runtime = formatDurationCompact((entry.endedAt ?? now) - (entry.startedAt ?? entry.createdAt));
260
- const status = resolveDisplayStatus(entry);
261
- const line = `${index}. ${label} (${resolveModelDisplay(sessionEntry, entry.model)}, ${runtime}${usageText ? `, ${usageText}` : ""}) ${status}${task.toLowerCase() !== label.toLowerCase() ? ` - ${task}` : ""}`;
262
- index += 1;
263
- return line;
264
- });
265
- const lines = ["active subagents:", "-----"];
266
- if (activeLines.length === 0) {
267
- lines.push("(none)");
268
- }
269
- else {
270
- lines.push(activeLines.join("\n"));
271
- }
272
- lines.push("", `recent subagents (last ${RECENT_WINDOW_MINUTES}m):`, "-----");
273
- if (recentLines.length === 0) {
274
- lines.push("(none)");
275
- }
276
- else {
277
- lines.push(recentLines.join("\n"));
278
- }
279
- return { shouldContinue: false, reply: { text: lines.join("\n") } };
280
- }
281
- if (action === "kill") {
282
- const target = restTokens[0];
283
- if (!target) {
284
- return {
285
- shouldContinue: false,
286
- reply: {
287
- text: handledPrefix === COMMAND
288
- ? "Usage: /subagents kill <id|#|all>"
289
- : "Usage: /kill <id|#|all>",
290
- },
291
- };
292
- }
293
- if (target === "all" || target === "*") {
294
- stopSubagentsForRequester({
295
- cfg: params.cfg,
296
- requesterSessionKey: requesterKey,
297
- });
298
- return { shouldContinue: false };
299
- }
300
- const resolved = resolveSubagentTarget(runs, target);
301
- if (!resolved.entry) {
302
- return {
303
- shouldContinue: false,
304
- reply: { text: `⚠️ ${resolved.error ?? "Unknown subagent."}` },
305
- };
306
- }
307
- if (resolved.entry.endedAt) {
308
- return {
309
- shouldContinue: false,
310
- reply: { text: `${formatRunLabel(resolved.entry)} is already finished.` },
311
- };
312
- }
313
- const childKey = resolved.entry.childSessionKey;
314
- const { storePath, store, entry } = loadSubagentSessionEntry(params, childKey);
315
- const sessionId = entry?.sessionId;
316
- if (sessionId) {
317
- abortEmbeddedPiRun(sessionId);
318
- }
319
- const cleared = clearSessionQueues([childKey, sessionId]);
320
- if (cleared.followupCleared > 0 || cleared.laneCleared > 0) {
321
- logVerbose(`subagents kill: cleared followups=${cleared.followupCleared} lane=${cleared.laneCleared} keys=${cleared.keys.join(",")}`);
322
- }
323
- if (entry) {
324
- entry.abortedLastRun = true;
325
- entry.updatedAt = Date.now();
326
- store[childKey] = entry;
327
- await updateSessionStore(storePath, (nextStore) => {
328
- nextStore[childKey] = entry;
329
- });
330
- }
331
- markSubagentRunTerminated({
332
- runId: resolved.entry.runId,
333
- childSessionKey: childKey,
334
- reason: "killed",
335
- });
336
- // Cascade: also stop any sub-sub-agents spawned by this child.
337
- stopSubagentsForRequester({
338
- cfg: params.cfg,
339
- requesterSessionKey: childKey,
340
- });
341
- return { shouldContinue: false };
342
- }
343
- if (action === "info") {
344
- const target = restTokens[0];
345
- if (!target) {
346
- return { shouldContinue: false, reply: { text: "ℹ️ Usage: /subagents info <id|#>" } };
347
- }
348
- const resolved = resolveSubagentTarget(runs, target);
349
- if (!resolved.entry) {
350
- return {
351
- shouldContinue: false,
352
- reply: { text: `⚠️ ${resolved.error ?? "Unknown subagent."}` },
353
- };
354
- }
355
- const run = resolved.entry;
356
- const { entry: sessionEntry } = loadSubagentSessionEntry(params, run.childSessionKey);
357
- const runtime = run.startedAt && Number.isFinite(run.startedAt)
358
- ? (formatDurationCompact((run.endedAt ?? Date.now()) - run.startedAt) ?? "n/a")
359
- : "n/a";
360
- const outcome = run.outcome
361
- ? `${run.outcome.status}${run.outcome.error ? ` (${run.outcome.error})` : ""}`
362
- : "n/a";
363
- const lines = [
364
- "ℹ️ Subagent info",
365
- `Status: ${resolveDisplayStatus(run)}`,
366
- `Label: ${formatRunLabel(run)}`,
367
- `Task: ${run.task}`,
368
- `Run: ${run.runId}`,
369
- `Session: ${run.childSessionKey}`,
370
- `SessionId: ${sessionEntry?.sessionId ?? "n/a"}`,
371
- `Transcript: ${sessionEntry?.sessionFile ?? "n/a"}`,
372
- `Runtime: ${runtime}`,
373
- `Created: ${formatTimestampWithAge(run.createdAt)}`,
374
- `Started: ${formatTimestampWithAge(run.startedAt)}`,
375
- `Ended: ${formatTimestampWithAge(run.endedAt)}`,
376
- `Cleanup: ${run.cleanup}`,
377
- run.archiveAtMs ? `Archive: ${formatTimestampWithAge(run.archiveAtMs)}` : undefined,
378
- run.cleanupHandled ? "Cleanup handled: yes" : undefined,
379
- `Outcome: ${outcome}`,
380
- ].filter(Boolean);
381
- return { shouldContinue: false, reply: { text: lines.join("\n") } };
382
- }
383
- if (action === "log") {
384
- const target = restTokens[0];
385
- if (!target) {
386
- return { shouldContinue: false, reply: { text: "📜 Usage: /subagents log <id|#> [limit]" } };
387
- }
388
- const includeTools = restTokens.some((token) => token.toLowerCase() === "tools");
389
- const limitToken = restTokens.find((token) => /^\d+$/.test(token));
390
- const limit = limitToken ? Math.min(200, Math.max(1, Number.parseInt(limitToken, 10))) : 20;
391
- const resolved = resolveSubagentTarget(runs, target);
392
- if (!resolved.entry) {
393
- return {
394
- shouldContinue: false,
395
- reply: { text: `⚠️ ${resolved.error ?? "Unknown subagent."}` },
396
- };
397
- }
398
- const history = await callGateway({
399
- method: "chat.history",
400
- params: { sessionKey: resolved.entry.childSessionKey, limit },
401
- });
402
- const rawMessages = Array.isArray(history?.messages) ? history.messages : [];
403
- const filtered = includeTools ? rawMessages : stripToolMessages(rawMessages);
404
- const lines = formatLogLines(filtered);
405
- const header = `📜 Subagent log: ${formatRunLabel(resolved.entry)}`;
406
- if (lines.length === 0) {
407
- return { shouldContinue: false, reply: { text: `${header}\n(no messages)` } };
408
- }
409
- return { shouldContinue: false, reply: { text: [header, ...lines].join("\n") } };
410
- }
411
- if (action === "send" || action === "steer") {
412
- const steerRequested = action === "steer";
413
- const target = restTokens[0];
414
- const message = restTokens.slice(1).join(" ").trim();
415
- if (!target || !message) {
416
- return {
417
- shouldContinue: false,
418
- reply: {
419
- text: steerRequested
420
- ? handledPrefix === COMMAND
421
- ? "Usage: /subagents steer <id|#> <message>"
422
- : `Usage: ${handledPrefix} <id|#> <message>`
423
- : "Usage: /subagents send <id|#> <message>",
424
- },
425
- };
426
- }
427
- const resolved = resolveSubagentTarget(runs, target);
428
- if (!resolved.entry) {
429
- return {
430
- shouldContinue: false,
431
- reply: { text: `⚠️ ${resolved.error ?? "Unknown subagent."}` },
432
- };
433
- }
434
- if (steerRequested && resolved.entry.endedAt) {
435
- return {
436
- shouldContinue: false,
437
- reply: { text: `${formatRunLabel(resolved.entry)} is already finished.` },
438
- };
439
- }
440
- const { entry: targetSessionEntry } = loadSubagentSessionEntry(params, resolved.entry.childSessionKey);
441
- const targetSessionId = typeof targetSessionEntry?.sessionId === "string" && targetSessionEntry.sessionId.trim()
442
- ? targetSessionEntry.sessionId.trim()
443
- : undefined;
444
- if (steerRequested) {
445
- // Suppress stale announce before interrupting the in-flight run.
446
- markSubagentRunForSteerRestart(resolved.entry.runId);
447
- // Force an immediate interruption and make steer the next run.
448
- if (targetSessionId) {
449
- abortEmbeddedPiRun(targetSessionId);
450
- }
451
- const cleared = clearSessionQueues([resolved.entry.childSessionKey, targetSessionId]);
452
- if (cleared.followupCleared > 0 || cleared.laneCleared > 0) {
453
- logVerbose(`subagents steer: cleared followups=${cleared.followupCleared} lane=${cleared.laneCleared} keys=${cleared.keys.join(",")}`);
454
- }
455
- // Best effort: wait for the interrupted run to settle so the steer
456
- // message is appended on the existing conversation state.
457
- try {
458
- await callGateway({
459
- method: "agent.wait",
460
- params: {
461
- runId: resolved.entry.runId,
462
- timeoutMs: STEER_ABORT_SETTLE_TIMEOUT_MS,
463
- },
464
- timeoutMs: STEER_ABORT_SETTLE_TIMEOUT_MS + 2_000,
465
- });
466
- }
467
- catch {
468
- // Continue even if wait fails; steer should still be attempted.
469
- }
470
- }
471
- const idempotencyKey = crypto.randomUUID();
472
- let runId = idempotencyKey;
473
- try {
474
- const response = await callGateway({
475
- method: "agent",
476
- params: {
477
- message,
478
- sessionKey: resolved.entry.childSessionKey,
479
- sessionId: targetSessionId,
480
- idempotencyKey,
481
- deliver: false,
482
- channel: INTERNAL_MESSAGE_CHANNEL,
483
- lane: AGENT_LANE_SUBAGENT,
484
- timeout: 0,
485
- },
486
- timeoutMs: 10_000,
487
- });
488
- const responseRunId = typeof response?.runId === "string" ? response.runId : undefined;
489
- if (responseRunId) {
490
- runId = responseRunId;
491
- }
492
- }
493
- catch (err) {
494
- if (steerRequested) {
495
- // Replacement launch failed; restore announce behavior for the
496
- // original run so completion is not silently suppressed.
497
- clearSubagentRunSteerRestart(resolved.entry.runId);
498
- }
499
- const messageText = err instanceof Error ? err.message : typeof err === "string" ? err : "error";
500
- return { shouldContinue: false, reply: { text: `send failed: ${messageText}` } };
501
- }
502
- if (steerRequested) {
503
- replaceSubagentRunAfterSteer({
504
- previousRunId: resolved.entry.runId,
505
- nextRunId: runId,
506
- fallback: resolved.entry,
507
- runTimeoutSeconds: resolved.entry.runTimeoutSeconds ?? 0,
508
- });
509
- return {
510
- shouldContinue: false,
511
- reply: {
512
- text: `steered ${formatRunLabel(resolved.entry)} (run ${runId.slice(0, 8)}).`,
513
- },
514
- };
515
- }
516
- const waitMs = 30_000;
517
- const wait = await callGateway({
518
- method: "agent.wait",
519
- params: { runId, timeoutMs: waitMs },
520
- timeoutMs: waitMs + 2000,
521
- });
522
- if (wait?.status === "timeout") {
523
- return {
524
- shouldContinue: false,
525
- reply: { text: `⏳ Subagent still running (run ${runId.slice(0, 8)}).` },
526
- };
527
- }
528
- if (wait?.status === "error") {
529
- const waitError = typeof wait.error === "string" ? wait.error : "unknown error";
530
- return {
531
- shouldContinue: false,
532
- reply: {
533
- text: `⚠️ Subagent error: ${waitError} (run ${runId.slice(0, 8)}).`,
534
- },
535
- };
536
- }
537
- const history = await callGateway({
538
- method: "chat.history",
539
- params: { sessionKey: resolved.entry.childSessionKey, limit: 50 },
540
- });
541
- const filtered = stripToolMessages(Array.isArray(history?.messages) ? history.messages : []);
542
- const last = filtered.length > 0 ? filtered[filtered.length - 1] : undefined;
543
- const replyText = last ? extractAssistantText(last) : undefined;
544
- return {
545
- shouldContinue: false,
546
- reply: {
547
- text: replyText ?? `✅ Sent to ${formatRunLabel(resolved.entry)} (run ${runId.slice(0, 8)}).`,
548
- },
549
- };
550
- }
551
- if (action === "spawn") {
552
- const agentId = restTokens[0];
553
- // Parse remaining tokens: task text with optional --model and --thinking flags.
554
- const taskParts = [];
555
- let model;
556
- let thinking;
557
- for (let i = 1; i < restTokens.length; i++) {
558
- if (restTokens[i] === "--model" && i + 1 < restTokens.length) {
559
- i += 1;
560
- model = restTokens[i];
561
- }
562
- else if (restTokens[i] === "--thinking" && i + 1 < restTokens.length) {
563
- i += 1;
564
- thinking = restTokens[i];
565
- }
566
- else {
567
- taskParts.push(restTokens[i]);
568
- }
569
- }
570
- const task = taskParts.join(" ").trim();
571
- if (!agentId || !task) {
572
- return {
573
- shouldContinue: false,
574
- reply: {
575
- text: "Usage: /subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]",
576
- },
577
- };
578
- }
579
- const commandTo = typeof params.command.to === "string" ? params.command.to.trim() : "";
580
- const originatingTo = typeof params.ctx.OriginatingTo === "string" ? params.ctx.OriginatingTo.trim() : "";
581
- const fallbackTo = typeof params.ctx.To === "string" ? params.ctx.To.trim() : "";
582
- // OriginatingTo reflects the active conversation target and is safer than
583
- // command.to for cross-surface command dispatch.
584
- const normalizedTo = originatingTo || commandTo || fallbackTo || undefined;
585
- const result = await spawnSubagentDirect({ task, agentId, model, thinking, cleanup: "keep", expectsCompletionMessage: true }, {
586
- agentSessionKey: requesterKey,
587
- agentChannel: params.ctx.OriginatingChannel ?? params.command.channel,
588
- agentAccountId: params.ctx.AccountId,
589
- agentTo: normalizedTo,
590
- agentThreadId: params.ctx.MessageThreadId,
591
- agentGroupId: params.sessionEntry?.groupId ?? null,
592
- agentGroupChannel: params.sessionEntry?.groupChannel ?? null,
593
- agentGroupSpace: params.sessionEntry?.space ?? null,
594
- });
595
- if (result.status === "accepted") {
596
- return {
597
- shouldContinue: false,
598
- reply: {
599
- text: `Spawned subagent ${agentId} (session ${result.childSessionKey}, run ${result.runId?.slice(0, 8)}).`,
600
- },
601
- };
602
- }
603
- return {
604
- shouldContinue: false,
605
- reply: { text: `Spawn failed: ${result.error ?? result.status}` },
606
- };
38
+ return stopWithText("⚠️ Missing session key.");
39
+ }
40
+ const ctx = {
41
+ params,
42
+ handledPrefix,
43
+ requesterKey,
44
+ runs: listSubagentRunsForRequester(requesterKey),
45
+ restTokens,
46
+ };
47
+ switch (action) {
48
+ case "help":
49
+ return handleSubagentsHelpAction();
50
+ case "agents":
51
+ return handleSubagentsAgentsAction(ctx);
52
+ case "focus":
53
+ return await handleSubagentsFocusAction(ctx);
54
+ case "unfocus":
55
+ return handleSubagentsUnfocusAction(ctx);
56
+ case "list":
57
+ return handleSubagentsListAction(ctx);
58
+ case "kill":
59
+ return await handleSubagentsKillAction(ctx);
60
+ case "info":
61
+ return handleSubagentsInfoAction(ctx);
62
+ case "log":
63
+ return await handleSubagentsLogAction(ctx);
64
+ case "send":
65
+ return await handleSubagentsSendAction(ctx, false);
66
+ case "steer":
67
+ return await handleSubagentsSendAction(ctx, true);
68
+ case "spawn":
69
+ return await handleSubagentsSpawnAction(ctx);
70
+ default:
71
+ return handleSubagentsHelpAction();
607
72
  }
608
- return { shouldContinue: false, reply: { text: buildSubagentsHelp() } };
609
73
  };