@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
@@ -1,38 +1,123 @@
1
- import { listAgentIds, resolveAgentDir, resolveAgentModelFallbacksOverride, resolveAgentModelPrimary, resolveAgentWorkspaceDir, } from "../agents/agent-scope.js";
1
+ import path from "node:path";
2
+ import { listAgentIds, resolveAgentDir, resolveEffectiveModelFallbacks, resolveAgentModelPrimary, resolveAgentSkillsFilter, resolveAgentWorkspaceDir, } from "../agents/agent-scope.js";
2
3
  import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
4
+ import { clearSessionAuthProfileOverride } from "../agents/auth-profiles/session-override.js";
3
5
  import { runCliAgent } from "../agents/cli-runner.js";
4
6
  import { getCliSessionId } from "../agents/cli-session.js";
5
7
  import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
8
+ import { AGENT_LANE_SUBAGENT } from "../agents/lanes.js";
6
9
  import { loadModelCatalog } from "../agents/model-catalog.js";
7
10
  import { runWithModelFallback } from "../agents/model-fallback.js";
8
- import { buildAllowedModelSet, isCliProvider, modelKey, resolveConfiguredModelRef, resolveThinkingDefault, } from "../agents/model-selection.js";
11
+ import { buildAllowedModelSet, isCliProvider, modelKey, normalizeModelRef, resolveConfiguredModelRef, resolveThinkingDefault, } from "../agents/model-selection.js";
9
12
  import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
10
13
  import { buildWorkspaceSkillSnapshot } from "../agents/skills.js";
11
14
  import { getSkillsSnapshotVersion } from "../agents/skills/refresh.js";
12
15
  import { resolveAgentTimeoutMs } from "../agents/timeout.js";
13
16
  import { ensureAgentWorkspace } from "../agents/workspace.js";
14
17
  import { formatThinkingLevels, formatXHighModelHint, normalizeThinkLevel, normalizeVerboseLevel, supportsXHighThinking, } from "../auto-reply/thinking.js";
18
+ import { formatCliCommand } from "../cli/command-format.js";
15
19
  import { createDefaultDeps } from "../cli/deps.js";
16
20
  import { loadConfig } from "../config/config.js";
17
- import { resolveAgentIdFromSessionKey, resolveSessionFilePath, updateSessionStore, } from "../config/sessions.js";
21
+ import { parseSessionThreadInfo, resolveAndPersistSessionFile, resolveAgentIdFromSessionKey, resolveSessionFilePath, resolveSessionTranscriptPath, updateSessionStore, } from "../config/sessions.js";
18
22
  import { clearAgentRunContext, emitAgentEvent, registerAgentRunContext, } from "../infra/agent-events.js";
19
23
  import { getRemoteSkillEligibility } from "../infra/skills-remote.js";
24
+ import { normalizeAgentId } from "../routing/session-key.js";
20
25
  import { defaultRuntime } from "../runtime.js";
21
- import { formatCliCommand } from "../cli/command-format.js";
22
26
  import { applyVerboseOverride } from "../sessions/level-overrides.js";
23
- import { resolveSendPolicy } from "../sessions/send-policy.js";
24
27
  import { applyModelOverrideToSessionEntry } from "../sessions/model-overrides.js";
25
- import { clearSessionAuthProfileOverride } from "../agents/auth-profiles/session-override.js";
28
+ import { resolveSendPolicy } from "../sessions/send-policy.js";
26
29
  import { resolveMessageChannel } from "../utils/message-channel.js";
27
30
  import { deliverAgentCommandResult } from "./agent/delivery.js";
28
31
  import { resolveAgentRunContext } from "./agent/run-context.js";
29
- import { resolveSession } from "./agent/session.js";
30
32
  import { updateSessionStoreAfterAgentRun } from "./agent/session-store.js";
31
- import { normalizeAgentId } from "../routing/session-key.js";
33
+ import { resolveSession } from "./agent/session.js";
34
+ async function persistSessionEntry(params) {
35
+ params.sessionStore[params.sessionKey] = params.entry;
36
+ await updateSessionStore(params.storePath, (store) => {
37
+ store[params.sessionKey] = params.entry;
38
+ });
39
+ }
40
+ function resolveFallbackRetryPrompt(params) {
41
+ if (!params.isFallbackRetry) {
42
+ return params.body;
43
+ }
44
+ return "Continue where you left off. The previous model attempt failed or timed out.";
45
+ }
46
+ function runAgentAttempt(params) {
47
+ const effectivePrompt = resolveFallbackRetryPrompt({
48
+ body: params.body,
49
+ isFallbackRetry: params.isFallbackRetry,
50
+ });
51
+ if (isCliProvider(params.providerOverride, params.cfg)) {
52
+ const cliSessionId = getCliSessionId(params.sessionEntry, params.providerOverride);
53
+ return runCliAgent({
54
+ sessionId: params.sessionId,
55
+ sessionKey: params.sessionKey,
56
+ agentId: params.sessionAgentId,
57
+ sessionFile: params.sessionFile,
58
+ workspaceDir: params.workspaceDir,
59
+ config: params.cfg,
60
+ prompt: effectivePrompt,
61
+ provider: params.providerOverride,
62
+ model: params.modelOverride,
63
+ thinkLevel: params.resolvedThinkLevel,
64
+ timeoutMs: params.timeoutMs,
65
+ runId: params.runId,
66
+ extraSystemPrompt: params.opts.extraSystemPrompt,
67
+ cliSessionId,
68
+ images: params.isFallbackRetry ? undefined : params.opts.images,
69
+ streamParams: params.opts.streamParams,
70
+ });
71
+ }
72
+ const authProfileId = params.providerOverride === params.primaryProvider
73
+ ? params.sessionEntry?.authProfileOverride
74
+ : undefined;
75
+ return runEmbeddedPiAgent({
76
+ sessionId: params.sessionId,
77
+ sessionKey: params.sessionKey,
78
+ agentId: params.sessionAgentId,
79
+ messageChannel: params.messageChannel,
80
+ agentAccountId: params.runContext.accountId,
81
+ messageTo: params.opts.replyTo ?? params.opts.to,
82
+ messageThreadId: params.opts.threadId,
83
+ groupId: params.runContext.groupId,
84
+ groupChannel: params.runContext.groupChannel,
85
+ groupSpace: params.runContext.groupSpace,
86
+ spawnedBy: params.spawnedBy,
87
+ currentChannelId: params.runContext.currentChannelId,
88
+ currentThreadTs: params.runContext.currentThreadTs,
89
+ replyToMode: params.runContext.replyToMode,
90
+ hasRepliedRef: params.runContext.hasRepliedRef,
91
+ senderIsOwner: true,
92
+ sessionFile: params.sessionFile,
93
+ workspaceDir: params.workspaceDir,
94
+ config: params.cfg,
95
+ skillsSnapshot: params.skillsSnapshot,
96
+ prompt: effectivePrompt,
97
+ images: params.isFallbackRetry ? undefined : params.opts.images,
98
+ clientTools: params.opts.clientTools,
99
+ provider: params.providerOverride,
100
+ model: params.modelOverride,
101
+ authProfileId,
102
+ authProfileIdSource: authProfileId ? params.sessionEntry?.authProfileOverrideSource : undefined,
103
+ thinkLevel: params.resolvedThinkLevel,
104
+ verboseLevel: params.resolvedVerboseLevel,
105
+ timeoutMs: params.timeoutMs,
106
+ runId: params.runId,
107
+ lane: params.opts.lane,
108
+ abortSignal: params.opts.abortSignal,
109
+ extraSystemPrompt: params.opts.extraSystemPrompt,
110
+ inputProvenance: params.opts.inputProvenance,
111
+ streamParams: params.opts.streamParams,
112
+ agentDir: params.agentDir,
113
+ onAgentEvent: params.onAgentEvent,
114
+ });
115
+ }
32
116
  export async function agentCommand(opts, runtime = defaultRuntime, deps = createDefaultDeps()) {
33
117
  const body = (opts.message ?? "").trim();
34
- if (!body)
118
+ if (!body) {
35
119
  throw new Error("Message (--message) is required");
120
+ }
36
121
  if (!opts.to && !opts.sessionId && !opts.sessionKey && !opts.agentId) {
37
122
  throw new Error("Pass --to <E.164>, --session-id, or --agent to choose a session");
38
123
  }
@@ -78,10 +163,16 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
78
163
  if (opts.verbose && !verboseOverride) {
79
164
  throw new Error('Invalid verbose level. Use "on", "full", or "off".');
80
165
  }
81
- const timeoutSecondsRaw = opts.timeout !== undefined ? Number.parseInt(String(opts.timeout), 10) : undefined;
166
+ const laneRaw = typeof opts.lane === "string" ? opts.lane.trim() : "";
167
+ const isSubagentLane = laneRaw === String(AGENT_LANE_SUBAGENT);
168
+ const timeoutSecondsRaw = opts.timeout !== undefined
169
+ ? Number.parseInt(String(opts.timeout), 10)
170
+ : isSubagentLane
171
+ ? 0
172
+ : undefined;
82
173
  if (timeoutSecondsRaw !== undefined &&
83
- (Number.isNaN(timeoutSecondsRaw) || timeoutSecondsRaw <= 0)) {
84
- throw new Error("--timeout must be a positive integer (seconds)");
174
+ (Number.isNaN(timeoutSecondsRaw) || timeoutSecondsRaw < 0)) {
175
+ throw new Error("--timeout must be a non-negative integer (seconds; 0 means no timeout)");
85
176
  }
86
177
  const timeoutMs = resolveAgentTimeoutMs({
87
178
  cfg,
@@ -123,11 +214,13 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
123
214
  }
124
215
  const needsSkillsSnapshot = isNewSession || !sessionEntry?.skillsSnapshot;
125
216
  const skillsSnapshotVersion = getSkillsSnapshotVersion(workspaceDir);
217
+ const skillFilter = resolveAgentSkillsFilter(cfg, sessionAgentId);
126
218
  const skillsSnapshot = needsSkillsSnapshot
127
219
  ? buildWorkspaceSkillSnapshot(workspaceDir, {
128
220
  config: cfg,
129
221
  eligibility: { remote: getRemoteSkillEligibility() },
130
222
  snapshotVersion: skillsSnapshotVersion,
223
+ skillFilter,
131
224
  })
132
225
  : sessionEntry?.skillsSnapshot;
133
226
  if (skillsSnapshot && sessionStore && sessionKey && needsSkillsSnapshot) {
@@ -141,9 +234,11 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
141
234
  updatedAt: Date.now(),
142
235
  skillsSnapshot,
143
236
  };
144
- sessionStore[sessionKey] = next;
145
- await updateSessionStore(storePath, (store) => {
146
- store[sessionKey] = next;
237
+ await persistSessionEntry({
238
+ sessionStore,
239
+ sessionKey,
240
+ storePath,
241
+ entry: next,
147
242
  });
148
243
  sessionEntry = next;
149
244
  }
@@ -153,16 +248,16 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
153
248
  sessionEntry ?? { sessionId, updatedAt: Date.now() };
154
249
  const next = { ...entry, sessionId, updatedAt: Date.now() };
155
250
  if (thinkOverride) {
156
- if (thinkOverride === "off")
157
- delete next.thinkingLevel;
158
- else
159
- next.thinkingLevel = thinkOverride;
251
+ next.thinkingLevel = thinkOverride;
160
252
  }
161
253
  applyVerboseOverride(next, verboseOverride);
162
- sessionStore[sessionKey] = next;
163
- await updateSessionStore(storePath, (store) => {
164
- store[sessionKey] = next;
254
+ await persistSessionEntry({
255
+ sessionStore,
256
+ sessionKey,
257
+ storePath,
258
+ entry: next,
165
259
  });
260
+ sessionEntry = next;
166
261
  }
167
262
  const agentModelPrimary = resolveAgentModelPrimary(cfg, sessionAgentId);
168
263
  const cfgForModelSelection = agentModelPrimary
@@ -182,11 +277,12 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
182
277
  },
183
278
  }
184
279
  : cfg;
185
- const { provider: defaultProvider, model: defaultModel } = resolveConfiguredModelRef({
280
+ const configuredDefaultRef = resolveConfiguredModelRef({
186
281
  cfg: cfgForModelSelection,
187
282
  defaultProvider: DEFAULT_PROVIDER,
188
283
  defaultModel: DEFAULT_MODEL,
189
284
  });
285
+ const { provider: defaultProvider, model: defaultModel } = normalizeModelRef(configuredDefaultRef.provider, configuredDefaultRef.model);
190
286
  let provider = defaultProvider;
191
287
  let model = defaultModel;
192
288
  const hasAllowlist = agentCfg?.models && Object.keys(agentCfg.models).length > 0;
@@ -211,8 +307,9 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
211
307
  const overrideProvider = sessionEntry.providerOverride?.trim() || defaultProvider;
212
308
  const overrideModel = sessionEntry.modelOverride?.trim();
213
309
  if (overrideModel) {
214
- const key = modelKey(overrideProvider, overrideModel);
215
- if (!isCliProvider(overrideProvider, cfg) &&
310
+ const normalizedOverride = normalizeModelRef(overrideProvider, overrideModel);
311
+ const key = modelKey(normalizedOverride.provider, normalizedOverride.model);
312
+ if (!isCliProvider(normalizedOverride.provider, cfg) &&
216
313
  allowedModelKeys.size > 0 &&
217
314
  !allowedModelKeys.has(key)) {
218
315
  const { updated } = applyModelOverrideToSessionEntry({
@@ -220,9 +317,11 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
220
317
  selection: { provider: defaultProvider, model: defaultModel, isDefault: true },
221
318
  });
222
319
  if (updated) {
223
- sessionStore[sessionKey] = entry;
224
- await updateSessionStore(storePath, (store) => {
225
- store[sessionKey] = entry;
320
+ await persistSessionEntry({
321
+ sessionStore,
322
+ sessionKey,
323
+ storePath,
324
+ entry,
226
325
  });
227
326
  }
228
327
  }
@@ -232,12 +331,13 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
232
331
  const storedModelOverride = sessionEntry?.modelOverride?.trim();
233
332
  if (storedModelOverride) {
234
333
  const candidateProvider = storedProviderOverride || defaultProvider;
235
- const key = modelKey(candidateProvider, storedModelOverride);
236
- if (isCliProvider(candidateProvider, cfg) ||
334
+ const normalizedStored = normalizeModelRef(candidateProvider, storedModelOverride);
335
+ const key = modelKey(normalizedStored.provider, normalizedStored.model);
336
+ if (isCliProvider(normalizedStored.provider, cfg) ||
237
337
  allowedModelKeys.size === 0 ||
238
338
  allowedModelKeys.has(key)) {
239
- provider = candidateProvider;
240
- model = storedModelOverride;
339
+ provider = normalizedStored.provider;
340
+ model = normalizedStored.model;
241
341
  }
242
342
  }
243
343
  if (sessionEntry) {
@@ -281,15 +381,35 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
281
381
  const entry = sessionEntry;
282
382
  entry.thinkingLevel = "high";
283
383
  entry.updatedAt = Date.now();
284
- sessionStore[sessionKey] = entry;
285
- await updateSessionStore(storePath, (store) => {
286
- store[sessionKey] = entry;
384
+ await persistSessionEntry({
385
+ sessionStore,
386
+ sessionKey,
387
+ storePath,
388
+ entry,
287
389
  });
288
390
  }
289
391
  }
290
- const sessionFile = resolveSessionFilePath(sessionId, sessionEntry, {
392
+ let sessionFile = resolveSessionFilePath(sessionId, sessionEntry, {
291
393
  agentId: sessionAgentId,
292
394
  });
395
+ if (sessionStore && sessionKey) {
396
+ const threadIdFromSessionKey = parseSessionThreadInfo(sessionKey).threadId;
397
+ const fallbackSessionFile = !sessionEntry?.sessionFile
398
+ ? resolveSessionTranscriptPath(sessionId, sessionAgentId, opts.threadId ?? threadIdFromSessionKey)
399
+ : undefined;
400
+ const resolvedSessionFile = await resolveAndPersistSessionFile({
401
+ sessionId,
402
+ sessionKey,
403
+ sessionStore,
404
+ storePath,
405
+ sessionEntry,
406
+ agentId: sessionAgentId,
407
+ sessionsDir: path.dirname(storePath),
408
+ fallbackSessionFile,
409
+ });
410
+ sessionFile = resolvedSessionFile.sessionFile;
411
+ sessionEntry = resolvedSessionFile.sessionEntry;
412
+ }
293
413
  const startedAt = Date.now();
294
414
  let lifecycleEnded = false;
295
415
  let result;
@@ -299,72 +419,48 @@ export async function agentCommand(opts, runtime = defaultRuntime, deps = create
299
419
  const runContext = resolveAgentRunContext(opts);
300
420
  const messageChannel = resolveMessageChannel(runContext.messageChannel, opts.replyChannel ?? opts.channel);
301
421
  const spawnedBy = opts.spawnedBy ?? sessionEntry?.spawnedBy;
422
+ // Keep fallback candidate resolution centralized so session model overrides,
423
+ // per-agent overrides, and default fallbacks stay consistent across callers.
424
+ const effectiveFallbacksOverride = resolveEffectiveModelFallbacks({
425
+ cfg,
426
+ agentId: sessionAgentId,
427
+ hasSessionModelOverride: Boolean(storedModelOverride),
428
+ });
429
+ // Track model fallback attempts so retries on an existing session don't
430
+ // re-inject the original prompt as a duplicate user message.
431
+ let fallbackAttemptIndex = 0;
302
432
  const fallbackResult = await runWithModelFallback({
303
433
  cfg,
304
434
  provider,
305
435
  model,
306
436
  agentDir,
307
- fallbacksOverride: resolveAgentModelFallbacksOverride(cfg, sessionAgentId),
437
+ fallbacksOverride: effectiveFallbacksOverride,
308
438
  run: (providerOverride, modelOverride) => {
309
- if (isCliProvider(providerOverride, cfg)) {
310
- const cliSessionId = getCliSessionId(sessionEntry, providerOverride);
311
- return runCliAgent({
312
- sessionId,
313
- sessionKey,
314
- sessionFile,
315
- workspaceDir,
316
- config: cfg,
317
- prompt: body,
318
- provider: providerOverride,
319
- model: modelOverride,
320
- thinkLevel: resolvedThinkLevel,
321
- timeoutMs,
322
- runId,
323
- extraSystemPrompt: opts.extraSystemPrompt,
324
- cliSessionId,
325
- images: opts.images,
326
- streamParams: opts.streamParams,
327
- });
328
- }
329
- const authProfileId = providerOverride === provider ? sessionEntry?.authProfileOverride : undefined;
330
- return runEmbeddedPiAgent({
439
+ const isFallbackRetry = fallbackAttemptIndex > 0;
440
+ fallbackAttemptIndex += 1;
441
+ return runAgentAttempt({
442
+ providerOverride,
443
+ modelOverride,
444
+ cfg,
445
+ sessionEntry,
331
446
  sessionId,
332
447
  sessionKey,
333
- messageChannel,
334
- agentAccountId: runContext.accountId,
335
- messageTo: opts.replyTo ?? opts.to,
336
- messageThreadId: opts.threadId,
337
- groupId: runContext.groupId,
338
- groupChannel: runContext.groupChannel,
339
- groupSpace: runContext.groupSpace,
340
- spawnedBy,
341
- currentChannelId: runContext.currentChannelId,
342
- currentThreadTs: runContext.currentThreadTs,
343
- replyToMode: runContext.replyToMode,
344
- hasRepliedRef: runContext.hasRepliedRef,
345
- senderIsOwner: true,
448
+ sessionAgentId,
346
449
  sessionFile,
347
450
  workspaceDir,
348
- config: cfg,
349
- skillsSnapshot,
350
- prompt: body,
351
- images: opts.images,
352
- clientTools: opts.clientTools,
353
- provider: providerOverride,
354
- model: modelOverride,
355
- authProfileId,
356
- authProfileIdSource: authProfileId
357
- ? sessionEntry?.authProfileOverrideSource
358
- : undefined,
359
- thinkLevel: resolvedThinkLevel,
360
- verboseLevel: resolvedVerboseLevel,
451
+ body,
452
+ isFallbackRetry,
453
+ resolvedThinkLevel,
361
454
  timeoutMs,
362
455
  runId,
363
- lane: opts.lane,
364
- abortSignal: opts.abortSignal,
365
- extraSystemPrompt: opts.extraSystemPrompt,
366
- streamParams: opts.streamParams,
456
+ opts,
457
+ runContext,
458
+ spawnedBy,
459
+ messageChannel,
460
+ skillsSnapshot,
461
+ resolvedVerboseLevel,
367
462
  agentDir,
463
+ primaryProvider: provider,
368
464
  onAgentEvent: (evt) => {
369
465
  // Track lifecycle end for fallback emission below.
370
466
  if (evt.stream === "lifecycle" &&
@@ -15,14 +15,18 @@ function bindingMatchKey(match) {
15
15
  export function describeBinding(binding) {
16
16
  const match = binding.match;
17
17
  const parts = [match.channel];
18
- if (match.accountId)
18
+ if (match.accountId) {
19
19
  parts.push(`accountId=${match.accountId}`);
20
- if (match.peer)
20
+ }
21
+ if (match.peer) {
21
22
  parts.push(`peer=${match.peer.kind}:${match.peer.id}`);
22
- if (match.guildId)
23
+ }
24
+ if (match.guildId) {
23
25
  parts.push(`guild=${match.guildId}`);
24
- if (match.teamId)
26
+ }
27
+ if (match.teamId) {
25
28
  parts.push(`team=${match.teamId}`);
29
+ }
26
30
  return parts.join(" ");
27
31
  }
28
32
  export function applyAgentBindings(cfg, bindings) {
@@ -68,8 +72,9 @@ export function applyAgentBindings(cfg, bindings) {
68
72
  }
69
73
  function resolveDefaultAccountId(cfg, provider) {
70
74
  const plugin = getChannelPlugin(provider);
71
- if (!plugin)
75
+ if (!plugin) {
72
76
  return DEFAULT_ACCOUNT_ID;
77
+ }
73
78
  return resolveChannelDefaultAccountId({ plugin, cfg });
74
79
  }
75
80
  export function buildChannelBindings(params) {
@@ -98,8 +103,9 @@ export function parseBindingSpecs(params) {
98
103
  const agentId = normalizeAgentId(params.agentId);
99
104
  for (const raw of specs) {
100
105
  const trimmed = raw?.trim();
101
- if (!trimmed)
106
+ if (!trimmed) {
102
107
  continue;
108
+ }
103
109
  const [channelRaw, accountRaw] = trimmed.split(":", 2);
104
110
  const channel = normalizeChannelId(channelRaw);
105
111
  if (!channel) {
@@ -118,8 +124,9 @@ export function parseBindingSpecs(params) {
118
124
  }
119
125
  }
120
126
  const match = { channel };
121
- if (accountId)
127
+ if (accountId) {
122
128
  match.accountId = accountId;
129
+ }
123
130
  bindings.push({ agentId, match });
124
131
  }
125
132
  return { bindings, errors };
@@ -13,8 +13,8 @@ import { WizardCancelledError } from "../wizard/prompts.js";
13
13
  import { applyAgentBindings, buildChannelBindings, describeBinding, parseBindingSpecs, } from "./agents.bindings.js";
14
14
  import { createQuietRuntime, requireValidConfig } from "./agents.command-shared.js";
15
15
  import { applyAgentConfig, findAgentEntryIndex, listAgentEntries } from "./agents.config.js";
16
- import { applyAuthChoice, warnIfModelConfigLooksOff } from "./auth-choice.js";
17
16
  import { promptAuthChoiceGrouped } from "./auth-choice-prompt.js";
17
+ import { applyAuthChoice, warnIfModelConfigLooksOff } from "./auth-choice.js";
18
18
  import { setupChannels } from "./onboard-channels.js";
19
19
  import { ensureWorkspaceAndSessions } from "./onboard-helpers.js";
20
20
  async function fileExists(pathname) {
@@ -28,8 +28,9 @@ async function fileExists(pathname) {
28
28
  }
29
29
  export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
30
30
  const cfg = await requireValidConfig(runtime);
31
- if (!cfg)
31
+ if (!cfg) {
32
32
  return;
33
+ }
33
34
  const workspaceFlag = opts.workspace?.trim();
34
35
  const nameInput = opts.name?.trim();
35
36
  const hasFlags = params?.hasFlags === true;
@@ -90,8 +91,9 @@ export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
90
91
  ? applyAgentBindings(nextConfig, bindingParse.bindings)
91
92
  : { config: nextConfig, added: [], skipped: [], conflicts: [] };
92
93
  await writeConfigFile(bindingResult.config);
93
- if (!opts.json)
94
+ if (!opts.json) {
94
95
  logConfigUpdated(runtime);
96
+ }
95
97
  const quietRuntime = opts.json ? createQuietRuntime(runtime) : runtime;
96
98
  await ensureWorkspaceAndSessions(workspaceDir, quietRuntime, {
97
99
  skipBootstrap: Boolean(bindingResult.config.agents?.defaults?.skipBootstrap),
@@ -116,8 +118,9 @@ export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
116
118
  runtime.log(`Agent: ${agentId}`);
117
119
  runtime.log(`Workspace: ${shortenHomePath(workspaceDir)}`);
118
120
  runtime.log(`Agent dir: ${shortenHomePath(agentDir)}`);
119
- if (model)
121
+ if (model) {
120
122
  runtime.log(`Model: ${model}`);
123
+ }
121
124
  if (bindingResult.conflicts.length > 0) {
122
125
  runtime.error([
123
126
  "Skipped bindings already claimed by another agent:",
@@ -129,13 +132,14 @@ export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
129
132
  }
130
133
  const prompter = createClackPrompter();
131
134
  try {
132
- await prompter.intro("Add Poolbot agent");
135
+ await prompter.intro("Add Pool Bot agent");
133
136
  const name = nameInput ??
134
137
  (await prompter.text({
135
138
  message: "Agent name",
136
139
  validate: (value) => {
137
- if (!value?.trim())
140
+ if (!value?.trim()) {
138
141
  return "Required";
142
+ }
139
143
  const normalized = normalizeAgentId(value);
140
144
  if (normalized === DEFAULT_AGENT_ID) {
141
145
  return `"${DEFAULT_AGENT_ID}" is reserved. Choose another name.`;
@@ -143,7 +147,7 @@ export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
143
147
  return undefined;
144
148
  },
145
149
  }));
146
- const agentName = String(name).trim();
150
+ const agentName = String(name ?? "").trim();
147
151
  const agentId = normalizeAgentId(agentName);
148
152
  if (agentName !== agentId) {
149
153
  await prompter.note(`Normalized id to "${agentId}".`, "Agent id");
@@ -165,7 +169,7 @@ export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
165
169
  initialValue: workspaceDefault,
166
170
  validate: (value) => (value?.trim() ? undefined : "Required"),
167
171
  });
168
- const workspaceDir = resolveUserPath(String(workspaceInput).trim() || workspaceDefault);
172
+ const workspaceDir = resolveUserPath(String(workspaceInput ?? "").trim() || workspaceDefault);
169
173
  const agentDir = resolveAgentDir(cfg, agentId);
170
174
  let nextConfig = applyAgentConfig(cfg, {
171
175
  agentId,
@@ -285,7 +289,7 @@ export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
285
289
  }
286
290
  catch (err) {
287
291
  if (err instanceof WizardCancelledError) {
288
- runtime.exit(0);
292
+ runtime.exit(1);
289
293
  return;
290
294
  }
291
295
  throw err;
@@ -38,8 +38,9 @@ function resolveAgentIdByWorkspace(cfg, workspaceDir) {
38
38
  }
39
39
  export async function agentsSetIdentityCommand(opts, runtime = defaultRuntime) {
40
40
  const cfg = await requireValidConfig(runtime);
41
- if (!cfg)
41
+ if (!cfg) {
42
42
  return;
43
+ }
43
44
  const agentRaw = coerceTrimmed(opts.agent);
44
45
  const nameRaw = coerceTrimmed(opts.name);
45
46
  const emojiRaw = coerceTrimmed(opts.emoji);
@@ -155,14 +156,19 @@ export async function agentsSetIdentityCommand(opts, runtime = defaultRuntime) {
155
156
  }
156
157
  logConfigUpdated(runtime);
157
158
  runtime.log(`Agent: ${agentId}`);
158
- if (nextIdentity.name)
159
+ if (nextIdentity.name) {
159
160
  runtime.log(`Name: ${nextIdentity.name}`);
160
- if (nextIdentity.theme)
161
+ }
162
+ if (nextIdentity.theme) {
161
163
  runtime.log(`Theme: ${nextIdentity.theme}`);
162
- if (nextIdentity.emoji)
164
+ }
165
+ if (nextIdentity.emoji) {
163
166
  runtime.log(`Emoji: ${nextIdentity.emoji}`);
164
- if (nextIdentity.avatar)
167
+ }
168
+ if (nextIdentity.avatar) {
165
169
  runtime.log(`Avatar: ${nextIdentity.avatar}`);
166
- if (workspaceDir)
170
+ }
171
+ if (workspaceDir) {
167
172
  runtime.log(`Workspace: ${shortenHomePath(workspaceDir)}`);
173
+ }
168
174
  }
@@ -1,6 +1,6 @@
1
+ import { formatCliCommand } from "../cli/command-format.js";
1
2
  import { normalizeAgentId } from "../routing/session-key.js";
2
3
  import { defaultRuntime } from "../runtime.js";
3
- import { formatCliCommand } from "../cli/command-format.js";
4
4
  import { shortenHomePath } from "../utils.js";
5
5
  import { describeBinding } from "./agents.bindings.js";
6
6
  import { requireValidConfig } from "./agents.command-shared.js";
@@ -12,10 +12,12 @@ function formatSummary(summary) {
12
12
  ? `${summary.id}${defaultTag} (${summary.name})`
13
13
  : `${summary.id}${defaultTag}`;
14
14
  const identityParts = [];
15
- if (summary.identityEmoji)
15
+ if (summary.identityEmoji) {
16
16
  identityParts.push(summary.identityEmoji);
17
- if (summary.identityName)
17
+ }
18
+ if (summary.identityName) {
18
19
  identityParts.push(summary.identityName);
20
+ }
19
21
  const identityLine = identityParts.length > 0 ? identityParts.join(" ") : null;
20
22
  const identitySource = summary.identitySource === "identity"
21
23
  ? "IDENTITY.md"
@@ -28,8 +30,9 @@ function formatSummary(summary) {
28
30
  }
29
31
  lines.push(` Workspace: ${shortenHomePath(summary.workspace)}`);
30
32
  lines.push(` Agent dir: ${shortenHomePath(summary.agentDir)}`);
31
- if (summary.model)
33
+ if (summary.model) {
32
34
  lines.push(` Model: ${summary.model}`);
35
+ }
33
36
  lines.push(` Routing rules: ${summary.bindings}`);
34
37
  if (summary.routes?.length) {
35
38
  lines.push(` Routing: ${summary.routes.join(", ")}`);
@@ -50,8 +53,9 @@ function formatSummary(summary) {
50
53
  }
51
54
  export async function agentsListCommand(opts, runtime = defaultRuntime) {
52
55
  const cfg = await requireValidConfig(runtime);
53
- if (!cfg)
56
+ if (!cfg) {
54
57
  return;
58
+ }
55
59
  const summaries = buildAgentSummaries(cfg);
56
60
  const bindingMap = new Map();
57
61
  for (const binding of cfg.bindings ?? []) {
@@ -84,8 +88,9 @@ export async function agentsListCommand(opts, runtime = defaultRuntime) {
84
88
  bindings,
85
89
  providerStatus,
86
90
  });
87
- if (providerLines.length > 0)
91
+ if (providerLines.length > 0) {
88
92
  summary.providers = providerLines;
93
+ }
89
94
  }
90
95
  if (opts.json) {
91
96
  runtime.log(JSON.stringify(summaries, null, 2));