@poolzin/pool-bot 2026.2.24 → 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 (646) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/acp/client.js +207 -18
  3. package/dist/acp/event-mapper.js +87 -22
  4. package/dist/acp/meta.js +12 -6
  5. package/dist/acp/secret-file.js +22 -0
  6. package/dist/agents/agent-paths.js +8 -9
  7. package/dist/agents/agent-scope.js +17 -5
  8. package/dist/agents/auth-profiles/oauth.js +148 -64
  9. package/dist/agents/auth-profiles/session-override.js +13 -7
  10. package/dist/agents/bash-process-registry.test-helpers.js +29 -0
  11. package/dist/agents/bash-tools.exec-approval-request.js +20 -0
  12. package/dist/agents/bash-tools.exec-host-gateway.js +240 -0
  13. package/dist/agents/bash-tools.exec-host-node.js +235 -0
  14. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  15. package/dist/agents/bash-tools.exec-types.js +1 -0
  16. package/dist/agents/bash-tools.process.js +224 -218
  17. package/dist/agents/bedrock-discovery.js +3 -1
  18. package/dist/agents/byteplus-models.js +97 -0
  19. package/dist/agents/chutes-oauth.js +1 -0
  20. package/dist/agents/cli-runner/helpers.js +4 -0
  21. package/dist/agents/compaction.js +41 -14
  22. package/dist/agents/content-blocks.js +16 -0
  23. package/dist/agents/doubao-models.js +121 -0
  24. package/dist/agents/failover-error.js +2 -0
  25. package/dist/agents/huggingface-models.js +5 -3
  26. package/dist/agents/live-model-filter.js +5 -0
  27. package/dist/agents/minimax-vlm.js +10 -8
  28. package/dist/agents/model-auth.js +6 -0
  29. package/dist/agents/model-catalog.js +3 -1
  30. package/dist/agents/model-fallback.js +96 -101
  31. package/dist/agents/model-selection.js +7 -1
  32. package/dist/agents/models-config.providers.js +364 -165
  33. package/dist/agents/ollama-stream.js +117 -4
  34. package/dist/agents/opencode-zen-models.js +22 -11
  35. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  36. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  37. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  38. package/dist/agents/pi-embedded-helpers.js +1 -1
  39. package/dist/agents/pi-embedded-payloads.js +1 -0
  40. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  41. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  42. package/dist/agents/pi-embedded-runner/google.js +20 -8
  43. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  44. package/dist/agents/pi-embedded-runner/run.js +71 -12
  45. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +34 -0
  46. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  47. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  48. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  49. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  50. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  51. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  52. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  53. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  54. package/dist/agents/pi-embedded-subscribe.js +9 -4
  55. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  56. package/dist/agents/pi-embedded-utils.js +3 -0
  57. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  58. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  59. package/dist/agents/pi-settings.js +40 -0
  60. package/dist/agents/pi-tools.policy.js +2 -1
  61. package/dist/agents/provider/config-loader.js +1 -1
  62. package/dist/agents/sandbox/browser.js +170 -33
  63. package/dist/agents/sandbox/config-hash.js +14 -27
  64. package/dist/agents/sandbox/config.js +21 -2
  65. package/dist/agents/sandbox/constants.js +2 -0
  66. package/dist/agents/sandbox/docker.js +16 -2
  67. package/dist/agents/sandbox/novnc-auth.js +62 -0
  68. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  69. package/dist/agents/sandbox/shared.js +10 -6
  70. package/dist/agents/sandbox-paths.js +24 -11
  71. package/dist/agents/schema/clean-for-gemini.js +132 -85
  72. package/dist/agents/session-slug.js +10 -5
  73. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  74. package/dist/agents/session-tool-result-guard.js +3 -1
  75. package/dist/agents/session-transcript-repair.js +40 -6
  76. package/dist/agents/skills/bundled-dir.js +19 -5
  77. package/dist/agents/skills/env-overrides.js +124 -43
  78. package/dist/agents/skills/frontmatter.js +6 -6
  79. package/dist/agents/skills/plugin-skills.js +14 -7
  80. package/dist/agents/skills/workspace.js +1 -0
  81. package/dist/agents/skills.test-helpers.js +13 -0
  82. package/dist/agents/stable-stringify.js +12 -0
  83. package/dist/agents/subagent-announce.js +251 -49
  84. package/dist/agents/subagent-lifecycle-events.js +19 -0
  85. package/dist/agents/subagent-registry-cleanup.js +31 -0
  86. package/dist/agents/subagent-registry-completion.js +68 -0
  87. package/dist/agents/subagent-registry-queries.js +117 -0
  88. package/dist/agents/subagent-registry-state.js +46 -0
  89. package/dist/agents/subagent-registry.js +252 -221
  90. package/dist/agents/subagent-registry.mocks.shared.js +12 -0
  91. package/dist/agents/subagent-registry.store.js +1 -0
  92. package/dist/agents/subagent-registry.types.js +1 -0
  93. package/dist/agents/subagent-spawn.js +195 -7
  94. package/dist/agents/system-prompt.js +22 -6
  95. package/dist/agents/test-helpers/assistant-message-fixtures.js +29 -0
  96. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  97. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  98. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +27 -0
  99. package/dist/agents/timeout.js +18 -6
  100. package/dist/agents/tool-call-id.js +1 -1
  101. package/dist/agents/tool-display-common.js +162 -29
  102. package/dist/agents/tool-images.js +82 -9
  103. package/dist/agents/tool-policy-shared.js +108 -0
  104. package/dist/agents/tool-policy.js +51 -26
  105. package/dist/agents/tools/browser-tool.js +160 -54
  106. package/dist/agents/tools/canvas-tool.js +27 -1
  107. package/dist/agents/tools/common.js +45 -0
  108. package/dist/agents/tools/cron-tool.test-helpers.js +12 -0
  109. package/dist/agents/tools/discord-actions-guild.js +4 -1
  110. package/dist/agents/tools/discord-actions-moderation-shared.js +27 -0
  111. package/dist/agents/tools/gateway-tool.js +3 -1
  112. package/dist/agents/tools/image-tool.js +214 -99
  113. package/dist/agents/tools/nodes-utils.js +1 -10
  114. package/dist/agents/tools/sessions-history-tool.js +140 -108
  115. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  116. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  117. package/dist/agents/tools/subagents-tool.js +2 -1
  118. package/dist/agents/tools/whatsapp-actions.js +10 -2
  119. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  120. package/dist/agents/transcript-policy.js +22 -8
  121. package/dist/agents/venice-models.js +11 -3
  122. package/dist/agents/workspace.js +222 -46
  123. package/dist/auto-reply/commands-registry.data.js +51 -0
  124. package/dist/auto-reply/commands-registry.js +19 -21
  125. package/dist/auto-reply/fallback-state.js +114 -0
  126. package/dist/auto-reply/group-activation.js +10 -5
  127. package/dist/auto-reply/inbound-debounce.js +10 -5
  128. package/dist/auto-reply/model-runtime.js +68 -0
  129. package/dist/auto-reply/reply/abort.js +1 -1
  130. package/dist/auto-reply/reply/agent-runner-execution.js +40 -5
  131. package/dist/auto-reply/reply/agent-runner.js +165 -39
  132. package/dist/auto-reply/reply/bash-command.js +41 -39
  133. package/dist/auto-reply/reply/command-gates.js +25 -0
  134. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  135. package/dist/auto-reply/reply/commands-bash.js +6 -5
  136. package/dist/auto-reply/reply/commands-config.js +30 -28
  137. package/dist/auto-reply/reply/commands-core.js +2 -1
  138. package/dist/auto-reply/reply/commands-info.js +1 -0
  139. package/dist/auto-reply/reply/commands-models.js +65 -14
  140. package/dist/auto-reply/reply/commands-session.js +237 -82
  141. package/dist/auto-reply/reply/commands-setunset-standard.js +13 -0
  142. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  143. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  144. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  145. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  146. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  147. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  148. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  149. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  150. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  151. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  152. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  153. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  154. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  155. package/dist/auto-reply/reply/commands-tts.js +10 -5
  156. package/dist/auto-reply/reply/config-value.js +10 -5
  157. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  158. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  159. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  160. package/dist/auto-reply/reply/followup-runner.js +1 -0
  161. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  162. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  163. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  164. package/dist/auto-reply/reply/get-reply.js +71 -12
  165. package/dist/auto-reply/reply/model-selection.js +80 -39
  166. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  167. package/dist/auto-reply/reply/queue/state.js +13 -12
  168. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  169. package/dist/auto-reply/reply/reply-reference.js +9 -8
  170. package/dist/auto-reply/reply/route-reply.js +15 -8
  171. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  172. package/dist/auto-reply/reply/session.js +22 -6
  173. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  174. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  175. package/dist/auto-reply/reply/typing.js +46 -21
  176. package/dist/auto-reply/send-policy.js +14 -7
  177. package/dist/auto-reply/status.js +140 -16
  178. package/dist/auto-reply/templating.js +10 -5
  179. package/dist/auto-reply/thinking.js +7 -16
  180. package/dist/auto-reply/tokens.js +21 -5
  181. package/dist/browser/bridge-server.js +36 -20
  182. package/dist/browser/cdp.helpers.js +7 -14
  183. package/dist/browser/cdp.js +35 -15
  184. package/dist/browser/chrome.profile-decoration.js +7 -4
  185. package/dist/browser/config.js +30 -0
  186. package/dist/browser/extension-relay-auth.js +55 -0
  187. package/dist/browser/extension-relay.js +74 -29
  188. package/dist/browser/navigation-guard.js +39 -0
  189. package/dist/browser/paths.js +77 -0
  190. package/dist/browser/profiles.js +13 -8
  191. package/dist/browser/pw-ai-module.js +10 -5
  192. package/dist/browser/pw-session.js +76 -39
  193. package/dist/browser/pw-tools-core.interactions.js +14 -7
  194. package/dist/browser/pw-tools-core.state.js +12 -6
  195. package/dist/browser/routes/agent.act.js +431 -424
  196. package/dist/browser/routes/agent.shared.js +47 -3
  197. package/dist/browser/routes/agent.snapshot.js +122 -116
  198. package/dist/browser/routes/agent.storage.js +303 -297
  199. package/dist/browser/routes/tabs.js +154 -100
  200. package/dist/browser/server-context.js +7 -0
  201. package/dist/browser/server-lifecycle.js +37 -0
  202. package/dist/build-info.json +3 -3
  203. package/dist/channels/allow-from.js +26 -0
  204. package/dist/channels/allowlists/resolve-utils.js +43 -19
  205. package/dist/channels/channel-config.js +14 -7
  206. package/dist/channels/draft-stream-loop.js +7 -0
  207. package/dist/channels/model-overrides.js +82 -0
  208. package/dist/channels/plugins/account-action-gate.js +13 -0
  209. package/dist/channels/plugins/message-actions.js +10 -0
  210. package/dist/channels/plugins/normalize/imessage.js +14 -7
  211. package/dist/channels/plugins/normalize/slack.js +10 -5
  212. package/dist/channels/plugins/normalize/telegram.js +14 -7
  213. package/dist/channels/plugins/outbound/discord.js +80 -8
  214. package/dist/channels/plugins/outbound/signal.js +11 -11
  215. package/dist/channels/plugins/setup-helpers.js +10 -5
  216. package/dist/channels/sender-label.js +14 -7
  217. package/dist/channels/session.js +4 -2
  218. package/dist/channels/status-reactions.js +297 -0
  219. package/dist/channels/telegram/api.js +18 -0
  220. package/dist/cli/argv.js +84 -21
  221. package/dist/cli/banner.js +3 -2
  222. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  223. package/dist/cli/cli-name.js +11 -11
  224. package/dist/cli/cli-utils.js +13 -3
  225. package/dist/cli/command-format.js +1 -1
  226. package/dist/cli/config-cli.js +1 -1
  227. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  228. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  229. package/dist/cli/daemon-cli/restart-health.js +126 -0
  230. package/dist/cli/daemon-cli/status.gather.js +9 -13
  231. package/dist/cli/daemon-cli/status.print.js +2 -10
  232. package/dist/cli/deps.js +27 -22
  233. package/dist/cli/exec-approvals-cli.js +92 -124
  234. package/dist/cli/gateway-cli/run-loop.js +23 -5
  235. package/dist/cli/memory-cli.js +158 -61
  236. package/dist/cli/node-cli/register.js +14 -5
  237. package/dist/cli/nodes-cli/register.push.js +63 -0
  238. package/dist/cli/nodes-media-utils.js +26 -0
  239. package/dist/cli/outbound-send-deps.js +2 -9
  240. package/dist/cli/outbound-send-mapping.js +11 -0
  241. package/dist/cli/pairing-cli.js +40 -14
  242. package/dist/cli/plugins-cli.js +250 -73
  243. package/dist/cli/ports.js +11 -10
  244. package/dist/cli/program/build-program.js +3 -1
  245. package/dist/cli/program/command-registry.js +214 -136
  246. package/dist/cli/program/command-tree.js +16 -0
  247. package/dist/cli/program/help.js +43 -12
  248. package/dist/cli/program/preaction.js +13 -9
  249. package/dist/cli/program/register.configure.js +3 -18
  250. package/dist/cli/program/register.maintenance.js +2 -2
  251. package/dist/cli/program/register.onboard.js +2 -0
  252. package/dist/cli/program/register.status-health-sessions.js +16 -17
  253. package/dist/cli/program/register.subclis.js +93 -52
  254. package/dist/cli/route.js +12 -8
  255. package/dist/cli/system-cli.js +36 -46
  256. package/dist/cli/test-runtime-capture.js +24 -0
  257. package/dist/cli/update-cli/shared.js +22 -9
  258. package/dist/cli/update-cli/update-command.js +89 -14
  259. package/dist/cli/update-cli/wizard.js +6 -12
  260. package/dist/commands/agent/run-context.js +18 -5
  261. package/dist/commands/agent/session-store.js +17 -4
  262. package/dist/commands/agent.js +185 -89
  263. package/dist/commands/agents.bindings.js +14 -7
  264. package/dist/commands/agents.commands.add.js +13 -9
  265. package/dist/commands/agents.commands.identity.js +12 -6
  266. package/dist/commands/agents.commands.list.js +11 -6
  267. package/dist/commands/agents.config.js +8 -10
  268. package/dist/commands/agents.providers.js +12 -6
  269. package/dist/commands/auth-choice-options.js +103 -75
  270. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  271. package/dist/commands/auth-choice.apply.js +4 -0
  272. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  273. package/dist/commands/auth-choice.apply.openai.js +3 -1
  274. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  275. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  276. package/dist/commands/channels/remove.js +13 -6
  277. package/dist/commands/channels/shared.js +4 -14
  278. package/dist/commands/channels.mock-harness.js +23 -0
  279. package/dist/commands/configure.commands.js +14 -0
  280. package/dist/commands/configure.gateway.js +2 -4
  281. package/dist/commands/configure.js +1 -1
  282. package/dist/commands/configure.shared.js +11 -0
  283. package/dist/commands/daemon-install-helpers.js +2 -2
  284. package/dist/commands/daemon-install-runtime-warning.js +11 -0
  285. package/dist/commands/dashboard.js +12 -10
  286. package/dist/commands/docs.js +14 -8
  287. package/dist/commands/doctor-config-flow.js +11 -9
  288. package/dist/commands/doctor-legacy-config.js +281 -0
  289. package/dist/commands/doctor-state-integrity.js +99 -23
  290. package/dist/commands/doctor-update.js +12 -9
  291. package/dist/commands/models/list.list-command.js +7 -5
  292. package/dist/commands/models/set-image.js +2 -21
  293. package/dist/commands/node-daemon-install-helpers.js +10 -8
  294. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  295. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  296. package/dist/commands/onboard-auth.credentials.js +90 -13
  297. package/dist/commands/onboard-auth.js +1 -1
  298. package/dist/commands/onboard-auth.models.js +6 -5
  299. package/dist/commands/onboard-hooks.js +1 -1
  300. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  301. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  302. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  303. package/dist/commands/onboard-remote.js +14 -7
  304. package/dist/commands/onboard.js +11 -13
  305. package/dist/commands/sandbox-display.js +6 -5
  306. package/dist/commands/sessions.test-helpers.js +61 -0
  307. package/dist/commands/status-all/diagnosis.js +14 -10
  308. package/dist/commands/status-all/format.js +1 -0
  309. package/dist/commands/status.gateway-probe.js +1 -16
  310. package/dist/commands/systemd-linger.js +12 -6
  311. package/dist/config/agent-limits.js +2 -0
  312. package/dist/config/commands.js +32 -15
  313. package/dist/config/config-paths.js +9 -11
  314. package/dist/config/config.js +1 -1
  315. package/dist/config/defaults.js +22 -2
  316. package/dist/config/discord-preview-streaming.js +104 -0
  317. package/dist/config/env-substitution.js +62 -34
  318. package/dist/config/env-vars.js +45 -7
  319. package/dist/config/includes.js +4 -0
  320. package/dist/config/io.js +656 -171
  321. package/dist/config/legacy.migrations.part-1.js +189 -78
  322. package/dist/config/legacy.shared.js +3 -1
  323. package/dist/config/merge-patch.js +54 -4
  324. package/dist/config/prototype-keys.js +4 -0
  325. package/dist/config/redact-snapshot.js +404 -76
  326. package/dist/config/schema.help.js +44 -7
  327. package/dist/config/schema.js +58 -570
  328. package/dist/config/schema.labels.js +38 -6
  329. package/dist/config/sessions/delivery-info.js +10 -3
  330. package/dist/config/sessions/main-session.js +10 -5
  331. package/dist/config/sessions/session-file.js +33 -0
  332. package/dist/config/sessions/session-key.js +10 -5
  333. package/dist/config/sessions/store.js +1 -1
  334. package/dist/config/sessions.js +1 -0
  335. package/dist/config/validation.js +140 -85
  336. package/dist/config/zod-schema.agent-runtime.js +11 -0
  337. package/dist/config/zod-schema.hooks.js +40 -11
  338. package/dist/config/zod-schema.installs.js +20 -0
  339. package/dist/config/zod-schema.js +156 -20
  340. package/dist/config/zod-schema.providers-core.js +78 -4
  341. package/dist/config/zod-schema.providers.js +6 -1
  342. package/dist/config/zod-schema.session.js +41 -2
  343. package/dist/cron/run-log.js +3 -0
  344. package/dist/cron/schedule.js +21 -10
  345. package/dist/cron/service/ops.js +35 -21
  346. package/dist/cron/service/timer.js +116 -16
  347. package/dist/cron/stagger.js +3 -1
  348. package/dist/daemon/cmd-argv.js +21 -0
  349. package/dist/daemon/cmd-set.js +58 -0
  350. package/dist/daemon/service-types.js +1 -0
  351. package/dist/discord/api.js +12 -6
  352. package/dist/discord/draft-chunking.js +22 -0
  353. package/dist/discord/draft-stream.js +124 -0
  354. package/dist/discord/monitor/agent-components.js +1 -1
  355. package/dist/discord/monitor/commands.js +5 -0
  356. package/dist/discord/monitor/exec-approvals.js +357 -162
  357. package/dist/discord/monitor/gateway-plugin.js +2 -1
  358. package/dist/discord/monitor/listeners.js +37 -27
  359. package/dist/discord/monitor/message-handler.js +4 -1
  360. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  361. package/dist/discord/monitor/message-handler.process.js +246 -217
  362. package/dist/discord/monitor/message-utils.js +143 -6
  363. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  364. package/dist/discord/monitor/model-picker.js +651 -0
  365. package/dist/discord/monitor/native-command.js +573 -16
  366. package/dist/discord/monitor/provider.allowlist.js +223 -0
  367. package/dist/discord/monitor/provider.js +275 -347
  368. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  369. package/dist/discord/monitor/reply-delivery.js +123 -16
  370. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  371. package/dist/discord/monitor/thread-bindings.js +4 -0
  372. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  373. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  374. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  375. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  376. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  377. package/dist/discord/resolve-users.js +33 -21
  378. package/dist/discord/send.channels.js +15 -0
  379. package/dist/discord/send.js +3 -2
  380. package/dist/discord/send.outbound.js +82 -26
  381. package/dist/discord/send.permissions.js +83 -30
  382. package/dist/discord/send.reactions.js +8 -4
  383. package/dist/discord/token.js +10 -5
  384. package/dist/discord/voice/command.js +263 -0
  385. package/dist/discord/voice/manager.js +531 -0
  386. package/dist/gateway/auth.js +72 -13
  387. package/dist/gateway/call.js +152 -83
  388. package/dist/gateway/canvas-capability.js +75 -0
  389. package/dist/gateway/client.js +28 -4
  390. package/dist/gateway/config-reload.js +3 -4
  391. package/dist/gateway/control-plane-audit.js +28 -0
  392. package/dist/gateway/control-plane-rate-limit.js +53 -0
  393. package/dist/gateway/control-ui.js +219 -96
  394. package/dist/gateway/events.js +1 -0
  395. package/dist/gateway/hooks-mapping.js +88 -38
  396. package/dist/gateway/hooks.js +109 -54
  397. package/dist/gateway/http-auth-helpers.js +3 -2
  398. package/dist/gateway/http-common.js +22 -0
  399. package/dist/gateway/http-endpoint-helpers.js +1 -0
  400. package/dist/gateway/method-scopes.js +169 -0
  401. package/dist/gateway/net.js +74 -9
  402. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  403. package/dist/gateway/node-registry.js +10 -5
  404. package/dist/gateway/openai-http.js +1 -0
  405. package/dist/gateway/openresponses-http.js +121 -110
  406. package/dist/gateway/origin-check.js +1 -18
  407. package/dist/gateway/probe-auth.js +2 -0
  408. package/dist/gateway/protocol/index.js +4 -2
  409. package/dist/gateway/protocol/schema/cron.js +1 -0
  410. package/dist/gateway/protocol/schema/devices.js +1 -0
  411. package/dist/gateway/protocol/schema/protocol-schemas.js +4 -1
  412. package/dist/gateway/protocol/schema/push.js +18 -0
  413. package/dist/gateway/protocol/schema/sessions.js +6 -0
  414. package/dist/gateway/protocol/schema.js +1 -0
  415. package/dist/gateway/role-policy.js +17 -0
  416. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  417. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  418. package/dist/gateway/server-chat.js +83 -25
  419. package/dist/gateway/server-constants.js +10 -9
  420. package/dist/gateway/server-cron.js +1 -0
  421. package/dist/gateway/server-http.js +247 -54
  422. package/dist/gateway/server-maintenance.js +20 -5
  423. package/dist/gateway/server-methods/agent.js +162 -24
  424. package/dist/gateway/server-methods/chat.js +465 -130
  425. package/dist/gateway/server-methods/config.js +193 -152
  426. package/dist/gateway/server-methods/devices.js +17 -3
  427. package/dist/gateway/server-methods/models.js +11 -1
  428. package/dist/gateway/server-methods/nodes.helpers.js +12 -0
  429. package/dist/gateway/server-methods/nodes.js +251 -69
  430. package/dist/gateway/server-methods/push.js +53 -0
  431. package/dist/gateway/server-methods/sessions.js +64 -8
  432. package/dist/gateway/server-methods/usage.js +162 -75
  433. package/dist/gateway/server-node-events.js +29 -0
  434. package/dist/gateway/server-reload-handlers.js +2 -3
  435. package/dist/gateway/server-runtime-config.js +39 -13
  436. package/dist/gateway/server-runtime-state.js +2 -0
  437. package/dist/gateway/server-startup-memory.js +17 -11
  438. package/dist/gateway/server-ws-runtime.js +1 -0
  439. package/dist/gateway/server.impl.js +296 -139
  440. package/dist/gateway/session-preview.test-helpers.js +11 -0
  441. package/dist/gateway/session-utils.fs.js +32 -34
  442. package/dist/gateway/sessions-resolve.js +17 -5
  443. package/dist/gateway/startup-auth.js +126 -0
  444. package/dist/gateway/test-helpers.agent-results.js +15 -0
  445. package/dist/gateway/test-helpers.mocks.js +37 -14
  446. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  447. package/dist/gateway/test-helpers.server.js +161 -77
  448. package/dist/gateway/tools-invoke-http.js +21 -10
  449. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  450. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  451. package/dist/hooks/bundled/session-memory/handler.js +170 -38
  452. package/dist/hooks/frontmatter.js +6 -6
  453. package/dist/hooks/gmail-watcher-lifecycle.js +23 -0
  454. package/dist/hooks/gmail-watcher.js +11 -6
  455. package/dist/hooks/internal-hooks.js +11 -1
  456. package/dist/hooks/llm-slug-generator.js +4 -1
  457. package/dist/hooks/workspace.js +47 -17
  458. package/dist/imessage/accounts.js +9 -20
  459. package/dist/imessage/monitor/inbound-processing.js +2 -1
  460. package/dist/infra/archive-path.js +49 -0
  461. package/dist/infra/archive.js +174 -73
  462. package/dist/infra/control-ui-assets.js +14 -6
  463. package/dist/infra/device-pairing.js +204 -144
  464. package/dist/infra/env.js +10 -5
  465. package/dist/infra/exec-approvals-allowlist.js +141 -70
  466. package/dist/infra/exec-approvals-analysis.js +78 -20
  467. package/dist/infra/exec-approvals.js +5 -17
  468. package/dist/infra/exec-safe-bin-policy.js +277 -0
  469. package/dist/infra/fixed-window-rate-limit.js +33 -0
  470. package/dist/infra/fs-safe.js +71 -39
  471. package/dist/infra/gateway-lock.js +6 -2
  472. package/dist/infra/git-root.js +61 -0
  473. package/dist/infra/heartbeat-active-hours.js +2 -2
  474. package/dist/infra/heartbeat-reason.js +40 -0
  475. package/dist/infra/heartbeat-runner.js +72 -32
  476. package/dist/infra/heartbeat-wake.js +6 -12
  477. package/dist/infra/host-env-security-policy.json +19 -0
  478. package/dist/infra/host-env-security.js +66 -0
  479. package/dist/infra/install-source-utils.js +91 -7
  480. package/dist/infra/net/ssrf.js +131 -38
  481. package/dist/infra/node-pairing.js +50 -105
  482. package/dist/infra/npm-integrity.js +45 -0
  483. package/dist/infra/npm-pack-install.js +40 -0
  484. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  485. package/dist/infra/outbound/channel-adapters.js +20 -7
  486. package/dist/infra/outbound/channel-selection.js +12 -6
  487. package/dist/infra/outbound/envelope.js +1 -1
  488. package/dist/infra/outbound/format.js +12 -6
  489. package/dist/infra/outbound/message-action-runner.js +107 -327
  490. package/dist/infra/outbound/message.js +59 -36
  491. package/dist/infra/outbound/outbound-policy.js +52 -25
  492. package/dist/infra/outbound/outbound-send-service.js +58 -71
  493. package/dist/infra/outbound/payloads.js +14 -7
  494. package/dist/infra/outbound/session-binding-service.js +123 -0
  495. package/dist/infra/pairing-files.js +10 -0
  496. package/dist/infra/path-guards.js +25 -0
  497. package/dist/infra/plain-object.js +9 -0
  498. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  499. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  500. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  501. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  502. package/dist/infra/push-apns.js +365 -0
  503. package/dist/infra/restart-sentinel.js +16 -1
  504. package/dist/infra/restart.js +229 -26
  505. package/dist/infra/retry-policy.js +4 -2
  506. package/dist/infra/retry.js +9 -5
  507. package/dist/infra/scp-host.js +54 -0
  508. package/dist/infra/session-cost-usage.js +107 -59
  509. package/dist/infra/session-maintenance-warning.js +3 -1
  510. package/dist/infra/shell-env.js +98 -34
  511. package/dist/infra/ssh-config.js +12 -6
  512. package/dist/infra/system-run-command.js +49 -4
  513. package/dist/infra/update-channels.js +10 -5
  514. package/dist/infra/update-startup.js +86 -9
  515. package/dist/line/accounts.js +5 -7
  516. package/dist/line/bot-access.js +8 -20
  517. package/dist/line/bot-handlers.js +3 -1
  518. package/dist/link-understanding/detect.js +15 -7
  519. package/dist/media/constants.js +15 -6
  520. package/dist/media/image-ops.js +7 -0
  521. package/dist/media/inbound-path-policy.js +114 -0
  522. package/dist/media/input-files.js +16 -0
  523. package/dist/media/local-roots.js +3 -2
  524. package/dist/media-understanding/apply.js +4 -1
  525. package/dist/media-understanding/concurrency.js +8 -20
  526. package/dist/memory/backend-config.js +45 -6
  527. package/dist/memory/embeddings.js +10 -4
  528. package/dist/memory/fs-utils.js +23 -0
  529. package/dist/memory/manager-search.js +12 -6
  530. package/dist/memory/manager-sync-ops.js +12 -2
  531. package/dist/memory/qmd-manager.js +466 -53
  532. package/dist/memory/query-expansion.js +167 -3
  533. package/dist/memory/status-format.js +10 -5
  534. package/dist/memory/sync-memory-files.js +1 -1
  535. package/dist/memory/test-manager.js +8 -0
  536. package/dist/node-host/invoke-system-run.js +281 -0
  537. package/dist/node-host/invoke.js +55 -337
  538. package/dist/pairing/pairing-store.js +22 -0
  539. package/dist/plugin-sdk/allow-from.js +1 -1
  540. package/dist/plugin-sdk/command-auth.js +3 -1
  541. package/dist/plugin-sdk/index.js +6 -3
  542. package/dist/plugin-sdk/temp-path.js +47 -0
  543. package/dist/plugin-sdk/webhook-targets.js +32 -0
  544. package/dist/plugins/bundled-dir.js +9 -6
  545. package/dist/plugins/discovery.js +217 -23
  546. package/dist/plugins/hook-runner-global.js +16 -0
  547. package/dist/plugins/hooks.js +50 -0
  548. package/dist/plugins/install.js +28 -16
  549. package/dist/plugins/loader.js +192 -26
  550. package/dist/plugins/logger.js +8 -0
  551. package/dist/plugins/manifest-registry.js +3 -0
  552. package/dist/plugins/path-safety.js +34 -0
  553. package/dist/plugins/registry.js +5 -2
  554. package/dist/plugins/runtime/index.js +271 -206
  555. package/dist/plugins/runtime.js +3 -17
  556. package/dist/plugins/update.js +78 -12
  557. package/dist/process/spawn-utils.js +14 -7
  558. package/dist/providers/github-copilot-models.js +4 -1
  559. package/dist/providers/github-copilot-token.js +11 -6
  560. package/dist/providers/qwen-portal-oauth.js +14 -6
  561. package/dist/routing/account-id.js +30 -0
  562. package/dist/routing/resolve-route.js +3 -7
  563. package/dist/routing/session-key.js +2 -16
  564. package/dist/security/audit-channel.js +100 -20
  565. package/dist/security/audit-extra.async.js +505 -179
  566. package/dist/security/audit-extra.js +12 -2
  567. package/dist/security/audit-extra.sync.js +421 -35
  568. package/dist/security/audit-fs.js +31 -13
  569. package/dist/security/audit.js +180 -370
  570. package/dist/security/dm-policy-shared.js +68 -0
  571. package/dist/security/external-content.js +46 -14
  572. package/dist/security/fix.js +49 -85
  573. package/dist/security/scan-paths.js +20 -0
  574. package/dist/security/secret-equal.js +3 -7
  575. package/dist/security/windows-acl.js +30 -15
  576. package/dist/shared/entry-status.js +6 -0
  577. package/dist/shared/frontmatter.js +5 -5
  578. package/dist/shared/node-list-parse.js +13 -0
  579. package/dist/shared/node-match.js +11 -4
  580. package/dist/shared/operator-scope-compat.js +42 -0
  581. package/dist/shared/text-chunking.js +29 -0
  582. package/dist/signal/accounts.js +7 -20
  583. package/dist/signal/monitor/event-handler.js +3 -1
  584. package/dist/slack/accounts.js +6 -19
  585. package/dist/slack/actions.js +11 -3
  586. package/dist/slack/blocks.test-helpers.js +31 -0
  587. package/dist/slack/monitor/auth.js +1 -1
  588. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  589. package/dist/slack/monitor/mrkdwn.js +8 -0
  590. package/dist/slack/monitor/replies.js +15 -7
  591. package/dist/slack/monitor/slash.js +22 -13
  592. package/dist/slack/resolve-channels.js +10 -5
  593. package/dist/slack/send.js +102 -12
  594. package/dist/slack/stream-mode.js +10 -0
  595. package/dist/slack/streaming.js +4 -2
  596. package/dist/telegram/accounts.js +19 -14
  597. package/dist/telegram/bot/helpers.js +3 -5
  598. package/dist/telegram/bot-access.js +35 -36
  599. package/dist/telegram/bot-handlers.js +120 -148
  600. package/dist/telegram/bot-message-context.js +68 -9
  601. package/dist/telegram/bot-message-dispatch.js +477 -210
  602. package/dist/telegram/bot-native-commands.js +16 -0
  603. package/dist/telegram/draft-stream.js +44 -8
  604. package/dist/telegram/inline-buttons.js +5 -15
  605. package/dist/telegram/monitor.js +11 -7
  606. package/dist/telegram/network-config.js +19 -7
  607. package/dist/telegram/reasoning-lane-coordinator.js +128 -0
  608. package/dist/telegram/send.js +3 -2
  609. package/dist/telegram/sent-message-cache.js +5 -6
  610. package/dist/telegram/status-reaction-variants.js +208 -0
  611. package/dist/telegram/sticker-cache.js +11 -9
  612. package/dist/terminal/prompt-select-styled.js +9 -0
  613. package/dist/terminal/theme.js +12 -12
  614. package/dist/test-utils/command-runner.js +6 -0
  615. package/dist/test-utils/internal-hook-event-payload.js +10 -0
  616. package/dist/test-utils/model-auth-mock.js +12 -0
  617. package/dist/test-utils/provider-usage-fetch.js +14 -0
  618. package/dist/test-utils/temp-home.js +33 -0
  619. package/dist/tts/tts.js +80 -567
  620. package/dist/tui/components/chat-log.js +50 -8
  621. package/dist/tui/theme/theme.js +10 -12
  622. package/dist/tui/tui-command-handlers.js +36 -27
  623. package/dist/tui/tui-event-handlers.js +122 -32
  624. package/dist/tui/tui-local-shell.js +16 -6
  625. package/dist/tui/tui.js +236 -48
  626. package/dist/utils/account-id.js +2 -4
  627. package/dist/utils/boolean.js +10 -5
  628. package/dist/utils/directive-tags.js +11 -0
  629. package/dist/utils/mask-api-key.js +10 -0
  630. package/dist/utils/queue-helpers.js +67 -12
  631. package/dist/utils/run-with-concurrency.js +39 -0
  632. package/dist/web/auto-reply/deliver-reply.js +8 -4
  633. package/dist/web/auto-reply/mentions.js +10 -5
  634. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  635. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  636. package/dist/web/inbound/access-control.js +5 -2
  637. package/dist/web/login-qr.js +12 -6
  638. package/dist/web/media.js +126 -15
  639. package/docs/tools/slash-commands.md +5 -1
  640. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  641. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  642. package/extensions/feishu/src/external-keys.ts +19 -0
  643. package/extensions/lobster/src/windows-spawn.ts +193 -0
  644. package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
  645. package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
  646. package/package.json +1 -1
@@ -2,9 +2,11 @@ import fs from "node:fs";
2
2
  import { lookupContextTokens } from "../agents/context.js";
3
3
  import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
4
4
  import { resolveModelAuthMode } from "../agents/model-auth.js";
5
- import { resolveConfiguredModelRef } from "../agents/model-selection.js";
5
+ import { buildModelAliasIndex, resolveConfiguredModelRef, resolveModelRefFromString, } from "../agents/model-selection.js";
6
6
  import { resolveSandboxRuntimeStatus } from "../agents/sandbox.js";
7
7
  import { derivePromptTokens, normalizeUsage } from "../agents/usage.js";
8
+ import { resolveChannelModelOverride } from "../channels/model-overrides.js";
9
+ import { isCommandFlagEnabled } from "../config/commands.js";
8
10
  import { resolveMainSessionKey, resolveSessionFilePath, resolveSessionFilePathOptions, } from "../config/sessions.js";
9
11
  import { formatTimeAgo } from "../infra/format-time/format-relative.js";
10
12
  import { resolveCommitHash } from "../infra/git-commit.js";
@@ -14,7 +16,34 @@ import { getTtsMaxLength, getTtsProvider, isSummarizationEnabled, resolveTtsAuto
14
16
  import { estimateUsageCost, formatTokenCount as formatTokenCountShared, formatUsd, resolveModelCostConfig, } from "../utils/usage-format.js";
15
17
  import { VERSION } from "../version.js";
16
18
  import { listChatCommands, listChatCommandsForConfig, } from "./commands-registry.js";
19
+ import { resolveActiveFallbackState } from "./fallback-state.js";
20
+ import { formatProviderModelRef, resolveSelectedAndActiveModel } from "./model-runtime.js";
17
21
  export const formatTokenCount = formatTokenCountShared;
22
+ function normalizeAuthMode(value) {
23
+ const normalized = value?.trim().toLowerCase();
24
+ if (!normalized) {
25
+ return undefined;
26
+ }
27
+ if (normalized === "api-key" || normalized.startsWith("api-key ")) {
28
+ return "api-key";
29
+ }
30
+ if (normalized === "oauth" || normalized.startsWith("oauth ")) {
31
+ return "oauth";
32
+ }
33
+ if (normalized === "token" || normalized.startsWith("token ")) {
34
+ return "token";
35
+ }
36
+ if (normalized === "aws-sdk" || normalized.startsWith("aws-sdk ")) {
37
+ return "aws-sdk";
38
+ }
39
+ if (normalized === "mixed" || normalized.startsWith("mixed ")) {
40
+ return "mixed";
41
+ }
42
+ if (normalized === "unknown") {
43
+ return "unknown";
44
+ }
45
+ return undefined;
46
+ }
18
47
  function resolveRuntimeLabel(args) {
19
48
  const sessionKey = args.sessionKey?.trim();
20
49
  if (args.config && sessionKey) {
@@ -156,6 +185,24 @@ const formatUsagePair = (input, output) => {
156
185
  const outputLabel = typeof output === "number" ? formatTokenCount(output) : "?";
157
186
  return `🧮 Tokens: ${inputLabel} in / ${outputLabel} out`;
158
187
  };
188
+ const formatCacheLine = (input, cacheRead, cacheWrite) => {
189
+ if (!cacheRead && !cacheWrite) {
190
+ return null;
191
+ }
192
+ if ((typeof cacheRead !== "number" || cacheRead <= 0) &&
193
+ (typeof cacheWrite !== "number" || cacheWrite <= 0)) {
194
+ return null;
195
+ }
196
+ const cachedLabel = typeof cacheRead === "number" ? formatTokenCount(cacheRead) : "0";
197
+ const newLabel = typeof cacheWrite === "number" ? formatTokenCount(cacheWrite) : "0";
198
+ const totalInput = (typeof cacheRead === "number" ? cacheRead : 0) +
199
+ (typeof cacheWrite === "number" ? cacheWrite : 0) +
200
+ (typeof input === "number" ? input : 0);
201
+ const hitRate = totalInput > 0 && typeof cacheRead === "number"
202
+ ? Math.round((cacheRead / totalInput) * 100)
203
+ : 0;
204
+ return `🗄️ Cache: ${hitRate}% hit · ${cachedLabel} cached, ${newLabel} new`;
205
+ };
159
206
  const formatMediaUnderstandingLine = (decisions) => {
160
207
  if (!decisions || decisions.length === 0) {
161
208
  return null;
@@ -229,14 +276,23 @@ export function buildStatusMessage(args) {
229
276
  defaultProvider: DEFAULT_PROVIDER,
230
277
  defaultModel: DEFAULT_MODEL,
231
278
  });
232
- const provider = entry?.providerOverride ?? resolved.provider ?? DEFAULT_PROVIDER;
233
- let model = entry?.modelOverride ?? resolved.model ?? DEFAULT_MODEL;
279
+ const selectedProvider = entry?.providerOverride ?? resolved.provider ?? DEFAULT_PROVIDER;
280
+ const selectedModel = entry?.modelOverride ?? resolved.model ?? DEFAULT_MODEL;
281
+ const modelRefs = resolveSelectedAndActiveModel({
282
+ selectedProvider,
283
+ selectedModel,
284
+ sessionEntry: entry,
285
+ });
286
+ let activeProvider = modelRefs.active.provider;
287
+ let activeModel = modelRefs.active.model;
234
288
  let contextTokens = entry?.contextTokens ??
235
289
  args.agent?.contextTokens ??
236
- lookupContextTokens(model) ??
290
+ lookupContextTokens(activeModel) ??
237
291
  DEFAULT_CONTEXT_TOKENS;
238
292
  let inputTokens = entry?.inputTokens;
239
293
  let outputTokens = entry?.outputTokens;
294
+ let cacheRead = entry?.cacheRead;
295
+ let cacheWrite = entry?.cacheWrite;
240
296
  let totalTokens = entry?.totalTokens ?? (entry?.inputTokens ?? 0) + (entry?.outputTokens ?? 0);
241
297
  // Prefer prompt-size tokens from the session transcript when it looks larger
242
298
  // (cached prompt tokens are often missing from agent meta/store).
@@ -247,8 +303,19 @@ export function buildStatusMessage(args) {
247
303
  if (!totalTokens || totalTokens === 0 || candidate > totalTokens) {
248
304
  totalTokens = candidate;
249
305
  }
250
- if (!model) {
251
- model = logUsage.model ?? model;
306
+ if (!entry?.model && logUsage.model) {
307
+ const slashIndex = logUsage.model.indexOf("/");
308
+ if (slashIndex > 0) {
309
+ const provider = logUsage.model.slice(0, slashIndex).trim();
310
+ const model = logUsage.model.slice(slashIndex + 1).trim();
311
+ if (provider && model) {
312
+ activeProvider = provider;
313
+ activeModel = model;
314
+ }
315
+ }
316
+ else {
317
+ activeModel = logUsage.model;
318
+ }
252
319
  }
253
320
  if (!contextTokens && logUsage.model) {
254
321
  contextTokens = lookupContextTokens(logUsage.model) ?? contextTokens;
@@ -310,13 +377,27 @@ export function buildStatusMessage(args) {
310
377
  `🪢 Queue: ${queueMode}${queueDetails}`,
311
378
  ];
312
379
  const activationLine = activationParts.filter(Boolean).join(" · ");
313
- const authMode = resolveModelAuthMode(provider, args.config);
314
- const authLabelValue = args.modelAuth ?? (authMode && authMode !== "unknown" ? authMode : undefined);
315
- const showCost = authLabelValue === "api-key" || authLabelValue === "mixed";
380
+ const selectedAuthMode = normalizeAuthMode(args.modelAuth) ?? resolveModelAuthMode(selectedProvider, args.config);
381
+ const selectedAuthLabelValue = args.modelAuth ??
382
+ (selectedAuthMode && selectedAuthMode !== "unknown" ? selectedAuthMode : undefined);
383
+ const activeAuthMode = normalizeAuthMode(args.activeModelAuth) ?? resolveModelAuthMode(activeProvider, args.config);
384
+ const activeAuthLabelValue = args.activeModelAuth ??
385
+ (activeAuthMode && activeAuthMode !== "unknown" ? activeAuthMode : undefined);
386
+ const selectedModelLabel = modelRefs.selected.label || "unknown";
387
+ const activeModelLabel = formatProviderModelRef(activeProvider, activeModel) || "unknown";
388
+ const fallbackState = resolveActiveFallbackState({
389
+ selectedModelRef: selectedModelLabel,
390
+ activeModelRef: activeModelLabel,
391
+ state: entry,
392
+ });
393
+ const effectiveCostAuthMode = fallbackState.active
394
+ ? activeAuthMode
395
+ : (selectedAuthMode ?? activeAuthMode);
396
+ const showCost = effectiveCostAuthMode === "api-key" || effectiveCostAuthMode === "mixed";
316
397
  const costConfig = showCost
317
398
  ? resolveModelCostConfig({
318
- provider,
319
- model,
399
+ provider: activeProvider,
400
+ model: activeModel,
320
401
  config: args.config,
321
402
  })
322
403
  : undefined;
@@ -331,12 +412,53 @@ export function buildStatusMessage(args) {
331
412
  })
332
413
  : undefined;
333
414
  const costLabel = showCost && hasUsage ? formatUsd(cost) : undefined;
334
- const modelLabel = model ? `${provider}/${model}` : "unknown";
335
- const authLabel = authLabelValue ? ` · 🔑 ${authLabelValue}` : "";
336
- const modelLine = `🧠 Model: ${modelLabel}${authLabel}`;
415
+ const selectedAuthLabel = selectedAuthLabelValue ? ` · 🔑 ${selectedAuthLabelValue}` : "";
416
+ const channelModelNote = (() => {
417
+ if (!args.config || !entry) {
418
+ return undefined;
419
+ }
420
+ if (entry.modelOverride?.trim() || entry.providerOverride?.trim()) {
421
+ return undefined;
422
+ }
423
+ const channelOverride = resolveChannelModelOverride({
424
+ cfg: args.config,
425
+ channel: entry.channel ?? entry.origin?.provider,
426
+ groupId: entry.groupId,
427
+ groupChannel: entry.groupChannel,
428
+ groupSubject: entry.subject,
429
+ parentSessionKey: args.parentSessionKey,
430
+ });
431
+ if (!channelOverride) {
432
+ return undefined;
433
+ }
434
+ const aliasIndex = buildModelAliasIndex({
435
+ cfg: args.config,
436
+ defaultProvider: DEFAULT_PROVIDER,
437
+ });
438
+ const resolvedOverride = resolveModelRefFromString({
439
+ raw: channelOverride.model,
440
+ defaultProvider: DEFAULT_PROVIDER,
441
+ aliasIndex,
442
+ });
443
+ if (!resolvedOverride) {
444
+ return undefined;
445
+ }
446
+ if (resolvedOverride.ref.provider !== selectedProvider ||
447
+ resolvedOverride.ref.model !== selectedModel) {
448
+ return undefined;
449
+ }
450
+ return "channel override";
451
+ })();
452
+ const modelNote = channelModelNote ? ` · ${channelModelNote}` : "";
453
+ const modelLine = `🧠 Model: ${selectedModelLabel}${selectedAuthLabel}${modelNote}`;
454
+ const showFallbackAuth = activeAuthLabelValue && activeAuthLabelValue !== selectedAuthLabelValue;
455
+ const fallbackLine = fallbackState.active
456
+ ? `↪️ Fallback: ${activeModelLabel}${showFallbackAuth ? ` · 🔑 ${activeAuthLabelValue}` : ""} (${fallbackState.reason ?? "selected model unavailable"})`
457
+ : null;
337
458
  const commit = resolveCommitHash();
338
459
  const versionLine = `🦞 Pool Bot ${VERSION}${commit ? ` (${commit})` : ""}`;
339
460
  const usagePair = formatUsagePair(inputTokens, outputTokens);
461
+ const cacheLine = formatCacheLine(inputTokens, cacheRead, cacheWrite);
340
462
  const costLine = costLabel ? `💵 Cost: ${costLabel}` : null;
341
463
  const usageCostLine = usagePair && costLine ? `${usagePair} · ${costLine}` : (usagePair ?? costLine);
342
464
  const mediaLine = formatMediaUnderstandingLine(args.mediaDecisions);
@@ -345,7 +467,9 @@ export function buildStatusMessage(args) {
345
467
  versionLine,
346
468
  args.timeLine,
347
469
  modelLine,
470
+ fallbackLine,
348
471
  usageCostLine,
472
+ cacheLine,
349
473
  `📚 ${contextLine}`,
350
474
  mediaLine,
351
475
  args.usageLine,
@@ -395,10 +519,10 @@ export function buildHelpMessage(cfg) {
395
519
  lines.push(" /new | /reset | /compact [instructions] | /stop");
396
520
  lines.push("");
397
521
  const optionParts = ["/think <level>", "/model <id>", "/verbose on|off"];
398
- if (cfg?.commands?.config === true) {
522
+ if (isCommandFlagEnabled(cfg, "config")) {
399
523
  optionParts.push("/config");
400
524
  }
401
- if (cfg?.commands?.debug === true) {
525
+ if (isCommandFlagEnabled(cfg, "debug")) {
402
526
  optionParts.push("/debug");
403
527
  }
404
528
  lines.push("Options");
@@ -1,8 +1,10 @@
1
1
  function formatTemplateValue(value) {
2
- if (value == null)
2
+ if (value == null) {
3
3
  return "";
4
- if (typeof value === "string")
4
+ }
5
+ if (typeof value === "string") {
5
6
  return value;
7
+ }
6
8
  if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
7
9
  return String(value);
8
10
  }
@@ -12,10 +14,12 @@ function formatTemplateValue(value) {
12
14
  if (Array.isArray(value)) {
13
15
  return value
14
16
  .flatMap((entry) => {
15
- if (entry == null)
17
+ if (entry == null) {
16
18
  return [];
17
- if (typeof entry === "string")
19
+ }
20
+ if (typeof entry === "string") {
18
21
  return [entry];
22
+ }
19
23
  if (typeof entry === "number" || typeof entry === "boolean" || typeof entry === "bigint") {
20
24
  return [String(entry)];
21
25
  }
@@ -30,8 +34,9 @@ function formatTemplateValue(value) {
30
34
  }
31
35
  // Simple {{Placeholder}} interpolation using inbound message context.
32
36
  export function applyTemplate(str, ctx) {
33
- if (!str)
37
+ if (!str) {
34
38
  return "";
39
+ }
35
40
  return str.replace(/{{\s*(\w+)\s*}}/g, (_, key) => {
36
41
  const value = ctx[key];
37
42
  return formatTemplateValue(value);
@@ -14,6 +14,7 @@ export function isBinaryThinkingProvider(provider) {
14
14
  export const XHIGH_MODEL_REFS = [
15
15
  "openai/gpt-5.2",
16
16
  "openai-codex/gpt-5.3-codex",
17
+ "openai-codex/gpt-5.3-codex-spark",
17
18
  "openai-codex/gpt-5.2-codex",
18
19
  "openai-codex/gpt-5.1-codex",
19
20
  "github-copilot/gpt-5.2-codex",
@@ -94,8 +95,7 @@ export function formatXHighModelHint() {
94
95
  }
95
96
  return `${refs.slice(0, -1).join(", ")} or ${refs[refs.length - 1]}`;
96
97
  }
97
- // Normalize verbose flags used to toggle agent verbosity.
98
- export function normalizeVerboseLevel(raw) {
98
+ function normalizeOnOffFullLevel(raw) {
99
99
  if (!raw) {
100
100
  return undefined;
101
101
  }
@@ -111,22 +111,13 @@ export function normalizeVerboseLevel(raw) {
111
111
  }
112
112
  return undefined;
113
113
  }
114
+ // Normalize verbose flags used to toggle agent verbosity.
115
+ export function normalizeVerboseLevel(raw) {
116
+ return normalizeOnOffFullLevel(raw);
117
+ }
114
118
  // Normalize system notice flags used to toggle system notifications.
115
119
  export function normalizeNoticeLevel(raw) {
116
- if (!raw) {
117
- return undefined;
118
- }
119
- const key = raw.toLowerCase();
120
- if (["off", "false", "no", "0"].includes(key)) {
121
- return "off";
122
- }
123
- if (["full", "all", "everything"].includes(key)) {
124
- return "full";
125
- }
126
- if (["on", "minimal", "true", "yes", "1"].includes(key)) {
127
- return "on";
128
- }
129
- return undefined;
120
+ return normalizeOnOffFullLevel(raw);
130
121
  }
131
122
  // Normalize response-usage display modes used to toggle per-response usage footers.
132
123
  export function normalizeUsageDisplay(raw) {
@@ -1,15 +1,31 @@
1
+ import { escapeRegExp } from "../utils.js";
1
2
  export const HEARTBEAT_TOKEN = "HEARTBEAT_OK";
2
3
  export const SILENT_REPLY_TOKEN = "NO_REPLY";
3
- function escapeRegExp(value) {
4
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5
- }
6
4
  export function isSilentReplyText(text, token = SILENT_REPLY_TOKEN) {
7
- if (!text)
5
+ if (!text) {
8
6
  return false;
7
+ }
9
8
  const escaped = escapeRegExp(token);
10
9
  const prefix = new RegExp(`^\\s*${escaped}(?=$|\\W)`);
11
- if (prefix.test(text))
10
+ if (prefix.test(text)) {
12
11
  return true;
12
+ }
13
13
  const suffix = new RegExp(`\\b${escaped}\\b\\W*$`);
14
14
  return suffix.test(text);
15
15
  }
16
+ export function isSilentReplyPrefixText(text, token = SILENT_REPLY_TOKEN) {
17
+ if (!text) {
18
+ return false;
19
+ }
20
+ const normalized = text.trimStart().toUpperCase();
21
+ if (!normalized) {
22
+ return false;
23
+ }
24
+ if (!normalized.includes("_")) {
25
+ return false;
26
+ }
27
+ if (/[^A-Z_]/.test(normalized)) {
28
+ return false;
29
+ }
30
+ return token.toUpperCase().startsWith(normalized);
31
+ }
@@ -1,33 +1,39 @@
1
1
  import express from "express";
2
+ import { isLoopbackHost } from "../gateway/net.js";
3
+ import { deleteBridgeAuthForPort, setBridgeAuthForPort } from "./bridge-auth-registry.js";
2
4
  import { registerBrowserRoutes } from "./routes/index.js";
3
5
  import { createBrowserRouteContext, } from "./server-context.js";
6
+ import { installBrowserAuthMiddleware, installBrowserCommonMiddleware, } from "./server-middleware.js";
4
7
  export async function startBrowserBridgeServer(params) {
5
8
  const host = params.host ?? "127.0.0.1";
9
+ if (!isLoopbackHost(host)) {
10
+ throw new Error(`bridge server must bind to loopback host (got ${host})`);
11
+ }
6
12
  const port = params.port ?? 0;
7
13
  const app = express();
8
- app.use(express.json({ limit: "1mb" }));
9
- app.use((req, res, next) => {
10
- const ctrl = new AbortController();
11
- const abort = () => ctrl.abort(new Error("request aborted"));
12
- req.once("aborted", abort);
13
- res.once("close", () => {
14
- if (!res.writableEnded) {
15
- abort();
14
+ installBrowserCommonMiddleware(app);
15
+ if (params.resolveSandboxNoVncToken) {
16
+ app.get("/sandbox/novnc", (req, res) => {
17
+ const rawToken = typeof req.query?.token === "string" ? req.query.token.trim() : "";
18
+ if (!rawToken) {
19
+ res.status(400).send("Missing token");
20
+ return;
16
21
  }
17
- });
18
- // Make the signal available to browser route handlers (best-effort).
19
- req.signal = ctrl.signal;
20
- next();
21
- });
22
- const authToken = params.authToken?.trim();
23
- if (authToken) {
24
- app.use((req, res, next) => {
25
- const auth = String(req.headers.authorization ?? "").trim();
26
- if (auth === `Bearer ${authToken}`)
27
- return next();
28
- res.status(401).send("Unauthorized");
22
+ const redirectUrl = params.resolveSandboxNoVncToken?.(rawToken);
23
+ if (!redirectUrl) {
24
+ res.status(404).send("Invalid or expired token");
25
+ return;
26
+ }
27
+ res.setHeader("Cache-Control", "no-store");
28
+ res.redirect(302, redirectUrl);
29
29
  });
30
30
  }
31
+ const authToken = params.authToken?.trim() || undefined;
32
+ const authPassword = params.authPassword?.trim() || undefined;
33
+ if (!authToken && !authPassword) {
34
+ throw new Error("bridge server requires auth (authToken/authPassword missing)");
35
+ }
36
+ installBrowserAuthMiddleware(app, { token: authToken, password: authPassword });
31
37
  const state = {
32
38
  server: null,
33
39
  port,
@@ -48,10 +54,20 @@ export async function startBrowserBridgeServer(params) {
48
54
  state.server = server;
49
55
  state.port = resolvedPort;
50
56
  state.resolved.controlPort = resolvedPort;
57
+ setBridgeAuthForPort(resolvedPort, { token: authToken, password: authPassword });
51
58
  const baseUrl = `http://${host}:${resolvedPort}`;
52
59
  return { server, port: resolvedPort, baseUrl, state };
53
60
  }
54
61
  export async function stopBrowserBridgeServer(server) {
62
+ try {
63
+ const address = server.address();
64
+ if (address?.port) {
65
+ deleteBridgeAuthForPort(address.port);
66
+ }
67
+ }
68
+ catch {
69
+ // ignore
70
+ }
55
71
  await new Promise((resolve) => {
56
72
  server.close(() => resolve());
57
73
  });
@@ -82,33 +82,26 @@ function createCdpSender(ws) {
82
82
  return { send, closeWithError };
83
83
  }
84
84
  export async function fetchJson(url, timeoutMs = 1500, init) {
85
+ const res = await fetchChecked(url, timeoutMs, init);
86
+ return (await res.json());
87
+ }
88
+ async function fetchChecked(url, timeoutMs = 1500, init) {
85
89
  const ctrl = new AbortController();
86
- const t = setTimeout(() => ctrl.abort(), timeoutMs);
90
+ const t = setTimeout(ctrl.abort.bind(ctrl), timeoutMs);
87
91
  try {
88
92
  const headers = getHeadersWithAuth(url, init?.headers || {});
89
93
  const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
90
94
  if (!res.ok) {
91
95
  throw new Error(`HTTP ${res.status}`);
92
96
  }
93
- return (await res.json());
97
+ return res;
94
98
  }
95
99
  finally {
96
100
  clearTimeout(t);
97
101
  }
98
102
  }
99
103
  export async function fetchOk(url, timeoutMs = 1500, init) {
100
- const ctrl = new AbortController();
101
- const t = setTimeout(() => ctrl.abort(), timeoutMs);
102
- try {
103
- const headers = getHeadersWithAuth(url, init?.headers || {});
104
- const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
105
- if (!res.ok) {
106
- throw new Error(`HTTP ${res.status}`);
107
- }
108
- }
109
- finally {
110
- clearTimeout(t);
111
- }
104
+ await fetchChecked(url, timeoutMs, init);
112
105
  }
113
106
  export async function withCdpSocket(wsUrl, fn, opts) {
114
107
  const headers = getHeadersWithAuth(wsUrl, opts?.headers ?? {});
@@ -1,4 +1,5 @@
1
1
  import { appendCdpPath, fetchJson, isLoopbackHost, withCdpSocket } from "./cdp.helpers.js";
2
+ import { assertBrowserNavigationAllowed, withBrowserNavigationPolicy } from "./navigation-guard.js";
2
3
  export { appendCdpPath, fetchJson, fetchOk, getHeadersWithAuth } from "./cdp.helpers.js";
3
4
  export function normalizeCdpWsUrl(wsUrl, cdpUrl) {
4
5
  const ws = new URL(wsUrl);
@@ -6,8 +7,9 @@ export function normalizeCdpWsUrl(wsUrl, cdpUrl) {
6
7
  if (isLoopbackHost(ws.hostname) && !isLoopbackHost(cdp.hostname)) {
7
8
  ws.hostname = cdp.hostname;
8
9
  const cdpPort = cdp.port || (cdp.protocol === "https:" ? "443" : "80");
9
- if (cdpPort)
10
+ if (cdpPort) {
10
11
  ws.port = cdpPort;
12
+ }
11
13
  ws.protocol = cdp.protocol === "https:" ? "wss:" : "ws:";
12
14
  }
13
15
  if (cdp.protocol === "https:" && ws.protocol === "ws:") {
@@ -18,8 +20,9 @@ export function normalizeCdpWsUrl(wsUrl, cdpUrl) {
18
20
  ws.password = cdp.password;
19
21
  }
20
22
  for (const [key, value] of cdp.searchParams.entries()) {
21
- if (!ws.searchParams.has(key))
23
+ if (!ws.searchParams.has(key)) {
22
24
  ws.searchParams.append(key, value);
25
+ }
23
26
  }
24
27
  return ws.toString();
25
28
  }
@@ -53,22 +56,29 @@ export async function captureScreenshot(opts) {
53
56
  ...(clip ? { clip } : {}),
54
57
  }));
55
58
  const base64 = result?.data;
56
- if (!base64)
59
+ if (!base64) {
57
60
  throw new Error("Screenshot failed: missing data");
61
+ }
58
62
  return Buffer.from(base64, "base64");
59
63
  });
60
64
  }
61
65
  export async function createTargetViaCdp(opts) {
66
+ await assertBrowserNavigationAllowed({
67
+ url: opts.url,
68
+ ...withBrowserNavigationPolicy(opts.ssrfPolicy),
69
+ });
62
70
  const version = await fetchJson(appendCdpPath(opts.cdpUrl, "/json/version"), 1500);
63
71
  const wsUrlRaw = String(version?.webSocketDebuggerUrl ?? "").trim();
64
72
  const wsUrl = wsUrlRaw ? normalizeCdpWsUrl(wsUrlRaw, opts.cdpUrl) : "";
65
- if (!wsUrl)
73
+ if (!wsUrl) {
66
74
  throw new Error("CDP /json/version missing webSocketDebuggerUrl");
75
+ }
67
76
  return await withCdpSocket(wsUrl, async (send) => {
68
77
  const created = (await send("Target.createTarget", { url: opts.url }));
69
78
  const targetId = String(created?.targetId ?? "").trim();
70
- if (!targetId)
79
+ if (!targetId) {
71
80
  throw new Error("CDP Target.createTarget returned no targetId");
81
+ }
72
82
  return { targetId };
73
83
  });
74
84
  }
@@ -83,17 +93,20 @@ export async function evaluateJavaScript(opts) {
83
93
  includeCommandLineAPI: true,
84
94
  }));
85
95
  const result = evaluated?.result;
86
- if (!result)
96
+ if (!result) {
87
97
  throw new Error("CDP Runtime.evaluate returned no result");
98
+ }
88
99
  return { result, exceptionDetails: evaluated.exceptionDetails };
89
100
  });
90
101
  }
91
102
  function axValue(v) {
92
- if (!v || typeof v !== "object")
103
+ if (!v || typeof v !== "object") {
93
104
  return "";
105
+ }
94
106
  const value = v.value;
95
- if (typeof value === "string")
107
+ if (typeof value === "string") {
96
108
  return value;
109
+ }
97
110
  if (typeof value === "number" || typeof value === "boolean") {
98
111
  return String(value);
99
112
  }
@@ -102,28 +115,33 @@ function axValue(v) {
102
115
  export function formatAriaSnapshot(nodes, limit) {
103
116
  const byId = new Map();
104
117
  for (const n of nodes) {
105
- if (n.nodeId)
118
+ if (n.nodeId) {
106
119
  byId.set(n.nodeId, n);
120
+ }
107
121
  }
108
122
  // Heuristic: pick a root-ish node (one that is not referenced as a child), else first.
109
123
  const referenced = new Set();
110
124
  for (const n of nodes) {
111
- for (const c of n.childIds ?? [])
125
+ for (const c of n.childIds ?? []) {
112
126
  referenced.add(c);
127
+ }
113
128
  }
114
129
  const root = nodes.find((n) => n.nodeId && !referenced.has(n.nodeId)) ?? nodes[0];
115
- if (!root?.nodeId)
130
+ if (!root?.nodeId) {
116
131
  return [];
132
+ }
117
133
  const out = [];
118
134
  const stack = [{ id: root.nodeId, depth: 0 }];
119
135
  while (stack.length && out.length < limit) {
120
136
  const popped = stack.pop();
121
- if (!popped)
137
+ if (!popped) {
122
138
  break;
139
+ }
123
140
  const { id, depth } = popped;
124
141
  const n = byId.get(id);
125
- if (!n)
142
+ if (!n) {
126
143
  continue;
144
+ }
127
145
  const role = axValue(n.role);
128
146
  const name = axValue(n.name);
129
147
  const value = axValue(n.value);
@@ -141,8 +159,9 @@ export function formatAriaSnapshot(nodes, limit) {
141
159
  const children = (n.childIds ?? []).filter((c) => byId.has(c));
142
160
  for (let i = children.length - 1; i >= 0; i--) {
143
161
  const child = children[i];
144
- if (child)
162
+ if (child) {
145
163
  stack.push({ id: child, depth: depth + 1 });
164
+ }
146
165
  }
147
166
  }
148
167
  return out;
@@ -210,8 +229,9 @@ export async function snapshotDom(opts) {
210
229
  returnByValue: true,
211
230
  });
212
231
  const value = evaluated.result?.value;
213
- if (!value || typeof value !== "object")
232
+ if (!value || typeof value !== "object") {
214
233
  return { nodes: [] };
234
+ }
215
235
  const nodes = value.nodes;
216
236
  return { nodes: Array.isArray(nodes) ? nodes : [] };
217
237
  }
@@ -2,16 +2,18 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { DEFAULT_CLAWD_BROWSER_COLOR, DEFAULT_CLAWD_BROWSER_PROFILE_NAME } from "./constants.js";
4
4
  function decoratedMarkerPath(userDataDir) {
5
- return path.join(userDataDir, ".clawd-profile-decorated");
5
+ return path.join(userDataDir, ".poolbot-profile-decorated");
6
6
  }
7
7
  function safeReadJson(filePath) {
8
8
  try {
9
- if (!fs.existsSync(filePath))
9
+ if (!fs.existsSync(filePath)) {
10
10
  return null;
11
+ }
11
12
  const raw = fs.readFileSync(filePath, "utf-8");
12
13
  const parsed = JSON.parse(raw);
13
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
14
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
14
15
  return null;
16
+ }
15
17
  return parsed;
16
18
  }
17
19
  catch {
@@ -35,8 +37,9 @@ function setDeep(obj, keys, value) {
35
37
  }
36
38
  function parseHexRgbToSignedArgbInt(hex) {
37
39
  const cleaned = hex.trim().replace(/^#/, "");
38
- if (!/^[0-9a-fA-F]{6}$/.test(cleaned))
40
+ if (!/^[0-9a-fA-F]{6}$/.test(cleaned)) {
39
41
  return null;
42
+ }
40
43
  const rgb = Number.parseInt(cleaned, 16);
41
44
  const argbUnsigned = (0xff << 24) | rgb;
42
45
  // Chrome stores colors as signed 32-bit ints (SkColor).