@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,11 +1,13 @@
1
- import { normalizeGoogleModelId } from "./models-config.providers.js";
2
- import { resolveAgentModelPrimary } from "./agent-scope.js";
1
+ import { resolveAgentConfig, resolveAgentModelPrimary } from "./agent-scope.js";
3
2
  import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js";
3
+ import { normalizeGoogleModelId } from "./models-config.providers.js";
4
4
  const ANTHROPIC_MODEL_ALIASES = {
5
5
  "opus-4.6": "claude-opus-4-6",
6
6
  "opus-4.5": "claude-opus-4-5",
7
+ "sonnet-4.6": "claude-sonnet-4-6",
7
8
  "sonnet-4.5": "claude-sonnet-4-5",
8
9
  };
10
+ const OPENAI_CODEX_OAUTH_MODEL_PREFIXES = ["gpt-5.3-codex"];
9
11
  function normalizeAliasKey(value) {
10
12
  return value.trim().toLowerCase();
11
13
  }
@@ -14,59 +16,115 @@ export function modelKey(provider, model) {
14
16
  }
15
17
  export function normalizeProviderId(provider) {
16
18
  const normalized = provider.trim().toLowerCase();
17
- if (normalized === "z.ai" || normalized === "z-ai")
19
+ if (normalized === "z.ai" || normalized === "z-ai") {
18
20
  return "zai";
19
- if (normalized === "opencode-zen")
21
+ }
22
+ if (normalized === "opencode-zen") {
20
23
  return "opencode";
21
- if (normalized === "qwen")
24
+ }
25
+ if (normalized === "qwen") {
22
26
  return "qwen-portal";
23
- if (normalized === "kimi-code")
27
+ }
28
+ if (normalized === "kimi-code") {
24
29
  return "kimi-coding";
30
+ }
25
31
  return normalized;
26
32
  }
33
+ export function findNormalizedProviderValue(entries, provider) {
34
+ if (!entries) {
35
+ return undefined;
36
+ }
37
+ const providerKey = normalizeProviderId(provider);
38
+ for (const [key, value] of Object.entries(entries)) {
39
+ if (normalizeProviderId(key) === providerKey) {
40
+ return value;
41
+ }
42
+ }
43
+ return undefined;
44
+ }
45
+ export function findNormalizedProviderKey(entries, provider) {
46
+ if (!entries) {
47
+ return undefined;
48
+ }
49
+ const providerKey = normalizeProviderId(provider);
50
+ return Object.keys(entries).find((key) => normalizeProviderId(key) === providerKey);
51
+ }
27
52
  export function isCliProvider(provider, cfg) {
28
53
  const normalized = normalizeProviderId(provider);
29
- if (normalized === "claude-cli")
54
+ if (normalized === "claude-cli") {
30
55
  return true;
31
- if (normalized === "codex-cli")
56
+ }
57
+ if (normalized === "codex-cli") {
32
58
  return true;
59
+ }
33
60
  const backends = cfg?.agents?.defaults?.cliBackends ?? {};
34
61
  return Object.keys(backends).some((key) => normalizeProviderId(key) === normalized);
35
62
  }
36
63
  function normalizeAnthropicModelId(model) {
37
64
  const trimmed = model.trim();
38
- if (!trimmed)
65
+ if (!trimmed) {
39
66
  return trimmed;
67
+ }
40
68
  const lower = trimmed.toLowerCase();
41
- const aliased = ANTHROPIC_MODEL_ALIASES[lower];
42
- if (aliased)
43
- return aliased;
44
- return trimmed;
69
+ return ANTHROPIC_MODEL_ALIASES[lower] ?? trimmed;
45
70
  }
46
71
  function normalizeProviderModelId(provider, model) {
47
- if (provider === "anthropic")
72
+ if (provider === "anthropic") {
48
73
  return normalizeAnthropicModelId(model);
49
- if (provider === "google")
74
+ }
75
+ if (provider === "google") {
50
76
  return normalizeGoogleModelId(model);
77
+ }
51
78
  return model;
52
79
  }
80
+ function shouldUseOpenAICodexProvider(provider, model) {
81
+ if (provider !== "openai") {
82
+ return false;
83
+ }
84
+ const normalized = model.trim().toLowerCase();
85
+ if (!normalized) {
86
+ return false;
87
+ }
88
+ return OPENAI_CODEX_OAUTH_MODEL_PREFIXES.some((prefix) => normalized === prefix || normalized.startsWith(`${prefix}-`));
89
+ }
90
+ export function normalizeModelRef(provider, model) {
91
+ const normalizedProvider = normalizeProviderId(provider);
92
+ const normalizedModel = normalizeProviderModelId(normalizedProvider, model.trim());
93
+ if (shouldUseOpenAICodexProvider(normalizedProvider, normalizedModel)) {
94
+ return { provider: "openai-codex", model: normalizedModel };
95
+ }
96
+ return { provider: normalizedProvider, model: normalizedModel };
97
+ }
53
98
  export function parseModelRef(raw, defaultProvider) {
54
99
  const trimmed = raw.trim();
55
- if (!trimmed)
100
+ if (!trimmed) {
56
101
  return null;
102
+ }
57
103
  const slash = trimmed.indexOf("/");
58
104
  if (slash === -1) {
59
- const provider = normalizeProviderId(defaultProvider);
60
- const model = normalizeProviderModelId(provider, trimmed);
61
- return { provider, model };
105
+ return normalizeModelRef(defaultProvider, trimmed);
62
106
  }
63
107
  const providerRaw = trimmed.slice(0, slash).trim();
64
- const provider = normalizeProviderId(providerRaw);
65
108
  const model = trimmed.slice(slash + 1).trim();
66
- if (!provider || !model)
109
+ if (!providerRaw || !model) {
67
110
  return null;
68
- const normalizedModel = normalizeProviderModelId(provider, model);
69
- return { provider, model: normalizedModel };
111
+ }
112
+ return normalizeModelRef(providerRaw, model);
113
+ }
114
+ export function normalizeModelSelection(value) {
115
+ if (typeof value === "string") {
116
+ const trimmed = value.trim();
117
+ return trimmed || undefined;
118
+ }
119
+ if (!value || typeof value !== "object") {
120
+ return undefined;
121
+ }
122
+ const primary = value.primary;
123
+ if (typeof primary === "string") {
124
+ const trimmed = primary.trim();
125
+ return trimmed || undefined;
126
+ }
127
+ return undefined;
70
128
  }
71
129
  export function resolveAllowlistModelKey(raw, defaultProvider) {
72
130
  const parsed = parseModelRef(raw, defaultProvider);
@@ -95,11 +153,13 @@ export function buildModelAliasIndex(params) {
95
153
  const rawModels = params.cfg.agents?.defaults?.models ?? {};
96
154
  for (const [keyRaw, entryRaw] of Object.entries(rawModels)) {
97
155
  const parsed = parseModelRef(String(keyRaw ?? ""), params.defaultProvider);
98
- if (!parsed)
156
+ if (!parsed) {
99
157
  continue;
158
+ }
100
159
  const alias = String(entryRaw?.alias ?? "").trim();
101
- if (!alias)
160
+ if (!alias) {
102
161
  continue;
162
+ }
103
163
  const aliasKey = normalizeAliasKey(alias);
104
164
  byAlias.set(aliasKey, { alias, ref: parsed });
105
165
  const key = modelKey(parsed.provider, parsed.model);
@@ -111,8 +171,9 @@ export function buildModelAliasIndex(params) {
111
171
  }
112
172
  export function resolveModelRefFromString(params) {
113
173
  const trimmed = params.raw.trim();
114
- if (!trimmed)
174
+ if (!trimmed) {
115
175
  return null;
176
+ }
116
177
  if (!trimmed.includes("/")) {
117
178
  const aliasKey = normalizeAliasKey(trimmed);
118
179
  const aliasMatch = params.aliasIndex?.byAlias.get(aliasKey);
@@ -121,15 +182,17 @@ export function resolveModelRefFromString(params) {
121
182
  }
122
183
  }
123
184
  const parsed = parseModelRef(trimmed, params.defaultProvider);
124
- if (!parsed)
185
+ if (!parsed) {
125
186
  return null;
187
+ }
126
188
  return { ref: parsed };
127
189
  }
128
190
  export function resolveConfiguredModelRef(params) {
129
191
  const rawModel = (() => {
130
192
  const raw = params.cfg.agents?.defaults?.model;
131
- if (typeof raw === "string")
193
+ if (typeof raw === "string") {
132
194
  return raw.trim();
195
+ }
133
196
  return raw?.primary?.trim() ?? "";
134
197
  })();
135
198
  if (rawModel) {
@@ -141,8 +204,9 @@ export function resolveConfiguredModelRef(params) {
141
204
  if (!trimmed.includes("/")) {
142
205
  const aliasKey = normalizeAliasKey(trimmed);
143
206
  const aliasMatch = aliasIndex.byAlias.get(aliasKey);
144
- if (aliasMatch)
207
+ if (aliasMatch) {
145
208
  return aliasMatch.ref;
209
+ }
146
210
  // Default to anthropic if no provider is specified, but warn as this is deprecated.
147
211
  console.warn(`[poolbot] Model "${trimmed}" specified without provider. Falling back to "anthropic/${trimmed}". Please use "anthropic/${trimmed}" in your config.`);
148
212
  return { provider: "anthropic", model: trimmed };
@@ -152,8 +216,9 @@ export function resolveConfiguredModelRef(params) {
152
216
  defaultProvider: params.defaultProvider,
153
217
  aliasIndex,
154
218
  });
155
- if (resolved)
219
+ if (resolved) {
156
220
  return resolved.ref;
221
+ }
157
222
  }
158
223
  return { provider: params.defaultProvider, model: params.defaultModel };
159
224
  }
@@ -184,6 +249,25 @@ export function resolveDefaultModelForAgent(params) {
184
249
  defaultModel: DEFAULT_MODEL,
185
250
  });
186
251
  }
252
+ export function resolveSubagentConfiguredModelSelection(params) {
253
+ const agentConfig = resolveAgentConfig(params.cfg, params.agentId);
254
+ return (normalizeModelSelection(agentConfig?.subagents?.model) ??
255
+ normalizeModelSelection(params.cfg.agents?.defaults?.subagents?.model) ??
256
+ normalizeModelSelection(agentConfig?.model));
257
+ }
258
+ export function resolveSubagentSpawnModelSelection(params) {
259
+ const runtimeDefault = resolveDefaultModelForAgent({
260
+ cfg: params.cfg,
261
+ agentId: params.agentId,
262
+ });
263
+ return (normalizeModelSelection(params.modelOverride) ??
264
+ resolveSubagentConfiguredModelSelection({
265
+ cfg: params.cfg,
266
+ agentId: params.agentId,
267
+ }) ??
268
+ normalizeModelSelection(params.cfg.agents?.defaults?.model?.primary) ??
269
+ `${runtimeDefault.provider}/${runtimeDefault.model}`);
270
+ }
187
271
  export function buildAllowedModelSet(params) {
188
272
  const rawAllowlist = (() => {
189
273
  const modelMap = params.cfg.agents?.defaults?.models ?? {};
@@ -191,13 +275,15 @@ export function buildAllowedModelSet(params) {
191
275
  })();
192
276
  const allowAny = rawAllowlist.length === 0;
193
277
  const defaultModel = params.defaultModel?.trim();
194
- const defaultKey = defaultModel && params.defaultProvider
195
- ? modelKey(params.defaultProvider, defaultModel)
196
- : undefined;
278
+ const defaultRef = defaultModel && params.defaultProvider
279
+ ? parseModelRef(defaultModel, params.defaultProvider)
280
+ : null;
281
+ const defaultKey = defaultRef ? modelKey(defaultRef.provider, defaultRef.model) : undefined;
197
282
  const catalogKeys = new Set(params.catalog.map((entry) => modelKey(entry.provider, entry.id)));
198
283
  if (allowAny) {
199
- if (defaultKey)
284
+ if (defaultKey) {
200
285
  catalogKeys.add(defaultKey);
286
+ }
201
287
  return {
202
288
  allowAny: true,
203
289
  allowedCatalog: params.catalog,
@@ -208,8 +294,9 @@ export function buildAllowedModelSet(params) {
208
294
  const configuredProviders = (params.cfg.models?.providers ?? {});
209
295
  for (const raw of rawAllowlist) {
210
296
  const parsed = parseModelRef(String(raw), params.defaultProvider);
211
- if (!parsed)
297
+ if (!parsed) {
212
298
  continue;
299
+ }
213
300
  const key = modelKey(parsed.provider, parsed.model);
214
301
  const providerKey = normalizeProviderId(parsed.provider);
215
302
  if (isCliProvider(parsed.provider, params.cfg)) {
@@ -229,8 +316,9 @@ export function buildAllowedModelSet(params) {
229
316
  }
230
317
  const allowedCatalog = params.catalog.filter((entry) => allowedKeys.has(modelKey(entry.provider, entry.id)));
231
318
  if (allowedCatalog.length === 0 && allowedKeys.size === 0) {
232
- if (defaultKey)
319
+ if (defaultKey) {
233
320
  catalogKeys.add(defaultKey);
321
+ }
234
322
  return {
235
323
  allowAny: true,
236
324
  allowedCatalog: params.catalog,
@@ -256,8 +344,9 @@ export function getModelRefStatus(params) {
256
344
  }
257
345
  export function resolveAllowedModelRef(params) {
258
346
  const trimmed = params.raw.trim();
259
- if (!trimmed)
347
+ if (!trimmed) {
260
348
  return { error: "invalid model: empty" };
349
+ }
261
350
  const aliasIndex = buildModelAliasIndex({
262
351
  cfg: params.cfg,
263
352
  defaultProvider: params.defaultProvider,
@@ -267,8 +356,9 @@ export function resolveAllowedModelRef(params) {
267
356
  defaultProvider: params.defaultProvider,
268
357
  aliasIndex,
269
358
  });
270
- if (!resolved)
359
+ if (!resolved) {
271
360
  return { error: `invalid model: ${trimmed}` };
361
+ }
272
362
  const status = getModelRefStatus({
273
363
  cfg: params.cfg,
274
364
  catalog: params.catalog,
@@ -283,11 +373,13 @@ export function resolveAllowedModelRef(params) {
283
373
  }
284
374
  export function resolveThinkingDefault(params) {
285
375
  const configured = params.cfg.agents?.defaults?.thinkingDefault;
286
- if (configured)
376
+ if (configured) {
287
377
  return configured;
378
+ }
288
379
  const candidate = params.catalog?.find((entry) => entry.provider === params.provider && entry.id === params.model);
289
- if (candidate?.reasoning)
380
+ if (candidate?.reasoning) {
290
381
  return "low";
382
+ }
291
383
  return "off";
292
384
  }
293
385
  /**
@@ -296,8 +388,9 @@ export function resolveThinkingDefault(params) {
296
388
  */
297
389
  export function resolveHooksGmailModel(params) {
298
390
  const hooksModel = params.cfg.hooks?.gmail?.model;
299
- if (!hooksModel?.trim())
391
+ if (!hooksModel?.trim()) {
300
392
  return null;
393
+ }
301
394
  const aliasIndex = buildModelAliasIndex({
302
395
  cfg: params.cfg,
303
396
  defaultProvider: params.defaultProvider,
@@ -16,7 +16,7 @@ async function readAuthJson(filePath) {
16
16
  }
17
17
  }
18
18
  /**
19
- * Convert an OpenClaw auth-profiles credential to pi-coding-agent auth.json format.
19
+ * Convert an Pool Bot auth-profiles credential to pi-coding-agent auth.json format.
20
20
  * Returns null if the credential cannot be converted.
21
21
  */
22
22
  function convertCredential(cred) {
@@ -76,7 +76,7 @@ function credentialsEqual(a, b) {
76
76
  /**
77
77
  * pi-coding-agent's ModelRegistry/AuthStorage expects credentials in auth.json.
78
78
  *
79
- * OpenClaw stores credentials in auth-profiles.json instead. This helper
79
+ * Pool Bot stores credentials in auth-profiles.json instead. This helper
80
80
  * bridges all credentials into agentDir/auth.json so pi-coding-agent can
81
81
  * (a) consider providers authenticated and (b) include built-in models in its
82
82
  * registry/catalog output.
@@ -1,17 +1,21 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { truncateUtf16Safe } from "../../utils.js";
3
4
  function isBase64Signature(value) {
4
5
  const trimmed = value.trim();
5
- if (!trimmed)
6
+ if (!trimmed) {
6
7
  return false;
8
+ }
7
9
  const compact = trimmed.replace(/\s+/g, "");
8
- if (!/^[A-Za-z0-9+/=_-]+$/.test(compact))
10
+ if (!/^[A-Za-z0-9+/=_-]+$/.test(compact)) {
9
11
  return false;
12
+ }
10
13
  const isUrl = compact.includes("-") || compact.includes("_");
11
14
  try {
12
15
  const buf = Buffer.from(compact, isUrl ? "base64url" : "base64");
13
- if (buf.length === 0)
16
+ if (buf.length === 0) {
14
17
  return false;
18
+ }
15
19
  const encoded = buf.toString(isUrl ? "base64url" : "base64");
16
20
  const normalize = (input) => input.replace(/=+$/g, "");
17
21
  return normalize(encoded) === normalize(compact);
@@ -27,8 +31,9 @@ function isBase64Signature(value) {
27
31
  * like "msg_abc123...". We only strip "msg_*" to preserve any provider-valid signatures.
28
32
  */
29
33
  export function stripThoughtSignatures(content, options) {
30
- if (!Array.isArray(content))
34
+ if (!Array.isArray(content)) {
31
35
  return content;
36
+ }
32
37
  const allowBase64Only = options?.allowBase64Only ?? false;
33
38
  const includeCamelCase = options?.includeCamelCase ?? false;
34
39
  const shouldStripSignature = (value) => {
@@ -38,8 +43,9 @@ export function stripThoughtSignatures(content, options) {
38
43
  return typeof value !== "string" || !isBase64Signature(value);
39
44
  };
40
45
  return content.map((block) => {
41
- if (!block || typeof block !== "object")
46
+ if (!block || typeof block !== "object") {
42
47
  return block;
48
+ }
43
49
  const rec = block;
44
50
  const stripSnake = shouldStripSignature(rec.thought_signature);
45
51
  const stripCamel = includeCamelCase ? shouldStripSignature(rec.thoughtSignature) : false;
@@ -47,14 +53,18 @@ export function stripThoughtSignatures(content, options) {
47
53
  return block;
48
54
  }
49
55
  const next = { ...rec };
50
- if (stripSnake)
56
+ if (stripSnake) {
51
57
  delete next.thought_signature;
52
- if (stripCamel)
58
+ }
59
+ if (stripCamel) {
53
60
  delete next.thoughtSignature;
61
+ }
54
62
  return next;
55
63
  });
56
64
  }
57
65
  export const DEFAULT_BOOTSTRAP_MAX_CHARS = 20_000;
66
+ export const DEFAULT_BOOTSTRAP_TOTAL_MAX_CHARS = 150_000;
67
+ const MIN_BOOTSTRAP_FILE_BUDGET_CHARS = 64;
58
68
  const BOOTSTRAP_HEAD_RATIO = 0.7;
59
69
  const BOOTSTRAP_TAIL_RATIO = 0.2;
60
70
  export function resolveBootstrapMaxChars(cfg) {
@@ -64,6 +74,13 @@ export function resolveBootstrapMaxChars(cfg) {
64
74
  }
65
75
  return DEFAULT_BOOTSTRAP_MAX_CHARS;
66
76
  }
77
+ export function resolveBootstrapTotalMaxChars(cfg) {
78
+ const raw = cfg?.agents?.defaults?.bootstrapTotalMaxChars;
79
+ if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) {
80
+ return Math.floor(raw);
81
+ }
82
+ return DEFAULT_BOOTSTRAP_TOTAL_MAX_CHARS;
83
+ }
67
84
  function trimBootstrapContent(content, fileName, maxChars) {
68
85
  const trimmed = content.trimEnd();
69
86
  if (trimmed.length <= maxChars) {
@@ -92,6 +109,19 @@ function trimBootstrapContent(content, fileName, maxChars) {
92
109
  originalLength: trimmed.length,
93
110
  };
94
111
  }
112
+ function clampToBudget(content, budget) {
113
+ if (budget <= 0) {
114
+ return "";
115
+ }
116
+ if (content.length <= budget) {
117
+ return content;
118
+ }
119
+ if (budget <= 3) {
120
+ return truncateUtf16Safe(content, budget);
121
+ }
122
+ const safe = budget - 1;
123
+ return `${truncateUtf16Safe(content, safe)}…`;
124
+ }
95
125
  export async function ensureSessionHeader(params) {
96
126
  const file = params.sessionFile;
97
127
  try {
@@ -114,24 +144,43 @@ export async function ensureSessionHeader(params) {
114
144
  }
115
145
  export function buildBootstrapContextFiles(files, opts) {
116
146
  const maxChars = opts?.maxChars ?? DEFAULT_BOOTSTRAP_MAX_CHARS;
147
+ const totalMaxChars = Math.max(1, Math.floor(opts?.totalMaxChars ?? Math.max(maxChars, DEFAULT_BOOTSTRAP_TOTAL_MAX_CHARS)));
148
+ let remainingTotalChars = totalMaxChars;
117
149
  const result = [];
118
150
  for (const file of files) {
151
+ if (remainingTotalChars <= 0) {
152
+ break;
153
+ }
119
154
  if (file.missing) {
155
+ const missingText = `[MISSING] Expected at: ${file.path}`;
156
+ const cappedMissingText = clampToBudget(missingText, remainingTotalChars);
157
+ if (!cappedMissingText) {
158
+ break;
159
+ }
160
+ remainingTotalChars = Math.max(0, remainingTotalChars - cappedMissingText.length);
120
161
  result.push({
121
- path: file.name,
122
- content: `[MISSING] Expected at: ${file.path}`,
162
+ path: file.path,
163
+ content: cappedMissingText,
123
164
  });
124
165
  continue;
125
166
  }
126
- const trimmed = trimBootstrapContent(file.content ?? "", file.name, maxChars);
127
- if (!trimmed.content)
167
+ if (remainingTotalChars < MIN_BOOTSTRAP_FILE_BUDGET_CHARS) {
168
+ opts?.warn?.(`remaining bootstrap budget is ${remainingTotalChars} chars (<${MIN_BOOTSTRAP_FILE_BUDGET_CHARS}); skipping additional bootstrap files`);
169
+ break;
170
+ }
171
+ const fileMaxChars = Math.max(1, Math.min(maxChars, remainingTotalChars));
172
+ const trimmed = trimBootstrapContent(file.content ?? "", file.name, fileMaxChars);
173
+ const contentWithinBudget = clampToBudget(trimmed.content, remainingTotalChars);
174
+ if (!contentWithinBudget) {
128
175
  continue;
129
- if (trimmed.truncated) {
176
+ }
177
+ if (trimmed.truncated || contentWithinBudget.length < trimmed.content.length) {
130
178
  opts?.warn?.(`workspace bootstrap file ${file.name} is ${trimmed.originalLength} chars (limit ${trimmed.maxChars}); truncating in injected context`);
131
179
  }
180
+ remainingTotalChars = Math.max(0, remainingTotalChars - contentWithinBudget.length);
132
181
  result.push({
133
- path: file.name,
134
- content: trimmed.content,
182
+ path: file.path,
183
+ content: contentWithinBudget,
135
184
  });
136
185
  }
137
186
  return result;
@@ -146,8 +195,9 @@ export function sanitizeGoogleTurnOrdering(messages) {
146
195
  content.trim() === GOOGLE_TURN_ORDER_BOOTSTRAP_TEXT) {
147
196
  return messages;
148
197
  }
149
- if (role !== "assistant")
198
+ if (role !== "assistant") {
150
199
  return messages;
200
+ }
151
201
  // Cloud Code Assist rejects histories that begin with a model turn (tool call or text).
152
202
  // Prepend a tiny synthetic user turn so the rest of the transcript can be used.
153
203
  const bootstrap = {