@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
@@ -0,0 +1,262 @@
1
+ import crypto from "node:crypto";
2
+ import { formatThinkingLevels, normalizeThinkLevel } from "../auto-reply/thinking.js";
3
+ import { loadConfig } from "../config/config.js";
4
+ import { callGateway } from "../gateway/call.js";
5
+ import { normalizeAgentId, parseAgentSessionKey } from "../routing/session-key.js";
6
+ import { normalizeDeliveryContext } from "../utils/delivery-context.js";
7
+ import { resolveAgentConfig } from "./agent-scope.js";
8
+ import { AGENT_LANE_SUBAGENT } from "./lanes.js";
9
+ import { resolveDefaultModelForAgent } from "./model-selection.js";
10
+ import { buildSubagentSystemPrompt } from "./subagent-announce.js";
11
+ import { getSubagentDepthFromSessionStore } from "./subagent-depth.js";
12
+ import { countActiveRunsForSession, registerSubagentRun } from "./subagent-registry.js";
13
+ import { readStringParam } from "./tools/common.js";
14
+ import { resolveDisplaySessionKey, resolveInternalSessionKey, resolveMainSessionAlias, } from "./tools/sessions-helpers.js";
15
+ export function splitModelRef(ref) {
16
+ if (!ref) {
17
+ return { provider: undefined, model: undefined };
18
+ }
19
+ const trimmed = ref.trim();
20
+ if (!trimmed) {
21
+ return { provider: undefined, model: undefined };
22
+ }
23
+ const [provider, model] = trimmed.split("/", 2);
24
+ if (model) {
25
+ return { provider, model };
26
+ }
27
+ return { provider: undefined, model: trimmed };
28
+ }
29
+ export function normalizeModelSelection(value) {
30
+ if (typeof value === "string") {
31
+ const trimmed = value.trim();
32
+ return trimmed || undefined;
33
+ }
34
+ if (!value || typeof value !== "object") {
35
+ return undefined;
36
+ }
37
+ const primary = value.primary;
38
+ if (typeof primary === "string" && primary.trim()) {
39
+ return primary.trim();
40
+ }
41
+ return undefined;
42
+ }
43
+ export async function spawnSubagentDirect(params, ctx) {
44
+ const task = params.task;
45
+ const label = params.label?.trim() || "";
46
+ const requestedAgentId = params.agentId;
47
+ const modelOverride = params.model;
48
+ const thinkingOverrideRaw = params.thinking;
49
+ const cleanup = params.cleanup === "keep" || params.cleanup === "delete" ? params.cleanup : "keep";
50
+ const requesterOrigin = normalizeDeliveryContext({
51
+ channel: ctx.agentChannel,
52
+ accountId: ctx.agentAccountId,
53
+ to: ctx.agentTo,
54
+ threadId: ctx.agentThreadId,
55
+ });
56
+ const runTimeoutSeconds = typeof params.runTimeoutSeconds === "number" && Number.isFinite(params.runTimeoutSeconds)
57
+ ? Math.max(0, Math.floor(params.runTimeoutSeconds))
58
+ : 0;
59
+ let modelWarning;
60
+ let modelApplied = false;
61
+ const cfg = loadConfig();
62
+ const { mainKey, alias } = resolveMainSessionAlias(cfg);
63
+ const requesterSessionKey = ctx.agentSessionKey;
64
+ const requesterInternalKey = requesterSessionKey
65
+ ? resolveInternalSessionKey({
66
+ key: requesterSessionKey,
67
+ alias,
68
+ mainKey,
69
+ })
70
+ : alias;
71
+ const requesterDisplayKey = resolveDisplaySessionKey({
72
+ key: requesterInternalKey,
73
+ alias,
74
+ mainKey,
75
+ });
76
+ const callerDepth = getSubagentDepthFromSessionStore(requesterInternalKey, { cfg });
77
+ const maxSpawnDepth = cfg.agents?.defaults?.subagents?.maxSpawnDepth ?? 1;
78
+ if (callerDepth >= maxSpawnDepth) {
79
+ return {
80
+ status: "forbidden",
81
+ error: `sessions_spawn is not allowed at this depth (current depth: ${callerDepth}, max: ${maxSpawnDepth})`,
82
+ };
83
+ }
84
+ const maxChildren = cfg.agents?.defaults?.subagents?.maxChildrenPerAgent ?? 5;
85
+ const activeChildren = countActiveRunsForSession(requesterInternalKey);
86
+ if (activeChildren >= maxChildren) {
87
+ return {
88
+ status: "forbidden",
89
+ error: `sessions_spawn has reached max active children for this session (${activeChildren}/${maxChildren})`,
90
+ };
91
+ }
92
+ const requesterAgentId = normalizeAgentId(ctx.requesterAgentIdOverride ?? parseAgentSessionKey(requesterInternalKey)?.agentId);
93
+ const targetAgentId = requestedAgentId ? normalizeAgentId(requestedAgentId) : requesterAgentId;
94
+ if (targetAgentId !== requesterAgentId) {
95
+ const allowAgents = resolveAgentConfig(cfg, requesterAgentId)?.subagents?.allowAgents ?? [];
96
+ const allowAny = allowAgents.some((value) => value.trim() === "*");
97
+ const normalizedTargetId = targetAgentId.toLowerCase();
98
+ const allowSet = new Set(allowAgents
99
+ .filter((value) => value.trim() && value.trim() !== "*")
100
+ .map((value) => normalizeAgentId(value).toLowerCase()));
101
+ if (!allowAny && !allowSet.has(normalizedTargetId)) {
102
+ const allowedText = allowSet.size > 0 ? Array.from(allowSet).join(", ") : "none";
103
+ return {
104
+ status: "forbidden",
105
+ error: `agentId is not allowed for sessions_spawn (allowed: ${allowedText})`,
106
+ };
107
+ }
108
+ }
109
+ const childSessionKey = `agent:${targetAgentId}:subagent:${crypto.randomUUID()}`;
110
+ const childDepth = callerDepth + 1;
111
+ const spawnedByKey = requesterInternalKey;
112
+ const targetAgentConfig = resolveAgentConfig(cfg, targetAgentId);
113
+ const runtimeDefaultModel = resolveDefaultModelForAgent({
114
+ cfg,
115
+ agentId: targetAgentId,
116
+ });
117
+ const resolvedModel = normalizeModelSelection(modelOverride) ??
118
+ normalizeModelSelection(targetAgentConfig?.subagents?.model) ??
119
+ normalizeModelSelection(cfg.agents?.defaults?.subagents?.model) ??
120
+ normalizeModelSelection(cfg.agents?.defaults?.model?.primary) ??
121
+ normalizeModelSelection(`${runtimeDefaultModel.provider}/${runtimeDefaultModel.model}`);
122
+ const resolvedThinkingDefaultRaw = readStringParam(targetAgentConfig?.subagents ?? {}, "thinking") ??
123
+ readStringParam(cfg.agents?.defaults?.subagents ?? {}, "thinking");
124
+ let thinkingOverride;
125
+ const thinkingCandidateRaw = thinkingOverrideRaw || resolvedThinkingDefaultRaw;
126
+ if (thinkingCandidateRaw) {
127
+ const normalized = normalizeThinkLevel(thinkingCandidateRaw);
128
+ if (!normalized) {
129
+ const { provider, model } = splitModelRef(resolvedModel);
130
+ const hint = formatThinkingLevels(provider, model);
131
+ return {
132
+ status: "error",
133
+ error: `Invalid thinking level "${thinkingCandidateRaw}". Use one of: ${hint}.`,
134
+ };
135
+ }
136
+ thinkingOverride = normalized;
137
+ }
138
+ try {
139
+ await callGateway({
140
+ method: "sessions.patch",
141
+ params: { key: childSessionKey, spawnDepth: childDepth },
142
+ timeoutMs: 10_000,
143
+ });
144
+ }
145
+ catch (err) {
146
+ const messageText = err instanceof Error ? err.message : typeof err === "string" ? err : "error";
147
+ return {
148
+ status: "error",
149
+ error: messageText,
150
+ childSessionKey,
151
+ };
152
+ }
153
+ if (resolvedModel) {
154
+ try {
155
+ await callGateway({
156
+ method: "sessions.patch",
157
+ params: { key: childSessionKey, model: resolvedModel },
158
+ timeoutMs: 10_000,
159
+ });
160
+ modelApplied = true;
161
+ }
162
+ catch (err) {
163
+ const messageText = err instanceof Error ? err.message : typeof err === "string" ? err : "error";
164
+ const recoverable = messageText.includes("invalid model") || messageText.includes("model not allowed");
165
+ if (!recoverable) {
166
+ return {
167
+ status: "error",
168
+ error: messageText,
169
+ childSessionKey,
170
+ };
171
+ }
172
+ modelWarning = messageText;
173
+ }
174
+ }
175
+ if (thinkingOverride !== undefined) {
176
+ try {
177
+ await callGateway({
178
+ method: "sessions.patch",
179
+ params: {
180
+ key: childSessionKey,
181
+ thinkingLevel: thinkingOverride === "off" ? null : thinkingOverride,
182
+ },
183
+ timeoutMs: 10_000,
184
+ });
185
+ }
186
+ catch (err) {
187
+ const messageText = err instanceof Error ? err.message : typeof err === "string" ? err : "error";
188
+ return {
189
+ status: "error",
190
+ error: messageText,
191
+ childSessionKey,
192
+ };
193
+ }
194
+ }
195
+ const childSystemPrompt = buildSubagentSystemPrompt({
196
+ requesterSessionKey,
197
+ requesterOrigin,
198
+ childSessionKey,
199
+ label: label || undefined,
200
+ task,
201
+ childDepth,
202
+ maxSpawnDepth,
203
+ });
204
+ const childIdem = crypto.randomUUID();
205
+ let childRunId = childIdem;
206
+ try {
207
+ const response = await callGateway({
208
+ method: "agent",
209
+ params: {
210
+ message: task,
211
+ sessionKey: childSessionKey,
212
+ channel: requesterOrigin?.channel,
213
+ to: requesterOrigin?.to ?? undefined,
214
+ accountId: requesterOrigin?.accountId ?? undefined,
215
+ threadId: requesterOrigin?.threadId != null ? String(requesterOrigin.threadId) : undefined,
216
+ idempotencyKey: childIdem,
217
+ deliver: false,
218
+ lane: AGENT_LANE_SUBAGENT,
219
+ extraSystemPrompt: childSystemPrompt,
220
+ thinking: thinkingOverride,
221
+ timeout: runTimeoutSeconds,
222
+ label: label || undefined,
223
+ spawnedBy: spawnedByKey,
224
+ groupId: ctx.agentGroupId ?? undefined,
225
+ groupChannel: ctx.agentGroupChannel ?? undefined,
226
+ groupSpace: ctx.agentGroupSpace ?? undefined,
227
+ },
228
+ timeoutMs: 10_000,
229
+ });
230
+ if (typeof response?.runId === "string" && response.runId) {
231
+ childRunId = response.runId;
232
+ }
233
+ }
234
+ catch (err) {
235
+ const messageText = err instanceof Error ? err.message : typeof err === "string" ? err : "error";
236
+ return {
237
+ status: "error",
238
+ error: messageText,
239
+ childSessionKey,
240
+ runId: childRunId,
241
+ };
242
+ }
243
+ registerSubagentRun({
244
+ runId: childRunId,
245
+ childSessionKey,
246
+ requesterSessionKey: requesterInternalKey,
247
+ requesterOrigin,
248
+ requesterDisplayKey,
249
+ task,
250
+ cleanup,
251
+ label: label || undefined,
252
+ model: resolvedModel,
253
+ runTimeoutSeconds,
254
+ });
255
+ return {
256
+ status: "accepted",
257
+ childSessionKey,
258
+ runId: childRunId,
259
+ modelApplied: resolvedModel ? modelApplied : undefined,
260
+ warning: modelWarning,
261
+ };
262
+ }
@@ -1,5 +1,6 @@
1
1
  import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
2
2
  import { listDeliverableMessageChannels } from "../utils/message-channel.js";
3
+ import { sanitizeForPromptLiteral } from "./sanitize-for-prompt.js";
3
4
  function buildSkillsSection(params) {
4
5
  if (params.isMinimal)
5
6
  return [];
@@ -66,6 +67,9 @@ function buildMessagingSection(params) {
66
67
  "## Messaging",
67
68
  "- Reply in current session → automatically routes to the source channel (Signal, Telegram, etc.)",
68
69
  "- Cross-session messaging → use sessions_send(sessionKey, message)",
70
+ "- Sub-agent orchestration → use subagents(action=list|steer|kill)",
71
+ "- `[System Message] ...` blocks are internal context and are not user-visible by default.",
72
+ `- If a \`[System Message]\` reports completed cron/subagent work and asks for a user update, rewrite it in your normal assistant voice and send that update (do not forward raw system text or default to ${SILENT_REPLY_TOKEN}).`,
69
73
  "- Never use exec/curl for provider messaging; Pool Bot handles all routing internally.",
70
74
  params.availableTools.has("message")
71
75
  ? [
@@ -76,7 +80,7 @@ function buildMessagingSection(params) {
76
80
  `- If multiple channels are configured, pass \`channel\` (${params.messageChannelOptions}).`,
77
81
  `- If you use \`message\` (\`action=send\`) to deliver your user-visible reply, respond with ONLY: ${SILENT_REPLY_TOKEN} (avoid duplicate replies).`,
78
82
  params.inlineButtonsEnabled
79
- ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data}]]` (callback_data routes back as a user message)."
83
+ ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data,style?}]]`; `style` can be `primary`, `success`, or `danger`."
80
84
  : params.runtimeChannel
81
85
  ? `- Inline buttons not enabled for ${params.runtimeChannel}. If you need them, ask to set ${params.runtimeChannel}.capabilities.inlineButtons ("dm"|"group"|"all"|"allowlist").`
82
86
  : "",
@@ -96,6 +100,22 @@ function buildVoiceSection(params) {
96
100
  return [];
97
101
  return ["## Voice (TTS)", hint, ""];
98
102
  }
103
+ function buildLlmsTxtSection(params) {
104
+ if (params.isMinimal) {
105
+ return [];
106
+ }
107
+ if (!params.availableTools.has("web_fetch")) {
108
+ return [];
109
+ }
110
+ return [
111
+ "## llms.txt Discovery",
112
+ "When exploring a new domain or website (via web_fetch or browser), check for an llms.txt file that describes how AI agents should interact with the site:",
113
+ "- Try `/llms.txt` or `/.well-known/llms.txt` at the domain root",
114
+ "- If found, follow its guidance for interacting with that site's content and APIs",
115
+ "- llms.txt is an emerging standard (like robots.txt for AI) — not all sites have one, so don't warn if missing",
116
+ "",
117
+ ];
118
+ }
99
119
  function buildDocsSection(params) {
100
120
  const docsPath = params.docsPath?.trim();
101
121
  if (!docsPath || params.isMinimal)
@@ -137,6 +157,7 @@ export function buildAgentSystemPrompt(params) {
137
157
  sessions_history: "Fetch history for another session/sub-agent",
138
158
  sessions_send: "Send a message to another session/sub-agent",
139
159
  sessions_spawn: "Spawn a sub-agent session",
160
+ subagents: "List, steer, or kill sub-agent runs for this requester session",
140
161
  session_status: "Show a /status-equivalent status card (usage + time + Reasoning/Verbose/Elevated); use for model-use questions (📊 session_status); optional per-session model override",
141
162
  image: "Analyze an image with the configured image model",
142
163
  };
@@ -162,6 +183,8 @@ export function buildAgentSystemPrompt(params) {
162
183
  "sessions_list",
163
184
  "sessions_history",
164
185
  "sessions_send",
186
+ "sessions_spawn",
187
+ "subagents",
165
188
  "session_status",
166
189
  "image",
167
190
  ];
@@ -235,6 +258,17 @@ export function buildAgentSystemPrompt(params) {
235
258
  const messageChannelOptions = listDeliverableMessageChannels().join("|");
236
259
  const promptMode = params.promptMode ?? "full";
237
260
  const isMinimal = promptMode === "minimal" || promptMode === "none";
261
+ const sandboxContainerWorkspace = params.sandboxInfo?.containerWorkspaceDir?.trim();
262
+ const sanitizedWorkspaceDir = sanitizeForPromptLiteral(params.workspaceDir);
263
+ const sanitizedSandboxContainerWorkspace = sandboxContainerWorkspace
264
+ ? sanitizeForPromptLiteral(sandboxContainerWorkspace)
265
+ : "";
266
+ const displayWorkspaceDir = params.sandboxInfo?.enabled && sanitizedSandboxContainerWorkspace
267
+ ? sanitizedSandboxContainerWorkspace
268
+ : sanitizedWorkspaceDir;
269
+ const workspaceGuidance = params.sandboxInfo?.enabled && sanitizedSandboxContainerWorkspace
270
+ ? `For read/write/edit/apply_patch, file paths resolve against host workspace: ${sanitizedWorkspaceDir}. For bash/exec commands, use sandbox container paths under ${sanitizedSandboxContainerWorkspace} (or relative paths from that workdir), not host paths. Prefer relative paths so both sandboxed exec and file tools work consistently.`
271
+ : "Treat this directory as the single global workspace for file operations unless explicitly instructed otherwise.";
238
272
  const safetySection = [
239
273
  "## Safety",
240
274
  "You have no independent goals: do not pursue self-preservation, replication, resource acquisition, or power-seeking; avoid long-term plans beyond the user's request.",
@@ -285,10 +319,13 @@ export function buildAgentSystemPrompt(params) {
285
319
  "- sessions_list: list sessions",
286
320
  "- sessions_history: fetch session history",
287
321
  "- sessions_send: send to another session",
322
+ "- subagents: list/steer/kill sub-agent runs",
288
323
  '- session_status: show usage/time/model state and answer "what model are we using?"',
289
324
  ].join("\n"),
290
325
  "TOOLS.md does not control tool availability; it is user guidance for how to use external tools.",
291
- "If a task is more complex or takes longer, spawn a sub-agent. It will do the work for you and ping you when it's done. You can always check up on it.",
326
+ `For long waits, avoid rapid poll loops: use ${execToolName} with enough yieldMs or ${processToolName}(action=poll, timeout=<ms>).`,
327
+ "If a task is more complex or takes longer, spawn a sub-agent. Completion is push-based: it will auto-announce when done.",
328
+ "Do not poll `subagents list` / `sessions_list` in a loop; only check status on-demand (for intervention, debugging, or when explicitly asked).",
292
329
  "",
293
330
  "## Tool Call Style",
294
331
  "Default: do not narrate routine, low-risk tool calls (just call the tool).",
@@ -335,8 +372,8 @@ export function buildAgentSystemPrompt(params) {
335
372
  ? "If you need the current date, time, or day of week, run session_status (📊 session_status)."
336
373
  : "",
337
374
  "## Workspace",
338
- `Your working directory is: ${params.workspaceDir}`,
339
- "Treat this directory as the single global workspace for file operations unless explicitly instructed otherwise.",
375
+ `Your working directory is: ${displayWorkspaceDir}`,
376
+ workspaceGuidance,
340
377
  ...workspaceNotes,
341
378
  "",
342
379
  ...docsSection,
@@ -346,17 +383,20 @@ export function buildAgentSystemPrompt(params) {
346
383
  "You are running in a sandboxed runtime (tools execute in Docker).",
347
384
  "Some tools may be unavailable due to sandbox policy.",
348
385
  "Sub-agents stay sandboxed (no elevated/host access). Need outside-sandbox read/write? Don't spawn; ask first.",
386
+ params.sandboxInfo.containerWorkspaceDir
387
+ ? `Sandbox container workdir: ${sanitizeForPromptLiteral(params.sandboxInfo.containerWorkspaceDir)}`
388
+ : "",
349
389
  params.sandboxInfo.workspaceDir
350
- ? `Sandbox workspace: ${params.sandboxInfo.workspaceDir}`
390
+ ? `Sandbox host mount source (file tools bridge only; not valid inside sandbox exec): ${sanitizeForPromptLiteral(params.sandboxInfo.workspaceDir)}`
351
391
  : "",
352
392
  params.sandboxInfo.workspaceAccess
353
393
  ? `Agent workspace access: ${params.sandboxInfo.workspaceAccess}${params.sandboxInfo.agentWorkspaceMount
354
- ? ` (mounted at ${params.sandboxInfo.agentWorkspaceMount})`
394
+ ? ` (mounted at ${sanitizeForPromptLiteral(params.sandboxInfo.agentWorkspaceMount)})`
355
395
  : ""}`
356
396
  : "",
357
397
  params.sandboxInfo.browserBridgeUrl ? "Sandbox browser: enabled." : "",
358
398
  params.sandboxInfo.browserNoVncUrl
359
- ? `Sandbox browser observer (noVNC): ${params.sandboxInfo.browserNoVncUrl}`
399
+ ? `Sandbox browser observer (noVNC): ${sanitizeForPromptLiteral(params.sandboxInfo.browserNoVncUrl)}`
360
400
  : "",
361
401
  params.sandboxInfo.hostBrowserAllowed === true
362
402
  ? "Host browser control: allowed."
@@ -397,6 +437,7 @@ export function buildAgentSystemPrompt(params) {
397
437
  messageToolHints: params.messageToolHints,
398
438
  }),
399
439
  ...buildVoiceSection({ isMinimal, ttsHint: params.ttsHint }),
440
+ ...buildLlmsTxtSection({ isMinimal, availableTools }),
400
441
  ];
401
442
  if (extraSystemPrompt) {
402
443
  // Use "Subagent Context" header for minimal mode (subagents), otherwise "Group Chat Context"
@@ -429,8 +470,9 @@ export function buildAgentSystemPrompt(params) {
429
470
  lines.push("## Reasoning Format", reasoningHint, "");
430
471
  }
431
472
  const contextFiles = params.contextFiles ?? [];
432
- if (contextFiles.length > 0) {
433
- const hasSoulFile = contextFiles.some((file) => {
473
+ const validContextFiles = contextFiles.filter((file) => typeof file.path === "string" && file.path.trim().length > 0);
474
+ if (validContextFiles.length > 0) {
475
+ const hasSoulFile = validContextFiles.some((file) => {
434
476
  const normalizedPath = file.path.trim().replace(/\\/g, "/");
435
477
  const baseName = normalizedPath.split("/").pop() ?? normalizedPath;
436
478
  return baseName.toLowerCase() === "soul.md";
@@ -440,7 +482,7 @@ export function buildAgentSystemPrompt(params) {
440
482
  lines.push("If SOUL.md is present, embody its persona and tone. Avoid stiff, generic replies; follow its guidance unless higher-priority instructions override it.");
441
483
  }
442
484
  lines.push("");
443
- for (const file of contextFiles) {
485
+ for (const file of validContextFiles) {
444
486
  lines.push(`## ${file.path}`, "", file.content, "");
445
487
  }
446
488
  }
@@ -0,0 +1,18 @@
1
+ import { vi } from "vitest";
2
+ export const stubTool = (name) => ({
3
+ name,
4
+ description: `${name} stub`,
5
+ parameters: { type: "object", properties: {} },
6
+ execute: vi.fn(),
7
+ });
8
+ vi.mock("../tools/image-tool.js", () => ({
9
+ createImageTool: () => stubTool("image"),
10
+ }));
11
+ vi.mock("../tools/web-tools.js", () => ({
12
+ createWebSearchTool: () => null,
13
+ createWebFetchTool: () => null,
14
+ }));
15
+ vi.mock("../../plugins/tools.js", () => ({
16
+ resolvePluginTools: () => [],
17
+ getPluginToolMeta: () => undefined,
18
+ }));
@@ -0,0 +1,74 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { resolveSandboxPath } from "../sandbox-paths.js";
4
+ export function createSandboxFsBridgeFromResolver(resolvePath) {
5
+ return {
6
+ resolvePath: ({ filePath, cwd }) => resolvePath(filePath, cwd),
7
+ readFile: async ({ filePath, cwd }) => {
8
+ const target = resolvePath(filePath, cwd);
9
+ return fs.readFile(target.hostPath);
10
+ },
11
+ writeFile: async ({ filePath, cwd, data, mkdir = true }) => {
12
+ const target = resolvePath(filePath, cwd);
13
+ if (mkdir) {
14
+ await fs.mkdir(path.dirname(target.hostPath), { recursive: true });
15
+ }
16
+ const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
17
+ await fs.writeFile(target.hostPath, buffer);
18
+ },
19
+ mkdirp: async ({ filePath, cwd }) => {
20
+ const target = resolvePath(filePath, cwd);
21
+ await fs.mkdir(target.hostPath, { recursive: true });
22
+ },
23
+ remove: async ({ filePath, cwd, recursive, force }) => {
24
+ const target = resolvePath(filePath, cwd);
25
+ await fs.rm(target.hostPath, {
26
+ recursive: recursive ?? false,
27
+ force: force ?? false,
28
+ });
29
+ },
30
+ rename: async ({ from, to, cwd }) => {
31
+ const source = resolvePath(from, cwd);
32
+ const target = resolvePath(to, cwd);
33
+ await fs.mkdir(path.dirname(target.hostPath), { recursive: true });
34
+ await fs.rename(source.hostPath, target.hostPath);
35
+ },
36
+ stat: async ({ filePath, cwd }) => {
37
+ try {
38
+ const target = resolvePath(filePath, cwd);
39
+ const stats = await fs.stat(target.hostPath);
40
+ return {
41
+ type: stats.isDirectory() ? "directory" : stats.isFile() ? "file" : "other",
42
+ size: stats.size,
43
+ mtimeMs: stats.mtimeMs,
44
+ };
45
+ }
46
+ catch (error) {
47
+ if (error.code === "ENOENT") {
48
+ return null;
49
+ }
50
+ throw error;
51
+ }
52
+ },
53
+ };
54
+ }
55
+ export function createHostSandboxFsBridge(rootDir) {
56
+ const root = path.resolve(rootDir);
57
+ const resolvePath = (filePath, cwd) => {
58
+ const resolved = resolveSandboxPath({
59
+ filePath,
60
+ cwd: cwd ?? root,
61
+ root,
62
+ });
63
+ const relativePath = resolved.relative
64
+ ? resolved.relative.split(path.sep).filter(Boolean).join(path.posix.sep)
65
+ : "";
66
+ const containerPath = relativePath ? path.posix.join("/workspace", relativePath) : "/workspace";
67
+ return {
68
+ hostPath: resolved.resolved,
69
+ relativePath,
70
+ containerPath,
71
+ };
72
+ };
73
+ return createSandboxFsBridgeFromResolver(resolvePath);
74
+ }