@poolzin/pool-bot 2026.2.11 → 2026.2.18

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 (535) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/agents/agent-scope.js +4 -0
  3. package/dist/agents/announce-idempotency.js +14 -0
  4. package/dist/agents/auth-profiles/usage.js +22 -0
  5. package/dist/agents/auth-profiles.js +1 -1
  6. package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +23 -0
  7. package/dist/agents/bash-tools.exec-runtime.js +438 -0
  8. package/dist/agents/bash-tools.shared.js +6 -0
  9. package/dist/agents/cli-runner/reliability.js +61 -0
  10. package/dist/agents/cli-watchdog-defaults.js +11 -0
  11. package/dist/agents/command-poll-backoff.js +63 -0
  12. package/dist/agents/current-time.js +16 -0
  13. package/dist/agents/glob-pattern.js +42 -0
  14. package/dist/agents/memory-search.js +33 -0
  15. package/dist/agents/model-alias-lines.js +18 -0
  16. package/dist/agents/model-auth-label.js +61 -0
  17. package/dist/agents/model-fallback.js +59 -8
  18. package/dist/agents/models-config.e2e-harness.js +115 -0
  19. package/dist/agents/ollama-stream.js +11 -3
  20. package/dist/agents/openclaw-tools.js +135 -0
  21. package/dist/agents/pi-auth-json.js +118 -0
  22. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +147 -0
  23. package/dist/agents/pi-embedded-subscribe.e2e-harness.js +90 -0
  24. package/dist/agents/pi-embedded-subscribe.handlers.compaction.js +63 -0
  25. package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +30 -0
  26. package/dist/agents/pi-extensions/session-manager-runtime-registry.js +23 -0
  27. package/dist/agents/pi-tools.before-tool-call.js +145 -4
  28. package/dist/agents/pi-tools.js +29 -9
  29. package/dist/agents/pi-tools.policy.js +85 -92
  30. package/dist/agents/pi-tools.schema.js +54 -27
  31. package/dist/agents/queued-file-writer.js +22 -0
  32. package/dist/agents/sandbox/docker.js +133 -40
  33. package/dist/agents/sandbox/fs-bridge.js +146 -0
  34. package/dist/agents/sandbox/fs-paths.js +205 -0
  35. package/dist/agents/sandbox/hash.js +4 -0
  36. package/dist/agents/sandbox/validate-sandbox-security.js +157 -0
  37. package/dist/agents/sandbox-paths.js +3 -0
  38. package/dist/agents/sandbox-tool-policy.js +26 -0
  39. package/dist/agents/sanitize-for-prompt.js +18 -0
  40. package/dist/agents/session-dirs.js +20 -0
  41. package/dist/agents/session-write-lock.js +203 -39
  42. package/dist/agents/skills/filter.js +24 -0
  43. package/dist/agents/skills/tools-dir.js +9 -0
  44. package/dist/agents/skills-install-download.js +290 -0
  45. package/dist/agents/skills-install-output.js +30 -0
  46. package/dist/agents/skills-install.download-test-utils.js +36 -0
  47. package/dist/agents/skills.e2e-test-helpers.js +13 -0
  48. package/dist/agents/subagent-announce-queue.js +59 -15
  49. package/dist/agents/subagent-depth.js +137 -0
  50. package/dist/agents/subagent-registry.js +448 -96
  51. package/dist/agents/subagent-spawn.js +262 -0
  52. package/dist/agents/system-prompt.js +52 -10
  53. package/dist/agents/test-helpers/fast-tool-stubs.js +18 -0
  54. package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +74 -0
  55. package/dist/agents/tool-display-common.js +782 -0
  56. package/dist/agents/tool-loop-detection.js +466 -0
  57. package/dist/agents/tool-policy.js +6 -0
  58. package/dist/agents/tools/image-tool.js +1 -1
  59. package/dist/agents/tools/sessions-access.js +178 -0
  60. package/dist/agents/tools/sessions-resolution.js +206 -0
  61. package/dist/agents/tools/subagents-tool.js +616 -0
  62. package/dist/agents/workspace-dir.js +18 -0
  63. package/dist/agents/workspace-dirs.js +14 -0
  64. package/dist/agents/workspace.js +70 -0
  65. package/dist/auto-reply/heartbeat-reply-payload.js +18 -0
  66. package/dist/auto-reply/reply/commands-export-session.js +163 -0
  67. package/dist/auto-reply/reply/commands-mesh.js +245 -0
  68. package/dist/auto-reply/reply/commands-setunset.js +28 -0
  69. package/dist/auto-reply/reply/commands-slash-parse.js +31 -0
  70. package/dist/auto-reply/reply/commands-system-prompt.js +117 -0
  71. package/dist/auto-reply/reply/directive-handling.levels.js +17 -0
  72. package/dist/auto-reply/reply/directive-handling.params.js +1 -0
  73. package/dist/auto-reply/reply/directive-parsing.js +36 -0
  74. package/dist/auto-reply/reply/dispatcher-registry.js +43 -0
  75. package/dist/auto-reply/reply/elevated-unavailable.js +20 -0
  76. package/dist/auto-reply/reply/post-compaction-audit.js +96 -0
  77. package/dist/auto-reply/reply/post-compaction-context.js +98 -0
  78. package/dist/auto-reply/reply/reply-delivery.js +92 -0
  79. package/dist/auto-reply/reply/session-reset-prompt.js +1 -0
  80. package/dist/auto-reply/reply/session-run-accounting.js +33 -0
  81. package/dist/auto-reply/reply.directive.directive-behavior.e2e-harness.js +115 -0
  82. package/dist/auto-reply/reply.directive.directive-behavior.e2e-mocks.js +12 -0
  83. package/dist/browser/bridge-auth-registry.js +26 -0
  84. package/dist/browser/client-actions-url.js +10 -0
  85. package/dist/browser/control-auth.js +73 -0
  86. package/dist/browser/csrf.js +64 -0
  87. package/dist/browser/http-auth.js +52 -0
  88. package/dist/browser/paths.js +37 -0
  89. package/dist/browser/proxy-files.js +32 -0
  90. package/dist/browser/pw-ai-state.js +7 -0
  91. package/dist/browser/resolved-config-refresh.js +42 -0
  92. package/dist/browser/routes/path-output.js +1 -0
  93. package/dist/browser/server-context.chrome-test-harness.js +20 -0
  94. package/dist/browser/server-middleware.js +31 -0
  95. package/dist/browser/test-port.js +16 -0
  96. package/dist/build-info.json +3 -3
  97. package/dist/canvas-host/file-resolver.js +43 -0
  98. package/dist/channels/account-summary.js +19 -0
  99. package/dist/channels/draft-stream-loop.js +77 -0
  100. package/dist/channels/plugins/account-helpers.js +26 -0
  101. package/dist/channels/telegram/allow-from.js +10 -0
  102. package/dist/cli/browser-cli-resize.js +22 -0
  103. package/dist/cli/browser-cli-shared.js +8 -0
  104. package/dist/cli/clawbot-cli.js +5 -0
  105. package/dist/cli/completion-cli.js +566 -0
  106. package/dist/cli/config-cli.js +63 -5
  107. package/dist/cli/daemon-cli/lifecycle-core.js +256 -0
  108. package/dist/cli/daemon-cli/register-service-commands.js +60 -0
  109. package/dist/cli/daemon-cli-compat.js +80 -0
  110. package/dist/cli/nodes-cli/pairing-render.js +26 -0
  111. package/dist/cli/program/action-reparse.js +17 -0
  112. package/dist/cli/program/command-registry.js +17 -0
  113. package/dist/cli/program/program-context.js +8 -0
  114. package/dist/cli/program/register.subclis.js +7 -0
  115. package/dist/cli/program/routes.js +233 -0
  116. package/dist/cli/qr-cli.js +132 -0
  117. package/dist/cli/requirements-test-fixtures.js +17 -0
  118. package/dist/cli/respawn-policy.js +4 -0
  119. package/dist/cli/shared/parse-port.js +18 -0
  120. package/dist/cli/skills-cli.format.js +241 -0
  121. package/dist/cli/update-cli/progress.js +121 -0
  122. package/dist/cli/update-cli/restart-helper.js +108 -0
  123. package/dist/cli/update-cli/shared.js +196 -0
  124. package/dist/cli/update-cli/status.js +97 -0
  125. package/dist/cli/update-cli/suppress-deprecations.js +17 -0
  126. package/dist/cli/update-cli/update-command.js +506 -0
  127. package/dist/cli/update-cli/wizard.js +130 -0
  128. package/dist/cli/update-cli.js +3 -9
  129. package/dist/cli/windows-argv.js +69 -0
  130. package/dist/commands/auth-choice-legacy.js +20 -0
  131. package/dist/commands/auth-choice.apply-helpers.js +8 -0
  132. package/dist/commands/channel-test-helpers.js +19 -0
  133. package/dist/commands/cleanup-plan.js +10 -0
  134. package/dist/commands/cleanup-utils.js +7 -0
  135. package/dist/commands/config-validation.js +15 -0
  136. package/dist/commands/doctor-completion.js +112 -0
  137. package/dist/commands/doctor-memory-search.js +119 -0
  138. package/dist/commands/doctor-session-locks.js +73 -0
  139. package/dist/commands/doctor.e2e-harness.js +364 -0
  140. package/dist/commands/gateway-presence.js +19 -0
  141. package/dist/commands/model-default.js +35 -0
  142. package/dist/commands/models/fallbacks-shared.js +102 -0
  143. package/dist/commands/models/shared.js +24 -0
  144. package/dist/commands/onboard-auth.config-gateways.js +64 -0
  145. package/dist/commands/onboard-auth.config-litellm.js +45 -0
  146. package/dist/commands/onboard-auth.config-shared.js +116 -0
  147. package/dist/commands/onboard-config.js +16 -0
  148. package/dist/commands/onboard-non-interactive.test-helpers.js +31 -0
  149. package/dist/commands/onboard-provider-auth-flags.js +136 -0
  150. package/dist/commands/openai-codex-oauth.js +40 -0
  151. package/dist/commands/test-runtime-config-helpers.js +21 -0
  152. package/dist/commands/test-wizard-helpers.js +68 -0
  153. package/dist/commands/vllm-setup.js +66 -0
  154. package/dist/compat/legacy-names.js +2 -0
  155. package/dist/config/backup-rotation.js +19 -0
  156. package/dist/config/env-preserve.js +122 -0
  157. package/dist/config/includes-scan.js +78 -0
  158. package/dist/config/plugins-allowlist.js +13 -0
  159. package/dist/config/schema.help.js +256 -0
  160. package/dist/config/schema.hints.js +189 -0
  161. package/dist/config/schema.irc.js +20 -0
  162. package/dist/config/schema.labels.js +317 -0
  163. package/dist/config/sessions/delivery-info.js +40 -0
  164. package/dist/config/types.irc.js +1 -0
  165. package/dist/config/zod-schema.agent-defaults.js +14 -0
  166. package/dist/config/zod-schema.agent-model.js +10 -0
  167. package/dist/config/zod-schema.agent-runtime.js +14 -0
  168. package/dist/config/zod-schema.allowdeny.js +35 -0
  169. package/dist/config/zod-schema.sensitive.js +4 -0
  170. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  171. package/dist/cron/isolated-agent/skills-snapshot.js +26 -0
  172. package/dist/cron/isolated-agent/subagent-followup.js +127 -0
  173. package/dist/cron/isolated-agent.mocks.js +12 -0
  174. package/dist/cron/isolated-agent.test-setup.js +22 -0
  175. package/dist/cron/legacy-delivery.js +43 -0
  176. package/dist/cron/webhook-url.js +22 -0
  177. package/dist/daemon/arg-split.js +40 -0
  178. package/dist/daemon/exec-file.js +23 -0
  179. package/dist/daemon/output.js +6 -0
  180. package/dist/daemon/runtime-format.js +31 -0
  181. package/dist/daemon/schtasks-exec.js +4 -0
  182. package/dist/daemon/service-audit.js +22 -0
  183. package/dist/discord/client.js +41 -0
  184. package/dist/discord/components-registry.js +57 -0
  185. package/dist/discord/components.js +816 -0
  186. package/dist/discord/guilds.js +12 -0
  187. package/dist/discord/monitor/gateway-plugin.js +48 -0
  188. package/dist/discord/monitor/presence.js +30 -0
  189. package/dist/discord/send.components.js +115 -0
  190. package/dist/discord/send.shared.js +4 -0
  191. package/dist/discord/ui.js +26 -0
  192. package/dist/discord/voice-message.js +254 -0
  193. package/dist/gateway/agent-event-assistant-text.js +5 -0
  194. package/dist/gateway/agent-prompt.js +33 -0
  195. package/dist/gateway/auth-rate-limit.js +136 -0
  196. package/dist/gateway/channel-health-monitor.js +114 -0
  197. package/dist/gateway/control-ui-contract.js +1 -0
  198. package/dist/gateway/control-ui-csp.js +15 -0
  199. package/dist/gateway/gateway-config-prompts.shared.js +25 -0
  200. package/dist/gateway/http-auth-helpers.js +18 -0
  201. package/dist/gateway/http-common.js +18 -0
  202. package/dist/gateway/http-endpoint-helpers.js +27 -0
  203. package/dist/gateway/node-invoke-sanitize.js +11 -0
  204. package/dist/gateway/node-invoke-system-run-approval.js +205 -0
  205. package/dist/gateway/probe-auth.js +21 -0
  206. package/dist/gateway/protocol/index.js +7 -2
  207. package/dist/gateway/protocol/schema/mesh.js +54 -0
  208. package/dist/gateway/protocol/schema/protocol-schemas.js +7 -0
  209. package/dist/gateway/protocol/schema.js +1 -0
  210. package/dist/gateway/server/ws-connection/auth-messages.js +54 -0
  211. package/dist/gateway/server-channels.js +11 -0
  212. package/dist/gateway/server-methods/attachment-normalize.js +16 -0
  213. package/dist/gateway/server-methods/base-hash.js +8 -0
  214. package/dist/gateway/server-methods/mesh.js +700 -0
  215. package/dist/gateway/server-methods/nodes.handlers.invoke-result.js +55 -0
  216. package/dist/gateway/server-methods/restart-request.js +13 -0
  217. package/dist/gateway/server-methods/validation.js +8 -0
  218. package/dist/gateway/server.agent.gateway-server-agent.mocks.js +35 -0
  219. package/dist/gateway/server.e2e-registry-helpers.js +1 -0
  220. package/dist/gateway/server.e2e-ws-harness.js +20 -0
  221. package/dist/gateway/test-helpers.js +2 -0
  222. package/dist/gateway/test-helpers.server.js +3 -1
  223. package/dist/gateway/test-http-response.js +12 -0
  224. package/dist/gateway/test-openai-responses-model.js +20 -0
  225. package/dist/gateway/test-temp-config.js +30 -0
  226. package/dist/gateway/test-with-server.js +32 -0
  227. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +46 -0
  228. package/dist/imessage/monitor/abort-handler.js +23 -0
  229. package/dist/imessage/monitor/inbound-processing.js +346 -0
  230. package/dist/imessage/monitor/parse-notification.js +64 -0
  231. package/dist/imessage/target-parsing-helpers.js +92 -0
  232. package/dist/infra/archive.js +244 -20
  233. package/dist/infra/detect-package-manager.js +26 -0
  234. package/dist/infra/exec-approvals-allowlist.js +257 -0
  235. package/dist/infra/exec-approvals-analysis.js +770 -0
  236. package/dist/infra/exec-approvals.js +13 -0
  237. package/dist/infra/file-lock.js +1 -0
  238. package/dist/infra/gemini-auth.js +39 -0
  239. package/dist/infra/heartbeat-active-hours.js +85 -0
  240. package/dist/infra/heartbeat-events-filter.js +50 -0
  241. package/dist/infra/heartbeat-runner.test-utils.js +39 -0
  242. package/dist/infra/http-body.js +265 -0
  243. package/dist/infra/install-package-dir.js +50 -0
  244. package/dist/infra/install-safe-path.js +49 -0
  245. package/dist/infra/json-files.js +49 -0
  246. package/dist/infra/jsonl-socket.js +52 -0
  247. package/dist/infra/map-size.js +14 -0
  248. package/dist/infra/net/hostname.js +7 -0
  249. package/dist/infra/npm-registry-spec.js +39 -0
  250. package/dist/infra/openclaw-root.js +109 -0
  251. package/dist/infra/outbound/delivery-queue.js +214 -0
  252. package/dist/infra/outbound/identity.js +23 -0
  253. package/dist/infra/outbound/message-action-params.js +307 -0
  254. package/dist/infra/outbound/tool-payload.js +21 -0
  255. package/dist/infra/package-json.js +23 -0
  256. package/dist/infra/pairing-files.js +19 -0
  257. package/dist/infra/pairing-token.js +9 -0
  258. package/dist/infra/path-prepend.js +51 -0
  259. package/dist/infra/path-safety.js +16 -0
  260. package/dist/infra/process-respawn.js +49 -0
  261. package/dist/infra/runtime-status.js +16 -0
  262. package/dist/infra/session-cost-usage.types.js +1 -0
  263. package/dist/infra/session-maintenance-warning.js +89 -0
  264. package/dist/infra/system-run-command.js +78 -0
  265. package/dist/infra/tmp-openclaw-dir.js +81 -0
  266. package/dist/infra/tmp-poolbot-dir.js +2 -0
  267. package/dist/infra/update-channels.js +19 -0
  268. package/dist/line/actions.js +45 -0
  269. package/dist/line/channel-access-token.js +9 -0
  270. package/dist/line/flex-templates/basic-cards.js +332 -0
  271. package/dist/line/flex-templates/common.js +18 -0
  272. package/dist/line/flex-templates/media-control-cards.js +453 -0
  273. package/dist/line/flex-templates/message.js +10 -0
  274. package/dist/line/flex-templates/schedule-cards.js +399 -0
  275. package/dist/line/flex-templates/types.js +1 -0
  276. package/dist/line/webhook-node.js +100 -0
  277. package/dist/line/webhook-utils.js +11 -0
  278. package/dist/logging/diagnostic-session-state.js +73 -0
  279. package/dist/logging/diagnostic.js +22 -0
  280. package/dist/logging/timestamps.js +14 -0
  281. package/dist/markdown/whatsapp.js +62 -0
  282. package/dist/media/base64.js +34 -0
  283. package/dist/media/local-roots.js +32 -0
  284. package/dist/media/outbound-attachment.js +10 -0
  285. package/dist/media/read-response-with-limit.js +41 -0
  286. package/dist/media/sniff-mime-from-base64.js +19 -0
  287. package/dist/media-understanding/audio-preflight.js +67 -0
  288. package/dist/media-understanding/fs.js +13 -0
  289. package/dist/media-understanding/output-extract.js +26 -0
  290. package/dist/media-understanding/providers/audio.test-helpers.js +34 -0
  291. package/dist/media-understanding/providers/google/inline-data.js +64 -0
  292. package/dist/media-understanding/providers/shared.js +7 -0
  293. package/dist/media-understanding/runner.entries.js +459 -0
  294. package/dist/memory/batch-error-utils.js +11 -0
  295. package/dist/memory/batch-http.js +27 -0
  296. package/dist/memory/batch-output.js +29 -0
  297. package/dist/memory/batch-runner.js +22 -0
  298. package/dist/memory/batch-upload.js +23 -0
  299. package/dist/memory/batch-utils.js +26 -0
  300. package/dist/memory/embeddings-debug.js +11 -0
  301. package/dist/memory/embeddings-remote-client.js +22 -0
  302. package/dist/memory/embeddings-remote-fetch.js +14 -0
  303. package/dist/memory/embeddings.js +36 -9
  304. package/dist/memory/hybrid.js +24 -5
  305. package/dist/memory/manager-embedding-ops.js +616 -0
  306. package/dist/memory/manager-sync-ops.js +953 -0
  307. package/dist/memory/manager.js +76 -28
  308. package/dist/memory/mmr.js +164 -0
  309. package/dist/memory/qmd-manager.js +1061 -0
  310. package/dist/memory/qmd-query-parser.js +107 -0
  311. package/dist/memory/qmd-scope.js +93 -0
  312. package/dist/memory/query-expansion.js +331 -0
  313. package/dist/memory/search-manager.js +0 -1
  314. package/dist/memory/sync-index.js +21 -0
  315. package/dist/memory/sync-progress.js +22 -0
  316. package/dist/memory/sync-stale.js +30 -0
  317. package/dist/memory/temporal-decay.js +119 -0
  318. package/dist/memory/test-embeddings-mock.js +16 -0
  319. package/dist/memory/test-manager-helpers.js +14 -0
  320. package/dist/memory/test-runtime-mocks.js +11 -0
  321. package/dist/node-host/invoke-browser.js +177 -0
  322. package/dist/node-host/invoke.js +685 -0
  323. package/dist/pairing/setup-code.js +285 -0
  324. package/dist/plugin-sdk/account-id.js +1 -0
  325. package/dist/plugin-sdk/agent-media-payload.js +13 -0
  326. package/dist/plugin-sdk/allow-from.js +47 -0
  327. package/dist/plugin-sdk/command-auth.js +23 -0
  328. package/dist/plugin-sdk/config-paths.js +9 -0
  329. package/dist/plugin-sdk/file-lock.js +116 -0
  330. package/dist/plugin-sdk/json-store.js +31 -0
  331. package/dist/plugin-sdk/onboarding.js +28 -0
  332. package/dist/plugin-sdk/provider-auth-result.js +29 -0
  333. package/dist/plugin-sdk/slack-message-actions.js +133 -0
  334. package/dist/plugin-sdk/status-helpers.js +35 -0
  335. package/dist/plugin-sdk/text-chunking.js +31 -0
  336. package/dist/plugin-sdk/tool-send.js +12 -0
  337. package/dist/plugin-sdk/webhook-path.js +27 -0
  338. package/dist/plugin-sdk/webhook-targets.js +34 -0
  339. package/dist/plugins/hooks.test-helpers.js +21 -0
  340. package/dist/plugins/uninstall.js +171 -0
  341. package/dist/process/kill-tree.js +98 -0
  342. package/dist/process/supervisor/adapters/child.js +143 -0
  343. package/dist/process/supervisor/adapters/env.js +13 -0
  344. package/dist/process/supervisor/adapters/pty.js +148 -0
  345. package/dist/process/supervisor/index.js +10 -0
  346. package/dist/process/supervisor/registry.js +117 -0
  347. package/dist/process/supervisor/supervisor.js +244 -0
  348. package/dist/process/supervisor/types.js +1 -0
  349. package/dist/providers/google-shared.test-helpers.js +75 -0
  350. package/dist/security/audit-channel.js +419 -0
  351. package/dist/security/audit-tool-policy.js +1 -0
  352. package/dist/security/scan-paths.js +12 -0
  353. package/dist/sessions/input-provenance.js +55 -0
  354. package/dist/sessions/session-key-utils.js +7 -0
  355. package/dist/shared/chat-content.js +31 -0
  356. package/dist/shared/chat-envelope.js +45 -0
  357. package/dist/shared/config-eval.js +117 -0
  358. package/dist/shared/device-auth.js +16 -0
  359. package/dist/shared/entry-metadata.js +9 -0
  360. package/dist/shared/entry-status.js +25 -0
  361. package/dist/shared/frontmatter.js +98 -0
  362. package/dist/shared/model-param-b.js +19 -0
  363. package/dist/shared/net/ipv4.js +17 -0
  364. package/dist/shared/node-match.js +53 -0
  365. package/dist/shared/pid-alive.js +12 -0
  366. package/dist/shared/process-scoped-map.js +10 -0
  367. package/dist/shared/requirements.js +128 -0
  368. package/dist/shared/subagents-format.js +84 -0
  369. package/dist/shared/usage-aggregates.js +28 -0
  370. package/dist/signal/monitor/mentions.js +45 -0
  371. package/dist/signal/rpc-context.js +19 -0
  372. package/dist/slack/blocks-fallback.js +76 -0
  373. package/dist/slack/blocks-input.js +40 -0
  374. package/dist/slack/draft-stream.js +106 -0
  375. package/dist/slack/message-actions.js +51 -0
  376. package/dist/slack/modal-metadata.js +32 -0
  377. package/dist/slack/monitor/events/interactions.js +462 -0
  378. package/dist/slack/monitor/room-context.js +17 -0
  379. package/dist/slack/stream-mode.js +41 -0
  380. package/dist/telegram/bot-native-command-menu.js +64 -0
  381. package/dist/telegram/bot.media.e2e-harness.js +81 -0
  382. package/dist/telegram/button-types.js +1 -0
  383. package/dist/telegram/group-access.js +65 -0
  384. package/dist/telegram/outbound-params.js +21 -0
  385. package/dist/telegram/poll-vote-cache.js +21 -0
  386. package/dist/terminal/health-style.js +36 -0
  387. package/dist/test-utils/chunk-test-helpers.js +21 -0
  388. package/dist/test-utils/env.js +72 -0
  389. package/dist/test-utils/exec-assertions.js +12 -0
  390. package/dist/test-utils/imessage-test-plugin.js +54 -0
  391. package/dist/test-utils/mock-http-response.js +17 -0
  392. package/dist/test-utils/vitest-mock-fn.js +1 -0
  393. package/dist/tts/tts-core.js +550 -0
  394. package/dist/utils/chunk-items.js +10 -0
  395. package/dist/utils/reaction-level.js +52 -0
  396. package/dist/utils/safe-json.js +22 -0
  397. package/dist/utils/with-timeout.js +14 -0
  398. package/dist/web/media.js +17 -5
  399. package/dist/whatsapp/resolve-outbound-target.js +42 -0
  400. package/dist/wizard/onboarding.completion.js +74 -0
  401. package/extensions/bluebubbles/package.json +1 -1
  402. package/extensions/bluebubbles/src/account-resolve.ts +29 -0
  403. package/extensions/bluebubbles/src/monitor-normalize.ts +796 -0
  404. package/extensions/bluebubbles/src/monitor-processing.ts +1007 -0
  405. package/extensions/bluebubbles/src/monitor-reply-cache.ts +185 -0
  406. package/extensions/bluebubbles/src/monitor-shared.ts +51 -0
  407. package/extensions/bluebubbles/src/multipart.ts +32 -0
  408. package/extensions/bluebubbles/src/send-helpers.ts +53 -0
  409. package/extensions/bluebubbles/src/test-harness.ts +50 -0
  410. package/extensions/bluebubbles/src/test-mocks.ts +11 -0
  411. package/extensions/copilot-proxy/package.json +1 -1
  412. package/extensions/device-pair/index.ts +554 -0
  413. package/extensions/diagnostics-otel/package.json +1 -1
  414. package/extensions/discord/package.json +1 -1
  415. package/extensions/discord/src/channel.js +366 -0
  416. package/extensions/discord/src/runtime.js +10 -0
  417. package/extensions/feishu/index.ts +63 -0
  418. package/extensions/feishu/src/accounts.ts +114 -0
  419. package/extensions/feishu/src/bitable.ts +739 -0
  420. package/extensions/feishu/src/bot.ts +965 -0
  421. package/extensions/feishu/src/channel.ts +351 -0
  422. package/extensions/feishu/src/client.ts +118 -0
  423. package/extensions/feishu/src/config-schema.ts +206 -0
  424. package/extensions/feishu/src/dedup.ts +33 -0
  425. package/extensions/feishu/src/directory.ts +177 -0
  426. package/extensions/feishu/src/doc-schema.ts +47 -0
  427. package/extensions/feishu/src/docx.ts +536 -0
  428. package/extensions/feishu/src/drive-schema.ts +46 -0
  429. package/extensions/feishu/src/drive.ts +227 -0
  430. package/extensions/feishu/src/dynamic-agent.ts +131 -0
  431. package/extensions/feishu/src/media.ts +449 -0
  432. package/extensions/feishu/src/mention.ts +126 -0
  433. package/extensions/feishu/src/monitor.ts +330 -0
  434. package/extensions/feishu/src/onboarding.ts +359 -0
  435. package/extensions/feishu/src/outbound.ts +55 -0
  436. package/extensions/feishu/src/perm-schema.ts +52 -0
  437. package/extensions/feishu/src/perm.ts +173 -0
  438. package/extensions/feishu/src/policy.ts +84 -0
  439. package/extensions/feishu/src/probe.ts +44 -0
  440. package/extensions/feishu/src/reactions.ts +160 -0
  441. package/extensions/feishu/src/reply-dispatcher.ts +239 -0
  442. package/extensions/feishu/src/runtime.ts +14 -0
  443. package/extensions/feishu/src/send-result.ts +29 -0
  444. package/extensions/feishu/src/send.ts +335 -0
  445. package/extensions/feishu/src/streaming-card.ts +223 -0
  446. package/extensions/feishu/src/targets.ts +78 -0
  447. package/extensions/feishu/src/tools-config.ts +21 -0
  448. package/extensions/feishu/src/types.ts +81 -0
  449. package/extensions/feishu/src/typing.ts +80 -0
  450. package/extensions/feishu/src/wiki-schema.ts +55 -0
  451. package/extensions/feishu/src/wiki.ts +232 -0
  452. package/extensions/google-antigravity-auth/package.json +1 -1
  453. package/extensions/google-gemini-cli-auth/package.json +1 -1
  454. package/extensions/googlechat/package.json +1 -1
  455. package/extensions/imessage/package.json +1 -1
  456. package/extensions/imessage/src/channel.js +253 -0
  457. package/extensions/imessage/src/runtime.js +10 -0
  458. package/extensions/irc/index.ts +17 -0
  459. package/extensions/irc/src/accounts.ts +268 -0
  460. package/extensions/irc/src/channel.ts +367 -0
  461. package/extensions/irc/src/client.ts +439 -0
  462. package/extensions/irc/src/config-schema.ts +97 -0
  463. package/extensions/irc/src/connect-options.ts +30 -0
  464. package/extensions/irc/src/control-chars.ts +22 -0
  465. package/extensions/irc/src/inbound.ts +334 -0
  466. package/extensions/irc/src/monitor.ts +147 -0
  467. package/extensions/irc/src/normalize.ts +117 -0
  468. package/extensions/irc/src/onboarding.ts +479 -0
  469. package/extensions/irc/src/policy.ts +157 -0
  470. package/extensions/irc/src/probe.ts +53 -0
  471. package/extensions/irc/src/protocol.ts +169 -0
  472. package/extensions/irc/src/runtime.ts +14 -0
  473. package/extensions/irc/src/send.ts +88 -0
  474. package/extensions/irc/src/types.ts +93 -0
  475. package/extensions/line/package.json +1 -1
  476. package/extensions/llm-task/package.json +1 -1
  477. package/extensions/lobster/package.json +1 -1
  478. package/extensions/matrix/CHANGELOG.md +5 -0
  479. package/extensions/matrix/package.json +1 -1
  480. package/extensions/matrix/src/matrix/client-bootstrap.ts +39 -0
  481. package/extensions/mattermost/package.json +1 -1
  482. package/extensions/mattermost/src/mattermost/monitor-onchar.ts +25 -0
  483. package/extensions/mattermost/src/mattermost/monitor-websocket.ts +221 -0
  484. package/extensions/mattermost/src/mattermost/reactions.ts +130 -0
  485. package/extensions/mattermost/src/mattermost/reconnect.ts +103 -0
  486. package/extensions/memory-core/package.json +1 -1
  487. package/extensions/memory-lancedb/package.json +1 -1
  488. package/extensions/minimax-portal-auth/index.ts +161 -0
  489. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  490. package/extensions/msteams/CHANGELOG.md +5 -0
  491. package/extensions/msteams/package.json +1 -1
  492. package/extensions/msteams/src/file-lock.ts +1 -0
  493. package/extensions/msteams/src/graph.ts +92 -0
  494. package/extensions/msteams/src/mentions.ts +114 -0
  495. package/extensions/msteams/src/test-runtime.ts +16 -0
  496. package/extensions/nextcloud-talk/package.json +1 -1
  497. package/extensions/nostr/CHANGELOG.md +5 -0
  498. package/extensions/nostr/package.json +1 -1
  499. package/extensions/open-prose/package.json +1 -1
  500. package/extensions/openai-codex-auth/index.ts +177 -0
  501. package/extensions/phone-control/index.ts +421 -0
  502. package/extensions/shared/resolve-target-test-helpers.ts +66 -0
  503. package/extensions/signal/package.json +1 -1
  504. package/extensions/signal/src/channel.js +273 -0
  505. package/extensions/signal/src/runtime.js +10 -0
  506. package/extensions/slack/package.json +1 -1
  507. package/extensions/slack/src/channel.js +489 -0
  508. package/extensions/slack/src/runtime.js +10 -0
  509. package/extensions/talk-voice/index.ts +150 -0
  510. package/extensions/telegram/package.json +1 -1
  511. package/extensions/telegram/src/channel.js +424 -0
  512. package/extensions/telegram/src/runtime.js +10 -0
  513. package/extensions/thread-ownership/index.ts +133 -0
  514. package/extensions/tlon/package.json +1 -1
  515. package/extensions/tlon/src/account-fields.ts +25 -0
  516. package/extensions/tlon/src/urbit/base-url.ts +57 -0
  517. package/extensions/tlon/src/urbit/channel-client.ts +157 -0
  518. package/extensions/tlon/src/urbit/channel-ops.ts +164 -0
  519. package/extensions/tlon/src/urbit/context.ts +47 -0
  520. package/extensions/tlon/src/urbit/errors.ts +51 -0
  521. package/extensions/tlon/src/urbit/fetch.ts +39 -0
  522. package/extensions/twitch/CHANGELOG.md +5 -0
  523. package/extensions/twitch/package.json +1 -1
  524. package/extensions/twitch/src/test-fixtures.ts +30 -0
  525. package/extensions/voice-call/CHANGELOG.md +5 -0
  526. package/extensions/voice-call/package.json +1 -1
  527. package/extensions/voice-call/src/allowlist.ts +19 -0
  528. package/extensions/whatsapp/package.json +1 -1
  529. package/extensions/whatsapp/src/channel.js +429 -0
  530. package/extensions/whatsapp/src/runtime.js +10 -0
  531. package/extensions/zalo/CHANGELOG.md +5 -0
  532. package/extensions/zalo/package.json +1 -1
  533. package/extensions/zalouser/CHANGELOG.md +5 -0
  534. package/extensions/zalouser/package.json +1 -1
  535. package/package.json +1 -1
@@ -5,12 +5,13 @@ import { createApplyPatchTool } from "./apply-patch.js";
5
5
  import { createExecTool, createProcessTool, } from "./bash-tools.js";
6
6
  import { listChannelAgentTools } from "./channel-tools.js";
7
7
  import { createPoolBotTools } from "./poolbot-tools.js";
8
+ import { resolveAgentConfig } from "./agent-scope.js";
8
9
  import { wrapToolWithAbortSignal } from "./pi-tools.abort.js";
9
10
  import { wrapToolWithBeforeToolCallHook } from "./pi-tools.before-tool-call.js";
10
11
  import { filterToolsByPolicy, isToolAllowedByPolicies, resolveEffectiveToolPolicy, resolveGroupToolPolicy, resolveSubagentToolPolicy, } from "./pi-tools.policy.js";
11
12
  import { assertRequiredParams, CLAUDE_PARAM_GROUPS, createPoolbotReadTool, createSandboxedEditTool, createSandboxedReadTool, createSandboxedWriteTool, normalizeToolParams, patchToolSchemaForClaudeCompatibility, wrapToolParamNormalization, } from "./pi-tools.read.js";
12
13
  import { cleanToolSchemaForGemini, normalizeToolParameters } from "./pi-tools.schema.js";
13
- import { buildPluginToolGroups, collectExplicitAllowlist, expandPolicyWithPluginGroups, normalizeToolName, resolveToolProfilePolicy, stripPluginOnlyAllowlist, applyOwnerOnlyToolPolicy, } from "./tool-policy.js";
14
+ import { buildPluginToolGroups, collectExplicitAllowlist, expandPolicyWithPluginGroups, mergeAlsoAllowPolicy, normalizeToolName, resolveToolProfilePolicy, stripPluginOnlyAllowlist, applyOwnerOnlyToolPolicy, } from "./tool-policy.js";
14
15
  import { getPluginToolMeta } from "../plugins/tools.js";
15
16
  import { logWarn } from "../logger.js";
16
17
  function isOpenAIProvider(provider) {
@@ -53,6 +54,26 @@ function resolveExecConfig(cfg) {
53
54
  applyPatch: globalExec?.applyPatch,
54
55
  };
55
56
  }
57
+ export function resolveToolLoopDetectionConfig(params) {
58
+ const global = params.cfg?.tools?.loopDetection;
59
+ const agent = params.agentId && params.cfg
60
+ ? resolveAgentConfig(params.cfg, params.agentId)?.tools?.loopDetection
61
+ : undefined;
62
+ if (!agent) {
63
+ return global;
64
+ }
65
+ if (!global) {
66
+ return agent;
67
+ }
68
+ return {
69
+ ...global,
70
+ ...agent,
71
+ detectors: {
72
+ ...global.detectors,
73
+ ...agent.detectors,
74
+ },
75
+ };
76
+ }
56
77
  export const __testing = {
57
78
  cleanToolSchemaForGemini,
58
79
  normalizeToolParams,
@@ -60,6 +81,8 @@ export const __testing = {
60
81
  wrapToolParamNormalization,
61
82
  assertRequiredParams,
62
83
  };
84
+ /** Alias for upstream compatibility — callers importing the upstream name get the pool-bot version. */
85
+ export const createOpenClawCodingTools = createPoolbotCodingTools;
63
86
  export function createPoolbotCodingTools(options) {
64
87
  const execToolName = "exec";
65
88
  const sandbox = options?.sandbox?.enabled ? options.sandbox : undefined;
@@ -85,13 +108,8 @@ export function createPoolbotCodingTools(options) {
85
108
  });
86
109
  const profilePolicy = resolveToolProfilePolicy(profile);
87
110
  const providerProfilePolicy = resolveToolProfilePolicy(providerProfile);
88
- const mergeAlsoAllow = (policy, alsoAllow) => {
89
- if (!policy?.allow || !Array.isArray(alsoAllow) || alsoAllow.length === 0)
90
- return policy;
91
- return { ...policy, allow: Array.from(new Set([...policy.allow, ...alsoAllow])) };
92
- };
93
- const profilePolicyWithAlsoAllow = mergeAlsoAllow(profilePolicy, profileAlsoAllow);
94
- const providerProfilePolicyWithAlsoAllow = mergeAlsoAllow(providerProfilePolicy, providerProfileAlsoAllow);
111
+ const profilePolicyWithAlsoAllow = mergeAlsoAllowPolicy(profilePolicy, profileAlsoAllow);
112
+ const providerProfilePolicyWithAlsoAllow = mergeAlsoAllowPolicy(providerProfilePolicy, providerProfileAlsoAllow);
95
113
  const scopeKey = options?.exec?.scopeKey ?? (agentId ? `agent:${agentId}` : undefined);
96
114
  const subagentPolicy = isSubagentSessionKey(options?.sessionKey) && options?.sessionKey
97
115
  ? resolveSubagentToolPolicy(options.config)
@@ -292,10 +310,12 @@ export function createPoolbotCodingTools(options) {
292
310
  : sandboxed;
293
311
  // Always normalize tool JSON Schemas before handing them to pi-agent/pi-ai.
294
312
  // Without this, some providers (notably OpenAI) will reject root-level union schemas.
295
- const normalized = subagentFiltered.map(normalizeToolParameters);
313
+ // Provider-specific cleaning: Gemini needs constraint keywords stripped, but Anthropic expects them.
314
+ const normalized = subagentFiltered.map((tool) => normalizeToolParameters(tool, { modelProvider: options?.modelProvider }));
296
315
  const withHooks = normalized.map((tool) => wrapToolWithBeforeToolCallHook(tool, {
297
316
  agentId,
298
317
  sessionKey: options?.sessionKey,
318
+ loopDetection: resolveToolLoopDetectionConfig({ cfg: options?.config, agentId }),
299
319
  }));
300
320
  const withAbort = options?.abortSignal
301
321
  ? withHooks.map((tool) => wrapToolWithAbortSignal(tool, options.abortSignal))
@@ -1,63 +1,42 @@
1
1
  import { getChannelDock } from "../channels/dock.js";
2
2
  import { resolveChannelGroupToolsPolicy } from "../config/group-policy.js";
3
+ import { resolveThreadParentSessionKey } from "../sessions/session-key-utils.js";
4
+ import { normalizeMessageChannel } from "../utils/message-channel.js";
3
5
  import { resolveAgentConfig, resolveAgentIdFromSessionKey } from "./agent-scope.js";
6
+ import { compileGlobPatterns, matchesAnyGlobPattern } from "./glob-pattern.js";
7
+ import { pickSandboxToolPolicy } from "./sandbox-tool-policy.js";
4
8
  import { expandToolGroups, normalizeToolName } from "./tool-policy.js";
5
- import { normalizeMessageChannel } from "../utils/message-channel.js";
6
- import { resolveThreadParentSessionKey } from "../sessions/session-key-utils.js";
7
- function compilePattern(pattern) {
8
- const normalized = normalizeToolName(pattern);
9
- if (!normalized)
10
- return { kind: "exact", value: "" };
11
- if (normalized === "*")
12
- return { kind: "all" };
13
- if (!normalized.includes("*"))
14
- return { kind: "exact", value: normalized };
15
- const escaped = normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
16
- return {
17
- kind: "regex",
18
- value: new RegExp(`^${escaped.replaceAll("\\*", ".*")}$`),
19
- };
20
- }
21
- function compilePatterns(patterns) {
22
- if (!Array.isArray(patterns))
23
- return [];
24
- return expandToolGroups(patterns)
25
- .map(compilePattern)
26
- .filter((pattern) => pattern.kind !== "exact" || pattern.value);
27
- }
28
- function matchesAny(name, patterns) {
29
- for (const pattern of patterns) {
30
- if (pattern.kind === "all")
31
- return true;
32
- if (pattern.kind === "exact" && name === pattern.value)
33
- return true;
34
- if (pattern.kind === "regex" && pattern.value.test(name))
35
- return true;
36
- }
37
- return false;
38
- }
39
9
  function makeToolPolicyMatcher(policy) {
40
- const deny = compilePatterns(policy.deny);
41
- const allow = compilePatterns(policy.allow);
10
+ const deny = compileGlobPatterns({
11
+ raw: expandToolGroups(policy.deny ?? []),
12
+ normalize: normalizeToolName,
13
+ });
14
+ const allow = compileGlobPatterns({
15
+ raw: expandToolGroups(policy.allow ?? []),
16
+ normalize: normalizeToolName,
17
+ });
42
18
  return (name) => {
43
19
  const normalized = normalizeToolName(name);
44
- if (matchesAny(normalized, deny))
20
+ if (matchesAnyGlobPattern(normalized, deny)) {
45
21
  return false;
46
- if (allow.length === 0)
22
+ }
23
+ if (allow.length === 0) {
47
24
  return true;
48
- if (matchesAny(normalized, allow))
25
+ }
26
+ if (matchesAnyGlobPattern(normalized, allow)) {
49
27
  return true;
50
- if (normalized === "apply_patch" && matchesAny("exec", allow))
28
+ }
29
+ if (normalized === "apply_patch" && matchesAnyGlobPattern("exec", allow)) {
51
30
  return true;
31
+ }
52
32
  return false;
53
33
  };
54
34
  }
55
- const DEFAULT_SUBAGENT_TOOL_DENY = [
56
- // Session management - main agent orchestrates
57
- "sessions_list",
58
- "sessions_history",
59
- "sessions_send",
60
- "sessions_spawn",
35
+ /**
36
+ * Tools always denied for sub-agents regardless of depth.
37
+ * These are system-level or interactive tools that sub-agents should never use.
38
+ */
39
+ const SUBAGENT_TOOL_DENY_ALWAYS = [
61
40
  // System admin - dangerous from subagent
62
41
  "gateway",
63
42
  "agents_list",
@@ -69,85 +48,95 @@ const DEFAULT_SUBAGENT_TOOL_DENY = [
69
48
  // Memory - pass relevant info in spawn prompt instead
70
49
  "memory_search",
71
50
  "memory_get",
51
+ // Direct session sends - subagents communicate through announce chain
52
+ "sessions_send",
72
53
  ];
73
- export function resolveSubagentToolPolicy(cfg) {
54
+ /**
55
+ * Additional tools denied for leaf sub-agents (depth >= maxSpawnDepth).
56
+ * These are tools that only make sense for orchestrator sub-agents that can spawn children.
57
+ */
58
+ const SUBAGENT_TOOL_DENY_LEAF = ["sessions_list", "sessions_history", "sessions_spawn"];
59
+ /**
60
+ * Build the deny list for a sub-agent at a given depth.
61
+ *
62
+ * - Depth 1 with maxSpawnDepth >= 2 (orchestrator): allowed to use sessions_spawn,
63
+ * subagents, sessions_list, sessions_history so it can manage its children.
64
+ * - Depth >= maxSpawnDepth (leaf): denied sessions_spawn and
65
+ * session management tools. Still allowed subagents (for list/status visibility).
66
+ */
67
+ function resolveSubagentDenyList(depth, maxSpawnDepth) {
68
+ const isLeaf = depth >= Math.max(1, Math.floor(maxSpawnDepth));
69
+ if (isLeaf) {
70
+ return [...SUBAGENT_TOOL_DENY_ALWAYS, ...SUBAGENT_TOOL_DENY_LEAF];
71
+ }
72
+ // Orchestrator sub-agent: only deny the always-denied tools.
73
+ // sessions_spawn, subagents, sessions_list, sessions_history are allowed.
74
+ return [...SUBAGENT_TOOL_DENY_ALWAYS];
75
+ }
76
+ export function resolveSubagentToolPolicy(cfg, depth) {
74
77
  const configured = cfg?.tools?.subagents?.tools;
75
- const deny = [
76
- ...DEFAULT_SUBAGENT_TOOL_DENY,
77
- ...(Array.isArray(configured?.deny) ? configured.deny : []),
78
- ];
78
+ const maxSpawnDepth = cfg?.agents?.defaults?.subagents?.maxSpawnDepth ?? 1;
79
+ const effectiveDepth = typeof depth === "number" && depth >= 0 ? depth : 1;
80
+ const baseDeny = resolveSubagentDenyList(effectiveDepth, maxSpawnDepth);
81
+ const deny = [...baseDeny, ...(Array.isArray(configured?.deny) ? configured.deny : [])];
79
82
  const allow = Array.isArray(configured?.allow) ? configured.allow : undefined;
80
83
  return { allow, deny };
81
84
  }
82
85
  export function isToolAllowedByPolicyName(name, policy) {
83
- if (!policy)
86
+ if (!policy) {
84
87
  return true;
88
+ }
85
89
  return makeToolPolicyMatcher(policy)(name);
86
90
  }
87
91
  export function filterToolsByPolicy(tools, policy) {
88
- if (!policy)
92
+ if (!policy) {
89
93
  return tools;
94
+ }
90
95
  const matcher = makeToolPolicyMatcher(policy);
91
96
  return tools.filter((tool) => matcher(tool.name));
92
97
  }
93
- function unionAllow(base, extra) {
94
- if (!Array.isArray(extra) || extra.length === 0)
95
- return base;
96
- // If the user is using alsoAllow without an allowlist, treat it as additive on top of
97
- // an implicit allow-all policy.
98
- if (!Array.isArray(base) || base.length === 0) {
99
- return Array.from(new Set(["*", ...extra]));
100
- }
101
- return Array.from(new Set([...base, ...extra]));
102
- }
103
- function pickToolPolicy(config) {
104
- if (!config)
105
- return undefined;
106
- const allow = Array.isArray(config.allow)
107
- ? unionAllow(config.allow, config.alsoAllow)
108
- : Array.isArray(config.alsoAllow) && config.alsoAllow.length > 0
109
- ? unionAllow(undefined, config.alsoAllow)
110
- : undefined;
111
- const deny = Array.isArray(config.deny) ? config.deny : undefined;
112
- if (!allow && !deny)
113
- return undefined;
114
- return { allow, deny };
115
- }
116
98
  function normalizeProviderKey(value) {
117
99
  return value.trim().toLowerCase();
118
100
  }
119
101
  function resolveGroupContextFromSessionKey(sessionKey) {
120
102
  const raw = (sessionKey ?? "").trim();
121
- if (!raw)
103
+ if (!raw) {
122
104
  return {};
105
+ }
123
106
  const base = resolveThreadParentSessionKey(raw) ?? raw;
124
107
  const parts = base.split(":").filter(Boolean);
125
108
  let body = parts[0] === "agent" ? parts.slice(2) : parts;
126
109
  if (body[0] === "subagent") {
127
110
  body = body.slice(1);
128
111
  }
129
- if (body.length < 3)
112
+ if (body.length < 3) {
130
113
  return {};
114
+ }
131
115
  const [channel, kind, ...rest] = body;
132
- if (kind !== "group" && kind !== "channel")
116
+ if (kind !== "group" && kind !== "channel") {
133
117
  return {};
118
+ }
134
119
  const groupId = rest.join(":").trim();
135
- if (!groupId)
120
+ if (!groupId) {
136
121
  return {};
122
+ }
137
123
  return { channel: channel.trim().toLowerCase(), groupId };
138
124
  }
139
125
  function resolveProviderToolPolicy(params) {
140
126
  const provider = params.modelProvider?.trim();
141
- if (!provider || !params.byProvider)
127
+ if (!provider || !params.byProvider) {
142
128
  return undefined;
129
+ }
143
130
  const entries = Object.entries(params.byProvider);
144
- if (entries.length === 0)
131
+ if (entries.length === 0) {
145
132
  return undefined;
133
+ }
146
134
  const lookup = new Map();
147
135
  for (const [key, value] of entries) {
148
136
  const normalized = normalizeProviderKey(key);
149
- if (!normalized)
137
+ if (!normalized) {
150
138
  continue;
139
+ }
151
140
  lookup.set(normalized, value);
152
141
  }
153
142
  const normalizedProvider = normalizeProviderKey(provider);
@@ -156,8 +145,9 @@ function resolveProviderToolPolicy(params) {
156
145
  const candidates = [...(fullModelId ? [fullModelId] : []), normalizedProvider];
157
146
  for (const key of candidates) {
158
147
  const match = lookup.get(key);
159
- if (match)
148
+ if (match) {
160
149
  return match;
150
+ }
161
151
  }
162
152
  return undefined;
163
153
  }
@@ -179,10 +169,10 @@ export function resolveEffectiveToolPolicy(params) {
179
169
  });
180
170
  return {
181
171
  agentId,
182
- globalPolicy: pickToolPolicy(globalTools),
183
- globalProviderPolicy: pickToolPolicy(providerPolicy),
184
- agentPolicy: pickToolPolicy(agentTools),
185
- agentProviderPolicy: pickToolPolicy(agentProviderPolicy),
172
+ globalPolicy: pickSandboxToolPolicy(globalTools),
173
+ globalProviderPolicy: pickSandboxToolPolicy(providerPolicy),
174
+ agentPolicy: pickSandboxToolPolicy(agentTools),
175
+ agentProviderPolicy: pickSandboxToolPolicy(agentProviderPolicy),
186
176
  profile,
187
177
  providerProfile: agentProviderPolicy?.profile ?? providerPolicy?.profile,
188
178
  // alsoAllow is applied at the profile stage (to avoid being filtered out early).
@@ -199,17 +189,20 @@ export function resolveEffectiveToolPolicy(params) {
199
189
  };
200
190
  }
201
191
  export function resolveGroupToolPolicy(params) {
202
- if (!params.config)
192
+ if (!params.config) {
203
193
  return undefined;
194
+ }
204
195
  const sessionContext = resolveGroupContextFromSessionKey(params.sessionKey);
205
196
  const spawnedContext = resolveGroupContextFromSessionKey(params.spawnedBy);
206
197
  const groupId = params.groupId ?? sessionContext.groupId ?? spawnedContext.groupId;
207
- if (!groupId)
198
+ if (!groupId) {
208
199
  return undefined;
200
+ }
209
201
  const channelRaw = params.messageProvider ?? sessionContext.channel ?? spawnedContext.channel;
210
202
  const channel = normalizeMessageChannel(channelRaw);
211
- if (!channel)
203
+ if (!channel) {
212
204
  return undefined;
205
+ }
213
206
  let dock;
214
207
  try {
215
208
  dock = getChannelDock(channel);
@@ -238,7 +231,7 @@ export function resolveGroupToolPolicy(params) {
238
231
  senderUsername: params.senderUsername,
239
232
  senderE164: params.senderE164,
240
233
  });
241
- return pickToolPolicy(toolsConfig);
234
+ return pickSandboxToolPolicy(toolsConfig);
242
235
  }
243
236
  export function isToolAllowedByPolicies(name, policies) {
244
237
  return policies.every((policy) => isToolAllowedByPolicyName(name, policy));
@@ -1,12 +1,15 @@
1
1
  import { cleanSchemaForGemini } from "./schema/clean-for-gemini.js";
2
2
  function extractEnumValues(schema) {
3
- if (!schema || typeof schema !== "object")
3
+ if (!schema || typeof schema !== "object") {
4
4
  return undefined;
5
+ }
5
6
  const record = schema;
6
- if (Array.isArray(record.enum))
7
+ if (Array.isArray(record.enum)) {
7
8
  return record.enum;
8
- if ("const" in record)
9
+ }
10
+ if ("const" in record) {
9
11
  return [record.const];
12
+ }
10
13
  const variants = Array.isArray(record.anyOf)
11
14
  ? record.anyOf
12
15
  : Array.isArray(record.oneOf)
@@ -22,50 +25,61 @@ function extractEnumValues(schema) {
22
25
  return undefined;
23
26
  }
24
27
  function mergePropertySchemas(existing, incoming) {
25
- if (!existing)
28
+ if (!existing) {
26
29
  return incoming;
27
- if (!incoming)
30
+ }
31
+ if (!incoming) {
28
32
  return existing;
33
+ }
29
34
  const existingEnum = extractEnumValues(existing);
30
35
  const incomingEnum = extractEnumValues(incoming);
31
36
  if (existingEnum || incomingEnum) {
32
37
  const values = Array.from(new Set([...(existingEnum ?? []), ...(incomingEnum ?? [])]));
33
38
  const merged = {};
34
39
  for (const source of [existing, incoming]) {
35
- if (!source || typeof source !== "object")
40
+ if (!source || typeof source !== "object") {
36
41
  continue;
42
+ }
37
43
  const record = source;
38
44
  for (const key of ["title", "description", "default"]) {
39
- if (!(key in merged) && key in record)
45
+ if (!(key in merged) && key in record) {
40
46
  merged[key] = record[key];
47
+ }
41
48
  }
42
49
  }
43
50
  const types = new Set(values.map((value) => typeof value));
44
- if (types.size === 1)
51
+ if (types.size === 1) {
45
52
  merged.type = Array.from(types)[0];
53
+ }
46
54
  merged.enum = values;
47
55
  return merged;
48
56
  }
49
57
  return existing;
50
58
  }
51
- export function normalizeToolParameters(tool) {
59
+ export function normalizeToolParameters(tool, options) {
52
60
  const schema = tool.parameters && typeof tool.parameters === "object"
53
61
  ? tool.parameters
54
62
  : undefined;
55
- if (!schema)
63
+ if (!schema) {
56
64
  return tool;
65
+ }
57
66
  // Provider quirks:
58
67
  // - Gemini rejects several JSON Schema keywords, so we scrub those.
59
68
  // - OpenAI rejects function tool schemas unless the *top-level* is `type: "object"`.
60
69
  // (TypeBox root unions compile to `{ anyOf: [...] }` without `type`).
70
+ // - Anthropic (google-antigravity) expects full JSON Schema draft 2020-12 compliance.
61
71
  //
62
72
  // Normalize once here so callers can always pass `tools` through unchanged.
73
+ const isGeminiProvider = options?.modelProvider?.toLowerCase().includes("google") ||
74
+ options?.modelProvider?.toLowerCase().includes("gemini");
75
+ const isAnthropicProvider = options?.modelProvider?.toLowerCase().includes("anthropic") ||
76
+ options?.modelProvider?.toLowerCase().includes("google-antigravity");
63
77
  // If schema already has type + properties (no top-level anyOf to merge),
64
- // still clean it for Gemini compatibility
78
+ // clean it for Gemini compatibility (but only if using Gemini, not Anthropic)
65
79
  if ("type" in schema && "properties" in schema && !Array.isArray(schema.anyOf)) {
66
80
  return {
67
81
  ...tool,
68
- parameters: cleanSchemaForGemini(schema),
82
+ parameters: isGeminiProvider && !isAnthropicProvider ? cleanSchemaForGemini(schema) : schema,
69
83
  };
70
84
  }
71
85
  // Some tool schemas (esp. unions) may omit `type` at the top-level. If we see
@@ -74,9 +88,12 @@ export function normalizeToolParameters(tool) {
74
88
  (typeof schema.properties === "object" || Array.isArray(schema.required)) &&
75
89
  !Array.isArray(schema.anyOf) &&
76
90
  !Array.isArray(schema.oneOf)) {
91
+ const schemaWithType = { ...schema, type: "object" };
77
92
  return {
78
93
  ...tool,
79
- parameters: cleanSchemaForGemini({ ...schema, type: "object" }),
94
+ parameters: isGeminiProvider && !isAnthropicProvider
95
+ ? cleanSchemaForGemini(schemaWithType)
96
+ : schemaWithType,
80
97
  };
81
98
  }
82
99
  const variantKey = Array.isArray(schema.anyOf)
@@ -84,18 +101,21 @@ export function normalizeToolParameters(tool) {
84
101
  : Array.isArray(schema.oneOf)
85
102
  ? "oneOf"
86
103
  : null;
87
- if (!variantKey)
104
+ if (!variantKey) {
88
105
  return tool;
106
+ }
89
107
  const variants = schema[variantKey];
90
108
  const mergedProperties = {};
91
109
  const requiredCounts = new Map();
92
110
  let objectVariants = 0;
93
111
  for (const entry of variants) {
94
- if (!entry || typeof entry !== "object")
112
+ if (!entry || typeof entry !== "object") {
95
113
  continue;
114
+ }
96
115
  const props = entry.properties;
97
- if (!props || typeof props !== "object")
116
+ if (!props || typeof props !== "object") {
98
117
  continue;
118
+ }
99
119
  objectVariants += 1;
100
120
  for (const [key, value] of Object.entries(props)) {
101
121
  if (!(key in mergedProperties)) {
@@ -108,8 +128,9 @@ export function normalizeToolParameters(tool) {
108
128
  ? entry.required
109
129
  : [];
110
130
  for (const key of required) {
111
- if (typeof key !== "string")
131
+ if (typeof key !== "string") {
112
132
  continue;
133
+ }
113
134
  requiredCounts.set(key, (requiredCounts.get(key) ?? 0) + 1);
114
135
  }
115
136
  }
@@ -124,24 +145,30 @@ export function normalizeToolParameters(tool) {
124
145
  .map(([key]) => key)
125
146
  : undefined;
126
147
  const nextSchema = { ...schema };
148
+ const flattenedSchema = {
149
+ type: "object",
150
+ ...(typeof nextSchema.title === "string" ? { title: nextSchema.title } : {}),
151
+ ...(typeof nextSchema.description === "string" ? { description: nextSchema.description } : {}),
152
+ properties: Object.keys(mergedProperties).length > 0 ? mergedProperties : (schema.properties ?? {}),
153
+ ...(mergedRequired && mergedRequired.length > 0 ? { required: mergedRequired } : {}),
154
+ additionalProperties: "additionalProperties" in schema ? schema.additionalProperties : true,
155
+ };
127
156
  return {
128
157
  ...tool,
129
158
  // Flatten union schemas into a single object schema:
130
159
  // - Gemini doesn't allow top-level `type` together with `anyOf`.
131
160
  // - OpenAI rejects schemas without top-level `type: "object"`.
161
+ // - Anthropic accepts proper JSON Schema with constraints.
132
162
  // Merging properties preserves useful enums like `action` while keeping schemas portable.
133
- parameters: cleanSchemaForGemini({
134
- type: "object",
135
- ...(typeof nextSchema.title === "string" ? { title: nextSchema.title } : {}),
136
- ...(typeof nextSchema.description === "string"
137
- ? { description: nextSchema.description }
138
- : {}),
139
- properties: Object.keys(mergedProperties).length > 0 ? mergedProperties : (schema.properties ?? {}),
140
- ...(mergedRequired && mergedRequired.length > 0 ? { required: mergedRequired } : {}),
141
- additionalProperties: "additionalProperties" in schema ? schema.additionalProperties : true,
142
- }),
163
+ parameters: isGeminiProvider && !isAnthropicProvider
164
+ ? cleanSchemaForGemini(flattenedSchema)
165
+ : flattenedSchema,
143
166
  };
144
167
  }
168
+ /**
169
+ * @deprecated Use normalizeToolParameters with modelProvider instead.
170
+ * This function should only be used for Gemini providers.
171
+ */
145
172
  export function cleanToolSchemaForGemini(schema) {
146
173
  return cleanSchemaForGemini(schema);
147
174
  }
@@ -0,0 +1,22 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export function getQueuedFileWriter(writers, filePath) {
4
+ const existing = writers.get(filePath);
5
+ if (existing) {
6
+ return existing;
7
+ }
8
+ const dir = path.dirname(filePath);
9
+ const ready = fs.mkdir(dir, { recursive: true }).catch(() => undefined);
10
+ let queue = Promise.resolve();
11
+ const writer = {
12
+ filePath,
13
+ write: (line) => {
14
+ queue = queue
15
+ .then(() => ready)
16
+ .then(() => fs.appendFile(filePath, line, "utf8"))
17
+ .catch(() => undefined);
18
+ },
19
+ };
20
+ writers.set(filePath, writer);
21
+ return writer;
22
+ }