@poolzin/pool-bot 2026.2.25 → 2026.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/dist/acp/event-mapper.js +87 -22
  2. package/dist/acp/meta.js +12 -6
  3. package/dist/agents/agent-paths.js +8 -9
  4. package/dist/agents/agent-scope.js +7 -5
  5. package/dist/agents/auth-profiles/oauth.js +148 -64
  6. package/dist/agents/auth-profiles/session-override.js +13 -7
  7. package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
  8. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  9. package/dist/agents/bedrock-discovery.js +3 -1
  10. package/dist/agents/byteplus-models.js +97 -0
  11. package/dist/agents/chutes-oauth.js +1 -0
  12. package/dist/agents/cli-runner/helpers.js +4 -0
  13. package/dist/agents/compaction.js +41 -14
  14. package/dist/agents/doubao-models.js +121 -0
  15. package/dist/agents/failover-error.js +2 -0
  16. package/dist/agents/huggingface-models.js +5 -3
  17. package/dist/agents/live-model-filter.js +5 -0
  18. package/dist/agents/minimax-vlm.js +10 -8
  19. package/dist/agents/model-auth.js +6 -0
  20. package/dist/agents/model-catalog.js +3 -1
  21. package/dist/agents/model-selection.js +7 -1
  22. package/dist/agents/models-config.providers.js +93 -11
  23. package/dist/agents/ollama-stream.js +117 -4
  24. package/dist/agents/opencode-zen-models.js +22 -11
  25. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  26. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  27. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  28. package/dist/agents/pi-embedded-helpers.js +1 -1
  29. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  30. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  31. package/dist/agents/pi-embedded-runner/google.js +20 -8
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  33. package/dist/agents/pi-embedded-runner/run.js +71 -12
  34. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  35. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  36. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  37. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  38. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  39. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  40. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  41. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  42. package/dist/agents/pi-embedded-subscribe.js +9 -4
  43. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  44. package/dist/agents/pi-embedded-utils.js +3 -0
  45. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  46. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  47. package/dist/agents/pi-settings.js +40 -0
  48. package/dist/agents/pi-tools.policy.js +2 -1
  49. package/dist/agents/provider/config-loader.js +1 -1
  50. package/dist/agents/sandbox/browser.js +170 -33
  51. package/dist/agents/sandbox/config-hash.js +14 -27
  52. package/dist/agents/sandbox/config.js +21 -2
  53. package/dist/agents/sandbox/constants.js +2 -0
  54. package/dist/agents/sandbox/docker.js +16 -2
  55. package/dist/agents/sandbox/novnc-auth.js +62 -0
  56. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  57. package/dist/agents/sandbox/shared.js +10 -6
  58. package/dist/agents/sandbox-paths.js +24 -11
  59. package/dist/agents/schema/clean-for-gemini.js +132 -85
  60. package/dist/agents/session-slug.js +10 -5
  61. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  62. package/dist/agents/session-tool-result-guard.js +3 -1
  63. package/dist/agents/session-transcript-repair.js +40 -6
  64. package/dist/agents/skills/bundled-dir.js +19 -5
  65. package/dist/agents/skills/env-overrides.js +124 -43
  66. package/dist/agents/skills/frontmatter.js +6 -6
  67. package/dist/agents/skills/plugin-skills.js +14 -7
  68. package/dist/agents/skills/workspace.js +1 -0
  69. package/dist/agents/subagent-announce.js +251 -49
  70. package/dist/agents/subagent-lifecycle-events.js +19 -0
  71. package/dist/agents/subagent-registry-cleanup.js +31 -0
  72. package/dist/agents/subagent-registry-completion.js +68 -0
  73. package/dist/agents/subagent-registry-queries.js +117 -0
  74. package/dist/agents/subagent-registry-state.js +46 -0
  75. package/dist/agents/subagent-registry.js +252 -221
  76. package/dist/agents/subagent-registry.store.js +1 -0
  77. package/dist/agents/subagent-registry.types.js +1 -0
  78. package/dist/agents/subagent-spawn.js +195 -7
  79. package/dist/agents/system-prompt.js +22 -6
  80. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  81. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  82. package/dist/agents/timeout.js +18 -6
  83. package/dist/agents/tool-call-id.js +1 -1
  84. package/dist/agents/tool-display-common.js +162 -29
  85. package/dist/agents/tool-images.js +82 -9
  86. package/dist/agents/tool-policy.js +51 -26
  87. package/dist/agents/tools/browser-tool.js +2 -2
  88. package/dist/agents/tools/canvas-tool.js +27 -1
  89. package/dist/agents/tools/common.js +45 -0
  90. package/dist/agents/tools/discord-actions-guild.js +4 -1
  91. package/dist/agents/tools/gateway-tool.js +3 -1
  92. package/dist/agents/tools/nodes-utils.js +1 -10
  93. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  94. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  95. package/dist/agents/tools/subagents-tool.js +2 -1
  96. package/dist/agents/tools/whatsapp-actions.js +10 -2
  97. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  98. package/dist/agents/transcript-policy.js +22 -8
  99. package/dist/agents/venice-models.js +11 -3
  100. package/dist/auto-reply/commands-registry.data.js +51 -0
  101. package/dist/auto-reply/commands-registry.js +4 -3
  102. package/dist/auto-reply/group-activation.js +10 -5
  103. package/dist/auto-reply/inbound-debounce.js +10 -5
  104. package/dist/auto-reply/reply/abort.js +1 -1
  105. package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
  106. package/dist/auto-reply/reply/bash-command.js +41 -39
  107. package/dist/auto-reply/reply/command-gates.js +25 -0
  108. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  109. package/dist/auto-reply/reply/commands-bash.js +6 -5
  110. package/dist/auto-reply/reply/commands-config.js +30 -28
  111. package/dist/auto-reply/reply/commands-core.js +2 -1
  112. package/dist/auto-reply/reply/commands-info.js +1 -0
  113. package/dist/auto-reply/reply/commands-models.js +65 -14
  114. package/dist/auto-reply/reply/commands-session.js +237 -82
  115. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  116. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  117. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  118. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  119. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  120. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  121. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  122. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  123. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  124. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  125. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  126. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  127. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  128. package/dist/auto-reply/reply/commands-tts.js +10 -5
  129. package/dist/auto-reply/reply/config-value.js +10 -5
  130. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  131. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  132. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  133. package/dist/auto-reply/reply/followup-runner.js +1 -0
  134. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  135. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  136. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  137. package/dist/auto-reply/reply/get-reply.js +71 -12
  138. package/dist/auto-reply/reply/model-selection.js +80 -39
  139. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  140. package/dist/auto-reply/reply/queue/state.js +13 -12
  141. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  142. package/dist/auto-reply/reply/reply-reference.js +9 -8
  143. package/dist/auto-reply/reply/route-reply.js +15 -8
  144. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  145. package/dist/auto-reply/reply/session.js +22 -6
  146. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  147. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  148. package/dist/auto-reply/reply/typing.js +46 -21
  149. package/dist/auto-reply/send-policy.js +14 -7
  150. package/dist/auto-reply/status.js +140 -16
  151. package/dist/auto-reply/templating.js +10 -5
  152. package/dist/auto-reply/thinking.js +7 -16
  153. package/dist/auto-reply/tokens.js +21 -5
  154. package/dist/browser/bridge-server.js +36 -20
  155. package/dist/browser/cdp.helpers.js +7 -14
  156. package/dist/browser/cdp.js +35 -15
  157. package/dist/browser/chrome.profile-decoration.js +7 -4
  158. package/dist/browser/config.js +4 -0
  159. package/dist/browser/extension-relay-auth.js +55 -0
  160. package/dist/browser/extension-relay.js +74 -29
  161. package/dist/browser/navigation-guard.js +9 -1
  162. package/dist/browser/paths.js +77 -0
  163. package/dist/browser/profiles.js +13 -8
  164. package/dist/browser/pw-ai-module.js +10 -5
  165. package/dist/browser/pw-session.js +76 -39
  166. package/dist/browser/pw-tools-core.interactions.js +14 -7
  167. package/dist/browser/pw-tools-core.state.js +12 -6
  168. package/dist/browser/routes/agent.act.js +2 -2
  169. package/dist/browser/server-context.js +7 -0
  170. package/dist/build-info.json +3 -3
  171. package/dist/channels/allow-from.js +2 -1
  172. package/dist/channels/allowlists/resolve-utils.js +43 -19
  173. package/dist/channels/channel-config.js +14 -7
  174. package/dist/channels/draft-stream-loop.js +7 -0
  175. package/dist/channels/model-overrides.js +82 -0
  176. package/dist/channels/plugins/normalize/imessage.js +14 -7
  177. package/dist/channels/plugins/normalize/slack.js +10 -5
  178. package/dist/channels/plugins/normalize/telegram.js +14 -7
  179. package/dist/channels/plugins/outbound/discord.js +80 -8
  180. package/dist/channels/plugins/outbound/signal.js +11 -11
  181. package/dist/channels/plugins/setup-helpers.js +10 -5
  182. package/dist/channels/sender-label.js +14 -7
  183. package/dist/channels/session.js +4 -2
  184. package/dist/channels/status-reactions.js +297 -0
  185. package/dist/cli/banner.js +1 -1
  186. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  187. package/dist/cli/cli-name.js +11 -11
  188. package/dist/cli/cli-utils.js +13 -3
  189. package/dist/cli/command-format.js +1 -1
  190. package/dist/cli/config-cli.js +1 -1
  191. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  192. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  193. package/dist/cli/daemon-cli/restart-health.js +126 -0
  194. package/dist/cli/daemon-cli/status.gather.js +9 -13
  195. package/dist/cli/daemon-cli/status.print.js +2 -10
  196. package/dist/cli/deps.js +27 -22
  197. package/dist/cli/gateway-cli/run-loop.js +23 -5
  198. package/dist/cli/node-cli/register.js +14 -5
  199. package/dist/cli/nodes-media-utils.js +7 -2
  200. package/dist/cli/outbound-send-deps.js +2 -9
  201. package/dist/cli/outbound-send-mapping.js +11 -0
  202. package/dist/cli/pairing-cli.js +40 -14
  203. package/dist/cli/plugins-cli.js +34 -41
  204. package/dist/cli/ports.js +11 -10
  205. package/dist/cli/program/command-registry.js +2 -11
  206. package/dist/cli/program/command-tree.js +16 -0
  207. package/dist/cli/program/preaction.js +13 -9
  208. package/dist/cli/program/register.configure.js +3 -18
  209. package/dist/cli/program/register.maintenance.js +2 -2
  210. package/dist/cli/program/register.onboard.js +2 -0
  211. package/dist/cli/program/register.status-health-sessions.js +16 -17
  212. package/dist/cli/program/register.subclis.js +93 -52
  213. package/dist/cli/route.js +11 -7
  214. package/dist/cli/system-cli.js +36 -46
  215. package/dist/cli/update-cli/shared.js +22 -9
  216. package/dist/cli/update-cli/update-command.js +89 -14
  217. package/dist/cli/update-cli/wizard.js +6 -12
  218. package/dist/commands/agent/run-context.js +18 -5
  219. package/dist/commands/agent/session-store.js +17 -4
  220. package/dist/commands/agent.js +22 -2
  221. package/dist/commands/agents.bindings.js +14 -7
  222. package/dist/commands/agents.commands.add.js +13 -9
  223. package/dist/commands/agents.commands.identity.js +12 -6
  224. package/dist/commands/agents.commands.list.js +11 -6
  225. package/dist/commands/agents.config.js +8 -10
  226. package/dist/commands/agents.providers.js +12 -6
  227. package/dist/commands/auth-choice-options.js +103 -75
  228. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  229. package/dist/commands/auth-choice.apply.js +4 -0
  230. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  231. package/dist/commands/auth-choice.apply.openai.js +3 -1
  232. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  233. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  234. package/dist/commands/channels/remove.js +13 -6
  235. package/dist/commands/channels/shared.js +4 -14
  236. package/dist/commands/configure.commands.js +14 -0
  237. package/dist/commands/configure.gateway.js +2 -4
  238. package/dist/commands/configure.js +1 -1
  239. package/dist/commands/configure.shared.js +11 -0
  240. package/dist/commands/daemon-install-helpers.js +2 -2
  241. package/dist/commands/dashboard.js +12 -10
  242. package/dist/commands/docs.js +14 -8
  243. package/dist/commands/doctor-config-flow.js +11 -9
  244. package/dist/commands/doctor-legacy-config.js +281 -0
  245. package/dist/commands/doctor-state-integrity.js +99 -23
  246. package/dist/commands/doctor-update.js +12 -9
  247. package/dist/commands/models/list.list-command.js +7 -5
  248. package/dist/commands/models/set-image.js +2 -21
  249. package/dist/commands/node-daemon-install-helpers.js +10 -8
  250. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  251. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  252. package/dist/commands/onboard-auth.credentials.js +90 -13
  253. package/dist/commands/onboard-auth.js +1 -1
  254. package/dist/commands/onboard-auth.models.js +6 -5
  255. package/dist/commands/onboard-hooks.js +1 -1
  256. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  257. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  258. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  259. package/dist/commands/onboard-remote.js +14 -7
  260. package/dist/commands/onboard.js +11 -13
  261. package/dist/commands/sandbox-display.js +6 -5
  262. package/dist/commands/status-all/diagnosis.js +14 -10
  263. package/dist/commands/status-all/format.js +1 -0
  264. package/dist/commands/status.gateway-probe.js +1 -16
  265. package/dist/commands/systemd-linger.js +12 -6
  266. package/dist/config/agent-limits.js +2 -0
  267. package/dist/config/commands.js +30 -16
  268. package/dist/config/config-paths.js +9 -11
  269. package/dist/config/defaults.js +22 -2
  270. package/dist/config/discord-preview-streaming.js +104 -0
  271. package/dist/config/env-vars.js +37 -8
  272. package/dist/config/includes.js +4 -0
  273. package/dist/config/io.js +97 -12
  274. package/dist/config/legacy.migrations.part-1.js +189 -78
  275. package/dist/config/legacy.shared.js +3 -1
  276. package/dist/config/merge-patch.js +4 -0
  277. package/dist/config/prototype-keys.js +4 -0
  278. package/dist/config/schema.help.js +44 -7
  279. package/dist/config/schema.labels.js +38 -6
  280. package/dist/config/sessions/delivery-info.js +10 -3
  281. package/dist/config/sessions/main-session.js +10 -5
  282. package/dist/config/sessions/session-file.js +33 -0
  283. package/dist/config/sessions/session-key.js +10 -5
  284. package/dist/config/sessions/store.js +1 -1
  285. package/dist/config/sessions.js +1 -0
  286. package/dist/config/zod-schema.agent-runtime.js +11 -0
  287. package/dist/config/zod-schema.js +148 -13
  288. package/dist/config/zod-schema.providers-core.js +78 -4
  289. package/dist/config/zod-schema.providers.js +6 -1
  290. package/dist/config/zod-schema.session.js +41 -2
  291. package/dist/cron/run-log.js +3 -0
  292. package/dist/cron/schedule.js +21 -10
  293. package/dist/cron/service/ops.js +35 -21
  294. package/dist/cron/service/timer.js +116 -16
  295. package/dist/cron/stagger.js +3 -1
  296. package/dist/discord/api.js +12 -6
  297. package/dist/discord/draft-chunking.js +22 -0
  298. package/dist/discord/draft-stream.js +124 -0
  299. package/dist/discord/monitor/agent-components.js +1 -1
  300. package/dist/discord/monitor/commands.js +5 -0
  301. package/dist/discord/monitor/gateway-plugin.js +2 -1
  302. package/dist/discord/monitor/listeners.js +37 -27
  303. package/dist/discord/monitor/message-handler.js +4 -1
  304. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  305. package/dist/discord/monitor/message-handler.process.js +246 -217
  306. package/dist/discord/monitor/message-utils.js +143 -6
  307. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  308. package/dist/discord/monitor/model-picker.js +651 -0
  309. package/dist/discord/monitor/native-command.js +573 -16
  310. package/dist/discord/monitor/provider.allowlist.js +223 -0
  311. package/dist/discord/monitor/provider.js +275 -347
  312. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  313. package/dist/discord/monitor/reply-delivery.js +123 -16
  314. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  315. package/dist/discord/monitor/thread-bindings.js +4 -0
  316. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  317. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  318. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  319. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  320. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  321. package/dist/discord/resolve-users.js +33 -21
  322. package/dist/discord/send.channels.js +15 -0
  323. package/dist/discord/send.js +3 -2
  324. package/dist/discord/send.outbound.js +82 -26
  325. package/dist/discord/send.permissions.js +83 -30
  326. package/dist/discord/send.reactions.js +8 -4
  327. package/dist/discord/token.js +10 -5
  328. package/dist/discord/voice/command.js +263 -0
  329. package/dist/discord/voice/manager.js +531 -0
  330. package/dist/gateway/auth.js +34 -10
  331. package/dist/gateway/call.js +4 -16
  332. package/dist/gateway/client.js +28 -4
  333. package/dist/gateway/config-reload.js +3 -4
  334. package/dist/gateway/control-ui.js +219 -96
  335. package/dist/gateway/hooks-mapping.js +88 -38
  336. package/dist/gateway/http-auth-helpers.js +3 -2
  337. package/dist/gateway/http-endpoint-helpers.js +1 -0
  338. package/dist/gateway/net.js +54 -12
  339. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  340. package/dist/gateway/node-registry.js +10 -5
  341. package/dist/gateway/openai-http.js +1 -0
  342. package/dist/gateway/openresponses-http.js +1 -0
  343. package/dist/gateway/origin-check.js +1 -18
  344. package/dist/gateway/protocol/index.js +4 -3
  345. package/dist/gateway/protocol/schema/cron.js +1 -0
  346. package/dist/gateway/protocol/schema/devices.js +1 -0
  347. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
  348. package/dist/gateway/protocol/schema/sessions.js +6 -0
  349. package/dist/gateway/role-policy.js +17 -0
  350. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  351. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  352. package/dist/gateway/server-chat.js +83 -25
  353. package/dist/gateway/server-constants.js +10 -9
  354. package/dist/gateway/server-cron.js +1 -0
  355. package/dist/gateway/server-http.js +16 -7
  356. package/dist/gateway/server-maintenance.js +20 -5
  357. package/dist/gateway/server-methods/chat.js +10 -6
  358. package/dist/gateway/server-methods/config.js +12 -14
  359. package/dist/gateway/server-methods/devices.js +17 -3
  360. package/dist/gateway/server-methods/models.js +11 -1
  361. package/dist/gateway/server-methods/sessions.js +64 -8
  362. package/dist/gateway/server-methods/usage.js +162 -75
  363. package/dist/gateway/server-node-events.js +29 -0
  364. package/dist/gateway/server-runtime-config.js +34 -13
  365. package/dist/gateway/server-startup-memory.js +17 -11
  366. package/dist/gateway/session-utils.fs.js +32 -34
  367. package/dist/gateway/sessions-resolve.js +17 -5
  368. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  369. package/dist/gateway/tools-invoke-http.js +21 -10
  370. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  371. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  372. package/dist/hooks/bundled/session-memory/handler.js +6 -5
  373. package/dist/hooks/frontmatter.js +6 -6
  374. package/dist/hooks/gmail-watcher.js +11 -6
  375. package/dist/hooks/internal-hooks.js +11 -1
  376. package/dist/hooks/llm-slug-generator.js +4 -1
  377. package/dist/hooks/workspace.js +47 -17
  378. package/dist/imessage/accounts.js +9 -20
  379. package/dist/imessage/monitor/inbound-processing.js +2 -1
  380. package/dist/infra/archive.js +174 -73
  381. package/dist/infra/control-ui-assets.js +14 -6
  382. package/dist/infra/device-pairing.js +108 -29
  383. package/dist/infra/env.js +10 -5
  384. package/dist/infra/exec-approvals-allowlist.js +122 -0
  385. package/dist/infra/exec-approvals-analysis.js +34 -3
  386. package/dist/infra/exec-approvals.js +5 -17
  387. package/dist/infra/exec-safe-bin-policy.js +53 -45
  388. package/dist/infra/fs-safe.js +71 -39
  389. package/dist/infra/gateway-lock.js +6 -2
  390. package/dist/infra/heartbeat-wake.js +6 -12
  391. package/dist/infra/host-env-security-policy.json +19 -0
  392. package/dist/infra/host-env-security.js +66 -0
  393. package/dist/infra/net/ssrf.js +131 -38
  394. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  395. package/dist/infra/outbound/channel-selection.js +12 -6
  396. package/dist/infra/outbound/envelope.js +1 -1
  397. package/dist/infra/outbound/format.js +12 -6
  398. package/dist/infra/outbound/payloads.js +14 -7
  399. package/dist/infra/outbound/session-binding-service.js +123 -0
  400. package/dist/infra/path-guards.js +25 -0
  401. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  402. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  403. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  404. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  405. package/dist/infra/retry-policy.js +4 -2
  406. package/dist/infra/retry.js +9 -5
  407. package/dist/infra/session-cost-usage.js +107 -59
  408. package/dist/infra/session-maintenance-warning.js +3 -1
  409. package/dist/infra/shell-env.js +98 -34
  410. package/dist/infra/ssh-config.js +12 -6
  411. package/dist/infra/system-run-command.js +49 -4
  412. package/dist/infra/update-channels.js +10 -5
  413. package/dist/line/accounts.js +5 -7
  414. package/dist/line/bot-access.js +8 -20
  415. package/dist/line/bot-handlers.js +3 -1
  416. package/dist/link-understanding/detect.js +15 -7
  417. package/dist/media/constants.js +15 -6
  418. package/dist/media/image-ops.js +7 -0
  419. package/dist/media/local-roots.js +3 -2
  420. package/dist/media-understanding/apply.js +4 -1
  421. package/dist/media-understanding/concurrency.js +8 -20
  422. package/dist/memory/backend-config.js +45 -6
  423. package/dist/memory/embeddings.js +10 -4
  424. package/dist/memory/fs-utils.js +23 -0
  425. package/dist/memory/manager-search.js +12 -6
  426. package/dist/memory/manager-sync-ops.js +12 -2
  427. package/dist/memory/qmd-manager.js +466 -53
  428. package/dist/memory/query-expansion.js +167 -3
  429. package/dist/memory/status-format.js +10 -5
  430. package/dist/memory/sync-memory-files.js +1 -1
  431. package/dist/node-host/invoke-system-run.js +281 -0
  432. package/dist/node-host/invoke.js +55 -337
  433. package/dist/pairing/pairing-store.js +22 -0
  434. package/dist/plugin-sdk/allow-from.js +1 -1
  435. package/dist/plugin-sdk/command-auth.js +3 -1
  436. package/dist/plugin-sdk/index.js +6 -3
  437. package/dist/plugin-sdk/webhook-targets.js +32 -0
  438. package/dist/plugins/bundled-dir.js +9 -6
  439. package/dist/plugins/hooks.js +50 -0
  440. package/dist/plugins/install.js +28 -16
  441. package/dist/plugins/runtime.js +3 -17
  442. package/dist/plugins/update.js +78 -12
  443. package/dist/process/spawn-utils.js +14 -7
  444. package/dist/providers/github-copilot-token.js +11 -6
  445. package/dist/providers/qwen-portal-oauth.js +14 -6
  446. package/dist/routing/account-id.js +30 -0
  447. package/dist/routing/resolve-route.js +3 -7
  448. package/dist/routing/session-key.js +2 -16
  449. package/dist/security/audit-channel.js +93 -2
  450. package/dist/security/audit-extra.async.js +159 -5
  451. package/dist/security/audit-extra.js +1 -1
  452. package/dist/security/audit-extra.sync.js +85 -6
  453. package/dist/security/audit.js +40 -4
  454. package/dist/security/dm-policy-shared.js +44 -0
  455. package/dist/security/external-content.js +26 -6
  456. package/dist/shared/entry-status.js +6 -0
  457. package/dist/shared/frontmatter.js +5 -5
  458. package/dist/shared/node-match.js +11 -4
  459. package/dist/shared/operator-scope-compat.js +8 -3
  460. package/dist/signal/accounts.js +7 -20
  461. package/dist/signal/monitor/event-handler.js +3 -1
  462. package/dist/slack/accounts.js +6 -19
  463. package/dist/slack/actions.js +11 -3
  464. package/dist/slack/monitor/auth.js +1 -1
  465. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  466. package/dist/slack/monitor/replies.js +15 -7
  467. package/dist/slack/monitor/slash.js +22 -13
  468. package/dist/slack/resolve-channels.js +10 -5
  469. package/dist/slack/send.js +102 -12
  470. package/dist/slack/stream-mode.js +10 -0
  471. package/dist/slack/streaming.js +4 -2
  472. package/dist/telegram/accounts.js +19 -14
  473. package/dist/telegram/bot/helpers.js +3 -5
  474. package/dist/telegram/bot-access.js +35 -36
  475. package/dist/telegram/bot-handlers.js +120 -148
  476. package/dist/telegram/bot-message-context.js +68 -9
  477. package/dist/telegram/bot-message-dispatch.js +155 -90
  478. package/dist/telegram/bot-native-commands.js +16 -0
  479. package/dist/telegram/draft-stream.js +14 -1
  480. package/dist/telegram/inline-buttons.js +5 -15
  481. package/dist/telegram/monitor.js +11 -7
  482. package/dist/telegram/network-config.js +19 -7
  483. package/dist/telegram/send.js +3 -2
  484. package/dist/telegram/sent-message-cache.js +5 -6
  485. package/dist/telegram/status-reaction-variants.js +208 -0
  486. package/dist/telegram/sticker-cache.js +11 -9
  487. package/dist/terminal/theme.js +12 -12
  488. package/dist/tts/tts.js +80 -567
  489. package/dist/tui/components/chat-log.js +41 -8
  490. package/dist/tui/theme/theme.js +10 -12
  491. package/dist/tui/tui-local-shell.js +16 -6
  492. package/dist/tui/tui.js +58 -6
  493. package/dist/utils/account-id.js +2 -4
  494. package/dist/utils/boolean.js +10 -5
  495. package/dist/utils/directive-tags.js +11 -0
  496. package/dist/utils/queue-helpers.js +67 -12
  497. package/dist/web/auto-reply/deliver-reply.js +8 -4
  498. package/dist/web/auto-reply/mentions.js +10 -5
  499. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  500. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  501. package/dist/web/inbound/access-control.js +5 -2
  502. package/dist/web/login-qr.js +12 -6
  503. package/dist/web/media.js +123 -16
  504. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  505. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  506. package/package.json +1 -1
@@ -1,21 +1,76 @@
1
- export function extractTextFromPrompt(prompt) {
1
+ const INLINE_CONTROL_ESCAPE_MAP = {
2
+ "\0": "\\0",
3
+ "\r": "\\r",
4
+ "\n": "\\n",
5
+ "\t": "\\t",
6
+ "\v": "\\v",
7
+ "\f": "\\f",
8
+ "\u2028": "\\u2028",
9
+ "\u2029": "\\u2029",
10
+ };
11
+ function escapeInlineControlChars(value) {
12
+ let escaped = "";
13
+ for (const char of value) {
14
+ const codePoint = char.codePointAt(0);
15
+ if (codePoint === undefined) {
16
+ escaped += char;
17
+ continue;
18
+ }
19
+ const isInlineControl = codePoint <= 0x1f ||
20
+ (codePoint >= 0x7f && codePoint <= 0x9f) ||
21
+ codePoint === 0x2028 ||
22
+ codePoint === 0x2029;
23
+ if (!isInlineControl) {
24
+ escaped += char;
25
+ continue;
26
+ }
27
+ const mapped = INLINE_CONTROL_ESCAPE_MAP[char];
28
+ if (mapped) {
29
+ escaped += mapped;
30
+ continue;
31
+ }
32
+ // Keep escaped control bytes readable and stable in logs/prompts.
33
+ escaped +=
34
+ codePoint <= 0xff
35
+ ? `\\x${codePoint.toString(16).padStart(2, "0")}`
36
+ : `\\u${codePoint.toString(16).padStart(4, "0")}`;
37
+ }
38
+ return escaped;
39
+ }
40
+ function escapeResourceTitle(value) {
41
+ // Keep title content, but escape characters that can break the resource-link annotation shape.
42
+ return escapeInlineControlChars(value).replace(/[()[\]]/g, (char) => `\\${char}`);
43
+ }
44
+ export function extractTextFromPrompt(prompt, maxBytes) {
2
45
  const parts = [];
46
+ // Track accumulated byte count per block to catch oversized prompts before full concatenation
47
+ let totalBytes = 0;
3
48
  for (const block of prompt) {
49
+ let blockText;
4
50
  if (block.type === "text") {
5
- parts.push(block.text);
6
- continue;
51
+ blockText = block.text;
7
52
  }
8
- if (block.type === "resource") {
53
+ else if (block.type === "resource") {
9
54
  const resource = block.resource;
10
- if (resource?.text)
11
- parts.push(resource.text);
12
- continue;
55
+ if (resource?.text) {
56
+ blockText = resource.text;
57
+ }
13
58
  }
14
- if (block.type === "resource_link") {
15
- const title = block.title ? ` (${block.title})` : "";
16
- const uri = block.uri ?? "";
17
- const line = uri ? `[Resource link${title}] ${uri}` : `[Resource link${title}]`;
18
- parts.push(line);
59
+ else if (block.type === "resource_link") {
60
+ const title = block.title ? ` (${escapeResourceTitle(block.title)})` : "";
61
+ const uri = block.uri ? escapeInlineControlChars(block.uri) : "";
62
+ blockText = uri ? `[Resource link${title}] ${uri}` : `[Resource link${title}]`;
63
+ }
64
+ if (blockText !== undefined) {
65
+ // Guard: reject before allocating the full concatenated string
66
+ if (maxBytes !== undefined) {
67
+ const separatorBytes = parts.length > 0 ? 1 : 0; // "\n" added by join() between blocks
68
+ totalBytes += separatorBytes + Buffer.byteLength(blockText, "utf-8");
69
+ if (totalBytes > maxBytes) {
70
+ throw new Error(`Prompt exceeds maximum allowed size of ${maxBytes} bytes`);
71
+ }
72
+ }
73
+ parts.push(blockText);
19
74
  }
20
75
  }
21
76
  return parts.join("\n");
@@ -23,11 +78,13 @@ export function extractTextFromPrompt(prompt) {
23
78
  export function extractAttachmentsFromPrompt(prompt) {
24
79
  const attachments = [];
25
80
  for (const block of prompt) {
26
- if (block.type !== "image")
81
+ if (block.type !== "image") {
27
82
  continue;
83
+ }
28
84
  const image = block;
29
- if (!image.data || !image.mimeType)
85
+ if (!image.data || !image.mimeType) {
30
86
  continue;
87
+ }
31
88
  attachments.push({
32
89
  type: "image",
33
90
  mimeType: image.mimeType,
@@ -38,8 +95,9 @@ export function extractAttachmentsFromPrompt(prompt) {
38
95
  }
39
96
  export function formatToolTitle(name, args) {
40
97
  const base = name ?? "tool";
41
- if (!args || Object.keys(args).length === 0)
98
+ if (!args || Object.keys(args).length === 0) {
42
99
  return base;
100
+ }
43
101
  const parts = Object.entries(args).map(([key, value]) => {
44
102
  const raw = typeof value === "string" ? value : JSON.stringify(value);
45
103
  const safe = raw.length > 100 ? `${raw.slice(0, 100)}...` : raw;
@@ -48,23 +106,30 @@ export function formatToolTitle(name, args) {
48
106
  return `${base}: ${parts.join(", ")}`;
49
107
  }
50
108
  export function inferToolKind(name) {
51
- if (!name)
109
+ if (!name) {
52
110
  return "other";
111
+ }
53
112
  const normalized = name.toLowerCase();
54
- if (normalized.includes("read"))
113
+ if (normalized.includes("read")) {
55
114
  return "read";
56
- if (normalized.includes("write") || normalized.includes("edit"))
115
+ }
116
+ if (normalized.includes("write") || normalized.includes("edit")) {
57
117
  return "edit";
58
- if (normalized.includes("delete") || normalized.includes("remove"))
118
+ }
119
+ if (normalized.includes("delete") || normalized.includes("remove")) {
59
120
  return "delete";
60
- if (normalized.includes("move") || normalized.includes("rename"))
121
+ }
122
+ if (normalized.includes("move") || normalized.includes("rename")) {
61
123
  return "move";
62
- if (normalized.includes("search") || normalized.includes("find"))
124
+ }
125
+ if (normalized.includes("search") || normalized.includes("find")) {
63
126
  return "search";
127
+ }
64
128
  if (normalized.includes("exec") || normalized.includes("run") || normalized.includes("bash")) {
65
129
  return "execute";
66
130
  }
67
- if (normalized.includes("fetch") || normalized.includes("http"))
131
+ if (normalized.includes("fetch") || normalized.includes("http")) {
68
132
  return "fetch";
133
+ }
69
134
  return "other";
70
135
  }
package/dist/acp/meta.js CHANGED
@@ -1,30 +1,36 @@
1
1
  export function readString(meta, keys) {
2
- if (!meta)
2
+ if (!meta) {
3
3
  return undefined;
4
+ }
4
5
  for (const key of keys) {
5
6
  const value = meta[key];
6
- if (typeof value === "string" && value.trim())
7
+ if (typeof value === "string" && value.trim()) {
7
8
  return value.trim();
9
+ }
8
10
  }
9
11
  return undefined;
10
12
  }
11
13
  export function readBool(meta, keys) {
12
- if (!meta)
14
+ if (!meta) {
13
15
  return undefined;
16
+ }
14
17
  for (const key of keys) {
15
18
  const value = meta[key];
16
- if (typeof value === "boolean")
19
+ if (typeof value === "boolean") {
17
20
  return value;
21
+ }
18
22
  }
19
23
  return undefined;
20
24
  }
21
25
  export function readNumber(meta, keys) {
22
- if (!meta)
26
+ if (!meta) {
23
27
  return undefined;
28
+ }
24
29
  for (const key of keys) {
25
30
  const value = meta[key];
26
- if (typeof value === "number" && Number.isFinite(value))
31
+ if (typeof value === "number" && Number.isFinite(value)) {
27
32
  return value;
33
+ }
28
34
  }
29
35
  return undefined;
30
36
  }
@@ -3,21 +3,20 @@ import { resolveStateDir } from "../config/paths.js";
3
3
  import { DEFAULT_AGENT_ID } from "../routing/session-key.js";
4
4
  import { resolveUserPath } from "../utils.js";
5
5
  export function resolvePoolbotAgentDir() {
6
- const override = process.env.POOLBOT_AGENT_DIR?.trim() ||
7
- process.env.CLAWDBOT_AGENT_DIR?.trim() ||
8
- process.env.PI_CODING_AGENT_DIR?.trim();
9
- if (override)
6
+ const override = process.env.POOLBOT_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
7
+ if (override) {
10
8
  return resolveUserPath(override);
9
+ }
11
10
  const defaultAgentDir = path.join(resolveStateDir(), "agents", DEFAULT_AGENT_ID, "agent");
12
11
  return resolveUserPath(defaultAgentDir);
13
12
  }
14
- export function ensurePoolbotAgentEnv() {
13
+ export function ensurePoolBotAgentEnv() {
15
14
  const dir = resolvePoolbotAgentDir();
16
- if (!process.env.POOLBOT_AGENT_DIR)
15
+ if (!process.env.POOLBOT_AGENT_DIR) {
17
16
  process.env.POOLBOT_AGENT_DIR = dir;
18
- if (!process.env.CLAWDBOT_AGENT_DIR)
19
- process.env.CLAWDBOT_AGENT_DIR = dir;
20
- if (!process.env.PI_CODING_AGENT_DIR)
17
+ }
18
+ if (!process.env.PI_CODING_AGENT_DIR) {
21
19
  process.env.PI_CODING_AGENT_DIR = dir;
20
+ }
22
21
  return dir;
23
22
  }
@@ -4,17 +4,19 @@ import { resolveStateDir } from "../config/paths.js";
4
4
  import { DEFAULT_AGENT_ID, normalizeAgentId, parseAgentSessionKey, } from "../routing/session-key.js";
5
5
  import { normalizeSkillFilter } from "./skills/filter.js";
6
6
  import { resolveUserPath } from "../utils.js";
7
+ import { createSubsystemLogger } from "../logging/subsystem.js";
7
8
  import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
9
+ const log = createSubsystemLogger("agent-scope");
8
10
  export { resolveAgentIdFromSessionKey } from "../routing/session-key.js";
9
11
  let defaultAgentWarned = false;
10
- function listAgents(cfg) {
12
+ export function listAgentEntries(cfg) {
11
13
  const list = cfg.agents?.list;
12
14
  if (!Array.isArray(list))
13
15
  return [];
14
16
  return list.filter((entry) => Boolean(entry && typeof entry === "object"));
15
17
  }
16
18
  export function listAgentIds(cfg) {
17
- const agents = listAgents(cfg);
19
+ const agents = listAgentEntries(cfg);
18
20
  if (agents.length === 0)
19
21
  return [DEFAULT_AGENT_ID];
20
22
  const seen = new Set();
@@ -29,13 +31,13 @@ export function listAgentIds(cfg) {
29
31
  return ids.length > 0 ? ids : [DEFAULT_AGENT_ID];
30
32
  }
31
33
  export function resolveDefaultAgentId(cfg) {
32
- const agents = listAgents(cfg);
34
+ const agents = listAgentEntries(cfg);
33
35
  if (agents.length === 0)
34
36
  return DEFAULT_AGENT_ID;
35
37
  const defaults = agents.filter((agent) => agent?.default);
36
38
  if (defaults.length > 1 && !defaultAgentWarned) {
37
39
  defaultAgentWarned = true;
38
- console.warn("Multiple agents marked default=true; using the first entry as default.");
40
+ log.warn("Multiple agents marked default=true; using the first entry as default.");
39
41
  }
40
42
  const chosen = (defaults[0] ?? agents[0])?.id?.trim();
41
43
  return normalizeAgentId(chosen || DEFAULT_AGENT_ID);
@@ -53,7 +55,7 @@ export function resolveSessionAgentId(params) {
53
55
  }
54
56
  function resolveAgentEntry(cfg, agentId) {
55
57
  const id = normalizeAgentId(agentId);
56
- return listAgents(cfg).find((entry) => normalizeAgentId(entry.id) === id);
58
+ return listAgentEntries(cfg).find((entry) => normalizeAgentId(entry.id) === id);
57
59
  }
58
60
  export function resolveAgentConfig(cfg, agentId) {
59
61
  const id = normalizeAgentId(agentId);
@@ -1,12 +1,37 @@
1
- import { getOAuthApiKey } from "@mariozechner/pi-ai";
2
- import lockfile from "proper-lockfile";
3
- import { refreshChutesTokens } from "../chutes-oauth.js";
1
+ import { getOAuthApiKey, getOAuthProviders, } from "@mariozechner/pi-ai";
2
+ import { withFileLock } from "../../infra/file-lock.js";
4
3
  import { refreshQwenPortalCredentials } from "../../providers/qwen-portal-oauth.js";
4
+ import { refreshChutesTokens } from "../chutes-oauth.js";
5
5
  import { AUTH_STORE_LOCK_OPTIONS, log } from "./constants.js";
6
6
  import { formatAuthDoctorHint } from "./doctor.js";
7
7
  import { ensureAuthStoreFile, resolveAuthStorePath } from "./paths.js";
8
8
  import { suggestOAuthProfileIdForLegacyDefault } from "./repair.js";
9
9
  import { ensureAuthProfileStore, saveAuthProfileStore } from "./store.js";
10
+ const OAUTH_PROVIDER_IDS = new Set(getOAuthProviders().map((provider) => provider.id));
11
+ const isOAuthProvider = (provider) => OAUTH_PROVIDER_IDS.has(provider);
12
+ const resolveOAuthProvider = (provider) => isOAuthProvider(provider) ? provider : null;
13
+ /** Bearer-token auth modes that are interchangeable (oauth tokens and raw tokens). */
14
+ const BEARER_AUTH_MODES = new Set(["oauth", "token"]);
15
+ const isCompatibleModeType = (mode, type) => {
16
+ if (!mode || !type) {
17
+ return false;
18
+ }
19
+ if (mode === type) {
20
+ return true;
21
+ }
22
+ // Both token and oauth represent bearer-token auth paths — allow bidirectional compat.
23
+ return BEARER_AUTH_MODES.has(mode) && BEARER_AUTH_MODES.has(type);
24
+ };
25
+ function isProfileConfigCompatible(params) {
26
+ const profileConfig = params.cfg?.auth?.profiles?.[params.profileId];
27
+ if (profileConfig && profileConfig.provider !== params.provider) {
28
+ return false;
29
+ }
30
+ if (profileConfig && !isCompatibleModeType(profileConfig.mode, params.mode)) {
31
+ return false;
32
+ }
33
+ return true;
34
+ }
10
35
  function buildOAuthApiKey(provider, credentials) {
11
36
  const needsProjectId = provider === "google-gemini-cli" || provider === "google-antigravity";
12
37
  return needsProjectId
@@ -16,18 +41,62 @@ function buildOAuthApiKey(provider, credentials) {
16
41
  })
17
42
  : credentials.access;
18
43
  }
44
+ function buildApiKeyProfileResult(params) {
45
+ return {
46
+ apiKey: params.apiKey,
47
+ provider: params.provider,
48
+ email: params.email,
49
+ };
50
+ }
51
+ function buildOAuthProfileResult(params) {
52
+ return buildApiKeyProfileResult({
53
+ apiKey: buildOAuthApiKey(params.provider, params.credentials),
54
+ provider: params.provider,
55
+ email: params.email,
56
+ });
57
+ }
58
+ function isExpiredCredential(expires) {
59
+ return (typeof expires === "number" && Number.isFinite(expires) && expires > 0 && Date.now() >= expires);
60
+ }
61
+ function adoptNewerMainOAuthCredential(params) {
62
+ if (!params.agentDir) {
63
+ return null;
64
+ }
65
+ try {
66
+ const mainStore = ensureAuthProfileStore(undefined);
67
+ const mainCred = mainStore.profiles[params.profileId];
68
+ if (mainCred?.type === "oauth" &&
69
+ mainCred.provider === params.cred.provider &&
70
+ Number.isFinite(mainCred.expires) &&
71
+ (!Number.isFinite(params.cred.expires) || mainCred.expires > params.cred.expires)) {
72
+ params.store.profiles[params.profileId] = { ...mainCred };
73
+ saveAuthProfileStore(params.store, params.agentDir);
74
+ log.info("adopted newer OAuth credentials from main agent", {
75
+ profileId: params.profileId,
76
+ agentDir: params.agentDir,
77
+ expires: new Date(mainCred.expires).toISOString(),
78
+ });
79
+ return mainCred;
80
+ }
81
+ }
82
+ catch (err) {
83
+ // Best-effort: don't crash if main agent store is missing or unreadable.
84
+ log.debug("adoptNewerMainOAuthCredential failed", {
85
+ profileId: params.profileId,
86
+ error: err instanceof Error ? err.message : String(err),
87
+ });
88
+ }
89
+ return null;
90
+ }
19
91
  async function refreshOAuthTokenWithLock(params) {
20
92
  const authPath = resolveAuthStorePath(params.agentDir);
21
93
  ensureAuthStoreFile(authPath);
22
- let release;
23
- try {
24
- release = await lockfile.lock(authPath, {
25
- ...AUTH_STORE_LOCK_OPTIONS,
26
- });
94
+ return await withFileLock(authPath, AUTH_STORE_LOCK_OPTIONS, async () => {
27
95
  const store = ensureAuthProfileStore(params.agentDir);
28
96
  const cred = store.profiles[params.profileId];
29
- if (!cred || cred.type !== "oauth")
97
+ if (!cred || cred.type !== "oauth") {
30
98
  return null;
99
+ }
31
100
  if (Date.now() < cred.expires) {
32
101
  return {
33
102
  apiKey: buildOAuthApiKey(cred.provider, cred),
@@ -49,9 +118,16 @@ async function refreshOAuthTokenWithLock(params) {
49
118
  const newCredentials = await refreshQwenPortalCredentials(cred);
50
119
  return { apiKey: newCredentials.access, newCredentials };
51
120
  })()
52
- : await getOAuthApiKey(cred.provider, oauthCreds);
53
- if (!result)
121
+ : await (async () => {
122
+ const oauthProvider = resolveOAuthProvider(cred.provider);
123
+ if (!oauthProvider) {
124
+ return null;
125
+ }
126
+ return await getOAuthApiKey(oauthProvider, oauthCreds);
127
+ })();
128
+ if (!result) {
54
129
  return null;
130
+ }
55
131
  store.profiles[params.profileId] = {
56
132
  ...cred,
57
133
  ...result.newCredentials,
@@ -59,104 +135,111 @@ async function refreshOAuthTokenWithLock(params) {
59
135
  };
60
136
  saveAuthProfileStore(store, params.agentDir);
61
137
  return result;
62
- }
63
- finally {
64
- if (release) {
65
- try {
66
- await release();
67
- }
68
- catch {
69
- // ignore unlock errors
70
- }
71
- }
72
- }
138
+ });
73
139
  }
74
140
  async function tryResolveOAuthProfile(params) {
75
141
  const { cfg, store, profileId } = params;
76
142
  const cred = store.profiles[profileId];
77
- if (!cred || cred.type !== "oauth")
78
- return null;
79
- const profileConfig = cfg?.auth?.profiles?.[profileId];
80
- if (profileConfig && profileConfig.provider !== cred.provider)
143
+ if (!cred || cred.type !== "oauth") {
81
144
  return null;
82
- if (profileConfig && profileConfig.mode !== cred.type)
145
+ }
146
+ if (!isProfileConfigCompatible({
147
+ cfg,
148
+ profileId,
149
+ provider: cred.provider,
150
+ mode: cred.type,
151
+ })) {
83
152
  return null;
153
+ }
84
154
  if (Date.now() < cred.expires) {
85
- return {
86
- apiKey: buildOAuthApiKey(cred.provider, cred),
155
+ return buildOAuthProfileResult({
87
156
  provider: cred.provider,
157
+ credentials: cred,
88
158
  email: cred.email,
89
- };
159
+ });
90
160
  }
91
161
  const refreshed = await refreshOAuthTokenWithLock({
92
162
  profileId,
93
163
  agentDir: params.agentDir,
94
164
  });
95
- if (!refreshed)
165
+ if (!refreshed) {
96
166
  return null;
97
- return {
167
+ }
168
+ return buildApiKeyProfileResult({
98
169
  apiKey: refreshed.apiKey,
99
170
  provider: cred.provider,
100
171
  email: cred.email,
101
- };
172
+ });
102
173
  }
103
174
  export async function resolveApiKeyForProfile(params) {
104
175
  const { cfg, store, profileId } = params;
105
176
  const cred = store.profiles[profileId];
106
- if (!cred)
107
- return null;
108
- const profileConfig = cfg?.auth?.profiles?.[profileId];
109
- if (profileConfig && profileConfig.provider !== cred.provider)
177
+ if (!cred) {
110
178
  return null;
111
- if (profileConfig && profileConfig.mode !== cred.type) {
179
+ }
180
+ if (!isProfileConfigCompatible({
181
+ cfg,
182
+ profileId,
183
+ provider: cred.provider,
184
+ mode: cred.type,
112
185
  // Compatibility: treat "oauth" config as compatible with stored token profiles.
113
- if (!(profileConfig.mode === "oauth" && cred.type === "token"))
114
- return null;
186
+ allowOAuthTokenCompatibility: true,
187
+ })) {
188
+ return null;
115
189
  }
116
190
  if (cred.type === "api_key") {
117
- return { apiKey: cred.key, provider: cred.provider, email: cred.email };
191
+ const key = cred.key?.trim();
192
+ if (!key) {
193
+ return null;
194
+ }
195
+ return buildApiKeyProfileResult({ apiKey: key, provider: cred.provider, email: cred.email });
118
196
  }
119
197
  if (cred.type === "token") {
120
198
  const token = cred.token?.trim();
121
- if (!token)
199
+ if (!token) {
122
200
  return null;
123
- if (typeof cred.expires === "number" &&
124
- Number.isFinite(cred.expires) &&
125
- cred.expires > 0 &&
126
- Date.now() >= cred.expires) {
201
+ }
202
+ if (isExpiredCredential(cred.expires)) {
127
203
  return null;
128
204
  }
129
- return { apiKey: token, provider: cred.provider, email: cred.email };
205
+ return buildApiKeyProfileResult({ apiKey: token, provider: cred.provider, email: cred.email });
130
206
  }
131
- if (Date.now() < cred.expires) {
132
- return {
133
- apiKey: buildOAuthApiKey(cred.provider, cred),
134
- provider: cred.provider,
135
- email: cred.email,
136
- };
207
+ const oauthCred = adoptNewerMainOAuthCredential({
208
+ store,
209
+ profileId,
210
+ agentDir: params.agentDir,
211
+ cred,
212
+ }) ?? cred;
213
+ if (Date.now() < oauthCred.expires) {
214
+ return buildOAuthProfileResult({
215
+ provider: oauthCred.provider,
216
+ credentials: oauthCred,
217
+ email: oauthCred.email,
218
+ });
137
219
  }
138
220
  try {
139
221
  const result = await refreshOAuthTokenWithLock({
140
222
  profileId,
141
223
  agentDir: params.agentDir,
142
224
  });
143
- if (!result)
225
+ if (!result) {
144
226
  return null;
145
- return {
227
+ }
228
+ return buildApiKeyProfileResult({
146
229
  apiKey: result.apiKey,
147
230
  provider: cred.provider,
148
231
  email: cred.email,
149
- };
232
+ });
150
233
  }
151
234
  catch (error) {
152
235
  const refreshedStore = ensureAuthProfileStore(params.agentDir);
153
236
  const refreshed = refreshedStore.profiles[profileId];
154
237
  if (refreshed?.type === "oauth" && Date.now() < refreshed.expires) {
155
- return {
156
- apiKey: buildOAuthApiKey(refreshed.provider, refreshed),
238
+ return buildOAuthProfileResult({
157
239
  provider: refreshed.provider,
240
+ credentials: refreshed,
158
241
  email: refreshed.email ?? cred.email,
159
- };
242
+ });
160
243
  }
161
244
  const fallbackProfileId = suggestOAuthProfileIdForLegacyDefault({
162
245
  cfg,
@@ -172,8 +255,9 @@ export async function resolveApiKeyForProfile(params) {
172
255
  profileId: fallbackProfileId,
173
256
  agentDir: params.agentDir,
174
257
  });
175
- if (fallbackResolved)
258
+ if (fallbackResolved) {
176
259
  return fallbackResolved;
260
+ }
177
261
  }
178
262
  catch {
179
263
  // keep original error
@@ -193,11 +277,11 @@ export async function resolveApiKeyForProfile(params) {
193
277
  agentDir: params.agentDir,
194
278
  expires: new Date(mainCred.expires).toISOString(),
195
279
  });
196
- return {
197
- apiKey: buildOAuthApiKey(mainCred.provider, mainCred),
280
+ return buildOAuthProfileResult({
198
281
  provider: mainCred.provider,
282
+ credentials: mainCred,
199
283
  email: mainCred.email,
200
- };
284
+ });
201
285
  }
202
286
  }
203
287
  catch {
@@ -213,6 +297,6 @@ export async function resolveApiKeyForProfile(params) {
213
297
  });
214
298
  throw new Error(`OAuth token refresh failed for ${cred.provider}: ${message}. ` +
215
299
  "Please try again or re-authenticate." +
216
- (hint ? `\n\n${hint}` : ""));
300
+ (hint ? `\n\n${hint}` : ""), { cause: error });
217
301
  }
218
302
  }
@@ -1,10 +1,11 @@
1
1
  import { updateSessionStore } from "../../config/sessions.js";
2
- import { normalizeProviderId } from "../model-selection.js";
3
2
  import { ensureAuthProfileStore, isProfileInCooldown, resolveAuthProfileOrder, } from "../auth-profiles.js";
3
+ import { normalizeProviderId } from "../model-selection.js";
4
4
  function isProfileForProvider(params) {
5
5
  const entry = params.store.profiles[params.profileId];
6
- if (!entry?.provider)
6
+ if (!entry?.provider) {
7
7
  return false;
8
+ }
8
9
  return normalizeProviderId(entry.provider) === normalizeProviderId(params.provider);
9
10
  }
10
11
  export async function clearSessionAuthProfileOverride(params) {
@@ -22,8 +23,9 @@ export async function clearSessionAuthProfileOverride(params) {
22
23
  }
23
24
  export async function resolveSessionAuthProfileOverride(params) {
24
25
  const { cfg, provider, agentDir, sessionEntry, sessionStore, sessionKey, storePath, isNewSession, } = params;
25
- if (!sessionEntry || !sessionStore || !sessionKey)
26
+ if (!sessionEntry || !sessionStore || !sessionKey) {
26
27
  return sessionEntry?.authProfileOverride;
28
+ }
27
29
  const store = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
28
30
  const order = resolveAuthProfileOrder({ cfg, store, provider });
29
31
  let current = sessionEntry.authProfileOverride?.trim();
@@ -39,17 +41,20 @@ export async function resolveSessionAuthProfileOverride(params) {
39
41
  await clearSessionAuthProfileOverride({ sessionEntry, sessionStore, sessionKey, storePath });
40
42
  current = undefined;
41
43
  }
42
- if (order.length === 0)
44
+ if (order.length === 0) {
43
45
  return undefined;
46
+ }
44
47
  const pickFirstAvailable = () => order.find((profileId) => !isProfileInCooldown(store, profileId)) ?? order[0];
45
48
  const pickNextAvailable = (active) => {
46
49
  const startIndex = order.indexOf(active);
47
- if (startIndex < 0)
50
+ if (startIndex < 0) {
48
51
  return pickFirstAvailable();
52
+ }
49
53
  for (let offset = 1; offset <= order.length; offset += 1) {
50
54
  const candidate = order[(startIndex + offset) % order.length];
51
- if (!isProfileInCooldown(store, candidate))
55
+ if (!isProfileInCooldown(store, candidate)) {
52
56
  return candidate;
57
+ }
53
58
  }
54
59
  return order[startIndex] ?? order[0];
55
60
  };
@@ -76,8 +81,9 @@ export async function resolveSessionAuthProfileOverride(params) {
76
81
  else if (!current || isProfileInCooldown(store, current)) {
77
82
  next = pickFirstAvailable();
78
83
  }
79
- if (!next)
84
+ if (!next) {
80
85
  return current;
86
+ }
81
87
  const shouldPersist = next !== sessionEntry.authProfileOverride ||
82
88
  sessionEntry.authProfileOverrideSource !== "auto" ||
83
89
  sessionEntry.authProfileOverrideCompactionCount !== compactionCount;