clawdbot 2026.1.4-1

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 (550) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +297 -0
  5. package/dist/agents/agent-paths.js +17 -0
  6. package/dist/agents/bash-process-registry.js +126 -0
  7. package/dist/agents/bash-tools.js +837 -0
  8. package/dist/agents/clawdbot-tools.js +30 -0
  9. package/dist/agents/clawdis-tools.js +27 -0
  10. package/dist/agents/context.js +34 -0
  11. package/dist/agents/defaults.js +6 -0
  12. package/dist/agents/model-auth.js +112 -0
  13. package/dist/agents/model-catalog.js +55 -0
  14. package/dist/agents/model-fallback.js +191 -0
  15. package/dist/agents/model-scan.js +263 -0
  16. package/dist/agents/model-selection.js +116 -0
  17. package/dist/agents/models-config.js +49 -0
  18. package/dist/agents/pi-embedded-helpers.js +74 -0
  19. package/dist/agents/pi-embedded-runner.js +407 -0
  20. package/dist/agents/pi-embedded-subscribe.js +568 -0
  21. package/dist/agents/pi-embedded-utils.js +20 -0
  22. package/dist/agents/pi-embedded.js +1 -0
  23. package/dist/agents/pi-oauth.js +88 -0
  24. package/dist/agents/pi-tools.js +433 -0
  25. package/dist/agents/sandbox-paths.js +68 -0
  26. package/dist/agents/sandbox.js +644 -0
  27. package/dist/agents/shell-utils.js +53 -0
  28. package/dist/agents/skills-install.js +244 -0
  29. package/dist/agents/skills-status.js +157 -0
  30. package/dist/agents/skills.js +470 -0
  31. package/dist/agents/steerable-agent-loop.js +338 -0
  32. package/dist/agents/steerable-provider-transport.js +48 -0
  33. package/dist/agents/system-prompt.js +104 -0
  34. package/dist/agents/tool-display.js +162 -0
  35. package/dist/agents/tool-images.js +138 -0
  36. package/dist/agents/tools/browser-tool.js +339 -0
  37. package/dist/agents/tools/canvas-tool.js +193 -0
  38. package/dist/agents/tools/common.js +88 -0
  39. package/dist/agents/tools/cron-tool.js +124 -0
  40. package/dist/agents/tools/discord-actions-guild.js +186 -0
  41. package/dist/agents/tools/discord-actions-messaging.js +285 -0
  42. package/dist/agents/tools/discord-actions-moderation.js +70 -0
  43. package/dist/agents/tools/discord-actions.js +56 -0
  44. package/dist/agents/tools/discord-schema.js +199 -0
  45. package/dist/agents/tools/discord-tool.js +16 -0
  46. package/dist/agents/tools/gateway-tool.js +46 -0
  47. package/dist/agents/tools/gateway.js +27 -0
  48. package/dist/agents/tools/image-tool.js +132 -0
  49. package/dist/agents/tools/nodes-tool.js +413 -0
  50. package/dist/agents/tools/nodes-utils.js +92 -0
  51. package/dist/agents/tools/sessions-helpers.js +88 -0
  52. package/dist/agents/tools/sessions-history-tool.js +53 -0
  53. package/dist/agents/tools/sessions-list-tool.js +143 -0
  54. package/dist/agents/tools/sessions-send-helpers.js +100 -0
  55. package/dist/agents/tools/sessions-send-tool.js +347 -0
  56. package/dist/agents/tools/slack-actions.js +129 -0
  57. package/dist/agents/tools/slack-schema.js +59 -0
  58. package/dist/agents/tools/slack-tool.js +16 -0
  59. package/dist/agents/usage.js +39 -0
  60. package/dist/agents/workspace.js +241 -0
  61. package/dist/auto-reply/chunk.js +76 -0
  62. package/dist/auto-reply/envelope.js +38 -0
  63. package/dist/auto-reply/group-activation.js +20 -0
  64. package/dist/auto-reply/heartbeat.js +57 -0
  65. package/dist/auto-reply/model.js +14 -0
  66. package/dist/auto-reply/reply/abort.js +14 -0
  67. package/dist/auto-reply/reply/agent-runner.js +371 -0
  68. package/dist/auto-reply/reply/block-streaming.js +34 -0
  69. package/dist/auto-reply/reply/body.js +29 -0
  70. package/dist/auto-reply/reply/commands.js +207 -0
  71. package/dist/auto-reply/reply/directive-handling.js +361 -0
  72. package/dist/auto-reply/reply/directives.js +47 -0
  73. package/dist/auto-reply/reply/followup-runner.js +149 -0
  74. package/dist/auto-reply/reply/groups.js +91 -0
  75. package/dist/auto-reply/reply/mentions.js +38 -0
  76. package/dist/auto-reply/reply/model-selection.js +114 -0
  77. package/dist/auto-reply/reply/queue.js +399 -0
  78. package/dist/auto-reply/reply/reply-tags.js +26 -0
  79. package/dist/auto-reply/reply/session-updates.js +87 -0
  80. package/dist/auto-reply/reply/session.js +160 -0
  81. package/dist/auto-reply/reply/typing.js +75 -0
  82. package/dist/auto-reply/reply.js +535 -0
  83. package/dist/auto-reply/send-policy.js +28 -0
  84. package/dist/auto-reply/status.js +158 -0
  85. package/dist/auto-reply/templating.js +9 -0
  86. package/dist/auto-reply/thinking.js +49 -0
  87. package/dist/auto-reply/tokens.js +2 -0
  88. package/dist/auto-reply/tool-meta.js +74 -0
  89. package/dist/auto-reply/transcription.js +57 -0
  90. package/dist/auto-reply/types.js +1 -0
  91. package/dist/browser/bridge-server.js +37 -0
  92. package/dist/browser/cdp.js +382 -0
  93. package/dist/browser/chrome.js +432 -0
  94. package/dist/browser/client-actions-core.js +67 -0
  95. package/dist/browser/client-actions-observe.js +24 -0
  96. package/dist/browser/client-actions-types.js +1 -0
  97. package/dist/browser/client-actions.js +3 -0
  98. package/dist/browser/client-fetch.js +43 -0
  99. package/dist/browser/client.js +105 -0
  100. package/dist/browser/config.js +140 -0
  101. package/dist/browser/constants.js +4 -0
  102. package/dist/browser/profiles-service.js +122 -0
  103. package/dist/browser/profiles.js +85 -0
  104. package/dist/browser/pw-ai.js +2 -0
  105. package/dist/browser/pw-session.js +144 -0
  106. package/dist/browser/pw-tools-core.js +363 -0
  107. package/dist/browser/routes/agent.js +535 -0
  108. package/dist/browser/routes/basic.js +155 -0
  109. package/dist/browser/routes/index.js +8 -0
  110. package/dist/browser/routes/tabs.js +105 -0
  111. package/dist/browser/routes/utils.js +62 -0
  112. package/dist/browser/screenshot.js +40 -0
  113. package/dist/browser/server-context.js +377 -0
  114. package/dist/browser/server.js +81 -0
  115. package/dist/browser/target-id.js +18 -0
  116. package/dist/browser/trash.js +21 -0
  117. package/dist/canvas-host/a2ui/.bundle.hash +1 -0
  118. package/dist/canvas-host/a2ui/a2ui.bundle.js +17768 -0
  119. package/dist/canvas-host/a2ui/index.html +246 -0
  120. package/dist/canvas-host/a2ui.js +187 -0
  121. package/dist/canvas-host/server.js +382 -0
  122. package/dist/cli/browser-cli-actions-input.js +459 -0
  123. package/dist/cli/browser-cli-actions-observe.js +56 -0
  124. package/dist/cli/browser-cli-examples.js +31 -0
  125. package/dist/cli/browser-cli-inspect.js +97 -0
  126. package/dist/cli/browser-cli-manage.js +286 -0
  127. package/dist/cli/browser-cli-shared.js +1 -0
  128. package/dist/cli/browser-cli.js +26 -0
  129. package/dist/cli/canvas-cli.js +416 -0
  130. package/dist/cli/cron-cli.js +454 -0
  131. package/dist/cli/deps.js +17 -0
  132. package/dist/cli/dns-cli.js +180 -0
  133. package/dist/cli/gateway-cli.js +489 -0
  134. package/dist/cli/gateway-rpc.js +20 -0
  135. package/dist/cli/hooks-cli.js +135 -0
  136. package/dist/cli/models-cli.js +248 -0
  137. package/dist/cli/nodes-camera.js +57 -0
  138. package/dist/cli/nodes-canvas.js +26 -0
  139. package/dist/cli/nodes-cli.js +946 -0
  140. package/dist/cli/nodes-screen.js +37 -0
  141. package/dist/cli/parse-duration.js +20 -0
  142. package/dist/cli/ports.js +97 -0
  143. package/dist/cli/program.js +406 -0
  144. package/dist/cli/prompt.js +19 -0
  145. package/dist/cli/tui-cli.js +35 -0
  146. package/dist/cli/wait.js +8 -0
  147. package/dist/commands/agent.js +645 -0
  148. package/dist/commands/antigravity-oauth.js +327 -0
  149. package/dist/commands/configure.js +480 -0
  150. package/dist/commands/doctor.js +484 -0
  151. package/dist/commands/health.js +108 -0
  152. package/dist/commands/models/aliases.js +64 -0
  153. package/dist/commands/models/fallbacks.js +99 -0
  154. package/dist/commands/models/image-fallbacks.js +99 -0
  155. package/dist/commands/models/list.js +323 -0
  156. package/dist/commands/models/scan.js +266 -0
  157. package/dist/commands/models/set-image.js +23 -0
  158. package/dist/commands/models/set.js +23 -0
  159. package/dist/commands/models/shared.js +72 -0
  160. package/dist/commands/models.js +7 -0
  161. package/dist/commands/onboard-auth.js +70 -0
  162. package/dist/commands/onboard-helpers.js +295 -0
  163. package/dist/commands/onboard-interactive.js +17 -0
  164. package/dist/commands/onboard-non-interactive.js +202 -0
  165. package/dist/commands/onboard-providers.js +634 -0
  166. package/dist/commands/onboard-remote.js +120 -0
  167. package/dist/commands/onboard-skills.js +148 -0
  168. package/dist/commands/onboard-types.js +1 -0
  169. package/dist/commands/onboard.js +12 -0
  170. package/dist/commands/send.js +124 -0
  171. package/dist/commands/sessions.js +212 -0
  172. package/dist/commands/setup.js +58 -0
  173. package/dist/commands/signal-install.js +135 -0
  174. package/dist/commands/status.js +207 -0
  175. package/dist/commands/update.js +16 -0
  176. package/dist/config/config.js +6 -0
  177. package/dist/config/defaults.js +61 -0
  178. package/dist/config/io.js +147 -0
  179. package/dist/config/legacy-migrate.js +13 -0
  180. package/dist/config/legacy.js +159 -0
  181. package/dist/config/paths.js +71 -0
  182. package/dist/config/schema.js +150 -0
  183. package/dist/config/sessions.js +282 -0
  184. package/dist/config/talk.js +31 -0
  185. package/dist/config/types.js +1 -0
  186. package/dist/config/validation.js +29 -0
  187. package/dist/config/zod-schema.js +831 -0
  188. package/dist/control-ui/assets/index-BFID3yAA.css +1 -0
  189. package/dist/control-ui/assets/index-CE_axlTS.js +2235 -0
  190. package/dist/control-ui/assets/index-CE_axlTS.js.map +1 -0
  191. package/dist/control-ui/index.html +15 -0
  192. package/dist/cron/isolated-agent.js +499 -0
  193. package/dist/cron/run-log.js +72 -0
  194. package/dist/cron/schedule.js +24 -0
  195. package/dist/cron/service.js +471 -0
  196. package/dist/cron/store.js +43 -0
  197. package/dist/cron/types.js +1 -0
  198. package/dist/daemon/constants.js +10 -0
  199. package/dist/daemon/launchd.js +276 -0
  200. package/dist/daemon/legacy.js +63 -0
  201. package/dist/daemon/program-args.js +76 -0
  202. package/dist/daemon/schtasks.js +257 -0
  203. package/dist/daemon/service.js +60 -0
  204. package/dist/daemon/systemd.js +266 -0
  205. package/dist/discord/index.js +2 -0
  206. package/dist/discord/monitor.js +1188 -0
  207. package/dist/discord/probe.js +54 -0
  208. package/dist/discord/send.js +577 -0
  209. package/dist/discord/token.js +8 -0
  210. package/dist/gateway/auth.js +121 -0
  211. package/dist/gateway/call.js +94 -0
  212. package/dist/gateway/chat-attachments.js +41 -0
  213. package/dist/gateway/client.js +180 -0
  214. package/dist/gateway/config-reload.js +274 -0
  215. package/dist/gateway/control-ui.js +184 -0
  216. package/dist/gateway/hooks-mapping.js +282 -0
  217. package/dist/gateway/hooks.js +168 -0
  218. package/dist/gateway/net.js +29 -0
  219. package/dist/gateway/protocol/index.js +61 -0
  220. package/dist/gateway/protocol/schema.js +560 -0
  221. package/dist/gateway/server-bridge-subscriptions.js +93 -0
  222. package/dist/gateway/server-bridge.js +1013 -0
  223. package/dist/gateway/server-browser.js +12 -0
  224. package/dist/gateway/server-chat.js +159 -0
  225. package/dist/gateway/server-constants.js +8 -0
  226. package/dist/gateway/server-discovery.js +62 -0
  227. package/dist/gateway/server-http.js +165 -0
  228. package/dist/gateway/server-methods/agent-job.js +125 -0
  229. package/dist/gateway/server-methods/agent.js +250 -0
  230. package/dist/gateway/server-methods/chat.js +200 -0
  231. package/dist/gateway/server-methods/config.js +50 -0
  232. package/dist/gateway/server-methods/connect.js +6 -0
  233. package/dist/gateway/server-methods/cron.js +83 -0
  234. package/dist/gateway/server-methods/health.js +28 -0
  235. package/dist/gateway/server-methods/models.js +16 -0
  236. package/dist/gateway/server-methods/nodes.js +294 -0
  237. package/dist/gateway/server-methods/providers.js +217 -0
  238. package/dist/gateway/server-methods/send.js +166 -0
  239. package/dist/gateway/server-methods/sessions.js +305 -0
  240. package/dist/gateway/server-methods/skills.js +83 -0
  241. package/dist/gateway/server-methods/system.js +118 -0
  242. package/dist/gateway/server-methods/talk.js +22 -0
  243. package/dist/gateway/server-methods/types.js +1 -0
  244. package/dist/gateway/server-methods/voicewake.js +30 -0
  245. package/dist/gateway/server-methods/web.js +58 -0
  246. package/dist/gateway/server-methods/wizard.js +100 -0
  247. package/dist/gateway/server-methods.js +53 -0
  248. package/dist/gateway/server-providers.js +644 -0
  249. package/dist/gateway/server-shared.js +1 -0
  250. package/dist/gateway/server-utils.js +35 -0
  251. package/dist/gateway/server.js +1437 -0
  252. package/dist/gateway/session-utils.js +216 -0
  253. package/dist/gateway/ws-log.js +349 -0
  254. package/dist/gateway/ws-logging.js +8 -0
  255. package/dist/globals.js +41 -0
  256. package/dist/hooks/gmail-ops.js +236 -0
  257. package/dist/hooks/gmail-setup-utils.js +278 -0
  258. package/dist/hooks/gmail-watcher.js +175 -0
  259. package/dist/hooks/gmail.js +177 -0
  260. package/dist/imessage/client.js +165 -0
  261. package/dist/imessage/index.js +3 -0
  262. package/dist/imessage/monitor.js +272 -0
  263. package/dist/imessage/probe.js +26 -0
  264. package/dist/imessage/send.js +83 -0
  265. package/dist/imessage/targets.js +176 -0
  266. package/dist/index.js +50 -0
  267. package/dist/infra/agent-events.js +46 -0
  268. package/dist/infra/binaries.js +9 -0
  269. package/dist/infra/bonjour-discovery.js +163 -0
  270. package/dist/infra/bonjour.js +200 -0
  271. package/dist/infra/bridge/server.js +562 -0
  272. package/dist/infra/canvas-host-url.js +54 -0
  273. package/dist/infra/env.js +8 -0
  274. package/dist/infra/errors.js +28 -0
  275. package/dist/infra/gateway-lock.js +8 -0
  276. package/dist/infra/heartbeat-events.js +21 -0
  277. package/dist/infra/heartbeat-runner.js +453 -0
  278. package/dist/infra/heartbeat-wake.js +61 -0
  279. package/dist/infra/is-main.js +37 -0
  280. package/dist/infra/machine-name.js +40 -0
  281. package/dist/infra/node-pairing.js +211 -0
  282. package/dist/infra/pam.js +42 -0
  283. package/dist/infra/path-env.js +92 -0
  284. package/dist/infra/ports.js +87 -0
  285. package/dist/infra/provider-summary.js +80 -0
  286. package/dist/infra/restart.js +29 -0
  287. package/dist/infra/retry.js +16 -0
  288. package/dist/infra/runtime-guard.js +59 -0
  289. package/dist/infra/system-events.js +44 -0
  290. package/dist/infra/system-presence.js +216 -0
  291. package/dist/infra/tailnet.js +46 -0
  292. package/dist/infra/tailscale.js +149 -0
  293. package/dist/infra/voicewake.js +77 -0
  294. package/dist/infra/widearea-dns.js +123 -0
  295. package/dist/infra/ws.js +13 -0
  296. package/dist/logger.js +52 -0
  297. package/dist/logging.js +490 -0
  298. package/dist/macos/gateway-daemon.js +141 -0
  299. package/dist/macos/relay.js +46 -0
  300. package/dist/media/constants.js +33 -0
  301. package/dist/media/host.js +42 -0
  302. package/dist/media/image-ops.js +121 -0
  303. package/dist/media/mime.js +115 -0
  304. package/dist/media/parse.js +81 -0
  305. package/dist/media/server.js +64 -0
  306. package/dist/media/store.js +139 -0
  307. package/dist/process/command-queue.js +97 -0
  308. package/dist/process/exec.js +75 -0
  309. package/dist/protocol.schema.json +2918 -0
  310. package/dist/provider-web.js +8 -0
  311. package/dist/providers/web/index.js +2 -0
  312. package/dist/runtime.js +8 -0
  313. package/dist/sessions/send-policy.js +68 -0
  314. package/dist/signal/client.js +134 -0
  315. package/dist/signal/daemon.js +69 -0
  316. package/dist/signal/index.js +3 -0
  317. package/dist/signal/monitor.js +336 -0
  318. package/dist/signal/probe.js +46 -0
  319. package/dist/signal/send.js +91 -0
  320. package/dist/slack/actions.js +97 -0
  321. package/dist/slack/index.js +5 -0
  322. package/dist/slack/monitor.js +1029 -0
  323. package/dist/slack/probe.js +47 -0
  324. package/dist/slack/send.js +131 -0
  325. package/dist/slack/token.js +10 -0
  326. package/dist/telegram/bot.js +394 -0
  327. package/dist/telegram/download.js +34 -0
  328. package/dist/telegram/index.js +4 -0
  329. package/dist/telegram/monitor.js +47 -0
  330. package/dist/telegram/probe.js +63 -0
  331. package/dist/telegram/proxy.js +9 -0
  332. package/dist/telegram/send.js +138 -0
  333. package/dist/telegram/token.js +30 -0
  334. package/dist/telegram/webhook-set.js +12 -0
  335. package/dist/telegram/webhook.js +56 -0
  336. package/dist/tui/commands.js +74 -0
  337. package/dist/tui/components/assistant-message.js +16 -0
  338. package/dist/tui/components/chat-log.js +92 -0
  339. package/dist/tui/components/custom-editor.js +53 -0
  340. package/dist/tui/components/selectors.js +8 -0
  341. package/dist/tui/components/tool-execution.js +111 -0
  342. package/dist/tui/components/user-message.js +17 -0
  343. package/dist/tui/gateway-chat.js +140 -0
  344. package/dist/tui/layout.js +41 -0
  345. package/dist/tui/message-list.js +57 -0
  346. package/dist/tui/theme/theme.js +80 -0
  347. package/dist/tui/theme.js +25 -0
  348. package/dist/tui/tui.js +708 -0
  349. package/dist/utils.js +133 -0
  350. package/dist/version.js +18 -0
  351. package/dist/web/active-listener.js +7 -0
  352. package/dist/web/auto-reply.js +1203 -0
  353. package/dist/web/inbound.js +481 -0
  354. package/dist/web/login-qr.js +204 -0
  355. package/dist/web/login.js +59 -0
  356. package/dist/web/media.js +148 -0
  357. package/dist/web/outbound.js +67 -0
  358. package/dist/web/qr-image.js +97 -0
  359. package/dist/web/reconnect.js +60 -0
  360. package/dist/web/reply-heartbeat-wake.js +61 -0
  361. package/dist/web/session.js +346 -0
  362. package/dist/wizard/clack-prompter.js +56 -0
  363. package/dist/wizard/onboarding.js +452 -0
  364. package/dist/wizard/prompts.js +6 -0
  365. package/dist/wizard/session.js +203 -0
  366. package/docs/AGENTS.default.md +116 -0
  367. package/docs/CNAME +1 -0
  368. package/docs/RELEASING.md +64 -0
  369. package/docs/_config.yml +51 -0
  370. package/docs/_layouts/default.html +145 -0
  371. package/docs/agent-send.md +21 -0
  372. package/docs/agent.md +104 -0
  373. package/docs/android/connect.md +131 -0
  374. package/docs/architecture.md +89 -0
  375. package/docs/assets/markdown.css +130 -0
  376. package/docs/assets/pixel-lobster.svg +60 -0
  377. package/docs/assets/terminal.css +497 -0
  378. package/docs/assets/theme.js +55 -0
  379. package/docs/audio.md +50 -0
  380. package/docs/background-process.md +74 -0
  381. package/docs/bash.md +32 -0
  382. package/docs/bonjour.md +159 -0
  383. package/docs/browser.md +289 -0
  384. package/docs/camera.md +152 -0
  385. package/docs/clawd.md +199 -0
  386. package/docs/clawdbot-mac.md +104 -0
  387. package/docs/configuration.md +1177 -0
  388. package/docs/control-api.md +49 -0
  389. package/docs/control-ui.md +83 -0
  390. package/docs/cron.md +374 -0
  391. package/docs/dashboard.md +17 -0
  392. package/docs/device-models.md +46 -0
  393. package/docs/discord.md +293 -0
  394. package/docs/discovery.md +112 -0
  395. package/docs/docker.md +251 -0
  396. package/docs/docs.json +86 -0
  397. package/docs/doctor.md +47 -0
  398. package/docs/elevated.md +31 -0
  399. package/docs/faq.md +640 -0
  400. package/docs/gateway/pairing.md +109 -0
  401. package/docs/gateway-lock.md +28 -0
  402. package/docs/gateway.md +174 -0
  403. package/docs/gmail-pubsub.md +191 -0
  404. package/docs/grammy.md +27 -0
  405. package/docs/group-messages.md +71 -0
  406. package/docs/groups.md +78 -0
  407. package/docs/health.md +28 -0
  408. package/docs/heartbeat.md +64 -0
  409. package/docs/images.md +52 -0
  410. package/docs/imessage.md +63 -0
  411. package/docs/index.md +182 -0
  412. package/docs/ios/connect.md +177 -0
  413. package/docs/ios/spec.md +236 -0
  414. package/docs/location-command.md +95 -0
  415. package/docs/logging.md +99 -0
  416. package/docs/lore.md +131 -0
  417. package/docs/mac/bun.md +133 -0
  418. package/docs/mac/canvas.md +161 -0
  419. package/docs/mac/child-process.md +72 -0
  420. package/docs/mac/dev-setup.md +81 -0
  421. package/docs/mac/health.md +28 -0
  422. package/docs/mac/icon.md +26 -0
  423. package/docs/mac/logging.md +51 -0
  424. package/docs/mac/menu-bar.md +69 -0
  425. package/docs/mac/peekaboo.md +170 -0
  426. package/docs/mac/permissions.md +40 -0
  427. package/docs/mac/release.md +76 -0
  428. package/docs/mac/remote.md +57 -0
  429. package/docs/mac/signing.md +41 -0
  430. package/docs/mac/skills.md +27 -0
  431. package/docs/mac/voice-overlay.md +52 -0
  432. package/docs/mac/voicewake.md +56 -0
  433. package/docs/mac/webchat.md +27 -0
  434. package/docs/mac/xpc.md +40 -0
  435. package/docs/models.md +90 -0
  436. package/docs/nix.md +49 -0
  437. package/docs/nodes.md +157 -0
  438. package/docs/onboarding-config-protocol.md +29 -0
  439. package/docs/onboarding.md +185 -0
  440. package/docs/presence.md +133 -0
  441. package/docs/queue.md +78 -0
  442. package/docs/refactor/browser-control-simplification.md +58 -0
  443. package/docs/refactor/canvas-a2ui.md +93 -0
  444. package/docs/refactor/cli-unification.md +64 -0
  445. package/docs/refactor/gateway-client.md +31 -0
  446. package/docs/refactor/gateway.md +99 -0
  447. package/docs/refactor/new-arch.md +171 -0
  448. package/docs/refactor/tui.md +26 -0
  449. package/docs/refactor/web-gateway-troubleshooting.md +37 -0
  450. package/docs/refactor/webagent-session.md +46 -0
  451. package/docs/remote-gateway-readme.md +148 -0
  452. package/docs/remote.md +66 -0
  453. package/docs/research/memory.md +227 -0
  454. package/docs/rpc.md +35 -0
  455. package/docs/security.md +168 -0
  456. package/docs/session-tool.md +119 -0
  457. package/docs/session.md +84 -0
  458. package/docs/sessions.md +8 -0
  459. package/docs/setup.md +118 -0
  460. package/docs/signal.md +113 -0
  461. package/docs/skills-config.md +58 -0
  462. package/docs/skills.md +149 -0
  463. package/docs/slack.md +158 -0
  464. package/docs/surface.md +20 -0
  465. package/docs/tailscale.md +71 -0
  466. package/docs/talk.md +79 -0
  467. package/docs/telegram.md +90 -0
  468. package/docs/templates/AGENTS.md +126 -0
  469. package/docs/templates/BOOTSTRAP.md +53 -0
  470. package/docs/templates/IDENTITY.md +17 -0
  471. package/docs/templates/SOUL.md +41 -0
  472. package/docs/templates/TOOLS.md +41 -0
  473. package/docs/templates/USER.md +22 -0
  474. package/docs/test.md +35 -0
  475. package/docs/thinking.md +46 -0
  476. package/docs/tools.md +248 -0
  477. package/docs/troubleshooting.md +227 -0
  478. package/docs/tui.md +69 -0
  479. package/docs/typebox.md +42 -0
  480. package/docs/voicewake.md +61 -0
  481. package/docs/web.md +115 -0
  482. package/docs/webchat.md +34 -0
  483. package/docs/webhook.md +132 -0
  484. package/docs/whatsapp-clawd.jpg +0 -0
  485. package/docs/whatsapp.md +142 -0
  486. package/docs/wizard.md +158 -0
  487. package/package.json +186 -0
  488. package/skills/apple-notes/SKILL.md +50 -0
  489. package/skills/apple-reminders/SKILL.md +67 -0
  490. package/skills/bear-notes/SKILL.md +79 -0
  491. package/skills/bird/SKILL.md +25 -0
  492. package/skills/blogwatcher/SKILL.md +46 -0
  493. package/skills/blucli/SKILL.md +27 -0
  494. package/skills/brave-search/SKILL.md +30 -0
  495. package/skills/brave-search/scripts/content.mjs +53 -0
  496. package/skills/brave-search/scripts/search.mjs +79 -0
  497. package/skills/camsnap/SKILL.md +25 -0
  498. package/skills/clawdhub/SKILL.md +53 -0
  499. package/skills/coding-agent/SKILL.md +275 -0
  500. package/skills/discord/SKILL.md +369 -0
  501. package/skills/eightctl/SKILL.md +29 -0
  502. package/skills/food-order/SKILL.md +41 -0
  503. package/skills/gemini/SKILL.md +23 -0
  504. package/skills/gifgrep/SKILL.md +47 -0
  505. package/skills/github/SKILL.md +47 -0
  506. package/skills/gog/SKILL.md +36 -0
  507. package/skills/goplaces/SKILL.md +30 -0
  508. package/skills/imsg/SKILL.md +25 -0
  509. package/skills/local-places/SERVER_README.md +101 -0
  510. package/skills/local-places/SKILL.md +91 -0
  511. package/skills/local-places/pyproject.toml +27 -0
  512. package/skills/local-places/src/local_places/__init__.py +2 -0
  513. package/skills/local-places/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
  514. package/skills/local-places/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
  515. package/skills/local-places/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
  516. package/skills/local-places/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
  517. package/skills/local-places/src/local_places/google_places.py +314 -0
  518. package/skills/local-places/src/local_places/main.py +65 -0
  519. package/skills/local-places/src/local_places/schemas.py +107 -0
  520. package/skills/mcporter/SKILL.md +38 -0
  521. package/skills/nano-banana-pro/SKILL.md +29 -0
  522. package/skills/nano-banana-pro/scripts/generate_image.py +167 -0
  523. package/skills/nano-pdf/SKILL.md +20 -0
  524. package/skills/notion/SKILL.md +156 -0
  525. package/skills/obsidian/SKILL.md +55 -0
  526. package/skills/openai-image-gen/SKILL.md +31 -0
  527. package/skills/openai-image-gen/scripts/gen.py +173 -0
  528. package/skills/openai-whisper/SKILL.md +19 -0
  529. package/skills/openai-whisper-api/SKILL.md +43 -0
  530. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  531. package/skills/openhue/SKILL.md +30 -0
  532. package/skills/oracle/SKILL.md +105 -0
  533. package/skills/ordercli/SKILL.md +47 -0
  534. package/skills/peekaboo/SKILL.md +153 -0
  535. package/skills/qmd/SKILL.md +26 -0
  536. package/skills/sag/SKILL.md +62 -0
  537. package/skills/slack/SKILL.md +143 -0
  538. package/skills/songsee/SKILL.md +29 -0
  539. package/skills/sonoscli/SKILL.md +26 -0
  540. package/skills/spotify-player/SKILL.md +34 -0
  541. package/skills/summarize/SKILL.md +49 -0
  542. package/skills/things-mac/SKILL.md +61 -0
  543. package/skills/tmux/SKILL.md +121 -0
  544. package/skills/tmux/scripts/find-sessions.sh +112 -0
  545. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  546. package/skills/trello/SKILL.md +84 -0
  547. package/skills/video-frames/SKILL.md +29 -0
  548. package/skills/video-frames/scripts/frame.sh +81 -0
  549. package/skills/wacli/SKILL.md +42 -0
  550. package/skills/weather/SKILL.md +49 -0
@@ -0,0 +1,143 @@
1
+ import path from "node:path";
2
+ import { Type } from "@sinclair/typebox";
3
+ import { loadConfig } from "../../config/config.js";
4
+ import { callGateway } from "../../gateway/call.js";
5
+ import { jsonResult, readStringArrayParam } from "./common.js";
6
+ import { classifySessionKind, deriveProvider, resolveDisplaySessionKey, resolveInternalSessionKey, resolveMainSessionAlias, stripToolMessages, } from "./sessions-helpers.js";
7
+ const SessionsListToolSchema = Type.Object({
8
+ kinds: Type.Optional(Type.Array(Type.String())),
9
+ limit: Type.Optional(Type.Integer({ minimum: 1 })),
10
+ activeMinutes: Type.Optional(Type.Integer({ minimum: 1 })),
11
+ messageLimit: Type.Optional(Type.Integer({ minimum: 0 })),
12
+ });
13
+ export function createSessionsListTool() {
14
+ return {
15
+ label: "Sessions",
16
+ name: "sessions_list",
17
+ description: "List sessions with optional filters and last messages.",
18
+ parameters: SessionsListToolSchema,
19
+ execute: async (_toolCallId, args) => {
20
+ const params = args;
21
+ const cfg = loadConfig();
22
+ const { mainKey, alias } = resolveMainSessionAlias(cfg);
23
+ const kindsRaw = readStringArrayParam(params, "kinds")?.map((value) => value.trim().toLowerCase());
24
+ const allowedKindsList = (kindsRaw ?? []).filter((value) => ["main", "group", "cron", "hook", "node", "other"].includes(value));
25
+ const allowedKinds = allowedKindsList.length
26
+ ? new Set(allowedKindsList)
27
+ : undefined;
28
+ const limit = typeof params.limit === "number" && Number.isFinite(params.limit)
29
+ ? Math.max(1, Math.floor(params.limit))
30
+ : undefined;
31
+ const activeMinutes = typeof params.activeMinutes === "number" &&
32
+ Number.isFinite(params.activeMinutes)
33
+ ? Math.max(1, Math.floor(params.activeMinutes))
34
+ : undefined;
35
+ const messageLimitRaw = typeof params.messageLimit === "number" &&
36
+ Number.isFinite(params.messageLimit)
37
+ ? Math.max(0, Math.floor(params.messageLimit))
38
+ : 0;
39
+ const messageLimit = Math.min(messageLimitRaw, 20);
40
+ const list = (await callGateway({
41
+ method: "sessions.list",
42
+ params: {
43
+ limit,
44
+ activeMinutes,
45
+ includeGlobal: true,
46
+ includeUnknown: true,
47
+ },
48
+ }));
49
+ const sessions = Array.isArray(list?.sessions) ? list.sessions : [];
50
+ const storePath = typeof list?.path === "string" ? list.path : undefined;
51
+ const rows = [];
52
+ for (const entry of sessions) {
53
+ if (!entry || typeof entry !== "object")
54
+ continue;
55
+ const key = typeof entry.key === "string" ? entry.key : "";
56
+ if (!key)
57
+ continue;
58
+ if (key === "unknown")
59
+ continue;
60
+ if (key === "global" && alias !== "global")
61
+ continue;
62
+ const gatewayKind = typeof entry.kind === "string" ? entry.kind : undefined;
63
+ const kind = classifySessionKind({ key, gatewayKind, alias, mainKey });
64
+ if (allowedKinds && !allowedKinds.has(kind))
65
+ continue;
66
+ const displayKey = resolveDisplaySessionKey({
67
+ key,
68
+ alias,
69
+ mainKey,
70
+ });
71
+ const surface = typeof entry.surface === "string" ? entry.surface : undefined;
72
+ const lastChannel = typeof entry.lastChannel === "string" ? entry.lastChannel : undefined;
73
+ const provider = deriveProvider({
74
+ key,
75
+ kind,
76
+ surface,
77
+ lastChannel,
78
+ });
79
+ const sessionId = typeof entry.sessionId === "string" ? entry.sessionId : undefined;
80
+ const transcriptPath = sessionId && storePath
81
+ ? path.join(path.dirname(storePath), `${sessionId}.jsonl`)
82
+ : undefined;
83
+ const row = {
84
+ key: displayKey,
85
+ kind,
86
+ provider,
87
+ displayName: typeof entry.displayName === "string"
88
+ ? entry.displayName
89
+ : undefined,
90
+ updatedAt: typeof entry.updatedAt === "number" ? entry.updatedAt : undefined,
91
+ sessionId,
92
+ model: typeof entry.model === "string" ? entry.model : undefined,
93
+ contextTokens: typeof entry.contextTokens === "number"
94
+ ? entry.contextTokens
95
+ : undefined,
96
+ totalTokens: typeof entry.totalTokens === "number"
97
+ ? entry.totalTokens
98
+ : undefined,
99
+ thinkingLevel: typeof entry.thinkingLevel === "string"
100
+ ? entry.thinkingLevel
101
+ : undefined,
102
+ verboseLevel: typeof entry.verboseLevel === "string"
103
+ ? entry.verboseLevel
104
+ : undefined,
105
+ systemSent: typeof entry.systemSent === "boolean"
106
+ ? entry.systemSent
107
+ : undefined,
108
+ abortedLastRun: typeof entry.abortedLastRun === "boolean"
109
+ ? entry.abortedLastRun
110
+ : undefined,
111
+ sendPolicy: typeof entry.sendPolicy === "string" ? entry.sendPolicy : undefined,
112
+ lastChannel,
113
+ lastTo: typeof entry.lastTo === "string" ? entry.lastTo : undefined,
114
+ transcriptPath,
115
+ };
116
+ if (messageLimit > 0) {
117
+ const resolvedKey = resolveInternalSessionKey({
118
+ key: displayKey,
119
+ alias,
120
+ mainKey,
121
+ });
122
+ const history = (await callGateway({
123
+ method: "chat.history",
124
+ params: { sessionKey: resolvedKey, limit: messageLimit },
125
+ }));
126
+ const rawMessages = Array.isArray(history?.messages)
127
+ ? history.messages
128
+ : [];
129
+ const filtered = stripToolMessages(rawMessages);
130
+ row.messages =
131
+ filtered.length > messageLimit
132
+ ? filtered.slice(-messageLimit)
133
+ : filtered;
134
+ }
135
+ rows.push(row);
136
+ }
137
+ return jsonResult({
138
+ count: rows.length,
139
+ sessions: rows,
140
+ });
141
+ },
142
+ };
143
+ }
@@ -0,0 +1,100 @@
1
+ const ANNOUNCE_SKIP_TOKEN = "ANNOUNCE_SKIP";
2
+ const REPLY_SKIP_TOKEN = "REPLY_SKIP";
3
+ const DEFAULT_PING_PONG_TURNS = 5;
4
+ const MAX_PING_PONG_TURNS = 5;
5
+ export function resolveAnnounceTargetFromKey(sessionKey) {
6
+ const parts = sessionKey.split(":").filter(Boolean);
7
+ if (parts.length < 3)
8
+ return null;
9
+ const [surface, kind, ...rest] = parts;
10
+ if (kind !== "group" && kind !== "channel")
11
+ return null;
12
+ const id = rest.join(":").trim();
13
+ if (!id)
14
+ return null;
15
+ if (!surface)
16
+ return null;
17
+ const channel = surface.toLowerCase();
18
+ if (channel === "discord") {
19
+ return { channel, to: `channel:${id}` };
20
+ }
21
+ if (channel === "signal") {
22
+ return { channel, to: `group:${id}` };
23
+ }
24
+ return { channel, to: id };
25
+ }
26
+ export function buildAgentToAgentMessageContext(params) {
27
+ const lines = [
28
+ "Agent-to-agent message context:",
29
+ params.requesterSessionKey
30
+ ? `Agent 1 (requester) session: ${params.requesterSessionKey}.`
31
+ : undefined,
32
+ params.requesterSurface
33
+ ? `Agent 1 (requester) surface: ${params.requesterSurface}.`
34
+ : undefined,
35
+ `Agent 2 (target) session: ${params.targetSessionKey}.`,
36
+ ].filter(Boolean);
37
+ return lines.join("\n");
38
+ }
39
+ export function buildAgentToAgentReplyContext(params) {
40
+ const currentLabel = params.currentRole === "requester"
41
+ ? "Agent 1 (requester)"
42
+ : "Agent 2 (target)";
43
+ const lines = [
44
+ "Agent-to-agent reply step:",
45
+ `Current agent: ${currentLabel}.`,
46
+ `Turn ${params.turn} of ${params.maxTurns}.`,
47
+ params.requesterSessionKey
48
+ ? `Agent 1 (requester) session: ${params.requesterSessionKey}.`
49
+ : undefined,
50
+ params.requesterSurface
51
+ ? `Agent 1 (requester) surface: ${params.requesterSurface}.`
52
+ : undefined,
53
+ `Agent 2 (target) session: ${params.targetSessionKey}.`,
54
+ params.targetChannel
55
+ ? `Agent 2 (target) surface: ${params.targetChannel}.`
56
+ : undefined,
57
+ `If you want to stop the ping-pong, reply exactly "${REPLY_SKIP_TOKEN}".`,
58
+ ].filter(Boolean);
59
+ return lines.join("\n");
60
+ }
61
+ export function buildAgentToAgentAnnounceContext(params) {
62
+ const lines = [
63
+ "Agent-to-agent announce step:",
64
+ params.requesterSessionKey
65
+ ? `Agent 1 (requester) session: ${params.requesterSessionKey}.`
66
+ : undefined,
67
+ params.requesterSurface
68
+ ? `Agent 1 (requester) surface: ${params.requesterSurface}.`
69
+ : undefined,
70
+ `Agent 2 (target) session: ${params.targetSessionKey}.`,
71
+ params.targetChannel
72
+ ? `Agent 2 (target) surface: ${params.targetChannel}.`
73
+ : undefined,
74
+ `Original request: ${params.originalMessage}`,
75
+ params.roundOneReply
76
+ ? `Round 1 reply: ${params.roundOneReply}`
77
+ : "Round 1 reply: (not available).",
78
+ params.latestReply
79
+ ? `Latest reply: ${params.latestReply}`
80
+ : "Latest reply: (not available).",
81
+ `If you want to remain silent, reply exactly "${ANNOUNCE_SKIP_TOKEN}".`,
82
+ "Any other reply will be posted to the target channel.",
83
+ "After this reply, the agent-to-agent conversation is over.",
84
+ ].filter(Boolean);
85
+ return lines.join("\n");
86
+ }
87
+ export function isAnnounceSkip(text) {
88
+ return (text ?? "").trim() === ANNOUNCE_SKIP_TOKEN;
89
+ }
90
+ export function isReplySkip(text) {
91
+ return (text ?? "").trim() === REPLY_SKIP_TOKEN;
92
+ }
93
+ export function resolvePingPongTurns(cfg) {
94
+ const raw = cfg?.session?.agentToAgent?.maxPingPongTurns;
95
+ const fallback = DEFAULT_PING_PONG_TURNS;
96
+ if (typeof raw !== "number" || !Number.isFinite(raw))
97
+ return fallback;
98
+ const rounded = Math.floor(raw);
99
+ return Math.max(0, Math.min(MAX_PING_PONG_TURNS, rounded));
100
+ }
@@ -0,0 +1,347 @@
1
+ import crypto from "node:crypto";
2
+ import { Type } from "@sinclair/typebox";
3
+ import { loadConfig } from "../../config/config.js";
4
+ import { callGateway } from "../../gateway/call.js";
5
+ import { jsonResult, readStringParam } from "./common.js";
6
+ import { extractAssistantText, resolveDisplaySessionKey, resolveInternalSessionKey, resolveMainSessionAlias, stripToolMessages, } from "./sessions-helpers.js";
7
+ import { buildAgentToAgentAnnounceContext, buildAgentToAgentMessageContext, buildAgentToAgentReplyContext, isAnnounceSkip, isReplySkip, resolveAnnounceTargetFromKey, resolvePingPongTurns, } from "./sessions-send-helpers.js";
8
+ const SessionsSendToolSchema = Type.Object({
9
+ sessionKey: Type.String(),
10
+ message: Type.String(),
11
+ timeoutSeconds: Type.Optional(Type.Integer({ minimum: 0 })),
12
+ });
13
+ export function createSessionsSendTool(opts) {
14
+ return {
15
+ label: "Session Send",
16
+ name: "sessions_send",
17
+ description: "Send a message into another session.",
18
+ parameters: SessionsSendToolSchema,
19
+ execute: async (_toolCallId, args) => {
20
+ const params = args;
21
+ const sessionKey = readStringParam(params, "sessionKey", {
22
+ required: true,
23
+ });
24
+ const message = readStringParam(params, "message", { required: true });
25
+ const cfg = loadConfig();
26
+ const { mainKey, alias } = resolveMainSessionAlias(cfg);
27
+ const resolvedKey = resolveInternalSessionKey({
28
+ key: sessionKey,
29
+ alias,
30
+ mainKey,
31
+ });
32
+ const timeoutSeconds = typeof params.timeoutSeconds === "number" &&
33
+ Number.isFinite(params.timeoutSeconds)
34
+ ? Math.max(0, Math.floor(params.timeoutSeconds))
35
+ : 30;
36
+ const timeoutMs = timeoutSeconds * 1000;
37
+ const announceTimeoutMs = timeoutSeconds === 0 ? 30_000 : timeoutMs;
38
+ const idempotencyKey = crypto.randomUUID();
39
+ let runId = idempotencyKey;
40
+ const displayKey = resolveDisplaySessionKey({
41
+ key: sessionKey,
42
+ alias,
43
+ mainKey,
44
+ });
45
+ const agentMessageContext = buildAgentToAgentMessageContext({
46
+ requesterSessionKey: opts?.agentSessionKey,
47
+ requesterSurface: opts?.agentSurface,
48
+ targetSessionKey: displayKey,
49
+ });
50
+ const sendParams = {
51
+ message,
52
+ sessionKey: resolvedKey,
53
+ idempotencyKey,
54
+ deliver: false,
55
+ lane: "nested",
56
+ extraSystemPrompt: agentMessageContext,
57
+ };
58
+ const requesterSessionKey = opts?.agentSessionKey;
59
+ const requesterSurface = opts?.agentSurface;
60
+ const maxPingPongTurns = resolvePingPongTurns(cfg);
61
+ const resolveAnnounceTarget = async () => {
62
+ const parsed = resolveAnnounceTargetFromKey(resolvedKey);
63
+ if (parsed)
64
+ return parsed;
65
+ try {
66
+ const list = (await callGateway({
67
+ method: "sessions.list",
68
+ params: {
69
+ includeGlobal: true,
70
+ includeUnknown: true,
71
+ limit: 200,
72
+ },
73
+ }));
74
+ const sessions = Array.isArray(list?.sessions) ? list.sessions : [];
75
+ const match = sessions.find((entry) => entry?.key === resolvedKey) ??
76
+ sessions.find((entry) => entry?.key === displayKey);
77
+ const channel = typeof match?.lastChannel === "string"
78
+ ? match.lastChannel
79
+ : undefined;
80
+ const to = typeof match?.lastTo === "string" ? match.lastTo : undefined;
81
+ if (channel && to)
82
+ return { channel, to };
83
+ }
84
+ catch {
85
+ // ignore; fall through to null
86
+ }
87
+ return null;
88
+ };
89
+ const readLatestAssistantReply = async (sessionKeyToRead) => {
90
+ const history = (await callGateway({
91
+ method: "chat.history",
92
+ params: { sessionKey: sessionKeyToRead, limit: 50 },
93
+ }));
94
+ const filtered = stripToolMessages(Array.isArray(history?.messages) ? history.messages : []);
95
+ const last = filtered.length > 0 ? filtered[filtered.length - 1] : undefined;
96
+ return last ? extractAssistantText(last) : undefined;
97
+ };
98
+ const runAgentStep = async (step) => {
99
+ const stepIdem = crypto.randomUUID();
100
+ const response = (await callGateway({
101
+ method: "agent",
102
+ params: {
103
+ message: step.message,
104
+ sessionKey: step.sessionKey,
105
+ idempotencyKey: stepIdem,
106
+ deliver: false,
107
+ lane: "nested",
108
+ extraSystemPrompt: step.extraSystemPrompt,
109
+ },
110
+ timeoutMs: 10_000,
111
+ }));
112
+ const stepRunId = typeof response?.runId === "string" && response.runId
113
+ ? response.runId
114
+ : stepIdem;
115
+ const stepAcceptedAt = typeof response?.acceptedAt === "number"
116
+ ? response.acceptedAt
117
+ : undefined;
118
+ const stepWaitMs = Math.min(step.timeoutMs, 60_000);
119
+ const wait = (await callGateway({
120
+ method: "agent.wait",
121
+ params: {
122
+ runId: stepRunId,
123
+ afterMs: stepAcceptedAt,
124
+ timeoutMs: stepWaitMs,
125
+ },
126
+ timeoutMs: stepWaitMs + 2000,
127
+ }));
128
+ if (wait?.status !== "ok")
129
+ return undefined;
130
+ return readLatestAssistantReply(step.sessionKey);
131
+ };
132
+ const runAgentToAgentFlow = async (roundOneReply, runInfo) => {
133
+ try {
134
+ let primaryReply = roundOneReply;
135
+ let latestReply = roundOneReply;
136
+ if (!primaryReply && runInfo?.runId) {
137
+ const waitMs = Math.min(announceTimeoutMs, 60_000);
138
+ const wait = (await callGateway({
139
+ method: "agent.wait",
140
+ params: {
141
+ runId: runInfo.runId,
142
+ afterMs: runInfo.acceptedAt,
143
+ timeoutMs: waitMs,
144
+ },
145
+ timeoutMs: waitMs + 2000,
146
+ }));
147
+ if (wait?.status === "ok") {
148
+ primaryReply = await readLatestAssistantReply(resolvedKey);
149
+ latestReply = primaryReply;
150
+ }
151
+ }
152
+ if (!latestReply)
153
+ return;
154
+ const announceTarget = await resolveAnnounceTarget();
155
+ const targetChannel = announceTarget?.channel ?? "unknown";
156
+ if (maxPingPongTurns > 0 &&
157
+ requesterSessionKey &&
158
+ requesterSessionKey !== resolvedKey) {
159
+ let currentSessionKey = requesterSessionKey;
160
+ let nextSessionKey = resolvedKey;
161
+ let incomingMessage = latestReply;
162
+ for (let turn = 1; turn <= maxPingPongTurns; turn += 1) {
163
+ const currentRole = currentSessionKey === requesterSessionKey
164
+ ? "requester"
165
+ : "target";
166
+ const replyPrompt = buildAgentToAgentReplyContext({
167
+ requesterSessionKey,
168
+ requesterSurface,
169
+ targetSessionKey: displayKey,
170
+ targetChannel,
171
+ currentRole,
172
+ turn,
173
+ maxTurns: maxPingPongTurns,
174
+ });
175
+ const replyText = await runAgentStep({
176
+ sessionKey: currentSessionKey,
177
+ message: incomingMessage,
178
+ extraSystemPrompt: replyPrompt,
179
+ timeoutMs: announceTimeoutMs,
180
+ });
181
+ if (!replyText || isReplySkip(replyText)) {
182
+ break;
183
+ }
184
+ latestReply = replyText;
185
+ incomingMessage = replyText;
186
+ const swap = currentSessionKey;
187
+ currentSessionKey = nextSessionKey;
188
+ nextSessionKey = swap;
189
+ }
190
+ }
191
+ const announcePrompt = buildAgentToAgentAnnounceContext({
192
+ requesterSessionKey,
193
+ requesterSurface,
194
+ targetSessionKey: displayKey,
195
+ targetChannel,
196
+ originalMessage: message,
197
+ roundOneReply: primaryReply,
198
+ latestReply,
199
+ });
200
+ const announceReply = await runAgentStep({
201
+ sessionKey: resolvedKey,
202
+ message: "Agent-to-agent announce step.",
203
+ extraSystemPrompt: announcePrompt,
204
+ timeoutMs: announceTimeoutMs,
205
+ });
206
+ if (announceTarget &&
207
+ announceReply &&
208
+ announceReply.trim() &&
209
+ !isAnnounceSkip(announceReply)) {
210
+ await callGateway({
211
+ method: "send",
212
+ params: {
213
+ to: announceTarget.to,
214
+ message: announceReply.trim(),
215
+ provider: announceTarget.channel,
216
+ idempotencyKey: crypto.randomUUID(),
217
+ },
218
+ timeoutMs: 10_000,
219
+ });
220
+ }
221
+ }
222
+ catch {
223
+ // Best-effort follow-ups; ignore failures to avoid breaking the caller response.
224
+ }
225
+ };
226
+ if (timeoutSeconds === 0) {
227
+ try {
228
+ const response = (await callGateway({
229
+ method: "agent",
230
+ params: sendParams,
231
+ timeoutMs: 10_000,
232
+ }));
233
+ const acceptedAt = typeof response?.acceptedAt === "number"
234
+ ? response.acceptedAt
235
+ : undefined;
236
+ if (typeof response?.runId === "string" && response.runId) {
237
+ runId = response.runId;
238
+ }
239
+ void runAgentToAgentFlow(undefined, { runId, acceptedAt });
240
+ return jsonResult({
241
+ runId,
242
+ status: "accepted",
243
+ sessionKey: displayKey,
244
+ });
245
+ }
246
+ catch (err) {
247
+ const messageText = err instanceof Error
248
+ ? err.message
249
+ : typeof err === "string"
250
+ ? err
251
+ : "error";
252
+ return jsonResult({
253
+ runId,
254
+ status: "error",
255
+ error: messageText,
256
+ sessionKey: displayKey,
257
+ });
258
+ }
259
+ }
260
+ let acceptedAt;
261
+ try {
262
+ const response = (await callGateway({
263
+ method: "agent",
264
+ params: sendParams,
265
+ timeoutMs: 10_000,
266
+ }));
267
+ if (typeof response?.runId === "string" && response.runId) {
268
+ runId = response.runId;
269
+ }
270
+ if (typeof response?.acceptedAt === "number") {
271
+ acceptedAt = response.acceptedAt;
272
+ }
273
+ }
274
+ catch (err) {
275
+ const messageText = err instanceof Error
276
+ ? err.message
277
+ : typeof err === "string"
278
+ ? err
279
+ : "error";
280
+ return jsonResult({
281
+ runId,
282
+ status: "error",
283
+ error: messageText,
284
+ sessionKey: displayKey,
285
+ });
286
+ }
287
+ let waitStatus;
288
+ let waitError;
289
+ try {
290
+ const wait = (await callGateway({
291
+ method: "agent.wait",
292
+ params: {
293
+ runId,
294
+ afterMs: acceptedAt,
295
+ timeoutMs,
296
+ },
297
+ timeoutMs: timeoutMs + 2000,
298
+ }));
299
+ waitStatus = typeof wait?.status === "string" ? wait.status : undefined;
300
+ waitError = typeof wait?.error === "string" ? wait.error : undefined;
301
+ }
302
+ catch (err) {
303
+ const messageText = err instanceof Error
304
+ ? err.message
305
+ : typeof err === "string"
306
+ ? err
307
+ : "error";
308
+ return jsonResult({
309
+ runId,
310
+ status: messageText.includes("gateway timeout") ? "timeout" : "error",
311
+ error: messageText,
312
+ sessionKey: displayKey,
313
+ });
314
+ }
315
+ if (waitStatus === "timeout") {
316
+ return jsonResult({
317
+ runId,
318
+ status: "timeout",
319
+ error: waitError,
320
+ sessionKey: displayKey,
321
+ });
322
+ }
323
+ if (waitStatus === "error") {
324
+ return jsonResult({
325
+ runId,
326
+ status: "error",
327
+ error: waitError ?? "agent error",
328
+ sessionKey: displayKey,
329
+ });
330
+ }
331
+ const history = (await callGateway({
332
+ method: "chat.history",
333
+ params: { sessionKey: resolvedKey, limit: 50 },
334
+ }));
335
+ const filtered = stripToolMessages(Array.isArray(history?.messages) ? history.messages : []);
336
+ const last = filtered.length > 0 ? filtered[filtered.length - 1] : undefined;
337
+ const reply = last ? extractAssistantText(last) : undefined;
338
+ void runAgentToAgentFlow(reply ?? undefined);
339
+ return jsonResult({
340
+ runId,
341
+ status: "ok",
342
+ reply,
343
+ sessionKey: displayKey,
344
+ });
345
+ },
346
+ };
347
+ }