@poolzin/pool-bot 2026.2.21 → 2026.2.23

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 (378) 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-catalog.js +40 -9
  14. package/dist/agents/model-forward-compat.js +60 -23
  15. package/dist/agents/model-selection.js +134 -41
  16. package/dist/agents/pi-auth-json.js +2 -2
  17. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  18. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  19. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  20. package/dist/agents/pi-embedded-helpers.js +2 -2
  21. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  22. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  23. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  24. package/dist/agents/pi-embedded-runner/google.js +109 -19
  25. package/dist/agents/pi-embedded-runner/history.js +35 -17
  26. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
  27. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  28. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  29. package/dist/agents/pi-embedded-runner/run.js +193 -25
  30. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  31. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  32. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  33. package/dist/agents/pi-embedded-runner.js +1 -1
  34. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  35. package/dist/agents/pi-embedded-subscribe.js +37 -0
  36. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  37. package/dist/agents/pi-model-discovery.js +9 -2
  38. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  39. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  40. package/dist/agents/pi-tools.js +113 -94
  41. package/dist/agents/pi-tools.read.js +337 -38
  42. package/dist/agents/poolbot-tools.js +14 -5
  43. package/dist/agents/sandbox/docker.js +10 -5
  44. package/dist/agents/sandbox/registry.js +96 -46
  45. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  46. package/dist/agents/sandbox-paths.js +43 -10
  47. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  48. package/dist/agents/session-tool-result-guard.js +39 -39
  49. package/dist/agents/session-transcript-repair.js +36 -33
  50. package/dist/agents/session-write-lock.js +62 -44
  51. package/dist/agents/skills/frontmatter.js +49 -88
  52. package/dist/agents/skills/workspace.js +335 -28
  53. package/dist/agents/subagent-announce.js +508 -174
  54. package/dist/agents/subagent-registry.js +45 -4
  55. package/dist/agents/subagent-spawn.js +16 -33
  56. package/dist/agents/system-prompt-report.js +27 -10
  57. package/dist/agents/system-prompt.js +26 -32
  58. package/dist/agents/tool-call-id.js +69 -17
  59. package/dist/agents/tool-display-common.js +1 -1
  60. package/dist/agents/tool-images.js +64 -31
  61. package/dist/agents/tools/canvas-tool.js +17 -11
  62. package/dist/agents/tools/common.js +37 -19
  63. package/dist/agents/tools/cron-tool.js +40 -38
  64. package/dist/agents/tools/gateway.js +70 -2
  65. package/dist/agents/tools/message-tool.js +181 -40
  66. package/dist/agents/tools/nodes-tool.js +128 -36
  67. package/dist/agents/tools/nodes-utils.js +12 -38
  68. package/dist/agents/tools/session-status-tool.js +24 -71
  69. package/dist/agents/tools/sessions-helpers.js +38 -210
  70. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  71. package/dist/agents/tools/telegram-actions.js +58 -7
  72. package/dist/agents/tools/web-fetch-utils.js +112 -7
  73. package/dist/agents/tools/web-fetch.js +279 -175
  74. package/dist/agents/tools/web-shared.js +71 -8
  75. package/dist/agents/usage.js +25 -16
  76. package/dist/auto-reply/commands-registry.data.js +85 -11
  77. package/dist/auto-reply/dispatch.js +40 -21
  78. package/dist/auto-reply/reply/abort.js +102 -33
  79. package/dist/auto-reply/reply/commands-core.js +82 -33
  80. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  81. package/dist/auto-reply/reply/commands-info.js +41 -12
  82. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  83. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  84. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  85. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  86. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  87. package/dist/auto-reply/reply/mentions.js +18 -11
  88. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  89. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  90. package/dist/auto-reply/reply/session.js +102 -21
  91. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  92. package/dist/auto-reply/status.js +73 -50
  93. package/dist/browser/extension-relay.js +3 -3
  94. package/dist/browser/http-auth.js +1 -1
  95. package/dist/browser/paths.js +2 -2
  96. package/dist/build-info.json +3 -3
  97. package/dist/channels/allowlist-match.js +20 -0
  98. package/dist/channels/allowlists/resolve-utils.js +65 -2
  99. package/dist/channels/chat-type.js +8 -4
  100. package/dist/channels/dock.js +127 -35
  101. package/dist/channels/draft-stream-loop.js +6 -2
  102. package/dist/channels/plugins/actions/telegram.js +42 -18
  103. package/dist/channels/plugins/allowlist-match.js +1 -1
  104. package/dist/channels/plugins/group-mentions.js +51 -41
  105. package/dist/channels/plugins/message-action-names.js +2 -0
  106. package/dist/channels/plugins/message-actions.js +24 -5
  107. package/dist/channels/plugins/normalize/discord.js +26 -4
  108. package/dist/channels/plugins/normalize/signal.js +35 -22
  109. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  110. package/dist/channels/plugins/outbound/imessage.js +15 -14
  111. package/dist/channels/registry.js +20 -7
  112. package/dist/cli/acp-cli.js +7 -5
  113. package/dist/cli/browser-cli-extension.js +25 -12
  114. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  115. package/dist/cli/browser-cli-state.js +101 -145
  116. package/dist/cli/command-options.js +28 -0
  117. package/dist/cli/completion-cli.js +6 -6
  118. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  119. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  120. package/dist/cli/cron-cli/shared.js +7 -1
  121. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  122. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  123. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  124. package/dist/cli/daemon-cli.js +1 -0
  125. package/dist/cli/devices-cli.js +33 -20
  126. package/dist/cli/gateway-cli/register.js +37 -105
  127. package/dist/cli/gateway-cli/run.js +49 -11
  128. package/dist/cli/nodes-camera.js +59 -4
  129. package/dist/cli/nodes-cli/register.camera.js +27 -24
  130. package/dist/cli/nodes-cli/rpc.js +21 -38
  131. package/dist/cli/qr-cli.js +2 -2
  132. package/dist/cli/skills-cli.format.js +2 -2
  133. package/dist/cli/update-cli/progress.js +2 -2
  134. package/dist/cli/update-cli/restart-helper.js +28 -7
  135. package/dist/cli/update-cli/shared.js +7 -7
  136. package/dist/cli/update-cli/status.js +1 -1
  137. package/dist/cli/update-cli/update-command.js +14 -8
  138. package/dist/cli/update-cli/wizard.js +2 -2
  139. package/dist/cli/update-cli.js +21 -1027
  140. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  141. package/dist/commands/channels/add-mutators.js +3 -35
  142. package/dist/commands/channels/add.js +39 -51
  143. package/dist/commands/config-validation.js +1 -1
  144. package/dist/commands/configure.gateway-auth.js +52 -15
  145. package/dist/commands/configure.gateway.js +84 -40
  146. package/dist/commands/doctor-completion.js +3 -3
  147. package/dist/commands/doctor-config-flow.js +536 -16
  148. package/dist/commands/doctor-gateway-services.js +103 -79
  149. package/dist/commands/doctor-memory-search.js +9 -9
  150. package/dist/commands/doctor-platform-notes.js +57 -30
  151. package/dist/commands/doctor-prompter.js +26 -15
  152. package/dist/commands/doctor-session-locks.js +1 -1
  153. package/dist/commands/doctor.js +21 -9
  154. package/dist/commands/model-picker.js +120 -95
  155. package/dist/commands/models/set.js +2 -21
  156. package/dist/commands/models/shared.js +65 -37
  157. package/dist/commands/onboard-helpers.js +81 -39
  158. package/dist/commands/openai-codex-oauth.js +1 -1
  159. package/dist/commands/sessions.js +52 -53
  160. package/dist/commands/status.summary.js +52 -34
  161. package/dist/commands/test-wizard-helpers.js +2 -2
  162. package/dist/config/defaults.js +79 -42
  163. package/dist/config/group-policy.js +50 -18
  164. package/dist/config/includes.js +37 -10
  165. package/dist/config/schema.help.js +5 -4
  166. package/dist/config/schema.hints.js +2 -2
  167. package/dist/config/schema.labels.js +1 -0
  168. package/dist/config/sessions/group.js +12 -11
  169. package/dist/config/sessions/paths.js +137 -11
  170. package/dist/config/sessions/store.js +185 -65
  171. package/dist/config/sessions/types.js +15 -1
  172. package/dist/config/sessions.js +1 -0
  173. package/dist/config/telegram-custom-commands.js +3 -2
  174. package/dist/config/types.js +2 -0
  175. package/dist/config/zod-schema.agent-defaults.js +6 -27
  176. package/dist/config/zod-schema.agent-runtime.js +171 -79
  177. package/dist/config/zod-schema.providers-core.js +138 -65
  178. package/dist/config/zod-schema.session.js +49 -22
  179. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  180. package/dist/cron/isolated-agent/run.js +224 -57
  181. package/dist/cron/normalize.js +48 -45
  182. package/dist/cron/run-log.js +14 -0
  183. package/dist/cron/service/jobs.js +190 -28
  184. package/dist/cron/service/normalize.js +29 -11
  185. package/dist/cron/service/store.js +30 -44
  186. package/dist/cron/service/timer.js +182 -96
  187. package/dist/cron/service.js +3 -0
  188. package/dist/cron/stagger.js +37 -0
  189. package/dist/daemon/inspect.js +132 -92
  190. package/dist/daemon/runtime-paths.js +25 -4
  191. package/dist/daemon/service-audit.js +47 -16
  192. package/dist/discord/accounts.js +23 -20
  193. package/dist/discord/monitor/agent-components.js +1115 -219
  194. package/dist/discord/monitor/allow-list.js +114 -34
  195. package/dist/discord/monitor/listeners.js +204 -97
  196. package/dist/discord/monitor/message-handler.js +21 -10
  197. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  198. package/dist/discord/monitor/message-handler.process.js +384 -123
  199. package/dist/discord/monitor/message-utils.js +86 -23
  200. package/dist/discord/monitor/native-command.js +77 -57
  201. package/dist/discord/monitor/provider.js +122 -117
  202. package/dist/discord/monitor/reply-context.js +20 -16
  203. package/dist/discord/monitor/reply-delivery.js +40 -8
  204. package/dist/discord/monitor/rest-fetch.js +22 -0
  205. package/dist/discord/monitor/threading.js +117 -24
  206. package/dist/discord/send.js +2 -1
  207. package/dist/discord/send.outbound.js +124 -11
  208. package/dist/discord/send.shared.js +112 -72
  209. package/dist/discord/voice-message.js +3 -3
  210. package/dist/gateway/auth.js +119 -44
  211. package/dist/gateway/call.js +76 -34
  212. package/dist/gateway/channel-health-monitor.js +57 -50
  213. package/dist/gateway/client.js +63 -29
  214. package/dist/gateway/control-ui-contract.js +1 -1
  215. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  216. package/dist/gateway/net.js +109 -1
  217. package/dist/gateway/protocol/index.js +5 -8
  218. package/dist/gateway/protocol/schema/agent.js +19 -1
  219. package/dist/gateway/protocol/schema/channels.js +21 -0
  220. package/dist/gateway/protocol/schema/cron.js +43 -30
  221. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  222. package/dist/gateway/protocol/schema/sessions.js +5 -1
  223. package/dist/gateway/protocol/schema.js +0 -1
  224. package/dist/gateway/server/presence-events.js +12 -0
  225. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  226. package/dist/gateway/server/ws-connection.js +58 -21
  227. package/dist/gateway/server-broadcast.js +18 -13
  228. package/dist/gateway/server-cron.js +177 -10
  229. package/dist/gateway/server-methods/agent-job.js +131 -38
  230. package/dist/gateway/server-methods/send.js +60 -14
  231. package/dist/gateway/server-methods/sessions.js +160 -96
  232. package/dist/gateway/server-methods/system.js +5 -7
  233. package/dist/gateway/server-methods-list.js +8 -0
  234. package/dist/gateway/server-methods.js +24 -8
  235. package/dist/gateway/server-node-events.js +278 -68
  236. package/dist/gateway/session-utils.fs.js +316 -75
  237. package/dist/gateway/session-utils.js +224 -70
  238. package/dist/gateway/sessions-patch.js +63 -20
  239. package/dist/gateway/test-temp-config.js +1 -1
  240. package/dist/gateway/tools-invoke-http.js +118 -70
  241. package/dist/gateway/ws-log.js +135 -107
  242. package/dist/hooks/frontmatter.js +36 -82
  243. package/dist/hooks/install.js +149 -139
  244. package/dist/hooks/internal-hooks.js +29 -4
  245. package/dist/hooks/plugin-hooks.js +2 -1
  246. package/dist/imessage/monitor/deliver.js +10 -4
  247. package/dist/imessage/monitor/monitor-provider.js +138 -375
  248. package/dist/imessage/monitor/runtime.js +4 -8
  249. package/dist/imessage/send.js +65 -19
  250. package/dist/infra/exec-approvals-allowlist.js +7 -0
  251. package/dist/infra/exec-approvals.js +35 -920
  252. package/dist/infra/exec-safe-bin-trust.js +64 -0
  253. package/dist/infra/heartbeat-runner.js +207 -134
  254. package/dist/infra/heartbeat-wake.js +183 -22
  255. package/dist/infra/install-source-utils.js +47 -0
  256. package/dist/infra/net/ssrf.js +170 -36
  257. package/dist/infra/outbound/deliver.js +224 -58
  258. package/dist/infra/outbound/message-action-spec.js +12 -5
  259. package/dist/infra/outbound/outbound-session.js +27 -25
  260. package/dist/infra/poolbot-root.js +32 -22
  261. package/dist/infra/ports.js +14 -11
  262. package/dist/infra/skills-remote.js +48 -37
  263. package/dist/infra/system-events.js +25 -11
  264. package/dist/infra/system-presence.js +26 -33
  265. package/dist/infra/tmp-poolbot-dir.js +81 -2
  266. package/dist/infra/wsl.js +37 -1
  267. package/dist/line/bot-message-context.js +163 -191
  268. package/dist/logging/subsystem.js +59 -22
  269. package/dist/markdown/ir.js +124 -50
  270. package/dist/media/store.js +1 -1
  271. package/dist/media-understanding/runner.entries.js +42 -25
  272. package/dist/media-understanding/runner.js +53 -488
  273. package/dist/memory/embeddings-gemini.js +53 -38
  274. package/dist/memory/manager-embedding-ops.js +48 -69
  275. package/dist/pairing/pairing-store.js +178 -119
  276. package/dist/plugin-sdk/index.js +34 -6
  277. package/dist/plugins/hooks.js +135 -14
  278. package/dist/plugins/install.js +190 -152
  279. package/dist/polls.js +11 -0
  280. package/dist/routing/resolve-route.js +190 -56
  281. package/dist/routing/session-key.js +38 -22
  282. package/dist/runtime.js +35 -9
  283. package/dist/security/audit-channel.js +1 -1
  284. package/dist/sessions/session-key-utils.js +29 -11
  285. package/dist/shared/frontmatter.js +5 -5
  286. package/dist/shared/node-list-types.js +1 -0
  287. package/dist/shared/string-normalization.js +15 -0
  288. package/dist/signal/monitor/event-handler.js +68 -36
  289. package/dist/signal/send.js +29 -37
  290. package/dist/slack/monitor/allow-list.js +10 -11
  291. package/dist/slack/monitor/commands.js +14 -3
  292. package/dist/slack/monitor/events/interactions.js +4 -4
  293. package/dist/slack/monitor/media.js +224 -16
  294. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  295. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  296. package/dist/slack/monitor/slash.js +357 -144
  297. package/dist/slack/streaming.js +77 -0
  298. package/dist/telegram/accounts.js +40 -13
  299. package/dist/telegram/allowed-updates.js +3 -0
  300. package/dist/telegram/bot/delivery.js +129 -66
  301. package/dist/telegram/bot/helpers.js +136 -122
  302. package/dist/telegram/bot-handlers.js +600 -339
  303. package/dist/telegram/bot-message-context.js +115 -73
  304. package/dist/telegram/bot-message-dispatch.js +235 -104
  305. package/dist/telegram/bot-native-command-menu.js +3 -1
  306. package/dist/telegram/bot-native-commands.js +213 -193
  307. package/dist/telegram/bot.js +24 -132
  308. package/dist/telegram/draft-stream.js +84 -75
  309. package/dist/telegram/format.js +150 -6
  310. package/dist/telegram/send.js +415 -255
  311. package/dist/telegram/targets.js +21 -2
  312. package/dist/telegram/update-offset-store.js +19 -3
  313. package/dist/terminal/restore.js +5 -2
  314. package/dist/test-utils/fetch-mock.js +5 -0
  315. package/dist/version.js +18 -5
  316. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  317. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  318. package/dist/web/inbound/media.js +34 -8
  319. package/dist/web/inbound/monitor.js +34 -17
  320. package/dist/web/inbound/send-api.js +18 -17
  321. package/dist/web/outbound.js +12 -5
  322. package/dist/wizard/clack-prompter.js +40 -7
  323. package/extensions/bluebubbles/package.json +1 -1
  324. package/extensions/copilot-proxy/package.json +1 -1
  325. package/extensions/device-pair/index.ts +2 -2
  326. package/extensions/diagnostics-otel/package.json +1 -1
  327. package/extensions/discord/package.json +1 -1
  328. package/extensions/feishu/package.json +1 -1
  329. package/extensions/google-antigravity-auth/package.json +1 -1
  330. package/extensions/google-gemini-cli-auth/package.json +1 -1
  331. package/extensions/googlechat/package.json +1 -1
  332. package/extensions/imessage/package.json +1 -1
  333. package/extensions/irc/package.json +1 -1
  334. package/extensions/irc/src/accounts.ts +1 -1
  335. package/extensions/irc/src/onboarding.ts +4 -4
  336. package/extensions/line/package.json +1 -1
  337. package/extensions/llm-task/package.json +1 -1
  338. package/extensions/lobster/package.json +1 -1
  339. package/extensions/matrix/CHANGELOG.md +10 -0
  340. package/extensions/matrix/package.json +1 -1
  341. package/extensions/mattermost/package.json +1 -1
  342. package/extensions/memory-core/package.json +1 -1
  343. package/extensions/memory-lancedb/package.json +1 -1
  344. package/extensions/minimax-portal-auth/package.json +1 -1
  345. package/extensions/msteams/CHANGELOG.md +10 -0
  346. package/extensions/msteams/package.json +1 -1
  347. package/extensions/nextcloud-talk/package.json +1 -1
  348. package/extensions/nostr/CHANGELOG.md +10 -0
  349. package/extensions/nostr/package.json +1 -1
  350. package/extensions/open-prose/package.json +1 -1
  351. package/extensions/openai-codex-auth/package.json +1 -1
  352. package/extensions/signal/package.json +1 -1
  353. package/extensions/slack/package.json +1 -1
  354. package/extensions/telegram/package.json +1 -1
  355. package/extensions/tlon/package.json +1 -1
  356. package/extensions/twitch/CHANGELOG.md +10 -0
  357. package/extensions/twitch/package.json +1 -1
  358. package/extensions/voice-call/CHANGELOG.md +10 -0
  359. package/extensions/voice-call/package.json +1 -1
  360. package/extensions/whatsapp/package.json +1 -1
  361. package/extensions/zalo/CHANGELOG.md +10 -0
  362. package/extensions/zalo/package.json +1 -1
  363. package/extensions/zalouser/CHANGELOG.md +10 -0
  364. package/extensions/zalouser/package.json +1 -1
  365. package/package.json +1 -1
  366. package/skills/apple-reminders/SKILL.md +100 -49
  367. package/skills/coding-agent/SKILL.md +34 -28
  368. package/skills/github/SKILL.md +131 -16
  369. package/skills/imsg/SKILL.md +112 -15
  370. package/skills/openhue/SKILL.md +101 -19
  371. package/skills/tmux/SKILL.md +111 -79
  372. package/skills/weather/SKILL.md +88 -25
  373. package/dist/agents/openclaw-tools.js +0 -151
  374. package/dist/agents/tool-security.js +0 -96
  375. package/dist/gateway/url-validation.js +0 -94
  376. package/dist/infra/openclaw-root.js +0 -109
  377. package/dist/infra/tmp-openclaw-dir.js +0 -81
  378. package/dist/media/path-sanitization.js +0 -78
@@ -1,7 +1,40 @@
1
+ import { normalizeProviderId } from "./model-selection.js";
1
2
  const KEY_SPLIT_RE = /[\s,;]+/g;
3
+ const GOOGLE_LIVE_SINGLE_KEY = "POOLBOT_LIVE_GEMINI_KEY";
4
+ const PROVIDER_PREFIX_OVERRIDES = {
5
+ google: "GEMINI",
6
+ "google-vertex": "GEMINI",
7
+ };
8
+ const PROVIDER_API_KEY_CONFIG = {
9
+ anthropic: {
10
+ liveSingle: "POOLBOT_LIVE_ANTHROPIC_KEY",
11
+ listVar: "POOLBOT_LIVE_ANTHROPIC_KEYS",
12
+ primaryVar: "ANTHROPIC_API_KEY",
13
+ prefixedVar: "ANTHROPIC_API_KEY_",
14
+ },
15
+ google: {
16
+ liveSingle: GOOGLE_LIVE_SINGLE_KEY,
17
+ listVar: "GEMINI_API_KEYS",
18
+ primaryVar: "GEMINI_API_KEY",
19
+ prefixedVar: "GEMINI_API_KEY_",
20
+ },
21
+ "google-vertex": {
22
+ liveSingle: GOOGLE_LIVE_SINGLE_KEY,
23
+ listVar: "GEMINI_API_KEYS",
24
+ primaryVar: "GEMINI_API_KEY",
25
+ prefixedVar: "GEMINI_API_KEY_",
26
+ },
27
+ openai: {
28
+ liveSingle: "POOLBOT_LIVE_OPENAI_KEY",
29
+ listVar: "OPENAI_API_KEYS",
30
+ primaryVar: "OPENAI_API_KEY",
31
+ prefixedVar: "OPENAI_API_KEY_",
32
+ },
33
+ };
2
34
  function parseKeyList(raw) {
3
- if (!raw)
35
+ if (!raw) {
4
36
  return [];
37
+ }
5
38
  return raw
6
39
  .split(KEY_SPLIT_RE)
7
40
  .map((value) => value.trim())
@@ -10,62 +43,126 @@ function parseKeyList(raw) {
10
43
  function collectEnvPrefixedKeys(prefix) {
11
44
  const keys = [];
12
45
  for (const [name, value] of Object.entries(process.env)) {
13
- if (!name.startsWith(prefix))
46
+ if (!name.startsWith(prefix)) {
14
47
  continue;
48
+ }
15
49
  const trimmed = value?.trim();
16
- if (!trimmed)
50
+ if (!trimmed) {
17
51
  continue;
52
+ }
18
53
  keys.push(trimmed);
19
54
  }
20
55
  return keys;
21
56
  }
22
- export function collectAnthropicApiKeys() {
23
- const forcedSingle = process.env.POOLBOT_LIVE_ANTHROPIC_KEY?.trim() ||
24
- process.env.CLAWDBOT_LIVE_ANTHROPIC_KEY?.trim();
25
- if (forcedSingle)
57
+ function resolveProviderApiKeyConfig(provider) {
58
+ const normalized = normalizeProviderId(provider);
59
+ const custom = PROVIDER_API_KEY_CONFIG[normalized];
60
+ const base = PROVIDER_PREFIX_OVERRIDES[normalized] ?? normalized.toUpperCase().replace(/-/g, "_");
61
+ const liveSingle = custom?.liveSingle ?? `POOLBOT_LIVE_${base}_KEY`;
62
+ const listVar = custom?.listVar ?? `${base}_API_KEYS`;
63
+ const primaryVar = custom?.primaryVar ?? `${base}_API_KEY`;
64
+ const prefixedVar = custom?.prefixedVar ?? `${base}_API_KEY_`;
65
+ if (normalized === "google" || normalized === "google-vertex") {
66
+ return {
67
+ liveSingle,
68
+ listVar,
69
+ primaryVar,
70
+ prefixedVar,
71
+ fallbackVars: ["GOOGLE_API_KEY"],
72
+ };
73
+ }
74
+ return {
75
+ liveSingle,
76
+ listVar,
77
+ primaryVar,
78
+ prefixedVar,
79
+ fallbackVars: [],
80
+ };
81
+ }
82
+ export function collectProviderApiKeys(provider) {
83
+ const config = resolveProviderApiKeyConfig(provider);
84
+ const forcedSingle = config.liveSingle ? process.env[config.liveSingle]?.trim() : undefined;
85
+ if (forcedSingle) {
26
86
  return [forcedSingle];
27
- const fromList = parseKeyList(process.env.POOLBOT_LIVE_ANTHROPIC_KEYS || process.env.CLAWDBOT_LIVE_ANTHROPIC_KEYS);
28
- const fromEnv = collectEnvPrefixedKeys("ANTHROPIC_API_KEY");
29
- const primary = process.env.ANTHROPIC_API_KEY?.trim();
87
+ }
88
+ const fromList = parseKeyList(config.listVar ? process.env[config.listVar] : undefined);
89
+ const primary = config.primaryVar ? process.env[config.primaryVar]?.trim() : undefined;
90
+ const fromPrefixed = config.prefixedVar ? collectEnvPrefixedKeys(config.prefixedVar) : [];
91
+ const fallback = config.fallbackVars
92
+ .map((envVar) => process.env[envVar]?.trim())
93
+ .filter(Boolean);
30
94
  const seen = new Set();
31
95
  const add = (value) => {
32
- if (!value)
96
+ if (!value) {
33
97
  return;
34
- if (seen.has(value))
98
+ }
99
+ if (seen.has(value)) {
35
100
  return;
101
+ }
36
102
  seen.add(value);
37
103
  };
38
- for (const value of fromList)
104
+ for (const value of fromList) {
105
+ add(value);
106
+ }
107
+ add(primary);
108
+ for (const value of fromPrefixed) {
39
109
  add(value);
40
- if (primary)
41
- add(primary);
42
- for (const value of fromEnv)
110
+ }
111
+ for (const value of fallback) {
43
112
  add(value);
113
+ }
44
114
  return Array.from(seen);
45
115
  }
46
- export function isAnthropicRateLimitError(message) {
116
+ export function collectAnthropicApiKeys() {
117
+ return collectProviderApiKeys("anthropic");
118
+ }
119
+ export function collectGeminiApiKeys() {
120
+ return collectProviderApiKeys("google");
121
+ }
122
+ export function isApiKeyRateLimitError(message) {
47
123
  const lower = message.toLowerCase();
48
- if (lower.includes("rate_limit"))
124
+ if (lower.includes("rate_limit")) {
125
+ return true;
126
+ }
127
+ if (lower.includes("rate limit")) {
128
+ return true;
129
+ }
130
+ if (lower.includes("429")) {
131
+ return true;
132
+ }
133
+ if (lower.includes("quota exceeded") || lower.includes("quota_exceeded")) {
49
134
  return true;
50
- if (lower.includes("rate limit"))
135
+ }
136
+ if (lower.includes("resource exhausted") || lower.includes("resource_exhausted")) {
51
137
  return true;
52
- if (lower.includes("429"))
138
+ }
139
+ if (lower.includes("too many requests")) {
53
140
  return true;
141
+ }
54
142
  return false;
55
143
  }
144
+ export function isAnthropicRateLimitError(message) {
145
+ return isApiKeyRateLimitError(message);
146
+ }
56
147
  export function isAnthropicBillingError(message) {
57
148
  const lower = message.toLowerCase();
58
- if (lower.includes("credit balance"))
149
+ if (lower.includes("credit balance")) {
59
150
  return true;
60
- if (lower.includes("insufficient credit"))
151
+ }
152
+ if (lower.includes("insufficient credit")) {
61
153
  return true;
62
- if (lower.includes("insufficient credits"))
154
+ }
155
+ if (lower.includes("insufficient credits")) {
63
156
  return true;
64
- if (lower.includes("payment required"))
157
+ }
158
+ if (lower.includes("payment required")) {
65
159
  return true;
66
- if (lower.includes("billing") && lower.includes("disabled"))
160
+ }
161
+ if (lower.includes("billing") && lower.includes("disabled")) {
67
162
  return true;
68
- if (lower.includes("402"))
163
+ }
164
+ if (/["']?(?: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\spayment/i.test(lower)) {
69
165
  return true;
166
+ }
70
167
  return false;
71
168
  }
@@ -1,15 +1,23 @@
1
- const ANTHROPIC_PREFIXES = ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5"];
1
+ const ANTHROPIC_PREFIXES = [
2
+ "claude-opus-4-6",
3
+ "claude-sonnet-4-6",
4
+ "claude-opus-4-5",
5
+ "claude-sonnet-4-5",
6
+ "claude-haiku-4-5",
7
+ ];
2
8
  const OPENAI_MODELS = ["gpt-5.2", "gpt-5.0"];
3
9
  const CODEX_MODELS = [
4
10
  "gpt-5.2",
5
11
  "gpt-5.2-codex",
12
+ "gpt-5.3-codex",
13
+ "gpt-5.3-codex-spark",
6
14
  "gpt-5.1-codex",
7
15
  "gpt-5.1-codex-mini",
8
16
  "gpt-5.1-codex-max",
9
17
  ];
10
18
  const GOOGLE_PREFIXES = ["gemini-3"];
11
- const ZAI_PREFIXES = ["glm-4.7"];
12
- const MINIMAX_PREFIXES = ["minimax-m2.1"];
19
+ const ZAI_PREFIXES = ["glm-5", "glm-4.7", "glm-4.7-flash", "glm-4.7-flashx"];
20
+ const MINIMAX_PREFIXES = ["minimax-m2.1", "minimax-m2.5"];
13
21
  const XAI_PREFIXES = ["grok-4"];
14
22
  function matchesPrefix(id, prefixes) {
15
23
  return prefixes.some((prefix) => id.startsWith(prefix));
@@ -23,8 +31,9 @@ function matchesAny(id, values) {
23
31
  export function isModernModelRef(ref) {
24
32
  const provider = ref.provider?.trim().toLowerCase() ?? "";
25
33
  const id = ref.id?.trim().toLowerCase() ?? "";
26
- if (!provider || !id)
34
+ if (!provider || !id) {
27
35
  return false;
36
+ }
28
37
  if (provider === "anthropic") {
29
38
  return matchesPrefix(id, ANTHROPIC_PREFIXES);
30
39
  }
@@ -5,6 +5,25 @@ let modelCatalogPromise = null;
5
5
  let hasLoggedModelCatalogError = false;
6
6
  const defaultImportPiSdk = () => import("./pi-model-discovery.js");
7
7
  let importPiSdk = defaultImportPiSdk;
8
+ const CODEX_PROVIDER = "openai-codex";
9
+ const OPENAI_CODEX_GPT53_MODEL_ID = "gpt-5.3-codex";
10
+ const OPENAI_CODEX_GPT53_SPARK_MODEL_ID = "gpt-5.3-codex-spark";
11
+ function applyOpenAICodexSparkFallback(models) {
12
+ const hasSpark = models.some((entry) => entry.provider === CODEX_PROVIDER &&
13
+ entry.id.toLowerCase() === OPENAI_CODEX_GPT53_SPARK_MODEL_ID);
14
+ if (hasSpark) {
15
+ return;
16
+ }
17
+ const baseModel = models.find((entry) => entry.provider === CODEX_PROVIDER && entry.id.toLowerCase() === OPENAI_CODEX_GPT53_MODEL_ID);
18
+ if (!baseModel) {
19
+ return;
20
+ }
21
+ models.push({
22
+ ...baseModel,
23
+ id: OPENAI_CODEX_GPT53_SPARK_MODEL_ID,
24
+ name: OPENAI_CODEX_GPT53_SPARK_MODEL_ID,
25
+ });
26
+ }
8
27
  export function resetModelCatalogCacheForTest() {
9
28
  modelCatalogPromise = null;
10
29
  hasLoggedModelCatalogError = false;
@@ -14,49 +33,61 @@ export function resetModelCatalogCacheForTest() {
14
33
  export function __setModelCatalogImportForTest(loader) {
15
34
  importPiSdk = loader ?? defaultImportPiSdk;
16
35
  }
36
+ function createAuthStorage(AuthStorageLike, path) {
37
+ const withFactory = AuthStorageLike;
38
+ if (typeof withFactory.create === "function") {
39
+ return withFactory.create(path);
40
+ }
41
+ return new AuthStorageLike(path);
42
+ }
17
43
  export async function loadModelCatalog(params) {
18
44
  if (params?.useCache === false) {
19
45
  modelCatalogPromise = null;
20
46
  }
21
- if (modelCatalogPromise)
47
+ if (modelCatalogPromise) {
22
48
  return modelCatalogPromise;
49
+ }
23
50
  modelCatalogPromise = (async () => {
24
51
  const models = [];
25
52
  const sortModels = (entries) => entries.sort((a, b) => {
26
53
  const p = a.provider.localeCompare(b.provider);
27
- if (p !== 0)
54
+ if (p !== 0) {
28
55
  return p;
56
+ }
29
57
  return a.name.localeCompare(b.name);
30
58
  });
31
59
  try {
32
60
  const cfg = params?.config ?? loadConfig();
33
61
  await ensurePoolbotModelsJson(cfg);
62
+ await (await import("./pi-auth-json.js")).ensurePiAuthJsonFromAuthProfiles(resolvePoolbotAgentDir());
34
63
  // IMPORTANT: keep the dynamic import *inside* the try/catch.
35
64
  // If this fails once (e.g. during a pnpm install that temporarily swaps node_modules),
36
65
  // we must not poison the cache with a rejected promise (otherwise all channel handlers
37
66
  // will keep failing until restart).
38
67
  const piSdk = await importPiSdk();
39
68
  const agentDir = resolvePoolbotAgentDir();
40
- const authStorage = piSdk.discoverAuthStorage(agentDir);
41
- const registry = piSdk.discoverModels(authStorage, agentDir);
69
+ const { join } = await import("node:path");
70
+ const authStorage = createAuthStorage(piSdk.AuthStorage, join(agentDir, "auth.json"));
71
+ const registry = new piSdk.ModelRegistry(authStorage, join(agentDir, "models.json"));
42
72
  const entries = Array.isArray(registry) ? registry : registry.getAll();
43
73
  for (const entry of entries) {
44
74
  const id = String(entry?.id ?? "").trim();
45
- if (!id)
75
+ if (!id) {
46
76
  continue;
77
+ }
47
78
  const provider = String(entry?.provider ?? "").trim();
48
- if (!provider)
79
+ if (!provider) {
49
80
  continue;
81
+ }
50
82
  const name = String(entry?.name ?? id).trim() || id;
51
83
  const contextWindow = typeof entry?.contextWindow === "number" && entry.contextWindow > 0
52
84
  ? entry.contextWindow
53
85
  : undefined;
54
86
  const reasoning = typeof entry?.reasoning === "boolean" ? entry.reasoning : undefined;
55
- const input = Array.isArray(entry?.input)
56
- ? entry.input
57
- : undefined;
87
+ const input = Array.isArray(entry?.input) ? entry.input : undefined;
58
88
  models.push({ id, name, provider, contextWindow, reasoning, input });
59
89
  }
90
+ applyOpenAICodexSparkFallback(models);
60
91
  if (models.length === 0) {
61
92
  // If we found nothing, don't cache this result so we can try again.
62
93
  modelCatalogPromise = null;
@@ -6,6 +6,9 @@ const OPENAI_CODEX_TEMPLATE_MODEL_IDS = ["gpt-5.2-codex"];
6
6
  const ANTHROPIC_OPUS_46_MODEL_ID = "claude-opus-4-6";
7
7
  const ANTHROPIC_OPUS_46_DOT_MODEL_ID = "claude-opus-4.6";
8
8
  const ANTHROPIC_OPUS_TEMPLATE_MODEL_IDS = ["claude-opus-4-5", "claude-opus-4.5"];
9
+ const ANTHROPIC_SONNET_46_MODEL_ID = "claude-sonnet-4-6";
10
+ const ANTHROPIC_SONNET_46_DOT_MODEL_ID = "claude-sonnet-4.6";
11
+ const ANTHROPIC_SONNET_TEMPLATE_MODEL_IDS = ["claude-sonnet-4-5", "claude-sonnet-4.5"];
9
12
  const ZAI_GLM5_MODEL_ID = "glm-5";
10
13
  const ZAI_GLM5_TEMPLATE_MODEL_IDS = ["glm-4.7"];
11
14
  const ANTIGRAVITY_OPUS_46_MODEL_ID = "claude-opus-4-6";
@@ -30,6 +33,22 @@ export const ANTIGRAVITY_OPUS_46_FORWARD_COMPAT_CANDIDATES = [
30
33
  templatePrefixes: ["google-antigravity/claude-opus-4-5", "google-antigravity/claude-opus-4.5"],
31
34
  },
32
35
  ];
36
+ function cloneFirstTemplateModel(params) {
37
+ const { normalizedProvider, trimmedModelId, templateIds, modelRegistry } = params;
38
+ for (const templateId of [...new Set(templateIds)].filter(Boolean)) {
39
+ const template = modelRegistry.find(normalizedProvider, templateId);
40
+ if (!template) {
41
+ continue;
42
+ }
43
+ return normalizeModelCompat({
44
+ ...template,
45
+ id: trimmedModelId,
46
+ name: trimmedModelId,
47
+ ...params.patch,
48
+ });
49
+ }
50
+ return undefined;
51
+ }
33
52
  function resolveOpenAICodexGpt53FallbackModel(provider, modelId, modelRegistry) {
34
53
  const normalizedProvider = normalizeProviderId(provider);
35
54
  const trimmedModelId = modelId.trim();
@@ -85,18 +104,41 @@ function resolveAnthropicOpus46ForwardCompatModel(provider, modelId, modelRegist
85
104
  templateIds.push(lower.replace(ANTHROPIC_OPUS_46_DOT_MODEL_ID, "claude-opus-4.5"));
86
105
  }
87
106
  templateIds.push(...ANTHROPIC_OPUS_TEMPLATE_MODEL_IDS);
88
- for (const templateId of [...new Set(templateIds)].filter(Boolean)) {
89
- const template = modelRegistry.find(normalizedProvider, templateId);
90
- if (!template) {
91
- continue;
92
- }
93
- return normalizeModelCompat({
94
- ...template,
95
- id: trimmedModelId,
96
- name: trimmedModelId,
97
- });
107
+ return cloneFirstTemplateModel({
108
+ normalizedProvider,
109
+ trimmedModelId,
110
+ templateIds,
111
+ modelRegistry,
112
+ });
113
+ }
114
+ function resolveAnthropicSonnet46ForwardCompatModel(provider, modelId, modelRegistry) {
115
+ const normalizedProvider = normalizeProviderId(provider);
116
+ if (normalizedProvider !== "anthropic") {
117
+ return undefined;
98
118
  }
99
- return undefined;
119
+ const trimmedModelId = modelId.trim();
120
+ const lower = trimmedModelId.toLowerCase();
121
+ const isSonnet46 = lower === ANTHROPIC_SONNET_46_MODEL_ID ||
122
+ lower === ANTHROPIC_SONNET_46_DOT_MODEL_ID ||
123
+ lower.startsWith(`${ANTHROPIC_SONNET_46_MODEL_ID}-`) ||
124
+ lower.startsWith(`${ANTHROPIC_SONNET_46_DOT_MODEL_ID}-`);
125
+ if (!isSonnet46) {
126
+ return undefined;
127
+ }
128
+ const templateIds = [];
129
+ if (lower.startsWith(ANTHROPIC_SONNET_46_MODEL_ID)) {
130
+ templateIds.push(lower.replace(ANTHROPIC_SONNET_46_MODEL_ID, "claude-sonnet-4-5"));
131
+ }
132
+ if (lower.startsWith(ANTHROPIC_SONNET_46_DOT_MODEL_ID)) {
133
+ templateIds.push(lower.replace(ANTHROPIC_SONNET_46_DOT_MODEL_ID, "claude-sonnet-4.5"));
134
+ }
135
+ templateIds.push(...ANTHROPIC_SONNET_TEMPLATE_MODEL_IDS);
136
+ return cloneFirstTemplateModel({
137
+ normalizedProvider,
138
+ trimmedModelId,
139
+ templateIds,
140
+ modelRegistry,
141
+ });
100
142
  }
101
143
  // Z.ai's GLM-5 may not be present in pi-ai's built-in model catalog yet.
102
144
  // When a user configures zai/glm-5 without a models.json entry, clone glm-4.7 as a forward-compat fallback.
@@ -166,22 +208,17 @@ function resolveAntigravityOpus46ForwardCompatModel(provider, modelId, modelRegi
166
208
  }
167
209
  templateIds.push(...ANTIGRAVITY_OPUS_TEMPLATE_MODEL_IDS);
168
210
  templateIds.push(...ANTIGRAVITY_OPUS_THINKING_TEMPLATE_MODEL_IDS);
169
- for (const templateId of [...new Set(templateIds)].filter(Boolean)) {
170
- const template = modelRegistry.find(normalizedProvider, templateId);
171
- if (!template) {
172
- continue;
173
- }
174
- return normalizeModelCompat({
175
- ...template,
176
- id: trimmedModelId,
177
- name: trimmedModelId,
178
- });
179
- }
180
- return undefined;
211
+ return cloneFirstTemplateModel({
212
+ normalizedProvider,
213
+ trimmedModelId,
214
+ templateIds,
215
+ modelRegistry,
216
+ });
181
217
  }
182
218
  export function resolveForwardCompatModel(provider, modelId, modelRegistry) {
183
219
  return (resolveOpenAICodexGpt53FallbackModel(provider, modelId, modelRegistry) ??
184
220
  resolveAnthropicOpus46ForwardCompatModel(provider, modelId, modelRegistry) ??
221
+ resolveAnthropicSonnet46ForwardCompatModel(provider, modelId, modelRegistry) ??
185
222
  resolveZaiGlm5ForwardCompatModel(provider, modelId, modelRegistry) ??
186
223
  resolveAntigravityOpus46ForwardCompatModel(provider, modelId, modelRegistry));
187
224
  }