@poolzin/pool-bot 2026.2.20 → 2026.2.22

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 (388) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/agents/api-key-rotation.js +47 -0
  3. package/dist/agents/apply-patch-update.js +19 -9
  4. package/dist/agents/apply-patch.js +72 -47
  5. package/dist/agents/bash-tools.exec.js +141 -559
  6. package/dist/agents/cli-backends.js +49 -6
  7. package/dist/agents/cli-runner/helpers.js +69 -152
  8. package/dist/agents/cli-runner.js +70 -19
  9. package/dist/agents/identity.js +20 -1
  10. package/dist/agents/image-sanitization.js +9 -0
  11. package/dist/agents/live-auth-keys.js +123 -26
  12. package/dist/agents/live-model-filter.js +13 -4
  13. package/dist/agents/model-auth.js +12 -0
  14. package/dist/agents/model-catalog.js +40 -9
  15. package/dist/agents/model-fallback.js +24 -0
  16. package/dist/agents/model-forward-compat.js +60 -23
  17. package/dist/agents/model-selection.js +134 -41
  18. package/dist/agents/pi-auth-json.js +2 -2
  19. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  20. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  21. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  22. package/dist/agents/pi-embedded-helpers.js +2 -2
  23. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  24. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  25. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  26. package/dist/agents/pi-embedded-runner/google.js +109 -19
  27. package/dist/agents/pi-embedded-runner/history.js +35 -17
  28. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -80
  29. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  30. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  31. package/dist/agents/pi-embedded-runner/run.js +193 -25
  32. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  33. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  34. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  35. package/dist/agents/pi-embedded-runner.js +1 -1
  36. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  37. package/dist/agents/pi-embedded-subscribe.js +37 -0
  38. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  39. package/dist/agents/pi-model-discovery.js +9 -2
  40. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  41. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  42. package/dist/agents/pi-tools.js +113 -94
  43. package/dist/agents/pi-tools.read.js +337 -38
  44. package/dist/agents/poolbot-tools.js +14 -5
  45. package/dist/agents/provider/config-loader.js +76 -0
  46. package/dist/agents/provider/index.js +15 -0
  47. package/dist/agents/provider/integration.js +136 -0
  48. package/dist/agents/provider/models-dev.js +129 -0
  49. package/dist/agents/provider/rate-limits.js +458 -0
  50. package/dist/agents/provider/request-monitor.js +449 -0
  51. package/dist/agents/provider/session-binding.js +376 -0
  52. package/dist/agents/provider/token-pool.js +541 -0
  53. package/dist/agents/sandbox/docker.js +10 -5
  54. package/dist/agents/sandbox/registry.js +96 -46
  55. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  56. package/dist/agents/sandbox-paths.js +43 -10
  57. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  58. package/dist/agents/session-tool-result-guard.js +39 -39
  59. package/dist/agents/session-transcript-repair.js +36 -33
  60. package/dist/agents/session-write-lock.js +62 -44
  61. package/dist/agents/skills/frontmatter.js +49 -88
  62. package/dist/agents/skills/workspace.js +335 -28
  63. package/dist/agents/subagent-announce.js +508 -174
  64. package/dist/agents/subagent-registry.js +45 -4
  65. package/dist/agents/subagent-spawn.js +16 -33
  66. package/dist/agents/system-prompt-report.js +27 -10
  67. package/dist/agents/system-prompt.js +26 -32
  68. package/dist/agents/tool-call-id.js +69 -17
  69. package/dist/agents/tool-display-common.js +1 -1
  70. package/dist/agents/tool-images.js +64 -31
  71. package/dist/agents/tools/canvas-tool.js +17 -11
  72. package/dist/agents/tools/common.js +37 -19
  73. package/dist/agents/tools/cron-tool.js +40 -38
  74. package/dist/agents/tools/gateway.js +70 -2
  75. package/dist/agents/tools/message-tool.js +181 -40
  76. package/dist/agents/tools/nodes-tool.js +128 -36
  77. package/dist/agents/tools/nodes-utils.js +12 -38
  78. package/dist/agents/tools/session-status-tool.js +24 -71
  79. package/dist/agents/tools/sessions-helpers.js +38 -210
  80. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  81. package/dist/agents/tools/telegram-actions.js +58 -7
  82. package/dist/agents/tools/web-fetch-utils.js +112 -7
  83. package/dist/agents/tools/web-fetch.js +279 -175
  84. package/dist/agents/tools/web-shared.js +71 -8
  85. package/dist/agents/usage.js +25 -16
  86. package/dist/auto-reply/commands-registry.data.js +85 -11
  87. package/dist/auto-reply/dispatch.js +40 -21
  88. package/dist/auto-reply/reply/abort.js +102 -33
  89. package/dist/auto-reply/reply/commands-core.js +82 -33
  90. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  91. package/dist/auto-reply/reply/commands-info.js +41 -12
  92. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  93. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  94. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  95. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  96. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  97. package/dist/auto-reply/reply/mentions.js +18 -11
  98. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  99. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  100. package/dist/auto-reply/reply/session.js +102 -21
  101. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  102. package/dist/auto-reply/status.js +73 -50
  103. package/dist/browser/extension-relay.js +3 -3
  104. package/dist/browser/http-auth.js +1 -1
  105. package/dist/browser/paths.js +2 -2
  106. package/dist/build-info.json +3 -3
  107. package/dist/channels/allowlist-match.js +20 -0
  108. package/dist/channels/allowlists/resolve-utils.js +65 -2
  109. package/dist/channels/chat-type.js +8 -4
  110. package/dist/channels/dock.js +127 -35
  111. package/dist/channels/draft-stream-loop.js +6 -2
  112. package/dist/channels/plugins/actions/telegram.js +42 -18
  113. package/dist/channels/plugins/allowlist-match.js +1 -1
  114. package/dist/channels/plugins/group-mentions.js +51 -41
  115. package/dist/channels/plugins/message-action-names.js +2 -0
  116. package/dist/channels/plugins/message-actions.js +24 -5
  117. package/dist/channels/plugins/normalize/discord.js +26 -4
  118. package/dist/channels/plugins/normalize/signal.js +35 -22
  119. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  120. package/dist/channels/plugins/outbound/imessage.js +15 -14
  121. package/dist/channels/registry.js +20 -7
  122. package/dist/cli/acp-cli.js +7 -5
  123. package/dist/cli/browser-cli-extension.js +25 -12
  124. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  125. package/dist/cli/browser-cli-state.js +101 -145
  126. package/dist/cli/command-options.js +28 -0
  127. package/dist/cli/completion-cli.js +6 -6
  128. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  129. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  130. package/dist/cli/cron-cli/shared.js +7 -1
  131. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  132. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  133. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  134. package/dist/cli/daemon-cli.js +1 -0
  135. package/dist/cli/devices-cli.js +33 -20
  136. package/dist/cli/gateway-cli/register.js +37 -105
  137. package/dist/cli/gateway-cli/run.js +49 -11
  138. package/dist/cli/nodes-camera.js +59 -4
  139. package/dist/cli/nodes-cli/register.camera.js +27 -24
  140. package/dist/cli/nodes-cli/rpc.js +21 -38
  141. package/dist/cli/qr-cli.js +2 -2
  142. package/dist/cli/skills-cli.format.js +2 -2
  143. package/dist/cli/update-cli/progress.js +2 -2
  144. package/dist/cli/update-cli/restart-helper.js +28 -7
  145. package/dist/cli/update-cli/shared.js +7 -7
  146. package/dist/cli/update-cli/status.js +1 -1
  147. package/dist/cli/update-cli/update-command.js +14 -8
  148. package/dist/cli/update-cli/wizard.js +2 -2
  149. package/dist/cli/update-cli.js +21 -1027
  150. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  151. package/dist/commands/channels/add-mutators.js +3 -35
  152. package/dist/commands/channels/add.js +39 -51
  153. package/dist/commands/config-validation.js +1 -1
  154. package/dist/commands/configure.gateway-auth.js +52 -15
  155. package/dist/commands/configure.gateway.js +84 -40
  156. package/dist/commands/doctor-completion.js +3 -3
  157. package/dist/commands/doctor-config-flow.js +536 -16
  158. package/dist/commands/doctor-gateway-services.js +103 -79
  159. package/dist/commands/doctor-memory-search.js +9 -9
  160. package/dist/commands/doctor-platform-notes.js +57 -30
  161. package/dist/commands/doctor-prompter.js +26 -15
  162. package/dist/commands/doctor-session-locks.js +1 -1
  163. package/dist/commands/doctor.js +21 -9
  164. package/dist/commands/model-picker.js +120 -95
  165. package/dist/commands/models/set.js +2 -21
  166. package/dist/commands/models/shared.js +65 -37
  167. package/dist/commands/onboard-helpers.js +81 -39
  168. package/dist/commands/openai-codex-oauth.js +1 -1
  169. package/dist/commands/sessions.js +52 -53
  170. package/dist/commands/status.summary.js +52 -34
  171. package/dist/commands/test-wizard-helpers.js +2 -2
  172. package/dist/config/defaults.js +79 -42
  173. package/dist/config/group-policy.js +50 -18
  174. package/dist/config/includes.js +37 -10
  175. package/dist/config/schema.help.js +5 -4
  176. package/dist/config/schema.hints.js +2 -2
  177. package/dist/config/schema.labels.js +1 -0
  178. package/dist/config/sessions/group.js +12 -11
  179. package/dist/config/sessions/paths.js +137 -11
  180. package/dist/config/sessions/store.js +185 -65
  181. package/dist/config/sessions/types.js +15 -1
  182. package/dist/config/sessions.js +1 -0
  183. package/dist/config/telegram-custom-commands.js +3 -2
  184. package/dist/config/types.js +2 -0
  185. package/dist/config/zod-schema.agent-defaults.js +6 -27
  186. package/dist/config/zod-schema.agent-runtime.js +171 -79
  187. package/dist/config/zod-schema.providers-core.js +138 -65
  188. package/dist/config/zod-schema.session.js +49 -22
  189. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  190. package/dist/cron/isolated-agent/run.js +224 -57
  191. package/dist/cron/normalize.js +48 -45
  192. package/dist/cron/run-log.js +14 -0
  193. package/dist/cron/service/jobs.js +190 -28
  194. package/dist/cron/service/normalize.js +29 -11
  195. package/dist/cron/service/store.js +30 -44
  196. package/dist/cron/service/timer.js +182 -96
  197. package/dist/cron/service.js +3 -0
  198. package/dist/cron/stagger.js +37 -0
  199. package/dist/daemon/inspect.js +132 -92
  200. package/dist/daemon/runtime-paths.js +25 -4
  201. package/dist/daemon/service-audit.js +47 -16
  202. package/dist/discord/accounts.js +23 -20
  203. package/dist/discord/monitor/agent-components.js +1115 -219
  204. package/dist/discord/monitor/allow-list.js +114 -34
  205. package/dist/discord/monitor/listeners.js +204 -97
  206. package/dist/discord/monitor/message-handler.js +21 -10
  207. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  208. package/dist/discord/monitor/message-handler.process.js +384 -123
  209. package/dist/discord/monitor/message-utils.js +86 -23
  210. package/dist/discord/monitor/native-command.js +77 -57
  211. package/dist/discord/monitor/provider.js +122 -117
  212. package/dist/discord/monitor/reply-context.js +20 -16
  213. package/dist/discord/monitor/reply-delivery.js +40 -8
  214. package/dist/discord/monitor/rest-fetch.js +22 -0
  215. package/dist/discord/monitor/threading.js +117 -24
  216. package/dist/discord/send.js +2 -1
  217. package/dist/discord/send.outbound.js +124 -11
  218. package/dist/discord/send.shared.js +112 -72
  219. package/dist/discord/voice-message.js +3 -3
  220. package/dist/gateway/auth.js +119 -44
  221. package/dist/gateway/call.js +76 -34
  222. package/dist/gateway/channel-health-monitor.js +57 -50
  223. package/dist/gateway/client.js +63 -29
  224. package/dist/gateway/control-ui-contract.js +1 -1
  225. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  226. package/dist/gateway/net.js +109 -1
  227. package/dist/gateway/protocol/index.js +5 -8
  228. package/dist/gateway/protocol/schema/agent.js +19 -1
  229. package/dist/gateway/protocol/schema/channels.js +21 -0
  230. package/dist/gateway/protocol/schema/cron.js +43 -30
  231. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  232. package/dist/gateway/protocol/schema/sessions.js +5 -1
  233. package/dist/gateway/protocol/schema.js +0 -1
  234. package/dist/gateway/server/presence-events.js +12 -0
  235. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  236. package/dist/gateway/server/ws-connection.js +58 -21
  237. package/dist/gateway/server-broadcast.js +18 -13
  238. package/dist/gateway/server-cron.js +177 -10
  239. package/dist/gateway/server-methods/agent-job.js +131 -38
  240. package/dist/gateway/server-methods/send.js +60 -14
  241. package/dist/gateway/server-methods/sessions.js +160 -96
  242. package/dist/gateway/server-methods/system.js +5 -7
  243. package/dist/gateway/server-methods-list.js +8 -0
  244. package/dist/gateway/server-methods.js +24 -8
  245. package/dist/gateway/server-node-events.js +278 -68
  246. package/dist/gateway/session-utils.fs.js +316 -75
  247. package/dist/gateway/session-utils.js +224 -70
  248. package/dist/gateway/sessions-patch.js +63 -20
  249. package/dist/gateway/test-temp-config.js +1 -1
  250. package/dist/gateway/tools-invoke-http.js +118 -70
  251. package/dist/gateway/ws-log.js +135 -107
  252. package/dist/hooks/frontmatter.js +36 -82
  253. package/dist/hooks/install.js +149 -139
  254. package/dist/hooks/internal-hooks.js +29 -4
  255. package/dist/hooks/plugin-hooks.js +2 -1
  256. package/dist/imessage/monitor/deliver.js +10 -4
  257. package/dist/imessage/monitor/monitor-provider.js +138 -375
  258. package/dist/imessage/monitor/runtime.js +4 -8
  259. package/dist/imessage/send.js +65 -19
  260. package/dist/infra/exec-approvals-allowlist.js +7 -0
  261. package/dist/infra/exec-approvals.js +35 -920
  262. package/dist/infra/exec-safe-bin-trust.js +64 -0
  263. package/dist/infra/heartbeat-runner.js +207 -134
  264. package/dist/infra/heartbeat-wake.js +183 -22
  265. package/dist/infra/install-source-utils.js +47 -0
  266. package/dist/infra/net/ssrf.js +170 -36
  267. package/dist/infra/outbound/deliver.js +224 -58
  268. package/dist/infra/outbound/message-action-spec.js +12 -5
  269. package/dist/infra/outbound/outbound-session.js +27 -25
  270. package/dist/infra/poolbot-root.js +32 -22
  271. package/dist/infra/ports.js +14 -11
  272. package/dist/infra/skills-remote.js +48 -37
  273. package/dist/infra/system-events.js +25 -11
  274. package/dist/infra/system-presence.js +26 -33
  275. package/dist/infra/tmp-poolbot-dir.js +81 -2
  276. package/dist/infra/wsl.js +37 -1
  277. package/dist/line/bot-message-context.js +163 -191
  278. package/dist/logging/subsystem.js +59 -22
  279. package/dist/markdown/ir.js +124 -50
  280. package/dist/media/store.js +1 -1
  281. package/dist/media-understanding/runner.entries.js +42 -25
  282. package/dist/media-understanding/runner.js +53 -488
  283. package/dist/memory/embeddings-gemini.js +53 -38
  284. package/dist/memory/manager-embedding-ops.js +48 -69
  285. package/dist/pairing/pairing-store.js +178 -119
  286. package/dist/plugin-sdk/index.js +34 -6
  287. package/dist/plugins/hooks.js +135 -14
  288. package/dist/plugins/install.js +190 -152
  289. package/dist/polls.js +11 -0
  290. package/dist/routing/resolve-route.js +190 -56
  291. package/dist/routing/session-key.js +38 -22
  292. package/dist/runtime.js +35 -9
  293. package/dist/security/audit-channel.js +1 -1
  294. package/dist/sessions/session-key-utils.js +29 -11
  295. package/dist/shared/frontmatter.js +5 -5
  296. package/dist/shared/node-list-types.js +1 -0
  297. package/dist/shared/string-normalization.js +15 -0
  298. package/dist/signal/monitor/event-handler.js +68 -36
  299. package/dist/signal/send.js +29 -37
  300. package/dist/slack/monitor/allow-list.js +10 -11
  301. package/dist/slack/monitor/commands.js +14 -3
  302. package/dist/slack/monitor/events/interactions.js +4 -4
  303. package/dist/slack/monitor/media.js +224 -16
  304. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  305. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  306. package/dist/slack/monitor/slash.js +357 -144
  307. package/dist/slack/streaming.js +77 -0
  308. package/dist/telegram/accounts.js +40 -13
  309. package/dist/telegram/allowed-updates.js +3 -0
  310. package/dist/telegram/bot/delivery.js +129 -66
  311. package/dist/telegram/bot/helpers.js +136 -122
  312. package/dist/telegram/bot-handlers.js +600 -339
  313. package/dist/telegram/bot-message-context.js +115 -73
  314. package/dist/telegram/bot-message-dispatch.js +235 -104
  315. package/dist/telegram/bot-native-command-menu.js +3 -1
  316. package/dist/telegram/bot-native-commands.js +213 -193
  317. package/dist/telegram/bot.js +24 -132
  318. package/dist/telegram/draft-stream.js +84 -75
  319. package/dist/telegram/format.js +150 -6
  320. package/dist/telegram/send.js +415 -255
  321. package/dist/telegram/targets.js +21 -2
  322. package/dist/telegram/update-offset-store.js +19 -3
  323. package/dist/terminal/restore.js +5 -2
  324. package/dist/test-utils/fetch-mock.js +5 -0
  325. package/dist/version.js +18 -5
  326. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  327. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  328. package/dist/web/inbound/media.js +34 -8
  329. package/dist/web/inbound/monitor.js +34 -17
  330. package/dist/web/inbound/send-api.js +18 -17
  331. package/dist/web/outbound.js +12 -5
  332. package/dist/wizard/clack-prompter.js +40 -7
  333. package/extensions/bluebubbles/package.json +1 -1
  334. package/extensions/copilot-proxy/package.json +1 -1
  335. package/extensions/diagnostics-otel/package.json +1 -1
  336. package/extensions/discord/package.json +1 -1
  337. package/extensions/feishu/package.json +1 -1
  338. package/extensions/google-antigravity-auth/package.json +1 -1
  339. package/extensions/google-gemini-cli-auth/package.json +1 -1
  340. package/extensions/googlechat/package.json +1 -1
  341. package/extensions/imessage/package.json +1 -1
  342. package/extensions/irc/package.json +1 -1
  343. package/extensions/line/package.json +1 -1
  344. package/extensions/llm-task/package.json +1 -1
  345. package/extensions/lobster/package.json +1 -1
  346. package/extensions/matrix/CHANGELOG.md +5 -0
  347. package/extensions/matrix/package.json +1 -1
  348. package/extensions/mattermost/package.json +1 -1
  349. package/extensions/memory-core/package.json +1 -1
  350. package/extensions/memory-lancedb/package.json +1 -1
  351. package/extensions/minimax-portal-auth/package.json +1 -1
  352. package/extensions/msteams/CHANGELOG.md +5 -0
  353. package/extensions/msteams/package.json +1 -1
  354. package/extensions/nextcloud-talk/package.json +1 -1
  355. package/extensions/nostr/CHANGELOG.md +5 -0
  356. package/extensions/nostr/package.json +1 -1
  357. package/extensions/open-prose/package.json +1 -1
  358. package/extensions/openai-codex-auth/package.json +1 -1
  359. package/extensions/signal/package.json +1 -1
  360. package/extensions/slack/package.json +1 -1
  361. package/extensions/telegram/package.json +1 -1
  362. package/extensions/tlon/package.json +1 -1
  363. package/extensions/twitch/CHANGELOG.md +5 -0
  364. package/extensions/twitch/package.json +1 -1
  365. package/extensions/voice-call/CHANGELOG.md +5 -0
  366. package/extensions/voice-call/package.json +1 -1
  367. package/extensions/whatsapp/package.json +1 -1
  368. package/extensions/zalo/CHANGELOG.md +5 -0
  369. package/extensions/zalo/package.json +1 -1
  370. package/extensions/zalouser/CHANGELOG.md +5 -0
  371. package/extensions/zalouser/package.json +1 -1
  372. package/package.json +1 -1
  373. package/skills/apple-reminders/SKILL.md +100 -49
  374. package/skills/coding-agent/SKILL.md +34 -28
  375. package/skills/github/SKILL.md +131 -16
  376. package/skills/imsg/SKILL.md +112 -15
  377. package/skills/openhue/SKILL.md +101 -19
  378. package/skills/plcode-controller/SKILL.md +156 -0
  379. package/skills/plcode-controller/assets/operator-prompts.md +65 -0
  380. package/skills/plcode-controller/references/command-cheatsheet.md +53 -0
  381. package/skills/plcode-controller/references/failure-handling.md +60 -0
  382. package/skills/plcode-controller/references/model-selection.md +57 -0
  383. package/skills/plcode-controller/references/plan-vs-build.md +52 -0
  384. package/skills/plcode-controller/references/question-handling.md +40 -0
  385. package/skills/plcode-controller/references/session-management.md +63 -0
  386. package/skills/plcode-controller/references/workflow.md +35 -0
  387. package/skills/tmux/SKILL.md +111 -79
  388. package/skills/weather/SKILL.md +88 -25
@@ -1,5 +1,23 @@
1
1
  import { formatSandboxToolPolicyBlockedMessage } from "../sandbox.js";
2
- export const BILLING_ERROR_USER_MESSAGE = "⚠️ API provider returned a billing error — your API key has run out of credits or has an insufficient balance. Check your provider's billing dashboard and top up or switch to a different API key.";
2
+ export function formatBillingErrorMessage(provider) {
3
+ const providerName = provider?.trim();
4
+ if (providerName) {
5
+ return `⚠️ ${providerName} returned a billing error — your API key has run out of credits or has an insufficient balance. Check your ${providerName} billing dashboard and top up or switch to a different API key.`;
6
+ }
7
+ return "⚠️ API provider returned a billing error — your API key has run out of credits or has an insufficient balance. Check your provider's billing dashboard and top up or switch to a different API key.";
8
+ }
9
+ export const BILLING_ERROR_USER_MESSAGE = formatBillingErrorMessage();
10
+ const RATE_LIMIT_ERROR_USER_MESSAGE = "⚠️ API rate limit reached. Please try again later.";
11
+ const OVERLOADED_ERROR_USER_MESSAGE = "The AI service is temporarily overloaded. Please try again in a moment.";
12
+ function formatRateLimitOrOverloadedErrorCopy(raw) {
13
+ if (isRateLimitErrorMessage(raw)) {
14
+ return RATE_LIMIT_ERROR_USER_MESSAGE;
15
+ }
16
+ if (isOverloadedErrorMessage(raw)) {
17
+ return OVERLOADED_ERROR_USER_MESSAGE;
18
+ }
19
+ return undefined;
20
+ }
3
21
  export function isContextOverflowError(errorMessage) {
4
22
  if (!errorMessage) {
5
23
  return false;
@@ -20,7 +38,8 @@ export function isContextOverflowError(errorMessage) {
20
38
  (lower.includes("413") && lower.includes("too large")));
21
39
  }
22
40
  const CONTEXT_WINDOW_TOO_SMALL_RE = /context window.*(too small|minimum is)/i;
23
- const CONTEXT_OVERFLOW_HINT_RE = /context.*overflow|context window.*(too (?:large|long)|exceed|over|limit|max(?:imum)?|requested|sent|tokens)|(?:prompt|request|input).*(too (?:large|long)|exceed|over|limit|max(?:imum)?)/i;
41
+ const CONTEXT_OVERFLOW_HINT_RE = /context.*overflow|context window.*(too (?:large|long)|exceed|over|limit|max(?:imum)?|requested|sent|tokens)|prompt.*(too (?:large|long)|exceed|over|limit|max(?:imum)?)|(?:request|input).*(?:context|window|length|token).*(too (?:large|long)|exceed|over|limit|max(?:imum)?)/i;
42
+ const RATE_LIMIT_HINT_RE = /rate limit|too many requests|requests per (?:minute|hour|day)|quota|throttl|429\b/i;
24
43
  export function isLikelyContextOverflowError(errorMessage) {
25
44
  if (!errorMessage) {
26
45
  return false;
@@ -28,9 +47,18 @@ export function isLikelyContextOverflowError(errorMessage) {
28
47
  if (CONTEXT_WINDOW_TOO_SMALL_RE.test(errorMessage)) {
29
48
  return false;
30
49
  }
50
+ // Rate limit errors can match the broad CONTEXT_OVERFLOW_HINT_RE pattern
51
+ // (e.g., "request reached organization TPD rate limit" matches request.*limit).
52
+ // Exclude them before checking context overflow heuristics.
53
+ if (isRateLimitErrorMessage(errorMessage)) {
54
+ return false;
55
+ }
31
56
  if (isContextOverflowError(errorMessage)) {
32
57
  return true;
33
58
  }
59
+ if (RATE_LIMIT_HINT_RE.test(errorMessage)) {
60
+ return false;
61
+ }
34
62
  return CONTEXT_OVERFLOW_HINT_RE.test(errorMessage);
35
63
  }
36
64
  export function isCompactionFailureError(errorMessage) {
@@ -45,15 +73,24 @@ export function isCompactionFailureError(errorMessage) {
45
73
  if (!hasCompactionTerm) {
46
74
  return false;
47
75
  }
48
- // For compaction failures, also accept "context overflow" without colon
49
- // since the error message itself describes a compaction/summarization failure
50
- return isContextOverflowError(errorMessage) || lower.includes("context overflow");
76
+ // Treat any likely overflow shape as a compaction failure when compaction terms are present.
77
+ // Providers often vary wording (e.g. "context window exceeded") across APIs.
78
+ if (isLikelyContextOverflowError(errorMessage)) {
79
+ return true;
80
+ }
81
+ // Keep explicit fallback for bare "context overflow" strings.
82
+ return lower.includes("context overflow");
51
83
  }
52
84
  const ERROR_PAYLOAD_PREFIX_RE = /^(?:error|api\s*error|apierror|openai\s*error|anthropic\s*error|gateway\s*error)[:\s-]+/i;
53
85
  const FINAL_TAG_RE = /<\s*\/?\s*final\s*>/gi;
54
86
  const ERROR_PREFIX_RE = /^(?:error|api\s*error|openai\s*error|anthropic\s*error|gateway\s*error|request failed|failed|exception)[:\s-]+/i;
55
87
  const CONTEXT_OVERFLOW_ERROR_HEAD_RE = /^(?:context overflow:|request_too_large\b|request size exceeds\b|request exceeds the maximum size\b|context length exceeded\b|maximum context length\b|prompt is too long\b|exceeds model context window\b)/i;
88
+ const BILLING_ERROR_HEAD_RE = /^(?:error[:\s-]+)?billing(?:\s+error)?(?:[:\s-]+|$)|^(?:error[:\s-]+)?(?:credit balance|insufficient credits?|payment required|http\s*402\b)/i;
56
89
  const HTTP_STATUS_PREFIX_RE = /^(?:http\s*)?(\d{3})\s+(.+)$/i;
90
+ const HTTP_STATUS_CODE_PREFIX_RE = /^(?:http\s*)?(\d{3})(?:\s+([\s\S]+))?$/i;
91
+ const HTML_ERROR_PREFIX_RE = /^\s*(?:<!doctype\s+html\b|<html\b)/i;
92
+ const CLOUDFLARE_HTML_ERROR_CODES = new Set([521, 522, 523, 524, 525, 526, 530]);
93
+ const TRANSIENT_HTTP_ERROR_CODES = new Set([500, 502, 503, 521, 522, 523, 524, 529]);
57
94
  const HTTP_ERROR_HINTS = [
58
95
  "error",
59
96
  "bad request",
@@ -71,6 +108,42 @@ const HTTP_ERROR_HINTS = [
71
108
  "too many requests",
72
109
  "permission",
73
110
  ];
111
+ function extractLeadingHttpStatus(raw) {
112
+ const match = raw.match(HTTP_STATUS_CODE_PREFIX_RE);
113
+ if (!match) {
114
+ return null;
115
+ }
116
+ const code = Number(match[1]);
117
+ if (!Number.isFinite(code)) {
118
+ return null;
119
+ }
120
+ return { code, rest: (match[2] ?? "").trim() };
121
+ }
122
+ export function isCloudflareOrHtmlErrorPage(raw) {
123
+ const trimmed = raw.trim();
124
+ if (!trimmed) {
125
+ return false;
126
+ }
127
+ const status = extractLeadingHttpStatus(trimmed);
128
+ if (!status || status.code < 500) {
129
+ return false;
130
+ }
131
+ if (CLOUDFLARE_HTML_ERROR_CODES.has(status.code)) {
132
+ return true;
133
+ }
134
+ return (status.code < 600 && HTML_ERROR_PREFIX_RE.test(status.rest) && /<\/html>/i.test(status.rest));
135
+ }
136
+ export function isTransientHttpError(raw) {
137
+ const trimmed = raw.trim();
138
+ if (!trimmed) {
139
+ return false;
140
+ }
141
+ const status = extractLeadingHttpStatus(trimmed);
142
+ if (!status) {
143
+ return false;
144
+ }
145
+ return TRANSIENT_HTTP_ERROR_CODES.has(status.code);
146
+ }
74
147
  function stripFinalTagsFromText(text) {
75
148
  if (!text) {
76
149
  return text;
@@ -103,6 +176,9 @@ function collapseConsecutiveDuplicateBlocks(text) {
103
176
  return result.join("\n\n");
104
177
  }
105
178
  function isLikelyHttpErrorText(raw) {
179
+ if (isCloudflareOrHtmlErrorPage(raw)) {
180
+ return true;
181
+ }
106
182
  const match = raw.match(HTTP_STATUS_PREFIX_RE);
107
183
  if (!match) {
108
184
  return false;
@@ -123,6 +199,15 @@ function shouldRewriteContextOverflowText(raw) {
123
199
  ERROR_PREFIX_RE.test(raw) ||
124
200
  CONTEXT_OVERFLOW_ERROR_HEAD_RE.test(raw));
125
201
  }
202
+ function shouldRewriteBillingText(raw) {
203
+ if (!isBillingErrorMessage(raw)) {
204
+ return false;
205
+ }
206
+ return (isRawApiErrorPayload(raw) ||
207
+ isLikelyHttpErrorText(raw) ||
208
+ ERROR_PREFIX_RE.test(raw) ||
209
+ BILLING_ERROR_HEAD_RE.test(raw));
210
+ }
126
211
  function isErrorPayloadObject(payload) {
127
212
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
128
213
  return false;
@@ -252,6 +337,10 @@ export function formatRawAssistantErrorForUi(raw) {
252
337
  if (!trimmed) {
253
338
  return "LLM request failed with an unknown error.";
254
339
  }
340
+ const leadingStatus = extractLeadingHttpStatus(trimmed);
341
+ if (leadingStatus && isCloudflareOrHtmlErrorPage(trimmed)) {
342
+ return `The AI service is temporarily unavailable (HTTP ${leadingStatus.code}). Please try again in a moment.`;
343
+ }
255
344
  const httpMatch = trimmed.match(HTTP_STATUS_PREFIX_RE);
256
345
  if (httpMatch) {
257
346
  const rest = httpMatch[2].trim();
@@ -307,11 +396,15 @@ export function formatAssistantErrorText(msg, opts) {
307
396
  if (invalidRequest?.[1]) {
308
397
  return `LLM request rejected: ${invalidRequest[1]}`;
309
398
  }
310
- if (isOverloadedErrorMessage(raw)) {
311
- return "The AI service is temporarily overloaded. Please try again in a moment.";
399
+ const transientCopy = formatRateLimitOrOverloadedErrorCopy(raw);
400
+ if (transientCopy) {
401
+ return transientCopy;
402
+ }
403
+ if (isTimeoutErrorMessage(raw)) {
404
+ return "LLM request timed out.";
312
405
  }
313
406
  if (isBillingErrorMessage(raw)) {
314
- return BILLING_ERROR_USER_MESSAGE;
407
+ return formatBillingErrorMessage(opts?.provider);
315
408
  }
316
409
  if (isLikelyHttpErrorText(raw) || isRawApiErrorPayload(raw)) {
317
410
  return formatRawAssistantErrorForUi(raw);
@@ -330,7 +423,7 @@ export function sanitizeUserFacingText(text, opts) {
330
423
  const stripped = stripFinalTagsFromText(text);
331
424
  const trimmed = stripped.trim();
332
425
  if (!trimmed) {
333
- return stripped;
426
+ return "";
334
427
  }
335
428
  // Only apply error-pattern rewrites when the caller knows this text is an error payload.
336
429
  // Otherwise we risk swallowing legitimate assistant text that merely *mentions* these errors.
@@ -350,8 +443,9 @@ export function sanitizeUserFacingText(text, opts) {
350
443
  return formatRawAssistantErrorForUi(trimmed);
351
444
  }
352
445
  if (ERROR_PREFIX_RE.test(trimmed)) {
353
- if (isOverloadedErrorMessage(trimmed) || isRateLimitErrorMessage(trimmed)) {
354
- return "The AI service is temporarily overloaded. Please try again in a moment.";
446
+ const prefixedCopy = formatRateLimitOrOverloadedErrorCopy(trimmed);
447
+ if (prefixedCopy) {
448
+ return prefixedCopy;
355
449
  }
356
450
  if (isTimeoutErrorMessage(trimmed)) {
357
451
  return "LLM request timed out.";
@@ -359,7 +453,16 @@ export function sanitizeUserFacingText(text, opts) {
359
453
  return formatRawAssistantErrorForUi(trimmed);
360
454
  }
361
455
  }
362
- return collapseConsecutiveDuplicateBlocks(stripped);
456
+ // Preserve legacy behavior for explicit billing-head text outside known
457
+ // error contexts (e.g., "billing: please upgrade your plan"), while
458
+ // keeping conversational billing mentions untouched.
459
+ if (shouldRewriteBillingText(trimmed)) {
460
+ return BILLING_ERROR_USER_MESSAGE;
461
+ }
462
+ // Strip leading blank lines (including whitespace-only lines) without clobbering indentation on
463
+ // the first content line (e.g. markdown/code blocks).
464
+ const withoutLeadingEmptyLines = stripped.replace(/^(?:[ \t]*\r?\n)+/, "");
465
+ return collapseConsecutiveDuplicateBlocks(withoutLeadingEmptyLines);
363
466
  }
364
467
  export function isRateLimitAssistantError(msg) {
365
468
  if (!msg || msg.stopReason !== "error") {
@@ -377,9 +480,18 @@ const ERROR_PATTERNS = {
377
480
  "usage limit",
378
481
  ],
379
482
  overloaded: [/overloaded_error|"type"\s*:\s*"overloaded_error"/i, "overloaded"],
380
- timeout: ["timeout", "timed out", "deadline exceeded", "context deadline exceeded"],
483
+ timeout: [
484
+ "timeout",
485
+ "timed out",
486
+ "deadline exceeded",
487
+ "context deadline exceeded",
488
+ /without sending (?:any )?chunks?/i,
489
+ /\bstop reason:\s*abort\b/i,
490
+ /\breason:\s*abort\b/i,
491
+ /\bunhandled stop reason:\s*abort\b/i,
492
+ ],
381
493
  billing: [
382
- /\b402\b/,
494
+ /["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment/i,
383
495
  "payment required",
384
496
  "insufficient credits",
385
497
  "credit balance",
@@ -434,7 +546,16 @@ export function isBillingErrorMessage(raw) {
434
546
  if (!value) {
435
547
  return false;
436
548
  }
437
- return matchesErrorPatterns(value, ERROR_PATTERNS.billing);
549
+ if (matchesErrorPatterns(value, ERROR_PATTERNS.billing)) {
550
+ return true;
551
+ }
552
+ if (!BILLING_ERROR_HEAD_RE.test(raw)) {
553
+ return false;
554
+ }
555
+ return (value.includes("upgrade") ||
556
+ value.includes("credits") ||
557
+ value.includes("payment") ||
558
+ value.includes("plan"));
438
559
  }
439
560
  export function isMissingToolCallInputError(raw) {
440
561
  if (!raw) {
@@ -510,6 +631,10 @@ export function classifyFailoverReason(raw) {
510
631
  if (isImageSizeError(raw)) {
511
632
  return null;
512
633
  }
634
+ if (isTransientHttpError(raw)) {
635
+ // Treat transient 5xx provider failures as retryable transport issues.
636
+ return "timeout";
637
+ }
513
638
  if (isRateLimitErrorMessage(raw)) {
514
639
  return "rate_limit";
515
640
  }
@@ -3,24 +3,32 @@ import { sanitizeContentBlocksImages } from "../tool-images.js";
3
3
  import { stripThoughtSignatures } from "./bootstrap.js";
4
4
  export function isEmptyAssistantMessageContent(message) {
5
5
  const content = message.content;
6
- if (content == null)
6
+ if (content == null) {
7
7
  return true;
8
- if (!Array.isArray(content))
8
+ }
9
+ if (!Array.isArray(content)) {
9
10
  return false;
11
+ }
10
12
  return content.every((block) => {
11
- if (!block || typeof block !== "object")
13
+ if (!block || typeof block !== "object") {
12
14
  return true;
15
+ }
13
16
  const rec = block;
14
- if (rec.type !== "text")
17
+ if (rec.type !== "text") {
15
18
  return false;
19
+ }
16
20
  return typeof rec.text !== "string" || rec.text.trim().length === 0;
17
21
  });
18
22
  }
19
23
  export async function sanitizeSessionMessagesImages(messages, label, options) {
20
24
  const sanitizeMode = options?.sanitizeMode ?? "full";
21
25
  const allowNonImageSanitization = sanitizeMode === "full";
26
+ const imageSanitization = {
27
+ maxDimensionPx: options?.maxDimensionPx,
28
+ maxBytes: options?.maxBytes,
29
+ };
22
30
  // We sanitize historical session messages because Anthropic can reject a request
23
- // if the transcript contains oversized base64 images (see MAX_IMAGE_DIMENSION_PX).
31
+ // if the transcript contains oversized base64 images (default max side 1200px).
24
32
  const sanitizedIds = allowNonImageSanitization && options?.sanitizeToolCallIds
25
33
  ? sanitizeToolCallIdsForCloudCodeAssist(messages, options.toolCallIdMode)
26
34
  : messages;
@@ -34,7 +42,7 @@ export async function sanitizeSessionMessagesImages(messages, label, options) {
34
42
  if (role === "toolResult") {
35
43
  const toolMsg = msg;
36
44
  const content = Array.isArray(toolMsg.content) ? toolMsg.content : [];
37
- const nextContent = (await sanitizeContentBlocksImages(content, label));
45
+ const nextContent = (await sanitizeContentBlocksImages(content, label, imageSanitization));
38
46
  out.push({ ...toolMsg, content: nextContent });
39
47
  continue;
40
48
  }
@@ -42,7 +50,7 @@ export async function sanitizeSessionMessagesImages(messages, label, options) {
42
50
  const userMsg = msg;
43
51
  const content = userMsg.content;
44
52
  if (Array.isArray(content)) {
45
- const nextContent = (await sanitizeContentBlocksImages(content, label));
53
+ const nextContent = (await sanitizeContentBlocksImages(content, label, imageSanitization));
46
54
  out.push({ ...userMsg, content: nextContent });
47
55
  continue;
48
56
  }
@@ -52,7 +60,7 @@ export async function sanitizeSessionMessagesImages(messages, label, options) {
52
60
  if (assistantMsg.stopReason === "error") {
53
61
  const content = assistantMsg.content;
54
62
  if (Array.isArray(content)) {
55
- const nextContent = (await sanitizeContentBlocksImages(content, label));
63
+ const nextContent = (await sanitizeContentBlocksImages(content, label, imageSanitization));
56
64
  out.push({ ...assistantMsg, content: nextContent });
57
65
  }
58
66
  else {
@@ -63,7 +71,7 @@ export async function sanitizeSessionMessagesImages(messages, label, options) {
63
71
  const content = assistantMsg.content;
64
72
  if (Array.isArray(content)) {
65
73
  if (!allowNonImageSanitization) {
66
- const nextContent = (await sanitizeContentBlocksImages(content, label));
74
+ const nextContent = (await sanitizeContentBlocksImages(content, label, imageSanitization));
67
75
  out.push({ ...assistantMsg, content: nextContent });
68
76
  continue;
69
77
  }
@@ -71,14 +79,16 @@ export async function sanitizeSessionMessagesImages(messages, label, options) {
71
79
  ? content // Keep signatures for Antigravity Claude
72
80
  : stripThoughtSignatures(content, options?.sanitizeThoughtSignatures); // Strip for Gemini
73
81
  const filteredContent = strippedContent.filter((block) => {
74
- if (!block || typeof block !== "object")
82
+ if (!block || typeof block !== "object") {
75
83
  return true;
84
+ }
76
85
  const rec = block;
77
- if (rec.type !== "text" || typeof rec.text !== "string")
86
+ if (rec.type !== "text" || typeof rec.text !== "string") {
78
87
  return true;
88
+ }
79
89
  return rec.text.trim().length > 0;
80
90
  });
81
- const finalContent = (await sanitizeContentBlocksImages(filteredContent, label));
91
+ const finalContent = (await sanitizeContentBlocksImages(filteredContent, label, imageSanitization));
82
92
  if (finalContent.length === 0) {
83
93
  continue;
84
94
  }
@@ -1,5 +1,5 @@
1
- export { buildBootstrapContextFiles, DEFAULT_BOOTSTRAP_MAX_CHARS, ensureSessionHeader, resolveBootstrapMaxChars, stripThoughtSignatures, } from "./pi-embedded-helpers/bootstrap.js";
2
- export { BILLING_ERROR_USER_MESSAGE, classifyFailoverReason, formatRawAssistantErrorForUi, formatAssistantErrorText, getApiErrorPayloadFingerprint, isAuthAssistantError, isAuthErrorMessage, isBillingAssistantError, parseApiErrorInfo, parseImageSizeError, sanitizeUserFacingText, isBillingErrorMessage, isCloudCodeAssistFormatError, isCompactionFailureError, isContextOverflowError, isLikelyContextOverflowError, isFailoverAssistantError, isFailoverErrorMessage, isImageDimensionErrorMessage, isImageSizeError, isOverloadedErrorMessage, isRawApiErrorPayload, isRateLimitAssistantError, isRateLimitErrorMessage, isTimeoutErrorMessage, parseImageDimensionError, } from "./pi-embedded-helpers/errors.js";
1
+ export { buildBootstrapContextFiles, DEFAULT_BOOTSTRAP_MAX_CHARS, DEFAULT_BOOTSTRAP_TOTAL_MAX_CHARS, ensureSessionHeader, resolveBootstrapMaxChars, resolveBootstrapTotalMaxChars, stripThoughtSignatures, } from "./pi-embedded-helpers/bootstrap.js";
2
+ export { BILLING_ERROR_USER_MESSAGE, formatBillingErrorMessage, classifyFailoverReason, formatRawAssistantErrorForUi, formatAssistantErrorText, getApiErrorPayloadFingerprint, isAuthAssistantError, isAuthErrorMessage, isBillingAssistantError, parseApiErrorInfo, sanitizeUserFacingText, isBillingErrorMessage, isCloudflareOrHtmlErrorPage, isCloudCodeAssistFormatError, isCompactionFailureError, isContextOverflowError, isLikelyContextOverflowError, isFailoverAssistantError, isFailoverErrorMessage, isImageDimensionErrorMessage, isImageSizeError, isOverloadedErrorMessage, isRawApiErrorPayload, isRateLimitAssistantError, isRateLimitErrorMessage, isTransientHttpError, isTimeoutErrorMessage, parseImageDimensionError, parseImageSizeError, } from "./pi-embedded-helpers/errors.js";
3
3
  export { isGoogleModelApi, sanitizeGoogleTurnOrdering } from "./pi-embedded-helpers/google.js";
4
4
  export { downgradeOpenAIReasoningBlocks } from "./pi-embedded-helpers/openai.js";
5
5
  export { isEmptyAssistantMessageContent, sanitizeSessionMessagesImages, } from "./pi-embedded-helpers/images.js";
@@ -1,9 +1,16 @@
1
- export function isAbortError(err) {
2
- if (!err || typeof err !== "object")
1
+ /**
2
+ * Runner abort check. Catches any abort-related message for embedded runners.
3
+ * More permissive than the core isAbortError since runners need to catch
4
+ * various abort signals from different sources.
5
+ */
6
+ export function isRunnerAbortError(err) {
7
+ if (!err || typeof err !== "object") {
3
8
  return false;
9
+ }
4
10
  const name = "name" in err ? String(err.name) : "";
5
- if (name === "AbortError")
11
+ if (name === "AbortError") {
6
12
  return true;
13
+ }
7
14
  const message = "message" in err && typeof err.message === "string" ? err.message.toLowerCase() : "";
8
15
  return message.includes("aborted");
9
16
  }