@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
@@ -43,6 +43,16 @@ const createUsageAccumulator = () => ({
43
43
  function createCompactionDiagId() {
44
44
  return `ovf-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
45
45
  }
46
+ // Defensive guard for the outer run loop across all retry branches.
47
+ const BASE_RUN_RETRY_ITERATIONS = 24;
48
+ const RUN_RETRY_ITERATIONS_PER_PROFILE = 8;
49
+ const MIN_RUN_RETRY_ITERATIONS = 32;
50
+ const MAX_RUN_RETRY_ITERATIONS = 160;
51
+ function resolveMaxRunRetryIterations(profileCandidateCount) {
52
+ const scaled = BASE_RUN_RETRY_ITERATIONS +
53
+ Math.max(1, profileCandidateCount) * RUN_RETRY_ITERATIONS_PER_PROFILE;
54
+ return Math.min(MAX_RUN_RETRY_ITERATIONS, Math.max(MIN_RUN_RETRY_ITERATIONS, scaled));
55
+ }
46
56
  const hasUsageValues = (usage) => !!usage &&
47
57
  [usage.input, usage.output, usage.cacheRead, usage.cacheWrite, usage.total].some((value) => typeof value === "number" && Number.isFinite(value) && value > 0);
48
58
  const mergeUsageIntoAccumulator = (target, usage) => {
@@ -89,6 +99,12 @@ const toNormalizedUsage = (usage) => {
89
99
  total: lastPromptTokens + usage.output || undefined,
90
100
  };
91
101
  };
102
+ function resolveActiveErrorContext(params) {
103
+ return {
104
+ provider: params.lastAssistant?.provider ?? params.provider,
105
+ model: params.lastAssistant?.model ?? params.model,
106
+ };
107
+ }
92
108
  export async function runEmbeddedPiAgent(params) {
93
109
  const sessionLane = resolveSessionLane(params.sessionKey?.trim() || params.sessionId);
94
110
  const globalLane = resolveGlobalLane(params.lane);
@@ -129,6 +145,7 @@ export async function runEmbeddedPiAgent(params) {
129
145
  // Legacy compatibility: before_agent_start is also checked for override
130
146
  // fields if present. New hook takes precedence when both are set.
131
147
  let modelResolveOverride;
148
+ let legacyBeforeAgentStartResult;
132
149
  const hookRunner = getGlobalHookRunner();
133
150
  const hookCtx = {
134
151
  agentId: workspaceResolution.agentId,
@@ -147,10 +164,11 @@ export async function runEmbeddedPiAgent(params) {
147
164
  }
148
165
  if (hookRunner?.hasHooks("before_agent_start")) {
149
166
  try {
150
- const legacyResult = await hookRunner.runBeforeAgentStart({ prompt: params.prompt }, hookCtx);
167
+ legacyBeforeAgentStartResult = await hookRunner.runBeforeAgentStart({ prompt: params.prompt }, hookCtx);
151
168
  modelResolveOverride = {
152
- providerOverride: modelResolveOverride?.providerOverride ?? legacyResult?.providerOverride,
153
- modelOverride: modelResolveOverride?.modelOverride ?? legacyResult?.modelOverride,
169
+ providerOverride: modelResolveOverride?.providerOverride ??
170
+ legacyBeforeAgentStartResult?.providerOverride,
171
+ modelOverride: modelResolveOverride?.modelOverride ?? legacyBeforeAgentStartResult?.modelOverride,
154
172
  };
155
173
  }
156
174
  catch (hookErr) {
@@ -167,7 +185,11 @@ export async function runEmbeddedPiAgent(params) {
167
185
  }
168
186
  const { model, error, authStorage, modelRegistry } = resolveModel(provider, modelId, agentDir, params.config);
169
187
  if (!model) {
170
- throw new Error(error ?? `Unknown model: ${provider}/${modelId}`);
188
+ throw new FailoverError(error ?? `Unknown model: ${provider}/${modelId}`, {
189
+ reason: "model_not_found",
190
+ provider,
191
+ model: modelId,
192
+ });
171
193
  }
172
194
  const ctxInfo = resolveContextWindowInfo({
173
195
  cfg: params.config,
@@ -335,13 +357,41 @@ export async function runEmbeddedPiAgent(params) {
335
357
  }
336
358
  }
337
359
  const MAX_OVERFLOW_COMPACTION_ATTEMPTS = 3;
360
+ const MAX_RUN_LOOP_ITERATIONS = resolveMaxRunRetryIterations(profileCandidates.length);
338
361
  let overflowCompactionAttempts = 0;
339
362
  let toolResultTruncationAttempted = false;
340
363
  const usageAccumulator = createUsageAccumulator();
341
364
  let lastRunPromptUsage;
342
365
  let autoCompactionCount = 0;
366
+ let runLoopIterations = 0;
343
367
  try {
344
368
  while (true) {
369
+ if (runLoopIterations >= MAX_RUN_LOOP_ITERATIONS) {
370
+ const message = `Exceeded retry limit after ${runLoopIterations} attempts ` +
371
+ `(max=${MAX_RUN_LOOP_ITERATIONS}).`;
372
+ log.error(`[run-retry-limit] sessionKey=${params.sessionKey ?? params.sessionId} ` +
373
+ `provider=${provider}/${modelId} attempts=${runLoopIterations} ` +
374
+ `maxAttempts=${MAX_RUN_LOOP_ITERATIONS}`);
375
+ return {
376
+ payloads: [
377
+ {
378
+ text: "Request failed after repeated internal retries. " +
379
+ "Please try again, or use /new to start a fresh session.",
380
+ isError: true,
381
+ },
382
+ ],
383
+ meta: {
384
+ durationMs: Date.now() - started,
385
+ agentMeta: {
386
+ sessionId: params.sessionId,
387
+ provider,
388
+ model: model.id,
389
+ },
390
+ error: { kind: "retry_limit", message },
391
+ },
392
+ };
393
+ }
394
+ runLoopIterations += 1;
345
395
  attemptedThinking.add(thinkLevel);
346
396
  await fs.mkdir(resolvedWorkspace, { recursive: true });
347
397
  const prompt = provider === "anthropic" ? scrubAnthropicRefusalMagic(params.prompt) : params.prompt;
@@ -376,6 +426,7 @@ export async function runEmbeddedPiAgent(params) {
376
426
  authStorage,
377
427
  modelRegistry,
378
428
  agentId: workspaceResolution.agentId,
429
+ legacyBeforeAgentStartResult,
379
430
  thinkLevel,
380
431
  verboseLevel: params.verboseLevel,
381
432
  reasoningLevel: params.reasoningLevel,
@@ -413,11 +464,17 @@ export async function runEmbeddedPiAgent(params) {
413
464
  const lastTurnTotal = lastAssistantUsage?.total ?? attemptUsage?.total;
414
465
  const attemptCompactionCount = Math.max(0, attempt.compactionCount ?? 0);
415
466
  autoCompactionCount += attemptCompactionCount;
467
+ const activeErrorContext = resolveActiveErrorContext({
468
+ lastAssistant,
469
+ provider,
470
+ model: modelId,
471
+ });
416
472
  const formattedAssistantErrorText = lastAssistant
417
473
  ? formatAssistantErrorText(lastAssistant, {
418
474
  cfg: params.config,
419
475
  sessionKey: params.sessionKey ?? params.sessionId,
420
- provider,
476
+ provider: activeErrorContext.provider,
477
+ model: activeErrorContext.model,
421
478
  })
422
479
  : undefined;
423
480
  const assistantErrorText = lastAssistant?.stopReason === "error"
@@ -533,8 +590,8 @@ export async function runEmbeddedPiAgent(params) {
533
590
  });
534
591
  if (truncResult.truncated) {
535
592
  log.info(`[context-overflow-recovery] Truncated ${truncResult.truncatedCount} tool result(s); retrying prompt`);
536
- // Session is now smaller; allow compaction retries again.
537
- overflowCompactionAttempts = 0;
593
+ // Do NOT reset overflowCompactionAttempts here the global cap must remain
594
+ // enforced across all iterations to prevent unbounded compaction cycles (OC-65).
538
595
  continue;
539
596
  }
540
597
  log.warn(`[context-overflow-recovery] Tool result truncation did not help: ${truncResult.reason ?? "unknown"}`);
@@ -725,7 +782,8 @@ export async function runEmbeddedPiAgent(params) {
725
782
  ? formatAssistantErrorText(lastAssistant, {
726
783
  cfg: params.config,
727
784
  sessionKey: params.sessionKey ?? params.sessionId,
728
- provider,
785
+ provider: activeErrorContext.provider,
786
+ model: activeErrorContext.model,
729
787
  })
730
788
  : undefined) ||
731
789
  lastAssistant?.errorMessage?.trim() ||
@@ -734,7 +792,7 @@ export async function runEmbeddedPiAgent(params) {
734
792
  : rateLimitFailure
735
793
  ? "LLM request rate limited."
736
794
  : billingFailure
737
- ? formatBillingErrorMessage(provider)
795
+ ? formatBillingErrorMessage(activeErrorContext.provider, activeErrorContext.model)
738
796
  : authFailure
739
797
  ? "LLM request unauthorized."
740
798
  : "LLM request failed.");
@@ -742,8 +800,8 @@ export async function runEmbeddedPiAgent(params) {
742
800
  (isTimeoutErrorMessage(message) ? 408 : undefined);
743
801
  throw new FailoverError(message, {
744
802
  reason: assistantFailoverReason ?? "unknown",
745
- provider,
746
- model: modelId,
803
+ provider: activeErrorContext.provider,
804
+ model: activeErrorContext.model,
747
805
  profileId: lastProfileId,
748
806
  status,
749
807
  });
@@ -776,7 +834,8 @@ export async function runEmbeddedPiAgent(params) {
776
834
  lastToolError: attempt.lastToolError,
777
835
  config: params.config,
778
836
  sessionKey: params.sessionKey ?? params.sessionId,
779
- provider,
837
+ provider: activeErrorContext.provider,
838
+ model: activeErrorContext.model,
780
839
  verboseLevel: params.verboseLevel,
781
840
  reasoningLevel: params.reasoningLevel,
782
841
  toolResultFormat: resolvedToolResultFormat,
@@ -1,4 +1,13 @@
1
1
  import { vi } from "vitest";
2
+ export const mockedGlobalHookRunner = {
3
+ hasHooks: vi.fn((_hookName) => false),
4
+ runBeforeAgentStart: vi.fn(async (_event, _ctx) => undefined),
5
+ runBeforePromptBuild: vi.fn(async (_event, _ctx) => undefined),
6
+ runBeforeModelResolve: vi.fn(async (_event, _ctx) => undefined),
7
+ };
8
+ vi.mock("../../plugins/hook-runner-global.js", () => ({
9
+ getGlobalHookRunner: vi.fn(() => mockedGlobalHookRunner),
10
+ }));
2
11
  vi.mock("../auth-profiles.js", () => ({
3
12
  isProfileInCooldown: vi.fn(() => false),
4
13
  markAuthProfileFailure: vi.fn(async () => { }),
@@ -78,7 +87,7 @@ vi.mock("../model-auth.js", () => ({
78
87
  resolveAuthProfileOrder: vi.fn(() => []),
79
88
  }));
80
89
  vi.mock("../models-config.js", () => ({
81
- ensurePoolbotModelsJson: vi.fn(async () => { }),
90
+ ensurePoolBotModelsJson: vi.fn(async () => { }),
82
91
  }));
83
92
  vi.mock("../context-window-guard.js", () => ({
84
93
  CONTEXT_WINDOW_HARD_MIN_TOKENS: 1000,
@@ -101,7 +110,7 @@ vi.mock("../../utils/message-channel.js", () => ({
101
110
  isMarkdownCapableMessageChannel: vi.fn(() => true),
102
111
  }));
103
112
  vi.mock("../agent-paths.js", () => ({
104
- resolvePoolbotAgentDir: vi.fn(() => "/tmp/agent-dir"),
113
+ resolvePoolBotAgentDir: vi.fn(() => "/tmp/agent-dir"),
105
114
  }));
106
115
  vi.mock("../defaults.js", () => ({
107
116
  DEFAULT_CONTEXT_TOKENS: 200000,
@@ -5,8 +5,7 @@ const SESSION_MANAGER_CACHE = new Map();
5
5
  const DEFAULT_SESSION_MANAGER_TTL_MS = 45_000; // 45 seconds
6
6
  function getSessionManagerTtl() {
7
7
  return resolveCacheTtlMs({
8
- envValue: process.env.POOLBOT_SESSION_MANAGER_CACHE_TTL_MS ||
9
- process.env.CLAWDBOT_SESSION_MANAGER_CACHE_TTL_MS,
8
+ envValue: process.env.POOLBOT_SESSION_MANAGER_CACHE_TTL_MS,
10
9
  defaultTtlMs: DEFAULT_SESSION_MANAGER_TTL_MS,
11
10
  });
12
11
  }
@@ -14,8 +13,9 @@ function isSessionManagerCacheEnabled() {
14
13
  return isCacheEnabled(getSessionManagerTtl());
15
14
  }
16
15
  export function trackSessionManagerAccess(sessionFile) {
17
- if (!isSessionManagerCacheEnabled())
16
+ if (!isSessionManagerCacheEnabled()) {
18
17
  return;
18
+ }
19
19
  const now = Date.now();
20
20
  SESSION_MANAGER_CACHE.set(sessionFile, {
21
21
  sessionFile,
@@ -23,20 +23,24 @@ export function trackSessionManagerAccess(sessionFile) {
23
23
  });
24
24
  }
25
25
  function isSessionManagerCached(sessionFile) {
26
- if (!isSessionManagerCacheEnabled())
26
+ if (!isSessionManagerCacheEnabled()) {
27
27
  return false;
28
+ }
28
29
  const entry = SESSION_MANAGER_CACHE.get(sessionFile);
29
- if (!entry)
30
+ if (!entry) {
30
31
  return false;
32
+ }
31
33
  const now = Date.now();
32
34
  const ttl = getSessionManagerTtl();
33
35
  return now - entry.loadedAt <= ttl;
34
36
  }
35
37
  export async function prewarmSessionFile(sessionFile) {
36
- if (!isSessionManagerCacheEnabled())
38
+ if (!isSessionManagerCacheEnabled()) {
37
39
  return;
38
- if (isSessionManagerCached(sessionFile))
40
+ }
41
+ if (isSessionManagerCached(sessionFile)) {
39
42
  return;
43
+ }
40
44
  try {
41
45
  // Read a small chunk to encourage OS page cache warmup.
42
46
  const handle = await fs.open(sessionFile, "r");
@@ -7,6 +7,8 @@ export function buildEmbeddedSystemPrompt(params) {
7
7
  reasoningLevel: params.reasoningLevel,
8
8
  extraSystemPrompt: params.extraSystemPrompt,
9
9
  ownerNumbers: params.ownerNumbers,
10
+ ownerDisplay: params.ownerDisplay,
11
+ ownerDisplaySecret: params.ownerDisplaySecret,
10
12
  reasoningTagHint: params.reasoningTagHint,
11
13
  heartbeatPrompt: params.heartbeatPrompt,
12
14
  skillsPrompt: params.skillsPrompt,
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Strip all `type: "thinking"` content blocks from assistant messages.
3
+ *
4
+ * If an assistant message becomes empty after stripping, it is replaced with
5
+ * a synthetic `{ type: "text", text: "" }` block to preserve turn structure
6
+ * (some providers require strict user/assistant alternation).
7
+ *
8
+ * Returns the original array reference when nothing was changed (callers can
9
+ * use reference equality to skip downstream work).
10
+ */
11
+ export function dropThinkingBlocks(messages) {
12
+ let touched = false;
13
+ const out = [];
14
+ for (const msg of messages) {
15
+ if (!msg || typeof msg !== "object" || msg.role !== "assistant") {
16
+ out.push(msg);
17
+ continue;
18
+ }
19
+ if (!Array.isArray(msg.content)) {
20
+ out.push(msg);
21
+ continue;
22
+ }
23
+ const nextContent = [];
24
+ let changed = false;
25
+ for (const block of msg.content) {
26
+ if (block && typeof block === "object" && block.type === "thinking") {
27
+ touched = true;
28
+ changed = true;
29
+ continue;
30
+ }
31
+ nextContent.push(block);
32
+ }
33
+ if (!changed) {
34
+ out.push(msg);
35
+ continue;
36
+ }
37
+ // Preserve the assistant turn even if all blocks were thinking-only.
38
+ const content = nextContent.length > 0 ? nextContent : [{ type: "text", text: "" }];
39
+ out.push({ ...msg, content });
40
+ }
41
+ return touched ? out : messages;
42
+ }
@@ -0,0 +1,19 @@
1
+ function addName(names, value) {
2
+ if (typeof value !== "string") {
3
+ return;
4
+ }
5
+ const trimmed = value.trim();
6
+ if (trimmed) {
7
+ names.add(trimmed);
8
+ }
9
+ }
10
+ export function collectAllowedToolNames(params) {
11
+ const names = new Set();
12
+ for (const tool of params.tools) {
13
+ addName(names, tool.name);
14
+ }
15
+ for (const tool of params.clientTools ?? []) {
16
+ addName(names, tool.function?.name);
17
+ }
18
+ return names;
19
+ }
@@ -1,20 +1,17 @@
1
1
  export function mapThinkingLevel(level) {
2
- // pi-agent-core supports "xhigh"; Poolbot enables it for specific models.
3
- if (!level)
2
+ // pi-agent-core supports "xhigh"; Pool Bot enables it for specific models.
3
+ if (!level) {
4
4
  return "off";
5
+ }
5
6
  return level;
6
7
  }
7
- export function resolveExecToolDefaults(config) {
8
- const tools = config?.tools;
9
- if (!tools?.exec)
10
- return undefined;
11
- return tools.exec;
12
- }
13
8
  export function describeUnknownError(error) {
14
- if (error instanceof Error)
9
+ if (error instanceof Error) {
15
10
  return error.message;
16
- if (typeof error === "string")
11
+ }
12
+ if (typeof error === "string") {
17
13
  return error;
14
+ }
18
15
  try {
19
16
  const serialized = JSON.stringify(error);
20
17
  return serialized ?? "Unknown error";
@@ -1,5 +1,8 @@
1
1
  import { emitAgentEvent } from "../infra/agent-events.js";
2
2
  import { createInlineCodeState } from "../markdown/code-spans.js";
3
+ import { formatAssistantErrorText } from "./pi-embedded-helpers.js";
4
+ import { isAssistantMessage } from "./pi-embedded-utils.js";
5
+ export { handleAutoCompactionEnd, handleAutoCompactionStart, } from "./pi-embedded-subscribe.handlers.compaction.js";
3
6
  export function handleAgentStart(ctx) {
4
7
  ctx.log.debug(`embedded run agent start: runId=${ctx.params.runId}`);
5
8
  emitAgentEvent({
@@ -15,65 +18,51 @@ export function handleAgentStart(ctx) {
15
18
  data: { phase: "start" },
16
19
  });
17
20
  }
18
- export function handleAutoCompactionStart(ctx) {
19
- ctx.state.compactionInFlight = true;
20
- ctx.ensureCompactionPromise();
21
- ctx.log.debug(`embedded run compaction start: runId=${ctx.params.runId}`);
22
- emitAgentEvent({
23
- runId: ctx.params.runId,
24
- stream: "compaction",
25
- data: { phase: "start" },
26
- });
27
- void ctx.params.onAgentEvent?.({
28
- stream: "compaction",
29
- data: { phase: "start" },
30
- });
31
- }
32
- export function handleAutoCompactionEnd(ctx, evt) {
33
- ctx.state.compactionInFlight = false;
34
- const willRetry = Boolean(evt.willRetry);
35
- if (willRetry) {
36
- ctx.noteCompactionRetry();
37
- ctx.resetForCompactionRetry();
38
- ctx.log.debug(`embedded run compaction retry: runId=${ctx.params.runId}`);
21
+ export function handleAgentEnd(ctx) {
22
+ const lastAssistant = ctx.state.lastAssistant;
23
+ const isError = isAssistantMessage(lastAssistant) && lastAssistant.stopReason === "error";
24
+ if (isError && lastAssistant) {
25
+ const friendlyError = formatAssistantErrorText(lastAssistant, {
26
+ cfg: ctx.params.config,
27
+ sessionKey: ctx.params.sessionKey,
28
+ provider: lastAssistant.provider,
29
+ model: lastAssistant.model,
30
+ });
31
+ const errorText = (friendlyError || lastAssistant.errorMessage || "LLM request failed.").trim();
32
+ ctx.log.warn(`embedded run agent end: runId=${ctx.params.runId} isError=true error=${errorText}`);
33
+ emitAgentEvent({
34
+ runId: ctx.params.runId,
35
+ stream: "lifecycle",
36
+ data: {
37
+ phase: "error",
38
+ error: errorText,
39
+ endedAt: Date.now(),
40
+ },
41
+ });
42
+ void ctx.params.onAgentEvent?.({
43
+ stream: "lifecycle",
44
+ data: {
45
+ phase: "error",
46
+ error: errorText,
47
+ },
48
+ });
39
49
  }
40
50
  else {
41
- ctx.maybeResolveCompactionWait();
42
- }
43
- emitAgentEvent({
44
- runId: ctx.params.runId,
45
- stream: "compaction",
46
- data: { phase: "end", willRetry },
47
- });
48
- void ctx.params.onAgentEvent?.({
49
- stream: "compaction",
50
- data: { phase: "end", willRetry },
51
- });
52
- }
53
- export function handleAgentEnd(ctx) {
54
- ctx.log.debug(`embedded run agent end: runId=${ctx.params.runId}`);
55
- emitAgentEvent({
56
- runId: ctx.params.runId,
57
- stream: "lifecycle",
58
- data: {
59
- phase: "end",
60
- endedAt: Date.now(),
61
- },
62
- });
63
- void ctx.params.onAgentEvent?.({
64
- stream: "lifecycle",
65
- data: { phase: "end" },
66
- });
67
- if (ctx.params.onBlockReply) {
68
- if (ctx.blockChunker?.hasBuffered()) {
69
- ctx.blockChunker.drain({ force: true, emit: ctx.emitBlockChunk });
70
- ctx.blockChunker.reset();
71
- }
72
- else if (ctx.state.blockBuffer.length > 0) {
73
- ctx.emitBlockChunk(ctx.state.blockBuffer);
74
- ctx.state.blockBuffer = "";
75
- }
51
+ ctx.log.debug(`embedded run agent end: runId=${ctx.params.runId} isError=${isError}`);
52
+ emitAgentEvent({
53
+ runId: ctx.params.runId,
54
+ stream: "lifecycle",
55
+ data: {
56
+ phase: "end",
57
+ endedAt: Date.now(),
58
+ },
59
+ });
60
+ void ctx.params.onAgentEvent?.({
61
+ stream: "lifecycle",
62
+ data: { phase: "end" },
63
+ });
76
64
  }
65
+ ctx.flushBlockReplyBuffer();
77
66
  ctx.state.blockState.thinking = false;
78
67
  ctx.state.blockState.final = false;
79
68
  ctx.state.blockState.inlineCode = createInlineCodeState();
@@ -2,7 +2,7 @@ import { emitAgentEvent } from "../infra/agent-events.js";
2
2
  import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
3
3
  import { normalizeTextForComparison } from "./pi-embedded-helpers.js";
4
4
  import { isMessagingTool, isMessagingToolSendAction } from "./pi-embedded-messaging.js";
5
- import { extractToolErrorMessage, extractToolResultMediaPaths, extractToolResultText, extractMessagingToolSend, isToolResultError, sanitizeToolResult, } from "./pi-embedded-subscribe.tools.js";
5
+ import { extractMessagingToolSend, extractToolErrorMessage, extractToolResultMediaPaths, extractToolResultText, filterToolResultMediaUrls, isToolResultError, sanitizeToolResult, } from "./pi-embedded-subscribe.tools.js";
6
6
  import { inferToolMetaFromArgs } from "./pi-embedded-utils.js";
7
7
  import { buildToolMutationState, isSameToolMutationAction } from "./tool-mutation.js";
8
8
  import { normalizeToolName } from "./tool-policy.js";
@@ -311,7 +311,7 @@ export async function handleToolExecutionEnd(ctx, evt) {
311
311
  // When shouldEmitToolOutput() is true, emitToolOutput already delivers media
312
312
  // via parseReplyDirectives (MEDIA: text extraction), so skip to avoid duplicates.
313
313
  if (ctx.params.onToolResult && !isToolError && !ctx.shouldEmitToolOutput()) {
314
- const mediaPaths = extractToolResultMediaPaths(result);
314
+ const mediaPaths = filterToolResultMediaUrls(toolName, extractToolResultMediaPaths(result));
315
315
  if (mediaPaths.length > 0) {
316
316
  try {
317
317
  void ctx.params.onToolResult({ mediaUrls: mediaPaths });
@@ -7,6 +7,7 @@ import { buildCodeSpanIndex, createInlineCodeState } from "../markdown/code-span
7
7
  import { EmbeddedBlockChunker } from "./pi-embedded-block-chunker.js";
8
8
  import { isMessagingToolDuplicateNormalized, normalizeTextForComparison, } from "./pi-embedded-helpers.js";
9
9
  import { createEmbeddedPiSessionEventHandler } from "./pi-embedded-subscribe.handlers.js";
10
+ import { filterToolResultMediaUrls } from "./pi-embedded-subscribe.tools.js";
10
11
  import { formatReasoningMessage, stripDowngradedToolCallText } from "./pi-embedded-utils.js";
11
12
  import { hasNonzeroUsage, normalizeUsage } from "./usage.js";
12
13
  const THINKING_TAG_SCAN_RE = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
@@ -44,6 +45,7 @@ export function subscribeEmbeddedPiSession(params) {
44
45
  assistantTextBaseline: 0,
45
46
  suppressBlockChunks: false, // Avoid late chunk inserts after final text merge.
46
47
  lastReasoningSent: undefined,
48
+ reasoningStreamOpen: false,
47
49
  compactionInFlight: false,
48
50
  pendingCompactionRetry: 0,
49
51
  compactionRetryResolve: undefined,
@@ -97,6 +99,7 @@ export function subscribeEmbeddedPiSession(params) {
97
99
  state.lastBlockReplyText = undefined;
98
100
  state.lastStreamedReasoning = undefined;
99
101
  state.lastReasoningSent = undefined;
102
+ state.reasoningStreamOpen = false;
100
103
  state.suppressBlockChunks = false;
101
104
  state.assistantMessageIndex += 1;
102
105
  state.lastAssistantTextMessageIndex = -1;
@@ -279,13 +282,14 @@ export function subscribeEmbeddedPiSession(params) {
279
282
  markdown: useMarkdown,
280
283
  });
281
284
  const { text: cleanedText, mediaUrls } = parseReplyDirectives(agg);
282
- if (!cleanedText && (!mediaUrls || mediaUrls.length === 0)) {
285
+ const filteredMediaUrls = filterToolResultMediaUrls(toolName, mediaUrls ?? []);
286
+ if (!cleanedText && filteredMediaUrls.length === 0) {
283
287
  return;
284
288
  }
285
289
  try {
286
290
  void params.onToolResult({
287
291
  text: cleanedText,
288
- mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
292
+ mediaUrls: filteredMediaUrls.length ? filteredMediaUrls : undefined,
289
293
  });
290
294
  }
291
295
  catch {
@@ -301,13 +305,14 @@ export function subscribeEmbeddedPiSession(params) {
301
305
  });
302
306
  const message = `${agg}\n${formatToolOutputBlock(output)}`;
303
307
  const { text: cleanedText, mediaUrls } = parseReplyDirectives(message);
304
- if (!cleanedText && (!mediaUrls || mediaUrls.length === 0)) {
308
+ const filteredMediaUrls = filterToolResultMediaUrls(toolName, mediaUrls ?? []);
309
+ if (!cleanedText && filteredMediaUrls.length === 0) {
305
310
  return;
306
311
  }
307
312
  try {
308
313
  void params.onToolResult({
309
314
  text: cleanedText,
310
- mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
315
+ mediaUrls: filteredMediaUrls.length ? filteredMediaUrls : undefined,
311
316
  });
312
317
  }
313
318
  catch {