@poolzin/pool-bot 2026.2.21 → 2026.2.22

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 (369) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/agents/api-key-rotation.js +47 -0
  3. package/dist/agents/apply-patch-update.js +19 -9
  4. package/dist/agents/apply-patch.js +72 -47
  5. package/dist/agents/bash-tools.exec.js +141 -559
  6. package/dist/agents/cli-backends.js +49 -6
  7. package/dist/agents/cli-runner/helpers.js +69 -152
  8. package/dist/agents/cli-runner.js +70 -19
  9. package/dist/agents/identity.js +20 -1
  10. package/dist/agents/image-sanitization.js +9 -0
  11. package/dist/agents/live-auth-keys.js +123 -26
  12. package/dist/agents/live-model-filter.js +13 -4
  13. package/dist/agents/model-catalog.js +40 -9
  14. package/dist/agents/model-forward-compat.js +60 -23
  15. package/dist/agents/model-selection.js +134 -41
  16. package/dist/agents/pi-auth-json.js +2 -2
  17. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  18. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  19. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  20. package/dist/agents/pi-embedded-helpers.js +2 -2
  21. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  22. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  23. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  24. package/dist/agents/pi-embedded-runner/google.js +109 -19
  25. package/dist/agents/pi-embedded-runner/history.js +35 -17
  26. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
  27. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  28. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  29. package/dist/agents/pi-embedded-runner/run.js +193 -25
  30. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  31. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  32. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  33. package/dist/agents/pi-embedded-runner.js +1 -1
  34. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  35. package/dist/agents/pi-embedded-subscribe.js +37 -0
  36. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  37. package/dist/agents/pi-model-discovery.js +9 -2
  38. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  39. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  40. package/dist/agents/pi-tools.js +113 -94
  41. package/dist/agents/pi-tools.read.js +337 -38
  42. package/dist/agents/poolbot-tools.js +14 -5
  43. package/dist/agents/sandbox/docker.js +10 -5
  44. package/dist/agents/sandbox/registry.js +96 -46
  45. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  46. package/dist/agents/sandbox-paths.js +43 -10
  47. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  48. package/dist/agents/session-tool-result-guard.js +39 -39
  49. package/dist/agents/session-transcript-repair.js +36 -33
  50. package/dist/agents/session-write-lock.js +62 -44
  51. package/dist/agents/skills/frontmatter.js +49 -88
  52. package/dist/agents/skills/workspace.js +335 -28
  53. package/dist/agents/subagent-announce.js +508 -174
  54. package/dist/agents/subagent-registry.js +45 -4
  55. package/dist/agents/subagent-spawn.js +16 -33
  56. package/dist/agents/system-prompt-report.js +27 -10
  57. package/dist/agents/system-prompt.js +26 -32
  58. package/dist/agents/tool-call-id.js +69 -17
  59. package/dist/agents/tool-display-common.js +1 -1
  60. package/dist/agents/tool-images.js +64 -31
  61. package/dist/agents/tools/canvas-tool.js +17 -11
  62. package/dist/agents/tools/common.js +37 -19
  63. package/dist/agents/tools/cron-tool.js +40 -38
  64. package/dist/agents/tools/gateway.js +70 -2
  65. package/dist/agents/tools/message-tool.js +181 -40
  66. package/dist/agents/tools/nodes-tool.js +128 -36
  67. package/dist/agents/tools/nodes-utils.js +12 -38
  68. package/dist/agents/tools/session-status-tool.js +24 -71
  69. package/dist/agents/tools/sessions-helpers.js +38 -210
  70. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  71. package/dist/agents/tools/telegram-actions.js +58 -7
  72. package/dist/agents/tools/web-fetch-utils.js +112 -7
  73. package/dist/agents/tools/web-fetch.js +279 -175
  74. package/dist/agents/tools/web-shared.js +71 -8
  75. package/dist/agents/usage.js +25 -16
  76. package/dist/auto-reply/commands-registry.data.js +85 -11
  77. package/dist/auto-reply/dispatch.js +40 -21
  78. package/dist/auto-reply/reply/abort.js +102 -33
  79. package/dist/auto-reply/reply/commands-core.js +82 -33
  80. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  81. package/dist/auto-reply/reply/commands-info.js +41 -12
  82. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  83. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  84. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  85. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  86. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  87. package/dist/auto-reply/reply/mentions.js +18 -11
  88. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  89. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  90. package/dist/auto-reply/reply/session.js +102 -21
  91. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  92. package/dist/auto-reply/status.js +73 -50
  93. package/dist/browser/extension-relay.js +3 -3
  94. package/dist/browser/http-auth.js +1 -1
  95. package/dist/browser/paths.js +2 -2
  96. package/dist/build-info.json +3 -3
  97. package/dist/channels/allowlist-match.js +20 -0
  98. package/dist/channels/allowlists/resolve-utils.js +65 -2
  99. package/dist/channels/chat-type.js +8 -4
  100. package/dist/channels/dock.js +127 -35
  101. package/dist/channels/draft-stream-loop.js +6 -2
  102. package/dist/channels/plugins/actions/telegram.js +42 -18
  103. package/dist/channels/plugins/allowlist-match.js +1 -1
  104. package/dist/channels/plugins/group-mentions.js +51 -41
  105. package/dist/channels/plugins/message-action-names.js +2 -0
  106. package/dist/channels/plugins/message-actions.js +24 -5
  107. package/dist/channels/plugins/normalize/discord.js +26 -4
  108. package/dist/channels/plugins/normalize/signal.js +35 -22
  109. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  110. package/dist/channels/plugins/outbound/imessage.js +15 -14
  111. package/dist/channels/registry.js +20 -7
  112. package/dist/cli/acp-cli.js +7 -5
  113. package/dist/cli/browser-cli-extension.js +25 -12
  114. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  115. package/dist/cli/browser-cli-state.js +101 -145
  116. package/dist/cli/command-options.js +28 -0
  117. package/dist/cli/completion-cli.js +6 -6
  118. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  119. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  120. package/dist/cli/cron-cli/shared.js +7 -1
  121. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  122. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  123. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  124. package/dist/cli/daemon-cli.js +1 -0
  125. package/dist/cli/devices-cli.js +33 -20
  126. package/dist/cli/gateway-cli/register.js +37 -105
  127. package/dist/cli/gateway-cli/run.js +49 -11
  128. package/dist/cli/nodes-camera.js +59 -4
  129. package/dist/cli/nodes-cli/register.camera.js +27 -24
  130. package/dist/cli/nodes-cli/rpc.js +21 -38
  131. package/dist/cli/qr-cli.js +2 -2
  132. package/dist/cli/skills-cli.format.js +2 -2
  133. package/dist/cli/update-cli/progress.js +2 -2
  134. package/dist/cli/update-cli/restart-helper.js +28 -7
  135. package/dist/cli/update-cli/shared.js +7 -7
  136. package/dist/cli/update-cli/status.js +1 -1
  137. package/dist/cli/update-cli/update-command.js +14 -8
  138. package/dist/cli/update-cli/wizard.js +2 -2
  139. package/dist/cli/update-cli.js +21 -1027
  140. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  141. package/dist/commands/channels/add-mutators.js +3 -35
  142. package/dist/commands/channels/add.js +39 -51
  143. package/dist/commands/config-validation.js +1 -1
  144. package/dist/commands/configure.gateway-auth.js +52 -15
  145. package/dist/commands/configure.gateway.js +84 -40
  146. package/dist/commands/doctor-completion.js +3 -3
  147. package/dist/commands/doctor-config-flow.js +536 -16
  148. package/dist/commands/doctor-gateway-services.js +103 -79
  149. package/dist/commands/doctor-memory-search.js +9 -9
  150. package/dist/commands/doctor-platform-notes.js +57 -30
  151. package/dist/commands/doctor-prompter.js +26 -15
  152. package/dist/commands/doctor-session-locks.js +1 -1
  153. package/dist/commands/doctor.js +21 -9
  154. package/dist/commands/model-picker.js +120 -95
  155. package/dist/commands/models/set.js +2 -21
  156. package/dist/commands/models/shared.js +65 -37
  157. package/dist/commands/onboard-helpers.js +81 -39
  158. package/dist/commands/openai-codex-oauth.js +1 -1
  159. package/dist/commands/sessions.js +52 -53
  160. package/dist/commands/status.summary.js +52 -34
  161. package/dist/commands/test-wizard-helpers.js +2 -2
  162. package/dist/config/defaults.js +79 -42
  163. package/dist/config/group-policy.js +50 -18
  164. package/dist/config/includes.js +37 -10
  165. package/dist/config/schema.help.js +5 -4
  166. package/dist/config/schema.hints.js +2 -2
  167. package/dist/config/schema.labels.js +1 -0
  168. package/dist/config/sessions/group.js +12 -11
  169. package/dist/config/sessions/paths.js +137 -11
  170. package/dist/config/sessions/store.js +185 -65
  171. package/dist/config/sessions/types.js +15 -1
  172. package/dist/config/sessions.js +1 -0
  173. package/dist/config/telegram-custom-commands.js +3 -2
  174. package/dist/config/types.js +2 -0
  175. package/dist/config/zod-schema.agent-defaults.js +6 -27
  176. package/dist/config/zod-schema.agent-runtime.js +171 -79
  177. package/dist/config/zod-schema.providers-core.js +138 -65
  178. package/dist/config/zod-schema.session.js +49 -22
  179. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  180. package/dist/cron/isolated-agent/run.js +224 -57
  181. package/dist/cron/normalize.js +48 -45
  182. package/dist/cron/run-log.js +14 -0
  183. package/dist/cron/service/jobs.js +190 -28
  184. package/dist/cron/service/normalize.js +29 -11
  185. package/dist/cron/service/store.js +30 -44
  186. package/dist/cron/service/timer.js +182 -96
  187. package/dist/cron/service.js +3 -0
  188. package/dist/cron/stagger.js +37 -0
  189. package/dist/daemon/inspect.js +132 -92
  190. package/dist/daemon/runtime-paths.js +25 -4
  191. package/dist/daemon/service-audit.js +47 -16
  192. package/dist/discord/accounts.js +23 -20
  193. package/dist/discord/monitor/agent-components.js +1115 -219
  194. package/dist/discord/monitor/allow-list.js +114 -34
  195. package/dist/discord/monitor/listeners.js +204 -97
  196. package/dist/discord/monitor/message-handler.js +21 -10
  197. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  198. package/dist/discord/monitor/message-handler.process.js +384 -123
  199. package/dist/discord/monitor/message-utils.js +86 -23
  200. package/dist/discord/monitor/native-command.js +77 -57
  201. package/dist/discord/monitor/provider.js +122 -117
  202. package/dist/discord/monitor/reply-context.js +20 -16
  203. package/dist/discord/monitor/reply-delivery.js +40 -8
  204. package/dist/discord/monitor/rest-fetch.js +22 -0
  205. package/dist/discord/monitor/threading.js +117 -24
  206. package/dist/discord/send.js +2 -1
  207. package/dist/discord/send.outbound.js +124 -11
  208. package/dist/discord/send.shared.js +112 -72
  209. package/dist/discord/voice-message.js +3 -3
  210. package/dist/gateway/auth.js +119 -44
  211. package/dist/gateway/call.js +76 -34
  212. package/dist/gateway/channel-health-monitor.js +57 -50
  213. package/dist/gateway/client.js +63 -29
  214. package/dist/gateway/control-ui-contract.js +1 -1
  215. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  216. package/dist/gateway/net.js +109 -1
  217. package/dist/gateway/protocol/index.js +5 -8
  218. package/dist/gateway/protocol/schema/agent.js +19 -1
  219. package/dist/gateway/protocol/schema/channels.js +21 -0
  220. package/dist/gateway/protocol/schema/cron.js +43 -30
  221. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  222. package/dist/gateway/protocol/schema/sessions.js +5 -1
  223. package/dist/gateway/protocol/schema.js +0 -1
  224. package/dist/gateway/server/presence-events.js +12 -0
  225. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  226. package/dist/gateway/server/ws-connection.js +58 -21
  227. package/dist/gateway/server-broadcast.js +18 -13
  228. package/dist/gateway/server-cron.js +177 -10
  229. package/dist/gateway/server-methods/agent-job.js +131 -38
  230. package/dist/gateway/server-methods/send.js +60 -14
  231. package/dist/gateway/server-methods/sessions.js +160 -96
  232. package/dist/gateway/server-methods/system.js +5 -7
  233. package/dist/gateway/server-methods-list.js +8 -0
  234. package/dist/gateway/server-methods.js +24 -8
  235. package/dist/gateway/server-node-events.js +278 -68
  236. package/dist/gateway/session-utils.fs.js +316 -75
  237. package/dist/gateway/session-utils.js +224 -70
  238. package/dist/gateway/sessions-patch.js +63 -20
  239. package/dist/gateway/test-temp-config.js +1 -1
  240. package/dist/gateway/tools-invoke-http.js +118 -70
  241. package/dist/gateway/ws-log.js +135 -107
  242. package/dist/hooks/frontmatter.js +36 -82
  243. package/dist/hooks/install.js +149 -139
  244. package/dist/hooks/internal-hooks.js +29 -4
  245. package/dist/hooks/plugin-hooks.js +2 -1
  246. package/dist/imessage/monitor/deliver.js +10 -4
  247. package/dist/imessage/monitor/monitor-provider.js +138 -375
  248. package/dist/imessage/monitor/runtime.js +4 -8
  249. package/dist/imessage/send.js +65 -19
  250. package/dist/infra/exec-approvals-allowlist.js +7 -0
  251. package/dist/infra/exec-approvals.js +35 -920
  252. package/dist/infra/exec-safe-bin-trust.js +64 -0
  253. package/dist/infra/heartbeat-runner.js +207 -134
  254. package/dist/infra/heartbeat-wake.js +183 -22
  255. package/dist/infra/install-source-utils.js +47 -0
  256. package/dist/infra/net/ssrf.js +170 -36
  257. package/dist/infra/outbound/deliver.js +224 -58
  258. package/dist/infra/outbound/message-action-spec.js +12 -5
  259. package/dist/infra/outbound/outbound-session.js +27 -25
  260. package/dist/infra/poolbot-root.js +32 -22
  261. package/dist/infra/ports.js +14 -11
  262. package/dist/infra/skills-remote.js +48 -37
  263. package/dist/infra/system-events.js +25 -11
  264. package/dist/infra/system-presence.js +26 -33
  265. package/dist/infra/tmp-poolbot-dir.js +81 -2
  266. package/dist/infra/wsl.js +37 -1
  267. package/dist/line/bot-message-context.js +163 -191
  268. package/dist/logging/subsystem.js +59 -22
  269. package/dist/markdown/ir.js +124 -50
  270. package/dist/media/store.js +1 -1
  271. package/dist/media-understanding/runner.entries.js +42 -25
  272. package/dist/media-understanding/runner.js +53 -488
  273. package/dist/memory/embeddings-gemini.js +53 -38
  274. package/dist/memory/manager-embedding-ops.js +48 -69
  275. package/dist/pairing/pairing-store.js +178 -119
  276. package/dist/plugin-sdk/index.js +34 -6
  277. package/dist/plugins/hooks.js +135 -14
  278. package/dist/plugins/install.js +190 -152
  279. package/dist/polls.js +11 -0
  280. package/dist/routing/resolve-route.js +190 -56
  281. package/dist/routing/session-key.js +38 -22
  282. package/dist/runtime.js +35 -9
  283. package/dist/security/audit-channel.js +1 -1
  284. package/dist/sessions/session-key-utils.js +29 -11
  285. package/dist/shared/frontmatter.js +5 -5
  286. package/dist/shared/node-list-types.js +1 -0
  287. package/dist/shared/string-normalization.js +15 -0
  288. package/dist/signal/monitor/event-handler.js +68 -36
  289. package/dist/signal/send.js +29 -37
  290. package/dist/slack/monitor/allow-list.js +10 -11
  291. package/dist/slack/monitor/commands.js +14 -3
  292. package/dist/slack/monitor/events/interactions.js +4 -4
  293. package/dist/slack/monitor/media.js +224 -16
  294. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  295. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  296. package/dist/slack/monitor/slash.js +357 -144
  297. package/dist/slack/streaming.js +77 -0
  298. package/dist/telegram/accounts.js +40 -13
  299. package/dist/telegram/allowed-updates.js +3 -0
  300. package/dist/telegram/bot/delivery.js +129 -66
  301. package/dist/telegram/bot/helpers.js +136 -122
  302. package/dist/telegram/bot-handlers.js +600 -339
  303. package/dist/telegram/bot-message-context.js +115 -73
  304. package/dist/telegram/bot-message-dispatch.js +235 -104
  305. package/dist/telegram/bot-native-command-menu.js +3 -1
  306. package/dist/telegram/bot-native-commands.js +213 -193
  307. package/dist/telegram/bot.js +24 -132
  308. package/dist/telegram/draft-stream.js +84 -75
  309. package/dist/telegram/format.js +150 -6
  310. package/dist/telegram/send.js +415 -255
  311. package/dist/telegram/targets.js +21 -2
  312. package/dist/telegram/update-offset-store.js +19 -3
  313. package/dist/terminal/restore.js +5 -2
  314. package/dist/test-utils/fetch-mock.js +5 -0
  315. package/dist/version.js +18 -5
  316. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  317. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  318. package/dist/web/inbound/media.js +34 -8
  319. package/dist/web/inbound/monitor.js +34 -17
  320. package/dist/web/inbound/send-api.js +18 -17
  321. package/dist/web/outbound.js +12 -5
  322. package/dist/wizard/clack-prompter.js +40 -7
  323. package/extensions/bluebubbles/package.json +1 -1
  324. package/extensions/copilot-proxy/package.json +1 -1
  325. package/extensions/diagnostics-otel/package.json +1 -1
  326. package/extensions/discord/package.json +1 -1
  327. package/extensions/feishu/package.json +1 -1
  328. package/extensions/google-antigravity-auth/package.json +1 -1
  329. package/extensions/google-gemini-cli-auth/package.json +1 -1
  330. package/extensions/googlechat/package.json +1 -1
  331. package/extensions/imessage/package.json +1 -1
  332. package/extensions/irc/package.json +1 -1
  333. package/extensions/line/package.json +1 -1
  334. package/extensions/llm-task/package.json +1 -1
  335. package/extensions/lobster/package.json +1 -1
  336. package/extensions/matrix/CHANGELOG.md +5 -0
  337. package/extensions/matrix/package.json +1 -1
  338. package/extensions/mattermost/package.json +1 -1
  339. package/extensions/memory-core/package.json +1 -1
  340. package/extensions/memory-lancedb/package.json +1 -1
  341. package/extensions/minimax-portal-auth/package.json +1 -1
  342. package/extensions/msteams/CHANGELOG.md +5 -0
  343. package/extensions/msteams/package.json +1 -1
  344. package/extensions/nextcloud-talk/package.json +1 -1
  345. package/extensions/nostr/CHANGELOG.md +5 -0
  346. package/extensions/nostr/package.json +1 -1
  347. package/extensions/open-prose/package.json +1 -1
  348. package/extensions/openai-codex-auth/package.json +1 -1
  349. package/extensions/signal/package.json +1 -1
  350. package/extensions/slack/package.json +1 -1
  351. package/extensions/telegram/package.json +1 -1
  352. package/extensions/tlon/package.json +1 -1
  353. package/extensions/twitch/CHANGELOG.md +5 -0
  354. package/extensions/twitch/package.json +1 -1
  355. package/extensions/voice-call/CHANGELOG.md +5 -0
  356. package/extensions/voice-call/package.json +1 -1
  357. package/extensions/whatsapp/package.json +1 -1
  358. package/extensions/zalo/CHANGELOG.md +5 -0
  359. package/extensions/zalo/package.json +1 -1
  360. package/extensions/zalouser/CHANGELOG.md +5 -0
  361. package/extensions/zalouser/package.json +1 -1
  362. package/package.json +1 -1
  363. package/skills/apple-reminders/SKILL.md +100 -49
  364. package/skills/coding-agent/SKILL.md +34 -28
  365. package/skills/github/SKILL.md +131 -16
  366. package/skills/imsg/SKILL.md +112 -15
  367. package/skills/openhue/SKILL.md +101 -19
  368. package/skills/tmux/SKILL.md +111 -79
  369. package/skills/weather/SKILL.md +88 -25
@@ -1,3 +1,4 @@
1
+ import { resolveNodeIdFromCandidates } from "../../shared/node-match.js";
1
2
  import { callGatewayTool } from "./gateway.js";
2
3
  function parseNodeList(value) {
3
4
  const obj = typeof value === "object" && value !== null ? value : {};
@@ -9,20 +10,13 @@ function parsePairingList(value) {
9
10
  const paired = Array.isArray(obj.paired) ? obj.paired : [];
10
11
  return { pending, paired };
11
12
  }
12
- function normalizeNodeKey(value) {
13
- return value
14
- .toLowerCase()
15
- .replace(/[^a-z0-9]+/g, "-")
16
- .replace(/^-+/, "")
17
- .replace(/-+$/, "");
18
- }
19
13
  async function loadNodes(opts) {
20
14
  try {
21
- const res = (await callGatewayTool("node.list", opts, {}));
15
+ const res = await callGatewayTool("node.list", opts, {});
22
16
  return parseNodeList(res);
23
17
  }
24
18
  catch {
25
- const res = (await callGatewayTool("node.pair.list", opts, {}));
19
+ const res = await callGatewayTool("node.pair.list", opts, {});
26
20
  const { paired } = parsePairingList(res);
27
21
  return paired.map((n) => ({
28
22
  nodeId: n.nodeId,
@@ -34,17 +28,20 @@ async function loadNodes(opts) {
34
28
  }
35
29
  function pickDefaultNode(nodes) {
36
30
  const withCanvas = nodes.filter((n) => Array.isArray(n.caps) ? n.caps.includes("canvas") : true);
37
- if (withCanvas.length === 0)
31
+ if (withCanvas.length === 0) {
38
32
  return null;
33
+ }
39
34
  const connected = withCanvas.filter((n) => n.connected);
40
35
  const candidates = connected.length > 0 ? connected : withCanvas;
41
- if (candidates.length === 1)
36
+ if (candidates.length === 1) {
42
37
  return candidates[0];
38
+ }
43
39
  const local = candidates.filter((n) => n.platform?.toLowerCase().startsWith("mac") &&
44
40
  typeof n.nodeId === "string" &&
45
41
  n.nodeId.startsWith("mac-"));
46
- if (local.length === 1)
42
+ if (local.length === 1) {
47
43
  return local[0];
44
+ }
48
45
  return null;
49
46
  }
50
47
  export async function listNodes(opts) {
@@ -55,36 +52,13 @@ export function resolveNodeIdFromList(nodes, query, allowDefault = false) {
55
52
  if (!q) {
56
53
  if (allowDefault) {
57
54
  const picked = pickDefaultNode(nodes);
58
- if (picked)
55
+ if (picked) {
59
56
  return picked.nodeId;
57
+ }
60
58
  }
61
59
  throw new Error("node required");
62
60
  }
63
- const qNorm = normalizeNodeKey(q);
64
- const matches = nodes.filter((n) => {
65
- if (n.nodeId === q)
66
- return true;
67
- if (typeof n.remoteIp === "string" && n.remoteIp === q)
68
- return true;
69
- const name = typeof n.displayName === "string" ? n.displayName : "";
70
- if (name && normalizeNodeKey(name) === qNorm)
71
- return true;
72
- if (q.length >= 6 && n.nodeId.startsWith(q))
73
- return true;
74
- return false;
75
- });
76
- if (matches.length === 1)
77
- return matches[0].nodeId;
78
- if (matches.length === 0) {
79
- const known = nodes
80
- .map((n) => n.displayName || n.remoteIp || n.nodeId)
81
- .filter(Boolean)
82
- .join(", ");
83
- throw new Error(`unknown node: ${q}${known ? ` (known: ${known})` : ""}`);
84
- }
85
- throw new Error(`ambiguous node: ${q} (matches: ${matches
86
- .map((n) => n.displayName || n.remoteIp || n.nodeId)
87
- .join(", ")})`);
61
+ return resolveNodeIdFromCandidates(nodes, q);
88
62
  }
89
63
  export async function resolveNodeId(opts, query, allowDefault = false) {
90
64
  const nodes = await loadNodes(opts);
@@ -1,85 +1,29 @@
1
1
  import { Type } from "@sinclair/typebox";
2
- import { resolveAgentDir } from "../../agents/agent-scope.js";
3
- import { ensureAuthProfileStore, resolveAuthProfileDisplayLabel, resolveAuthProfileOrder, } from "../../agents/auth-profiles.js";
4
- import { getCustomProviderApiKey, resolveEnvApiKey } from "../../agents/model-auth.js";
5
- import { loadModelCatalog } from "../../agents/model-catalog.js";
6
- import { buildAllowedModelSet, buildModelAliasIndex, modelKey, normalizeProviderId, resolveDefaultModelForAgent, resolveModelRefFromString, } from "../../agents/model-selection.js";
7
- import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.js";
8
2
  import { normalizeGroupActivation } from "../../auto-reply/group-activation.js";
9
3
  import { getFollowupQueueDepth, resolveQueueSettings } from "../../auto-reply/reply/queue.js";
10
4
  import { buildStatusMessage } from "../../auto-reply/status.js";
11
5
  import { loadConfig } from "../../config/config.js";
12
6
  import { loadSessionStore, resolveStorePath, updateSessionStore, } from "../../config/sessions.js";
7
+ import { loadCombinedSessionStoreForGateway } from "../../gateway/session-utils.js";
13
8
  import { formatUsageWindowSummary, loadProviderUsageSummary, resolveUsageProviderId, } from "../../infra/provider-usage.js";
14
9
  import { buildAgentMainSessionKey, DEFAULT_AGENT_ID, resolveAgentIdFromSessionKey, } from "../../routing/session-key.js";
15
10
  import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js";
11
+ import { resolveAgentDir } from "../agent-scope.js";
12
+ import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.js";
13
+ import { resolveModelAuthLabel } from "../model-auth-label.js";
14
+ import { loadModelCatalog } from "../model-catalog.js";
15
+ import { buildAllowedModelSet, buildModelAliasIndex, modelKey, resolveDefaultModelForAgent, resolveModelRefFromString, } from "../model-selection.js";
16
16
  import { readStringParam } from "./common.js";
17
17
  import { shouldResolveSessionIdInput, resolveInternalSessionKey, resolveMainSessionAlias, createAgentToAgentPolicy, } from "./sessions-helpers.js";
18
- import { loadCombinedSessionStoreForGateway } from "../../gateway/session-utils.js";
19
18
  const SessionStatusToolSchema = Type.Object({
20
19
  sessionKey: Type.Optional(Type.String()),
21
20
  model: Type.Optional(Type.String()),
22
21
  });
23
- function formatApiKeySnippet(apiKey) {
24
- const compact = apiKey.replace(/\s+/g, "");
25
- if (!compact)
26
- return "unknown";
27
- const edge = compact.length >= 12 ? 6 : 4;
28
- const head = compact.slice(0, edge);
29
- const tail = compact.slice(-edge);
30
- return `${head}…${tail}`;
31
- }
32
- function resolveModelAuthLabel(params) {
33
- const resolvedProvider = params.provider?.trim();
34
- if (!resolvedProvider)
35
- return undefined;
36
- const providerKey = normalizeProviderId(resolvedProvider);
37
- const store = ensureAuthProfileStore(params.agentDir, {
38
- allowKeychainPrompt: false,
39
- });
40
- const profileOverride = params.sessionEntry?.authProfileOverride?.trim();
41
- const order = resolveAuthProfileOrder({
42
- cfg: params.cfg,
43
- store,
44
- provider: providerKey,
45
- preferredProfile: profileOverride,
46
- });
47
- const candidates = [profileOverride, ...order].filter(Boolean);
48
- for (const profileId of candidates) {
49
- const profile = store.profiles[profileId];
50
- if (!profile || normalizeProviderId(profile.provider) !== providerKey) {
51
- continue;
52
- }
53
- const label = resolveAuthProfileDisplayLabel({
54
- cfg: params.cfg,
55
- store,
56
- profileId,
57
- });
58
- if (profile.type === "oauth") {
59
- return `oauth${label ? ` (${label})` : ""}`;
60
- }
61
- if (profile.type === "token") {
62
- return `token ${formatApiKeySnippet(profile.token)}${label ? ` (${label})` : ""}`;
63
- }
64
- return `api-key ${formatApiKeySnippet(profile.key)}${label ? ` (${label})` : ""}`;
65
- }
66
- const envKey = resolveEnvApiKey(providerKey);
67
- if (envKey?.apiKey) {
68
- if (envKey.source.includes("OAUTH_TOKEN")) {
69
- return `oauth (${envKey.source})`;
70
- }
71
- return `api-key ${formatApiKeySnippet(envKey.apiKey)} (${envKey.source})`;
72
- }
73
- const customKey = getCustomProviderApiKey(params.cfg, providerKey);
74
- if (customKey) {
75
- return `api-key ${formatApiKeySnippet(customKey)} (models.json)`;
76
- }
77
- return "unknown";
78
- }
79
22
  function resolveSessionEntry(params) {
80
23
  const keyRaw = params.keyRaw.trim();
81
- if (!keyRaw)
24
+ if (!keyRaw) {
82
25
  return null;
26
+ }
83
27
  const internal = resolveInternalSessionKey({
84
28
  key: keyRaw,
85
29
  alias: params.alias,
@@ -98,31 +42,37 @@ function resolveSessionEntry(params) {
98
42
  }
99
43
  for (const key of candidates) {
100
44
  const entry = params.store[key];
101
- if (entry)
45
+ if (entry) {
102
46
  return { key, entry };
47
+ }
103
48
  }
104
49
  return null;
105
50
  }
106
51
  function resolveSessionKeyFromSessionId(params) {
107
52
  const trimmed = params.sessionId.trim();
108
- if (!trimmed)
53
+ if (!trimmed) {
109
54
  return null;
55
+ }
110
56
  const { store } = loadCombinedSessionStoreForGateway(params.cfg);
111
57
  const match = Object.entries(store).find(([key, entry]) => {
112
- if (entry?.sessionId !== trimmed)
58
+ if (entry?.sessionId !== trimmed) {
113
59
  return false;
114
- if (!params.agentId)
60
+ }
61
+ if (!params.agentId) {
115
62
  return true;
63
+ }
116
64
  return resolveAgentIdFromSessionKey(key) === params.agentId;
117
65
  });
118
66
  return match?.[0] ?? null;
119
67
  }
120
68
  async function resolveModelOverride(params) {
121
69
  const raw = params.raw.trim();
122
- if (!raw)
70
+ if (!raw) {
123
71
  return { kind: "reset" };
124
- if (raw.toLowerCase() === "default")
72
+ }
73
+ if (raw.toLowerCase() === "default") {
125
74
  return { kind: "reset" };
75
+ }
126
76
  const configDefault = resolveDefaultModelForAgent({
127
77
  cfg: params.cfg,
128
78
  agentId: params.agentId,
@@ -178,8 +128,9 @@ export function createSessionStatusTool(opts) {
178
128
  }
179
129
  const requesterAgentId = resolveAgentIdFromSessionKey(opts?.agentSessionKey ?? requestedKeyRaw);
180
130
  const ensureAgentAccess = (targetAgentId) => {
181
- if (targetAgentId === requesterAgentId)
131
+ if (targetAgentId === requesterAgentId) {
182
132
  return;
133
+ }
183
134
  // Gate cross-agent access behind tools.agentToAgent settings.
184
135
  if (!a2aPolicy.enabled) {
185
136
  throw new Error("Agent-to-agent status is disabled. Set tools.agentToAgent.enabled=true to allow cross-agent access.");
@@ -322,8 +273,10 @@ export function createSessionStatusTool(opts) {
322
273
  ...agentDefaults,
323
274
  model: agentModel,
324
275
  },
276
+ agentId,
325
277
  sessionEntry: resolved.entry,
326
278
  sessionKey: resolved.key,
279
+ sessionStorePath: storePath,
327
280
  groupActivation,
328
281
  modelAuth: resolveModelAuthLabel({
329
282
  provider: providerForCard,
@@ -1,216 +1,46 @@
1
- import { callGateway } from "../../gateway/call.js";
1
+ export { createAgentToAgentPolicy, createSessionVisibilityGuard, resolveEffectiveSessionToolsVisibility, resolveSandboxSessionToolsVisibility, resolveSandboxedSessionToolContext, resolveSessionToolsVisibility, } from "./sessions-access.js";
2
+ export { isRequesterSpawnedSessionVisible, listSpawnedSessionKeys, looksLikeSessionId, looksLikeSessionKey, resolveDisplaySessionKey, resolveInternalSessionKey, resolveMainSessionAlias, resolveSessionReference, shouldResolveSessionIdInput, } from "./sessions-resolution.js";
3
+ import { extractTextFromChatContent } from "../../shared/chat-content.js";
2
4
  import { sanitizeUserFacingText } from "../pi-embedded-helpers.js";
3
5
  import { stripDowngradedToolCallText, stripMinimaxToolCallXml, stripThinkingTagsFromText, } from "../pi-embedded-utils.js";
4
- import { isAcpSessionKey, normalizeMainKey } from "../../routing/session-key.js";
5
6
  function normalizeKey(value) {
6
7
  const trimmed = value?.trim();
7
8
  return trimmed ? trimmed : undefined;
8
9
  }
9
- export function resolveMainSessionAlias(cfg) {
10
- const mainKey = normalizeMainKey(cfg.session?.mainKey);
11
- const scope = cfg.session?.scope ?? "per-sender";
12
- const alias = scope === "global" ? "global" : mainKey;
13
- return { mainKey, alias, scope };
14
- }
15
- export function resolveDisplaySessionKey(params) {
16
- if (params.key === params.alias)
17
- return "main";
18
- if (params.key === params.mainKey)
19
- return "main";
20
- return params.key;
21
- }
22
- export function resolveInternalSessionKey(params) {
23
- if (params.key === "main")
24
- return params.alias;
25
- return params.key;
26
- }
27
- export function createAgentToAgentPolicy(cfg) {
28
- const routingA2A = cfg.tools?.agentToAgent;
29
- const enabled = routingA2A?.enabled === true;
30
- const allowPatterns = Array.isArray(routingA2A?.allow) ? routingA2A.allow : [];
31
- const matchesAllow = (agentId) => {
32
- if (allowPatterns.length === 0)
33
- return true;
34
- return allowPatterns.some((pattern) => {
35
- const raw = String(pattern ?? "").trim();
36
- if (!raw)
37
- return false;
38
- if (raw === "*")
39
- return true;
40
- if (!raw.includes("*"))
41
- return raw === agentId;
42
- const escaped = raw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
43
- const re = new RegExp(`^${escaped.replaceAll("\\*", ".*")}$`, "i");
44
- return re.test(agentId);
45
- });
46
- };
47
- const isAllowed = (requesterAgentId, targetAgentId) => {
48
- if (requesterAgentId === targetAgentId)
49
- return true;
50
- if (!enabled)
51
- return false;
52
- return matchesAllow(requesterAgentId) && matchesAllow(targetAgentId);
53
- };
54
- return { enabled, matchesAllow, isAllowed };
55
- }
56
- const SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
57
- export function looksLikeSessionId(value) {
58
- return SESSION_ID_RE.test(value.trim());
59
- }
60
- export function looksLikeSessionKey(value) {
61
- const raw = value.trim();
62
- if (!raw)
63
- return false;
64
- // These are canonical key shapes that should never be treated as sessionIds.
65
- if (raw === "main" || raw === "global" || raw === "unknown")
66
- return true;
67
- if (isAcpSessionKey(raw))
68
- return true;
69
- if (raw.startsWith("agent:"))
70
- return true;
71
- if (raw.startsWith("cron:") || raw.startsWith("hook:"))
72
- return true;
73
- if (raw.startsWith("node-") || raw.startsWith("node:"))
74
- return true;
75
- if (raw.includes(":group:") || raw.includes(":channel:"))
76
- return true;
77
- return false;
78
- }
79
- export function shouldResolveSessionIdInput(value) {
80
- // Treat anything that doesn't look like a well-formed key as a sessionId candidate.
81
- return looksLikeSessionId(value) || !looksLikeSessionKey(value);
82
- }
83
- async function resolveSessionKeyFromSessionId(params) {
84
- try {
85
- // Resolve via gateway so we respect store routing and visibility rules.
86
- const result = (await callGateway({
87
- method: "sessions.resolve",
88
- params: {
89
- sessionId: params.sessionId,
90
- spawnedBy: params.restrictToSpawned ? params.requesterInternalKey : undefined,
91
- includeGlobal: !params.restrictToSpawned,
92
- includeUnknown: !params.restrictToSpawned,
93
- },
94
- }));
95
- const key = typeof result?.key === "string" ? result.key.trim() : "";
96
- if (!key) {
97
- throw new Error(`Session not found: ${params.sessionId} (use the full sessionKey from sessions_list)`);
98
- }
99
- return {
100
- ok: true,
101
- key,
102
- displayKey: resolveDisplaySessionKey({
103
- key,
104
- alias: params.alias,
105
- mainKey: params.mainKey,
106
- }),
107
- resolvedViaSessionId: true,
108
- };
109
- }
110
- catch (err) {
111
- if (params.restrictToSpawned) {
112
- return {
113
- ok: false,
114
- status: "forbidden",
115
- error: `Session not visible from this sandboxed agent session: ${params.sessionId}`,
116
- };
117
- }
118
- const message = err instanceof Error ? err.message : String(err);
119
- return {
120
- ok: false,
121
- status: "error",
122
- error: message ||
123
- `Session not found: ${params.sessionId} (use the full sessionKey from sessions_list)`,
124
- };
125
- }
126
- }
127
- async function resolveSessionKeyFromKey(params) {
128
- try {
129
- // Try key-based resolution first so non-standard keys keep working.
130
- const result = (await callGateway({
131
- method: "sessions.resolve",
132
- params: {
133
- key: params.key,
134
- spawnedBy: params.restrictToSpawned ? params.requesterInternalKey : undefined,
135
- },
136
- }));
137
- const key = typeof result?.key === "string" ? result.key.trim() : "";
138
- if (!key)
139
- return null;
140
- return {
141
- ok: true,
142
- key,
143
- displayKey: resolveDisplaySessionKey({
144
- key,
145
- alias: params.alias,
146
- mainKey: params.mainKey,
147
- }),
148
- resolvedViaSessionId: false,
149
- };
150
- }
151
- catch {
152
- return null;
153
- }
154
- }
155
- export async function resolveSessionReference(params) {
156
- const raw = params.sessionKey.trim();
157
- if (shouldResolveSessionIdInput(raw)) {
158
- // Prefer key resolution to avoid misclassifying custom keys as sessionIds.
159
- const resolvedByKey = await resolveSessionKeyFromKey({
160
- key: raw,
161
- alias: params.alias,
162
- mainKey: params.mainKey,
163
- requesterInternalKey: params.requesterInternalKey,
164
- restrictToSpawned: params.restrictToSpawned,
165
- });
166
- if (resolvedByKey)
167
- return resolvedByKey;
168
- return await resolveSessionKeyFromSessionId({
169
- sessionId: raw,
170
- alias: params.alias,
171
- mainKey: params.mainKey,
172
- requesterInternalKey: params.requesterInternalKey,
173
- restrictToSpawned: params.restrictToSpawned,
174
- });
175
- }
176
- const resolvedKey = resolveInternalSessionKey({
177
- key: raw,
178
- alias: params.alias,
179
- mainKey: params.mainKey,
180
- });
181
- const displayKey = resolveDisplaySessionKey({
182
- key: resolvedKey,
183
- alias: params.alias,
184
- mainKey: params.mainKey,
185
- });
186
- return { ok: true, key: resolvedKey, displayKey, resolvedViaSessionId: false };
187
- }
188
10
  export function classifySessionKind(params) {
189
11
  const key = params.key;
190
- if (key === params.alias || key === params.mainKey)
12
+ if (key === params.alias || key === params.mainKey) {
191
13
  return "main";
192
- if (key.startsWith("cron:"))
14
+ }
15
+ if (key.startsWith("cron:")) {
193
16
  return "cron";
194
- if (key.startsWith("hook:"))
17
+ }
18
+ if (key.startsWith("hook:")) {
195
19
  return "hook";
196
- if (key.startsWith("node-") || key.startsWith("node:"))
20
+ }
21
+ if (key.startsWith("node-") || key.startsWith("node:")) {
197
22
  return "node";
198
- if (params.gatewayKind === "group")
23
+ }
24
+ if (params.gatewayKind === "group") {
199
25
  return "group";
26
+ }
200
27
  if (key.includes(":group:") || key.includes(":channel:")) {
201
28
  return "group";
202
29
  }
203
30
  return "other";
204
31
  }
205
32
  export function deriveChannel(params) {
206
- if (params.kind === "cron" || params.kind === "hook" || params.kind === "node")
33
+ if (params.kind === "cron" || params.kind === "hook" || params.kind === "node") {
207
34
  return "internal";
35
+ }
208
36
  const channel = normalizeKey(params.channel ?? undefined);
209
- if (channel)
37
+ if (channel) {
210
38
  return channel;
39
+ }
211
40
  const lastChannel = normalizeKey(params.lastChannel ?? undefined);
212
- if (lastChannel)
41
+ if (lastChannel) {
213
42
  return lastChannel;
43
+ }
214
44
  const parts = params.key.split(":").filter(Boolean);
215
45
  if (parts.length >= 3 && (parts[1] === "group" || parts[1] === "channel")) {
216
46
  return parts[0];
@@ -219,10 +49,11 @@ export function deriveChannel(params) {
219
49
  }
220
50
  export function stripToolMessages(messages) {
221
51
  return messages.filter((msg) => {
222
- if (!msg || typeof msg !== "object")
52
+ if (!msg || typeof msg !== "object") {
223
53
  return true;
54
+ }
224
55
  const role = msg.role;
225
- return role !== "toolResult";
56
+ return role !== "toolResult" && role !== "tool";
226
57
  });
227
58
  }
228
59
  /**
@@ -230,32 +61,29 @@ export function stripToolMessages(messages) {
230
61
  * This ensures user-facing text doesn't leak internal tool representations.
231
62
  */
232
63
  export function sanitizeTextContent(text) {
233
- if (!text)
64
+ if (!text) {
234
65
  return text;
66
+ }
235
67
  return stripThinkingTagsFromText(stripDowngradedToolCallText(stripMinimaxToolCallXml(text)));
236
68
  }
237
69
  export function extractAssistantText(message) {
238
- if (!message || typeof message !== "object")
70
+ if (!message || typeof message !== "object") {
239
71
  return undefined;
240
- if (message.role !== "assistant")
72
+ }
73
+ if (message.role !== "assistant") {
241
74
  return undefined;
75
+ }
242
76
  const content = message.content;
243
- if (!Array.isArray(content))
77
+ if (!Array.isArray(content)) {
244
78
  return undefined;
245
- const chunks = [];
246
- for (const block of content) {
247
- if (!block || typeof block !== "object")
248
- continue;
249
- if (block.type !== "text")
250
- continue;
251
- const text = block.text;
252
- if (typeof text === "string") {
253
- const sanitized = sanitizeTextContent(text);
254
- if (sanitized.trim()) {
255
- chunks.push(sanitized);
256
- }
257
- }
258
79
  }
259
- const joined = chunks.join("").trim();
260
- return joined ? sanitizeUserFacingText(joined) : undefined;
80
+ const joined = extractTextFromChatContent(content, {
81
+ sanitizeText: sanitizeTextContent,
82
+ joinWith: "",
83
+ normalizeText: (text) => text.trim(),
84
+ }) ?? "";
85
+ const stopReason = message.stopReason;
86
+ const errorMessage = message.errorMessage;
87
+ const errorContext = stopReason === "error" || (typeof errorMessage === "string" && Boolean(errorMessage.trim()));
88
+ return joined ? sanitizeUserFacingText(joined, { errorContext }) : undefined;
261
89
  }