@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,17 @@
1
+ export async function resolveCurrentDirectiveLevels(params) {
2
+ const resolvedDefaultThinkLevel = params.sessionEntry?.thinkingLevel ??
3
+ params.agentCfg?.thinkingDefault ??
4
+ (await params.resolveDefaultThinkingLevel());
5
+ const currentThinkLevel = resolvedDefaultThinkLevel;
6
+ const currentVerboseLevel = params.sessionEntry?.verboseLevel ??
7
+ params.agentCfg?.verboseDefault;
8
+ const currentReasoningLevel = params.sessionEntry?.reasoningLevel ?? "off";
9
+ const currentElevatedLevel = params.sessionEntry?.elevatedLevel ??
10
+ params.agentCfg?.elevatedDefault;
11
+ return {
12
+ currentThinkLevel,
13
+ currentVerboseLevel,
14
+ currentReasoningLevel,
15
+ currentElevatedLevel,
16
+ };
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ export function skipDirectiveArgPrefix(raw) {
2
+ let i = 0;
3
+ const len = raw.length;
4
+ while (i < len && /\s/.test(raw[i])) {
5
+ i += 1;
6
+ }
7
+ if (raw[i] === ":") {
8
+ i += 1;
9
+ while (i < len && /\s/.test(raw[i])) {
10
+ i += 1;
11
+ }
12
+ }
13
+ return i;
14
+ }
15
+ export function takeDirectiveToken(raw, startIndex) {
16
+ let i = startIndex;
17
+ const len = raw.length;
18
+ while (i < len && /\s/.test(raw[i])) {
19
+ i += 1;
20
+ }
21
+ if (i >= len) {
22
+ return { token: null, nextIndex: i };
23
+ }
24
+ const start = i;
25
+ while (i < len && !/\s/.test(raw[i])) {
26
+ i += 1;
27
+ }
28
+ if (start === i) {
29
+ return { token: null, nextIndex: i };
30
+ }
31
+ const token = raw.slice(start, i);
32
+ while (i < len && /\s/.test(raw[i])) {
33
+ i += 1;
34
+ }
35
+ return { token, nextIndex: i };
36
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Global registry for tracking active reply dispatchers.
3
+ * Used to ensure gateway restart waits for all replies to complete.
4
+ */
5
+ const activeDispatchers = new Set();
6
+ let nextId = 0;
7
+ /**
8
+ * Register a reply dispatcher for global tracking.
9
+ * Returns an unregister function to call when the dispatcher is no longer needed.
10
+ */
11
+ export function registerDispatcher(dispatcher) {
12
+ const id = `dispatcher-${++nextId}`;
13
+ const tracked = {
14
+ id,
15
+ pending: dispatcher.pending,
16
+ waitForIdle: dispatcher.waitForIdle,
17
+ };
18
+ activeDispatchers.add(tracked);
19
+ const unregister = () => {
20
+ activeDispatchers.delete(tracked);
21
+ };
22
+ return { id, unregister };
23
+ }
24
+ /**
25
+ * Get the total number of pending replies across all dispatchers.
26
+ */
27
+ export function getTotalPendingReplies() {
28
+ let total = 0;
29
+ for (const dispatcher of activeDispatchers) {
30
+ total += dispatcher.pending();
31
+ }
32
+ return total;
33
+ }
34
+ /**
35
+ * Clear all registered dispatchers (for testing).
36
+ * WARNING: Only use this in test cleanup!
37
+ */
38
+ export function clearAllDispatchers() {
39
+ if (!process.env.VITEST && process.env.NODE_ENV !== "test") {
40
+ throw new Error("clearAllDispatchers() is only available in test environments");
41
+ }
42
+ activeDispatchers.clear();
43
+ }
@@ -0,0 +1,20 @@
1
+ import { formatCliCommand } from "../../cli/command-format.js";
2
+ export function formatElevatedUnavailableMessage(params) {
3
+ const lines = [];
4
+ lines.push(`elevated is not available right now (runtime=${params.runtimeSandboxed ? "sandboxed" : "direct"}).`);
5
+ if (params.failures.length > 0) {
6
+ lines.push(`Failing gates: ${params.failures.map((f) => `${f.gate} (${f.key})`).join(", ")}`);
7
+ }
8
+ else {
9
+ lines.push("Failing gates: enabled (tools.elevated.enabled / agents.list[].tools.elevated.enabled), allowFrom (tools.elevated.allowFrom.<provider>).");
10
+ }
11
+ lines.push("Fix-it keys:");
12
+ lines.push("- tools.elevated.enabled");
13
+ lines.push("- tools.elevated.allowFrom.<provider>");
14
+ lines.push("- agents.list[].tools.elevated.enabled");
15
+ lines.push("- agents.list[].tools.elevated.allowFrom.<provider>");
16
+ if (params.sessionKey) {
17
+ lines.push(`See: ${formatCliCommand(`openclaw sandbox explain --session ${params.sessionKey}`)}`);
18
+ }
19
+ return lines.join("\n");
20
+ }
@@ -0,0 +1,96 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ // Default required files — constants, extensible to config later
4
+ const DEFAULT_REQUIRED_READS = [
5
+ "WORKFLOW_AUTO.md",
6
+ /memory\/\d{4}-\d{2}-\d{2}\.md/, // daily memory files
7
+ ];
8
+ /**
9
+ * Audit whether agent read required startup files after compaction.
10
+ * Returns list of missing file patterns.
11
+ */
12
+ export function auditPostCompactionReads(readFilePaths, workspaceDir, requiredReads = DEFAULT_REQUIRED_READS) {
13
+ const normalizedReads = readFilePaths.map((p) => path.resolve(workspaceDir, p));
14
+ const missingPatterns = [];
15
+ for (const required of requiredReads) {
16
+ if (typeof required === "string") {
17
+ const requiredResolved = path.resolve(workspaceDir, required);
18
+ const found = normalizedReads.some((r) => r === requiredResolved);
19
+ if (!found) {
20
+ missingPatterns.push(required);
21
+ }
22
+ }
23
+ else {
24
+ // RegExp — match against relative paths from workspace
25
+ const found = readFilePaths.some((p) => {
26
+ const rel = path.relative(workspaceDir, path.resolve(workspaceDir, p));
27
+ // Normalize to forward slashes for cross-platform RegExp matching
28
+ const normalizedRel = rel.split(path.sep).join("/");
29
+ return required.test(normalizedRel);
30
+ });
31
+ if (!found) {
32
+ missingPatterns.push(required.source);
33
+ }
34
+ }
35
+ }
36
+ return { passed: missingPatterns.length === 0, missingPatterns };
37
+ }
38
+ /**
39
+ * Read messages from a session JSONL file.
40
+ * Returns messages from the last N lines (default 100).
41
+ */
42
+ export function readSessionMessages(sessionFile, maxLines = 100) {
43
+ if (!fs.existsSync(sessionFile)) {
44
+ return [];
45
+ }
46
+ try {
47
+ const content = fs.readFileSync(sessionFile, "utf-8");
48
+ const lines = content.trim().split("\n");
49
+ const recentLines = lines.slice(-maxLines);
50
+ const messages = [];
51
+ for (const line of recentLines) {
52
+ try {
53
+ const entry = JSON.parse(line);
54
+ if (entry.type === "message" && entry.message) {
55
+ messages.push(entry.message);
56
+ }
57
+ }
58
+ catch {
59
+ // Skip malformed lines
60
+ }
61
+ }
62
+ return messages;
63
+ }
64
+ catch {
65
+ return [];
66
+ }
67
+ }
68
+ /**
69
+ * Extract file paths from Read tool calls in agent messages.
70
+ * Looks for tool_use blocks with name="read" and extracts path/file_path args.
71
+ */
72
+ export function extractReadPaths(messages) {
73
+ const paths = [];
74
+ for (const msg of messages) {
75
+ if (msg.role !== "assistant" || !Array.isArray(msg.content)) {
76
+ continue;
77
+ }
78
+ for (const block of msg.content) {
79
+ if (block.type === "tool_use" && block.name === "read") {
80
+ const filePath = block.input?.file_path ?? block.input?.path;
81
+ if (typeof filePath === "string") {
82
+ paths.push(filePath);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ return paths;
88
+ }
89
+ /** Format the audit warning message */
90
+ export function formatAuditWarning(missingPatterns) {
91
+ const fileList = missingPatterns.map((p) => ` - ${p}`).join("\n");
92
+ return ("⚠️ Post-Compaction Audit: The following required startup files were not read after context reset:\n" +
93
+ fileList +
94
+ "\n\nPlease read them now using the Read tool before continuing. " +
95
+ "This ensures your operating protocols are restored after memory compaction.");
96
+ }
@@ -0,0 +1,98 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const MAX_CONTEXT_CHARS = 3000;
4
+ /**
5
+ * Read critical sections from workspace AGENTS.md for post-compaction injection.
6
+ * Returns formatted system event text, or null if no AGENTS.md or no relevant sections.
7
+ */
8
+ export async function readPostCompactionContext(workspaceDir) {
9
+ const agentsPath = path.join(workspaceDir, "AGENTS.md");
10
+ try {
11
+ if (!fs.existsSync(agentsPath)) {
12
+ return null;
13
+ }
14
+ const content = await fs.promises.readFile(agentsPath, "utf-8");
15
+ // Extract "## Session Startup" and "## Red Lines" sections
16
+ // Each section ends at the next "## " heading or end of file
17
+ const sections = extractSections(content, ["Session Startup", "Red Lines"]);
18
+ if (sections.length === 0) {
19
+ return null;
20
+ }
21
+ const combined = sections.join("\n\n");
22
+ const safeContent = combined.length > MAX_CONTEXT_CHARS
23
+ ? combined.slice(0, MAX_CONTEXT_CHARS) + "\n...[truncated]..."
24
+ : combined;
25
+ return ("[Post-compaction context refresh]\n\n" +
26
+ "Session was just compacted. The conversation summary above is a hint, NOT a substitute for your startup sequence. " +
27
+ "Execute your Session Startup sequence now — read the required files before responding to the user.\n\n" +
28
+ "Critical rules from AGENTS.md:\n\n" +
29
+ safeContent);
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Extract named sections from markdown content.
37
+ * Matches H2 (##) or H3 (###) headings case-insensitively.
38
+ * Skips content inside fenced code blocks.
39
+ * Captures until the next heading of same or higher level, or end of string.
40
+ */
41
+ export function extractSections(content, sectionNames) {
42
+ const results = [];
43
+ const lines = content.split("\n");
44
+ for (const name of sectionNames) {
45
+ let sectionLines = [];
46
+ let inSection = false;
47
+ let sectionLevel = 0;
48
+ let inCodeBlock = false;
49
+ for (const line of lines) {
50
+ // Track fenced code blocks
51
+ if (line.trimStart().startsWith("```")) {
52
+ inCodeBlock = !inCodeBlock;
53
+ if (inSection) {
54
+ sectionLines.push(line);
55
+ }
56
+ continue;
57
+ }
58
+ // Skip heading detection inside code blocks
59
+ if (inCodeBlock) {
60
+ if (inSection) {
61
+ sectionLines.push(line);
62
+ }
63
+ continue;
64
+ }
65
+ // Check if this line is a heading
66
+ const headingMatch = line.match(/^(#{2,3})\s+(.+?)\s*$/);
67
+ if (headingMatch) {
68
+ const level = headingMatch[1].length; // 2 or 3
69
+ const headingText = headingMatch[2];
70
+ if (!inSection) {
71
+ // Check if this is our target section (case-insensitive)
72
+ if (headingText.toLowerCase() === name.toLowerCase()) {
73
+ inSection = true;
74
+ sectionLevel = level;
75
+ sectionLines = [line];
76
+ continue;
77
+ }
78
+ }
79
+ else {
80
+ // We're in section — stop if we hit a heading of same or higher level
81
+ if (level <= sectionLevel) {
82
+ break;
83
+ }
84
+ // Lower-level heading (e.g., ### inside ##) — include it
85
+ sectionLines.push(line);
86
+ continue;
87
+ }
88
+ }
89
+ if (inSection) {
90
+ sectionLines.push(line);
91
+ }
92
+ }
93
+ if (sectionLines.length > 0) {
94
+ results.push(sectionLines.join("\n").trim());
95
+ }
96
+ }
97
+ return results;
98
+ }
@@ -0,0 +1,92 @@
1
+ import { logVerbose } from "../../globals.js";
2
+ import { SILENT_REPLY_TOKEN } from "../tokens.js";
3
+ import { createBlockReplyPayloadKey } from "./block-reply-pipeline.js";
4
+ import { parseReplyDirectives } from "./reply-directives.js";
5
+ import { applyReplyTagsToPayload, isRenderablePayload } from "./reply-payloads.js";
6
+ export function normalizeReplyPayloadDirectives(params) {
7
+ const parseMode = params.parseMode ?? "always";
8
+ const silentToken = params.silentToken ?? SILENT_REPLY_TOKEN;
9
+ const sourceText = params.payload.text ?? "";
10
+ const shouldParse = parseMode === "always" ||
11
+ (parseMode === "auto" &&
12
+ (sourceText.includes("[[") ||
13
+ sourceText.includes("MEDIA:") ||
14
+ sourceText.includes(silentToken)));
15
+ const parsed = shouldParse
16
+ ? parseReplyDirectives(sourceText, {
17
+ currentMessageId: params.currentMessageId,
18
+ silentToken,
19
+ })
20
+ : undefined;
21
+ let text = parsed ? parsed.text || undefined : params.payload.text || undefined;
22
+ if (params.trimLeadingWhitespace && text) {
23
+ text = text.trimStart() || undefined;
24
+ }
25
+ const mediaUrls = params.payload.mediaUrls ?? parsed?.mediaUrls;
26
+ const mediaUrl = params.payload.mediaUrl ?? parsed?.mediaUrl ?? mediaUrls?.[0];
27
+ return {
28
+ payload: {
29
+ ...params.payload,
30
+ text,
31
+ mediaUrls,
32
+ mediaUrl,
33
+ replyToId: params.payload.replyToId ?? parsed?.replyToId,
34
+ replyToTag: params.payload.replyToTag || parsed?.replyToTag,
35
+ replyToCurrent: params.payload.replyToCurrent || parsed?.replyToCurrent,
36
+ audioAsVoice: Boolean(params.payload.audioAsVoice || parsed?.audioAsVoice),
37
+ },
38
+ isSilent: parsed?.isSilent ?? false,
39
+ };
40
+ }
41
+ const hasRenderableMedia = (payload) => Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0;
42
+ export function createBlockReplyDeliveryHandler(params) {
43
+ return async (payload) => {
44
+ const { text, skip } = params.normalizeStreamingText(payload);
45
+ if (skip && !hasRenderableMedia(payload)) {
46
+ return;
47
+ }
48
+ const taggedPayload = applyReplyTagsToPayload({
49
+ ...payload,
50
+ text,
51
+ mediaUrl: payload.mediaUrl ?? payload.mediaUrls?.[0],
52
+ replyToId: payload.replyToId ??
53
+ (payload.replyToCurrent === false ? undefined : params.currentMessageId),
54
+ }, params.currentMessageId);
55
+ // Let through payloads with audioAsVoice flag even if empty (need to track it).
56
+ if (!isRenderablePayload(taggedPayload) && !payload.audioAsVoice) {
57
+ return;
58
+ }
59
+ const normalized = normalizeReplyPayloadDirectives({
60
+ payload: taggedPayload,
61
+ currentMessageId: params.currentMessageId,
62
+ silentToken: SILENT_REPLY_TOKEN,
63
+ trimLeadingWhitespace: true,
64
+ parseMode: "auto",
65
+ });
66
+ const blockPayload = params.applyReplyToMode(normalized.payload);
67
+ const blockHasMedia = hasRenderableMedia(blockPayload);
68
+ // Skip empty payloads unless they have audioAsVoice flag (need to track it).
69
+ if (!blockPayload.text && !blockHasMedia && !blockPayload.audioAsVoice) {
70
+ return;
71
+ }
72
+ if (normalized.isSilent && !blockHasMedia) {
73
+ return;
74
+ }
75
+ if (blockPayload.text) {
76
+ void params.typingSignals.signalTextDelta(blockPayload.text).catch((err) => {
77
+ logVerbose(`block reply typing signal failed: ${String(err)}`);
78
+ });
79
+ }
80
+ // Use pipeline if available (block streaming enabled), otherwise send directly.
81
+ if (params.blockStreamingEnabled && params.blockReplyPipeline) {
82
+ params.blockReplyPipeline.enqueue(blockPayload);
83
+ }
84
+ else if (params.blockStreamingEnabled) {
85
+ // Send directly when flushing before tool execution (no pipeline but streaming enabled).
86
+ // Track sent key to avoid duplicate in final payloads.
87
+ params.directlySentBlockKeys.add(createBlockReplyPayloadKey(blockPayload));
88
+ await params.onBlockReply(blockPayload);
89
+ }
90
+ // When streaming is disabled entirely, blocks are accumulated in final text instead.
91
+ };
92
+ }
@@ -0,0 +1 @@
1
+ export const BARE_SESSION_RESET_PROMPT = "A new session was started via /new or /reset. Greet the user in your configured persona, if one is provided. Be yourself - use your defined voice, mannerisms, and mood. Keep it to 1-3 sentences and ask what they want to do. If the runtime model differs from default_model in the system prompt, mention the default model. Do not mention internal steps, files, tools, or reasoning.";
@@ -0,0 +1,33 @@
1
+ import { deriveSessionTotalTokens } from "../../agents/usage.js";
2
+ import { incrementCompactionCount } from "./session-updates.js";
3
+ import { persistSessionUsageUpdate } from "./session-usage.js";
4
+ export async function persistRunSessionUsage(params) {
5
+ await persistSessionUsageUpdate({
6
+ storePath: params.storePath,
7
+ sessionKey: params.sessionKey,
8
+ usage: params.usage,
9
+ lastCallUsage: params.lastCallUsage,
10
+ promptTokens: params.promptTokens,
11
+ modelUsed: params.modelUsed,
12
+ providerUsed: params.providerUsed,
13
+ contextTokensUsed: params.contextTokensUsed,
14
+ systemPromptReport: params.systemPromptReport,
15
+ cliSessionId: params.cliSessionId,
16
+ logLabel: params.logLabel,
17
+ });
18
+ }
19
+ export async function incrementRunCompactionCount(params) {
20
+ const tokensAfterCompaction = params.lastCallUsage
21
+ ? deriveSessionTotalTokens({
22
+ usage: params.lastCallUsage,
23
+ contextTokens: params.contextTokensUsed,
24
+ })
25
+ : undefined;
26
+ return incrementCompactionCount({
27
+ sessionEntry: params.sessionEntry,
28
+ sessionStore: params.sessionStore,
29
+ sessionKey: params.sessionKey,
30
+ storePath: params.storePath,
31
+ tokensAfter: tokensAfterCompaction,
32
+ });
33
+ }
@@ -0,0 +1,115 @@
1
+ import path from "node:path";
2
+ import { afterEach, beforeEach, expect, vi } from "vitest";
3
+ import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
4
+ import { loadModelCatalog } from "../agents/model-catalog.js";
5
+ import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
6
+ import { loadSessionStore } from "../config/sessions.js";
7
+ export { loadModelCatalog } from "../agents/model-catalog.js";
8
+ export { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
9
+ export const MAIN_SESSION_KEY = "agent:main:main";
10
+ export const DEFAULT_TEST_MODEL_CATALOG = [
11
+ { id: "claude-opus-4-5", name: "Opus 4.5", provider: "anthropic" },
12
+ { id: "claude-sonnet-4-1", name: "Sonnet 4.1", provider: "anthropic" },
13
+ { id: "gpt-4.1-mini", name: "GPT-4.1 Mini", provider: "openai" },
14
+ ];
15
+ export function replyText(res) {
16
+ if (Array.isArray(res)) {
17
+ return typeof res[0]?.text === "string" ? res[0]?.text : undefined;
18
+ }
19
+ return typeof res?.text === "string" ? res.text : undefined;
20
+ }
21
+ export function replyTexts(res) {
22
+ const payloads = Array.isArray(res) ? res : [res];
23
+ return payloads
24
+ .map((entry) => (typeof entry?.text === "string" ? entry.text : undefined))
25
+ .filter((value) => Boolean(value));
26
+ }
27
+ export async function withTempHome(fn) {
28
+ return withTempHomeBase(async (home) => {
29
+ return await fn(home);
30
+ }, {
31
+ env: {
32
+ POOLBOT_AGENT_DIR: (home) => path.join(home, ".openclaw", "agent"),
33
+ PI_CODING_AGENT_DIR: (home) => path.join(home, ".openclaw", "agent"),
34
+ },
35
+ prefix: "openclaw-reply-",
36
+ });
37
+ }
38
+ export function sessionStorePath(home) {
39
+ return path.join(home, "sessions.json");
40
+ }
41
+ export function makeWhatsAppDirectiveConfig(home, defaults, extra = {}) {
42
+ return {
43
+ agents: {
44
+ defaults: {
45
+ workspace: path.join(home, "poolbot"),
46
+ ...defaults,
47
+ },
48
+ },
49
+ channels: { whatsapp: { allowFrom: ["*"] } },
50
+ session: { store: sessionStorePath(home) },
51
+ ...extra,
52
+ };
53
+ }
54
+ export const AUTHORIZED_WHATSAPP_COMMAND = {
55
+ From: "+1222",
56
+ To: "+1222",
57
+ Provider: "whatsapp",
58
+ SenderE164: "+1222",
59
+ CommandAuthorized: true,
60
+ };
61
+ export function makeElevatedDirectiveConfig(home) {
62
+ return makeWhatsAppDirectiveConfig(home, {
63
+ model: "anthropic/claude-opus-4-5",
64
+ elevatedDefault: "on",
65
+ }, {
66
+ tools: {
67
+ elevated: {
68
+ allowFrom: { whatsapp: ["+1222"] },
69
+ },
70
+ },
71
+ channels: { whatsapp: { allowFrom: ["+1222"] } },
72
+ session: { store: sessionStorePath(home) },
73
+ });
74
+ }
75
+ export function assertModelSelection(storePath, selection = {}) {
76
+ const store = loadSessionStore(storePath);
77
+ const entry = store[MAIN_SESSION_KEY];
78
+ expect(entry).toBeDefined();
79
+ expect(entry?.modelOverride).toBe(selection.model);
80
+ expect(entry?.providerOverride).toBe(selection.provider);
81
+ }
82
+ export function installDirectiveBehaviorE2EHooks() {
83
+ beforeEach(() => {
84
+ vi.mocked(runEmbeddedPiAgent).mockReset();
85
+ vi.mocked(loadModelCatalog).mockResolvedValue(DEFAULT_TEST_MODEL_CATALOG);
86
+ });
87
+ afterEach(() => {
88
+ vi.restoreAllMocks();
89
+ });
90
+ }
91
+ export function makeRestrictedElevatedDisabledConfig(home) {
92
+ return {
93
+ agents: {
94
+ defaults: {
95
+ model: "anthropic/claude-opus-4-5",
96
+ workspace: path.join(home, "poolbot"),
97
+ },
98
+ list: [
99
+ {
100
+ id: "restricted",
101
+ tools: {
102
+ elevated: { enabled: false },
103
+ },
104
+ },
105
+ ],
106
+ },
107
+ tools: {
108
+ elevated: {
109
+ allowFrom: { whatsapp: ["+1222"] },
110
+ },
111
+ },
112
+ channels: { whatsapp: { allowFrom: ["+1222"] } },
113
+ session: { store: path.join(home, "sessions.json") },
114
+ };
115
+ }
@@ -0,0 +1,12 @@
1
+ import { vi } from "vitest";
2
+ vi.mock("../agents/pi-embedded.js", () => ({
3
+ abortEmbeddedPiRun: vi.fn().mockReturnValue(false),
4
+ runEmbeddedPiAgent: vi.fn(),
5
+ queueEmbeddedPiMessage: vi.fn().mockReturnValue(false),
6
+ resolveEmbeddedSessionLane: (key) => `session:${key.trim() || "main"}`,
7
+ isEmbeddedPiRunActive: vi.fn().mockReturnValue(false),
8
+ isEmbeddedPiRunStreaming: vi.fn().mockReturnValue(false),
9
+ }));
10
+ vi.mock("../agents/model-catalog.js", () => ({
11
+ loadModelCatalog: vi.fn(),
12
+ }));
@@ -0,0 +1,26 @@
1
+ // In-process registry for loopback-only bridge servers that require auth, but
2
+ // are addressed via dynamic ephemeral ports (e.g. sandbox browser bridge).
3
+ const authByPort = new Map();
4
+ export function setBridgeAuthForPort(port, auth) {
5
+ if (!Number.isFinite(port) || port <= 0) {
6
+ return;
7
+ }
8
+ const token = typeof auth.token === "string" ? auth.token.trim() : "";
9
+ const password = typeof auth.password === "string" ? auth.password.trim() : "";
10
+ authByPort.set(port, {
11
+ token: token || undefined,
12
+ password: password || undefined,
13
+ });
14
+ }
15
+ export function getBridgeAuthForPort(port) {
16
+ if (!Number.isFinite(port) || port <= 0) {
17
+ return undefined;
18
+ }
19
+ return authByPort.get(port);
20
+ }
21
+ export function deleteBridgeAuthForPort(port) {
22
+ if (!Number.isFinite(port) || port <= 0) {
23
+ return;
24
+ }
25
+ authByPort.delete(port);
26
+ }
@@ -0,0 +1,10 @@
1
+ export function buildProfileQuery(profile) {
2
+ return profile ? `?profile=${encodeURIComponent(profile)}` : "";
3
+ }
4
+ export function withBaseUrl(baseUrl, path) {
5
+ const trimmed = baseUrl?.trim();
6
+ if (!trimmed) {
7
+ return path;
8
+ }
9
+ return `${trimmed.replace(/\/$/, "")}${path}`;
10
+ }