@swarmclawai/swarmclaw 0.8.4 → 0.8.7

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 (394) hide show
  1. package/README.md +9 -9
  2. package/bin/swarmclaw.js +5 -1
  3. package/bin/worker-cmd.js +73 -0
  4. package/package.json +2 -1
  5. package/src/app/api/agents/[id]/route.ts +17 -7
  6. package/src/app/api/agents/route.ts +21 -8
  7. package/src/app/api/approvals/route.test.ts +6 -6
  8. package/src/app/api/approvals/route.ts +2 -1
  9. package/src/app/api/auth/route.ts +2 -3
  10. package/src/app/api/chatrooms/[id]/chat/route.test.ts +299 -0
  11. package/src/app/api/chatrooms/[id]/chat/route.ts +3 -2
  12. package/src/app/api/chatrooms/[id]/route.ts +7 -6
  13. package/src/app/api/chats/[id]/chat/route.test.ts +496 -0
  14. package/src/app/api/chats/[id]/chat/route.ts +7 -3
  15. package/src/app/api/chats/[id]/clear/route.ts +9 -9
  16. package/src/app/api/chats/[id]/devserver/route.ts +2 -1
  17. package/src/app/api/chats/[id]/edit-resend/route.ts +3 -4
  18. package/src/app/api/chats/[id]/fork/route.ts +3 -5
  19. package/src/app/api/chats/[id]/restore/route.ts +6 -7
  20. package/src/app/api/chats/[id]/retry/route.ts +3 -4
  21. package/src/app/api/chats/[id]/route.ts +61 -62
  22. package/src/app/api/chats/route.ts +7 -1
  23. package/src/app/api/connectors/[id]/route.ts +7 -8
  24. package/src/app/api/connectors/route.ts +5 -4
  25. package/src/app/api/eval/run/route.ts +2 -1
  26. package/src/app/api/eval/suite/route.ts +2 -1
  27. package/src/app/api/external-agents/route.test.ts +1 -1
  28. package/src/app/api/external-agents/route.ts +2 -2
  29. package/src/app/api/files/serve/route.ts +1 -1
  30. package/src/app/api/gateways/[id]/route.ts +7 -5
  31. package/src/app/api/gateways/route.ts +1 -1
  32. package/src/app/api/knowledge/upload/route.ts +1 -1
  33. package/src/app/api/logs/route.ts +5 -7
  34. package/src/app/api/memory-images/[filename]/route.ts +2 -3
  35. package/src/app/api/openclaw/agent-files/route.ts +4 -3
  36. package/src/app/api/openclaw/approvals/route.ts +3 -4
  37. package/src/app/api/openclaw/config-sync/route.ts +3 -2
  38. package/src/app/api/openclaw/cron/route.ts +3 -2
  39. package/src/app/api/openclaw/dotenv-keys/route.ts +2 -1
  40. package/src/app/api/openclaw/exec-config/route.ts +3 -2
  41. package/src/app/api/openclaw/gateway/route.ts +5 -4
  42. package/src/app/api/openclaw/history/route.ts +3 -2
  43. package/src/app/api/openclaw/media/route.ts +2 -1
  44. package/src/app/api/openclaw/permissions/route.ts +3 -2
  45. package/src/app/api/openclaw/sandbox-env/route.ts +3 -2
  46. package/src/app/api/openclaw/skills/install/route.ts +2 -1
  47. package/src/app/api/openclaw/skills/remove/route.ts +2 -1
  48. package/src/app/api/openclaw/skills/route.ts +3 -2
  49. package/src/app/api/orchestrator/run/route.ts +5 -14
  50. package/src/app/api/perf/route.ts +43 -0
  51. package/src/app/api/plugins/dependencies/route.ts +2 -1
  52. package/src/app/api/plugins/install/route.ts +2 -1
  53. package/src/app/api/plugins/marketplace/route.ts +3 -2
  54. package/src/app/api/plugins/settings/route.ts +2 -1
  55. package/src/app/api/preview-server/route.ts +11 -10
  56. package/src/app/api/projects/[id]/route.ts +1 -1
  57. package/src/app/api/schedules/[id]/route.test.ts +128 -0
  58. package/src/app/api/schedules/[id]/route.ts +43 -43
  59. package/src/app/api/schedules/[id]/run/route.ts +11 -62
  60. package/src/app/api/schedules/route.ts +21 -87
  61. package/src/app/api/settings/route.ts +2 -0
  62. package/src/app/api/setup/doctor/route.ts +9 -8
  63. package/src/app/api/tasks/[id]/approve/route.ts +33 -30
  64. package/src/app/api/tasks/[id]/route.ts +12 -35
  65. package/src/app/api/tasks/import/github/route.ts +2 -1
  66. package/src/app/api/tasks/route.ts +79 -91
  67. package/src/app/api/wallets/[id]/approve/route.ts +2 -1
  68. package/src/app/api/wallets/[id]/route.ts +13 -19
  69. package/src/app/api/wallets/[id]/send/route.ts +2 -1
  70. package/src/app/api/wallets/route.ts +2 -1
  71. package/src/app/api/webhooks/[id]/route.ts +2 -1
  72. package/src/app/api/webhooks/route.test.ts +3 -1
  73. package/src/app/page.tsx +23 -331
  74. package/src/cli/index.js +19 -0
  75. package/src/cli/index.ts +38 -7
  76. package/src/cli/spec.js +9 -0
  77. package/src/components/activity/activity-feed.tsx +7 -4
  78. package/src/components/agents/agent-card.tsx +32 -6
  79. package/src/components/agents/agent-chat-list.tsx +55 -22
  80. package/src/components/agents/agent-files-editor.tsx +3 -2
  81. package/src/components/agents/agent-sheet.tsx +123 -22
  82. package/src/components/agents/inspector-panel.tsx +1 -1
  83. package/src/components/agents/openclaw-skills-panel.tsx +2 -1
  84. package/src/components/agents/trash-list.tsx +1 -1
  85. package/src/components/auth/access-key-gate.tsx +8 -2
  86. package/src/components/auth/setup-wizard.tsx +10 -9
  87. package/src/components/auth/user-picker.tsx +3 -2
  88. package/src/components/chat/chat-area.tsx +20 -1
  89. package/src/components/chat/chat-card.tsx +18 -3
  90. package/src/components/chat/chat-header.tsx +24 -4
  91. package/src/components/chat/chat-list.tsx +2 -11
  92. package/src/components/chat/heartbeat-history-panel.tsx +2 -1
  93. package/src/components/chat/message-bubble.tsx +45 -6
  94. package/src/components/chat/message-list.tsx +280 -145
  95. package/src/components/chat/streaming-bubble.tsx +217 -60
  96. package/src/components/chat/swarm-panel.test.ts +274 -0
  97. package/src/components/chat/swarm-panel.tsx +410 -0
  98. package/src/components/chat/swarm-status-card.tsx +346 -0
  99. package/src/components/chat/tool-call-bubble.tsx +48 -23
  100. package/src/components/chatrooms/chatroom-list.tsx +8 -5
  101. package/src/components/chatrooms/chatroom-message.tsx +10 -7
  102. package/src/components/chatrooms/chatroom-view.tsx +12 -9
  103. package/src/components/connectors/connector-health.tsx +6 -4
  104. package/src/components/connectors/connector-list.tsx +16 -11
  105. package/src/components/connectors/connector-sheet.tsx +12 -6
  106. package/src/components/home/home-view.tsx +38 -24
  107. package/src/components/input/chat-input.tsx +10 -1
  108. package/src/components/layout/app-layout.tsx +2 -38
  109. package/src/components/layout/sheet-layer.tsx +50 -0
  110. package/src/components/mcp-servers/mcp-server-list.tsx +37 -5
  111. package/src/components/mcp-servers/mcp-server-sheet.tsx +12 -2
  112. package/src/components/plugins/plugin-list.tsx +8 -4
  113. package/src/components/plugins/plugin-sheet.tsx +2 -1
  114. package/src/components/providers/provider-list.tsx +3 -2
  115. package/src/components/providers/provider-sheet.tsx +2 -1
  116. package/src/components/runs/run-list.tsx +11 -7
  117. package/src/components/schedules/schedule-card.tsx +5 -3
  118. package/src/components/shared/agent-switch-dialog.tsx +1 -1
  119. package/src/components/shared/attachment-chip.tsx +19 -3
  120. package/src/components/shared/notification-center.tsx +6 -3
  121. package/src/components/shared/settings/plugin-manager.tsx +3 -2
  122. package/src/components/shared/settings/section-embedding.tsx +2 -1
  123. package/src/components/shared/settings/section-orchestrator.tsx +2 -1
  124. package/src/components/shared/settings/section-user-preferences.tsx +107 -0
  125. package/src/components/shared/settings/settings-page.tsx +13 -9
  126. package/src/components/skills/clawhub-browser.tsx +15 -4
  127. package/src/components/skills/skill-list.tsx +15 -4
  128. package/src/components/tasks/approvals-panel.tsx +2 -1
  129. package/src/components/tasks/task-board.tsx +35 -37
  130. package/src/components/tasks/task-sheet.tsx +4 -3
  131. package/src/components/ui/full-screen-loader.tsx +164 -0
  132. package/src/components/wallets/wallet-approval-dialog.tsx +2 -1
  133. package/src/components/wallets/wallet-panel.tsx +6 -5
  134. package/src/components/wallets/wallet-section.tsx +3 -2
  135. package/src/components/webhooks/webhook-list.tsx +4 -5
  136. package/src/components/webhooks/webhook-sheet.tsx +6 -6
  137. package/src/hooks/use-app-bootstrap.ts +202 -0
  138. package/src/hooks/use-mounted-ref.ts +14 -0
  139. package/src/hooks/use-now.ts +31 -0
  140. package/src/hooks/use-openclaw-gateway.ts +2 -1
  141. package/src/instrumentation.ts +20 -8
  142. package/src/lib/agent-default-tools.test.ts +52 -0
  143. package/src/lib/agent-default-tools.ts +40 -0
  144. package/src/lib/api-client.test.ts +21 -0
  145. package/src/lib/api-client.ts +6 -11
  146. package/src/lib/canvas-content.test.ts +360 -0
  147. package/src/lib/chat-streaming-state.test.ts +49 -2
  148. package/src/lib/chat-streaming-state.ts +26 -10
  149. package/src/lib/fetch-timeout.test.ts +54 -0
  150. package/src/lib/fetch-timeout.ts +60 -3
  151. package/src/lib/live-tool-events.test.ts +77 -0
  152. package/src/lib/live-tool-events.ts +73 -0
  153. package/src/lib/local-observability.test.ts +2 -2
  154. package/src/lib/openclaw-endpoint.test.ts +1 -1
  155. package/src/lib/providers/anthropic.ts +12 -16
  156. package/src/lib/providers/index.ts +4 -2
  157. package/src/lib/providers/ollama.ts +9 -6
  158. package/src/lib/providers/openai.ts +11 -14
  159. package/src/lib/runtime-env.test.ts +8 -8
  160. package/src/lib/schedule-dedupe-advanced.test.ts +2 -2
  161. package/src/lib/schedule-dedupe.test.ts +1 -1
  162. package/src/lib/schedule-dedupe.ts +3 -2
  163. package/src/lib/server/agent-thread-session.test.ts +6 -6
  164. package/src/lib/server/agent-thread-session.ts +6 -9
  165. package/src/lib/server/alert-dispatch.ts +2 -1
  166. package/src/lib/server/api-routes.test.ts +6 -6
  167. package/src/lib/server/approval-connector-notify.test.ts +4 -4
  168. package/src/lib/server/approvals-auto-approve.test.ts +29 -29
  169. package/src/lib/server/approvals.test.ts +317 -0
  170. package/src/lib/server/approvals.ts +5 -4
  171. package/src/lib/server/autonomy-runtime.test.ts +11 -11
  172. package/src/lib/server/browser-state.ts +2 -2
  173. package/src/lib/server/capability-router.test.ts +1 -1
  174. package/src/lib/server/capability-router.ts +3 -2
  175. package/src/lib/server/chat-execution-advanced.test.ts +15 -2
  176. package/src/lib/server/chat-execution-connector-delivery.ts +67 -0
  177. package/src/lib/server/chat-execution-disabled.test.ts +3 -3
  178. package/src/lib/server/chat-execution-eval-history.test.ts +3 -3
  179. package/src/lib/server/chat-execution-heartbeat.test.ts +42 -1
  180. package/src/lib/server/chat-execution-session-sync.test.ts +119 -0
  181. package/src/lib/server/chat-execution-tool-events.ts +116 -0
  182. package/src/lib/server/chat-execution-utils.test.ts +479 -0
  183. package/src/lib/server/chat-execution-utils.ts +533 -0
  184. package/src/lib/server/chat-execution.ts +153 -748
  185. package/src/lib/server/chat-streaming-utils.ts +174 -0
  186. package/src/lib/server/chat-turn-tool-routing.ts +310 -0
  187. package/src/lib/server/chatroom-session-persistence.test.ts +2 -2
  188. package/src/lib/server/clawhub-client.ts +2 -1
  189. package/src/lib/server/collection-helpers.test.ts +92 -0
  190. package/src/lib/server/collection-helpers.ts +25 -3
  191. package/src/lib/server/connectors/access.ts +146 -0
  192. package/src/lib/server/connectors/bluebubbles.test.ts +1 -1
  193. package/src/lib/server/connectors/bluebubbles.ts +4 -4
  194. package/src/lib/server/connectors/commands.ts +367 -0
  195. package/src/lib/server/connectors/connector-routing.test.ts +4 -4
  196. package/src/lib/server/connectors/delivery.ts +142 -0
  197. package/src/lib/server/connectors/discord.ts +37 -40
  198. package/src/lib/server/connectors/email.ts +11 -10
  199. package/src/lib/server/connectors/googlechat.ts +4 -4
  200. package/src/lib/server/connectors/inbound-audio-transcription.ts +2 -1
  201. package/src/lib/server/connectors/ingress-delivery.ts +23 -0
  202. package/src/lib/server/connectors/manager-roundtrip.test.ts +300 -0
  203. package/src/lib/server/connectors/manager.test.ts +352 -77
  204. package/src/lib/server/connectors/manager.ts +134 -673
  205. package/src/lib/server/connectors/matrix.ts +4 -4
  206. package/src/lib/server/connectors/message-sentinel.ts +7 -0
  207. package/src/lib/server/connectors/openclaw.test.ts +1 -1
  208. package/src/lib/server/connectors/openclaw.ts +8 -10
  209. package/src/lib/server/connectors/outbox.test.ts +192 -0
  210. package/src/lib/server/connectors/outbox.ts +369 -0
  211. package/src/lib/server/connectors/pairing.test.ts +18 -1
  212. package/src/lib/server/connectors/pairing.ts +49 -4
  213. package/src/lib/server/connectors/policy.ts +9 -3
  214. package/src/lib/server/connectors/reconnect-state.ts +71 -0
  215. package/src/lib/server/connectors/response-media.ts +256 -0
  216. package/src/lib/server/connectors/runtime-state.ts +67 -0
  217. package/src/lib/server/connectors/session.test.ts +357 -0
  218. package/src/lib/server/connectors/session.ts +422 -0
  219. package/src/lib/server/connectors/signal.ts +7 -7
  220. package/src/lib/server/connectors/slack.ts +43 -43
  221. package/src/lib/server/connectors/teams.ts +4 -4
  222. package/src/lib/server/connectors/telegram.ts +37 -43
  223. package/src/lib/server/connectors/types.ts +31 -1
  224. package/src/lib/server/connectors/whatsapp.test.ts +108 -0
  225. package/src/lib/server/connectors/whatsapp.ts +106 -34
  226. package/src/lib/server/context-manager.test.ts +409 -0
  227. package/src/lib/server/cost.test.ts +1 -1
  228. package/src/lib/server/daemon-policy.ts +78 -0
  229. package/src/lib/server/daemon-state-connectors.test.ts +167 -0
  230. package/src/lib/server/daemon-state.test.ts +283 -55
  231. package/src/lib/server/daemon-state.ts +106 -109
  232. package/src/lib/server/data-dir.test.ts +5 -5
  233. package/src/lib/server/data-dir.ts +4 -0
  234. package/src/lib/server/delegation-jobs-advanced.test.ts +1 -1
  235. package/src/lib/server/delegation-jobs.test.ts +87 -0
  236. package/src/lib/server/delegation-jobs.ts +42 -48
  237. package/src/lib/server/devserver-launch.ts +1 -1
  238. package/src/lib/server/document-utils.ts +7 -9
  239. package/src/lib/server/elevenlabs.ts +2 -1
  240. package/src/lib/server/embeddings.test.ts +105 -0
  241. package/src/lib/server/ethereum.ts +3 -2
  242. package/src/lib/server/eval/agent-regression.ts +3 -2
  243. package/src/lib/server/eval/runner.ts +2 -1
  244. package/src/lib/server/eval/scorer.ts +2 -1
  245. package/src/lib/server/evm-swap.ts +2 -1
  246. package/src/lib/server/gateway/protocol.test.ts +1 -1
  247. package/src/lib/server/guardian.ts +2 -1
  248. package/src/lib/server/heartbeat-blocked-suppression.test.ts +151 -0
  249. package/src/lib/server/heartbeat-service-timer.test.ts +6 -6
  250. package/src/lib/server/heartbeat-service.test.ts +406 -0
  251. package/src/lib/server/heartbeat-service.ts +54 -7
  252. package/src/lib/server/heartbeat-wake.test.ts +19 -0
  253. package/src/lib/server/heartbeat-wake.ts +17 -16
  254. package/src/lib/server/integrity-monitor.test.ts +149 -0
  255. package/src/lib/server/json-utils.ts +22 -0
  256. package/src/lib/server/knowledge-db.test.ts +13 -13
  257. package/src/lib/server/link-understanding.ts +2 -1
  258. package/src/lib/server/llm-response-cache.test.ts +1 -1
  259. package/src/lib/server/main-agent-loop-advanced.test.ts +65 -3
  260. package/src/lib/server/main-agent-loop.test.ts +6 -6
  261. package/src/lib/server/main-agent-loop.ts +21 -7
  262. package/src/lib/server/mcp-client.test.ts +1 -1
  263. package/src/lib/server/mcp-conformance.test.ts +1 -1
  264. package/src/lib/server/mcp-conformance.ts +3 -2
  265. package/src/lib/server/memory-consolidation.ts +2 -1
  266. package/src/lib/server/memory-db.test.ts +485 -0
  267. package/src/lib/server/memory-db.ts +39 -26
  268. package/src/lib/server/memory-graph.test.ts +2 -2
  269. package/src/lib/server/memory-policy.test.ts +7 -7
  270. package/src/lib/server/memory-retrieval.test.ts +1 -1
  271. package/src/lib/server/openclaw-config-sync.ts +2 -1
  272. package/src/lib/server/openclaw-deploy.test.ts +1 -1
  273. package/src/lib/server/openclaw-deploy.ts +8 -12
  274. package/src/lib/server/openclaw-exec-config.ts +2 -1
  275. package/src/lib/server/openclaw-gateway.ts +6 -7
  276. package/src/lib/server/openclaw-skills-normalize.ts +2 -1
  277. package/src/lib/server/openclaw-sync.ts +7 -5
  278. package/src/lib/server/orchestrator-lg-structure.test.ts +17 -0
  279. package/src/lib/server/orchestrator-lg.ts +199 -327
  280. package/src/lib/server/path-utils.ts +31 -0
  281. package/src/lib/server/perf.ts +161 -0
  282. package/src/lib/server/plugins-approval-guidance.ts +115 -0
  283. package/src/lib/server/plugins.test.ts +1 -1
  284. package/src/lib/server/plugins.ts +22 -132
  285. package/src/lib/server/process-manager.ts +5 -8
  286. package/src/lib/server/provider-health.test.ts +137 -0
  287. package/src/lib/server/provider-health.ts +3 -3
  288. package/src/lib/server/provider-model-discovery.ts +3 -12
  289. package/src/lib/server/queue-followups.test.ts +9 -9
  290. package/src/lib/server/queue-reconcile.test.ts +2 -2
  291. package/src/lib/server/queue-recovery.test.ts +269 -0
  292. package/src/lib/server/queue.test.ts +570 -0
  293. package/src/lib/server/queue.ts +62 -455
  294. package/src/lib/server/resolve-image.ts +30 -0
  295. package/src/lib/server/runtime-settings.test.ts +4 -4
  296. package/src/lib/server/runtime-storage-write-paths.test.ts +60 -0
  297. package/src/lib/server/schedule-normalization.test.ts +279 -0
  298. package/src/lib/server/schedule-service.ts +263 -0
  299. package/src/lib/server/scheduler.ts +17 -74
  300. package/src/lib/server/session-mailbox.test.ts +191 -0
  301. package/src/lib/server/session-run-manager.test.ts +640 -0
  302. package/src/lib/server/session-run-manager.ts +59 -15
  303. package/src/lib/server/session-tools/autonomy-tools.test.ts +20 -20
  304. package/src/lib/server/session-tools/calendar.ts +2 -1
  305. package/src/lib/server/session-tools/canvas.ts +2 -1
  306. package/src/lib/server/session-tools/chatroom.ts +2 -1
  307. package/src/lib/server/session-tools/connector.ts +26 -28
  308. package/src/lib/server/session-tools/context-mgmt.ts +3 -2
  309. package/src/lib/server/session-tools/crawl.ts +4 -3
  310. package/src/lib/server/session-tools/crud.ts +105 -324
  311. package/src/lib/server/session-tools/delegate-fallback.test.ts +9 -9
  312. package/src/lib/server/session-tools/delegate.ts +6 -8
  313. package/src/lib/server/session-tools/discovery-approvals.test.ts +15 -15
  314. package/src/lib/server/session-tools/discovery.ts +4 -3
  315. package/src/lib/server/session-tools/document.ts +2 -1
  316. package/src/lib/server/session-tools/email.ts +2 -1
  317. package/src/lib/server/session-tools/extract.ts +2 -1
  318. package/src/lib/server/session-tools/file.ts +4 -3
  319. package/src/lib/server/session-tools/http.ts +2 -1
  320. package/src/lib/server/session-tools/human-loop.ts +2 -1
  321. package/src/lib/server/session-tools/image-gen.ts +4 -3
  322. package/src/lib/server/session-tools/index.ts +26 -30
  323. package/src/lib/server/session-tools/mailbox.ts +2 -1
  324. package/src/lib/server/session-tools/manage-connectors.test.ts +4 -4
  325. package/src/lib/server/session-tools/manage-schedules.test.ts +12 -12
  326. package/src/lib/server/session-tools/manage-tasks-advanced.test.ts +5 -5
  327. package/src/lib/server/session-tools/manage-tasks.test.ts +2 -2
  328. package/src/lib/server/session-tools/monitor.ts +2 -1
  329. package/src/lib/server/session-tools/platform.ts +2 -1
  330. package/src/lib/server/session-tools/plugin-creator.ts +2 -1
  331. package/src/lib/server/session-tools/replicate.ts +3 -2
  332. package/src/lib/server/session-tools/session-tools-wiring.test.ts +6 -6
  333. package/src/lib/server/session-tools/shell.ts +4 -9
  334. package/src/lib/server/session-tools/subagent.ts +322 -170
  335. package/src/lib/server/session-tools/table.ts +6 -5
  336. package/src/lib/server/session-tools/wallet-tool.test.ts +3 -3
  337. package/src/lib/server/session-tools/wallet.ts +7 -6
  338. package/src/lib/server/session-tools/web-browser-config.test.ts +1 -0
  339. package/src/lib/server/session-tools/web-utils.ts +317 -0
  340. package/src/lib/server/session-tools/web.ts +62 -328
  341. package/src/lib/server/skill-prompt-budget.test.ts +1 -1
  342. package/src/lib/server/skills-normalize.ts +2 -1
  343. package/src/lib/server/storage-item-access.test.ts +302 -0
  344. package/src/lib/server/storage.ts +366 -314
  345. package/src/lib/server/stream-agent-chat.test.ts +82 -3
  346. package/src/lib/server/stream-agent-chat.ts +146 -510
  347. package/src/lib/server/stream-continuation.ts +412 -0
  348. package/src/lib/server/subagent-lineage.test.ts +647 -0
  349. package/src/lib/server/subagent-lineage.ts +435 -0
  350. package/src/lib/server/subagent-runtime.test.ts +484 -0
  351. package/src/lib/server/subagent-runtime.ts +419 -0
  352. package/src/lib/server/subagent-swarm.test.ts +391 -0
  353. package/src/lib/server/subagent-swarm.ts +564 -0
  354. package/src/lib/server/system-events.ts +3 -3
  355. package/src/lib/server/task-followups.test.ts +491 -0
  356. package/src/lib/server/task-followups.ts +391 -0
  357. package/src/lib/server/task-lifecycle.test.ts +205 -0
  358. package/src/lib/server/task-lifecycle.ts +200 -0
  359. package/src/lib/server/task-quality-gate.test.ts +1 -1
  360. package/src/lib/server/task-resume.ts +208 -0
  361. package/src/lib/server/task-service.test.ts +108 -0
  362. package/src/lib/server/task-service.ts +264 -0
  363. package/src/lib/server/task-validation.test.ts +1 -1
  364. package/src/lib/server/test-utils/run-with-temp-data-dir.ts +42 -0
  365. package/src/lib/server/tool-capability-policy.test.ts +2 -2
  366. package/src/lib/server/tool-capability-policy.ts +3 -2
  367. package/src/lib/server/tool-planning.ts +2 -1
  368. package/src/lib/server/tool-retry.ts +2 -3
  369. package/src/lib/server/wake-dispatcher.test.ts +303 -0
  370. package/src/lib/server/wake-dispatcher.ts +318 -0
  371. package/src/lib/server/wake-mode.test.ts +161 -0
  372. package/src/lib/server/wake-mode.ts +174 -0
  373. package/src/lib/server/wallet-service.ts +8 -9
  374. package/src/lib/server/watch-jobs.ts +2 -1
  375. package/src/lib/server/workspace-context.ts +2 -2
  376. package/src/lib/shared-utils.test.ts +142 -0
  377. package/src/lib/shared-utils.ts +62 -0
  378. package/src/lib/tool-event-summary.ts +2 -1
  379. package/src/lib/view-routes.test.ts +100 -0
  380. package/src/lib/wallet.test.ts +322 -6
  381. package/src/proxy.test.ts +4 -4
  382. package/src/proxy.ts +2 -3
  383. package/src/stores/set-if-changed.ts +40 -0
  384. package/src/stores/slices/agent-slice.ts +111 -0
  385. package/src/stores/slices/auth-slice.ts +25 -0
  386. package/src/stores/slices/data-slice.ts +301 -0
  387. package/src/stores/slices/index.ts +7 -0
  388. package/src/stores/slices/session-slice.ts +112 -0
  389. package/src/stores/slices/task-slice.ts +63 -0
  390. package/src/stores/slices/ui-slice.ts +192 -0
  391. package/src/stores/use-app-store.ts +17 -822
  392. package/src/stores/use-approval-store.ts +2 -1
  393. package/src/stores/use-chat-store.ts +8 -1
  394. package/src/types/index.ts +10 -0
@@ -0,0 +1,419 @@
1
+ /**
2
+ * Native Subagent Runtime
3
+ *
4
+ * Replaces CLI bridge delegation with direct, in-process subagent execution.
5
+ * Uses lineage nodes for lifecycle state tracking (no separate state machine
6
+ * registry). Provides a handle registry for promise-based waiting.
7
+ */
8
+
9
+ import { genId } from '@/lib/id'
10
+ import { DEFAULT_DELEGATION_MAX_DEPTH } from '@/lib/runtime-loop'
11
+ import { loadAgents, loadSessions, saveSessions } from './storage'
12
+ import { enqueueSessionRun, type EnqueueSessionRunResult } from './session-run-manager'
13
+ import { loadRuntimeSettings } from './runtime-settings'
14
+ import { applyResolvedRoute, resolvePrimaryAgentRoute } from './agent-runtime-config'
15
+ import { resolveSubagentBrowserProfileId } from './session-tools/subagent'
16
+ import {
17
+ appendDelegationCheckpoint,
18
+ completeDelegationJob,
19
+ createDelegationJob,
20
+ failDelegationJob,
21
+ getDelegationJob,
22
+ registerDelegationRuntime,
23
+ startDelegationJob,
24
+ } from './delegation-jobs'
25
+ import {
26
+ createLineageNode,
27
+ completeLineageNode,
28
+ failLineageNode,
29
+ cancelLineageNode,
30
+ getLineageNode,
31
+ getLineageNodeBySession,
32
+ getAncestors,
33
+ getChildren,
34
+ getDescendants,
35
+ buildLineageTree,
36
+ cancelSubtree,
37
+ transitionState,
38
+ isTerminalState,
39
+ cleanupTerminalNodes,
40
+ type LineageNode,
41
+ type LineageTree,
42
+ type SubagentState,
43
+ } from './subagent-lineage'
44
+ import { errorMessage, hmrSingleton } from '@/lib/shared-utils'
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Types
48
+ // ---------------------------------------------------------------------------
49
+
50
+ export interface SpawnSubagentInput {
51
+ /** Agent to spawn */
52
+ agentId: string
53
+ /** Message/task for the subagent */
54
+ message: string
55
+ /** Working directory override */
56
+ cwd?: string
57
+ /** Inherit parent's browser profile */
58
+ shareBrowserProfile?: boolean
59
+ /** Inherit parent session's plugins/tools (default true) */
60
+ inheritPlugins?: boolean
61
+ /** Wait for completion (default true) */
62
+ waitForCompletion?: boolean
63
+ /** Timeout in seconds for waiting */
64
+ timeoutSec?: number
65
+ }
66
+
67
+ export interface SubagentHandle {
68
+ /** Delegation job ID */
69
+ jobId: string
70
+ /** Child session ID */
71
+ sessionId: string
72
+ /** Lineage node ID */
73
+ lineageId: string
74
+ /** Agent info */
75
+ agentId: string
76
+ agentName: string
77
+ /** Session run handle (for abort) */
78
+ run: EnqueueSessionRunResult
79
+ /** Promise that resolves when the subagent completes */
80
+ promise: Promise<SubagentResult>
81
+ }
82
+
83
+ export interface SubagentResult {
84
+ jobId: string
85
+ sessionId: string
86
+ lineageId: string
87
+ agentId: string
88
+ agentName: string
89
+ status: 'completed' | 'failed' | 'cancelled' | 'timed_out'
90
+ response: string | null
91
+ error: string | null
92
+ depth: number
93
+ parentSessionId: string | null
94
+ childCount: number
95
+ durationMs: number
96
+ }
97
+
98
+ export interface SubagentContext {
99
+ sessionId?: string
100
+ cwd: string
101
+ /** Pre-loaded sessions map — avoids repeated SQLite reads in batch/swarm */
102
+ _sessions?: Record<string, unknown>
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // Handle Registry (for promise-based waiting instead of polling)
107
+ // ---------------------------------------------------------------------------
108
+
109
+ const handleRegistry = hmrSingleton('__swarmclaw_subagent_handles__', () => new Map<string, SubagentHandle>())
110
+
111
+ /** Retrieve a handle by job ID (for promise-based waiting). */
112
+ export function getHandle(jobId: string): SubagentHandle | null {
113
+ return handleRegistry.get(jobId) ?? null
114
+ }
115
+
116
+ // ---------------------------------------------------------------------------
117
+ // Plugin Inheritance
118
+ // ---------------------------------------------------------------------------
119
+
120
+ /**
121
+ * Merge parent session plugins with agent-defined plugins.
122
+ * Agent plugins take precedence (listed first), parent plugins fill in gaps.
123
+ * Case-insensitive deduplication, original casing preserved.
124
+ */
125
+ function mergePlugins(
126
+ agentPlugins: string[],
127
+ parentSession: Record<string, unknown> | null | undefined,
128
+ ): string[] {
129
+ const parentPlugins = (
130
+ Array.isArray(parentSession?.plugins) ? parentSession.plugins
131
+ : Array.isArray(parentSession?.tools) ? parentSession.tools
132
+ : []
133
+ ) as string[]
134
+
135
+ if (parentPlugins.length === 0) return agentPlugins
136
+ if (agentPlugins.length === 0) return [...parentPlugins]
137
+
138
+ const seen = new Set<string>()
139
+ const merged: string[] = []
140
+ for (const id of [...agentPlugins, ...parentPlugins]) {
141
+ const trimmed = typeof id === 'string' ? id.trim() : ''
142
+ const normalized = trimmed.toLowerCase()
143
+ if (normalized && !seen.has(normalized)) {
144
+ seen.add(normalized)
145
+ merged.push(trimmed)
146
+ }
147
+ }
148
+ return merged
149
+ }
150
+
151
+ // ---------------------------------------------------------------------------
152
+ // Depth Guard
153
+ // ---------------------------------------------------------------------------
154
+
155
+ function getSessionDepth(
156
+ sessionId: string | undefined,
157
+ maxDepth: number,
158
+ sessions?: Record<string, unknown>,
159
+ ): number {
160
+ if (!sessionId) return 0
161
+ const allSessions = sessions ?? loadSessions()
162
+ let depth = 0
163
+ let current = sessionId
164
+ while (current && depth < maxDepth + 1) {
165
+ const session = allSessions[current] as Record<string, unknown> | undefined
166
+ if (!session?.parentSessionId) break
167
+ current = session.parentSessionId as string
168
+ depth++
169
+ }
170
+ return depth
171
+ }
172
+
173
+ // ---------------------------------------------------------------------------
174
+ // Core: Spawn a Native Subagent
175
+ // ---------------------------------------------------------------------------
176
+
177
+ export function spawnSubagent(
178
+ input: SpawnSubagentInput,
179
+ context: SubagentContext,
180
+ ): SubagentHandle {
181
+ const runtime = loadRuntimeSettings()
182
+ const maxDepth = runtime.delegationMaxDepth || DEFAULT_DELEGATION_MAX_DEPTH
183
+ const agents = loadAgents()
184
+ const agent = agents[input.agentId]
185
+
186
+ if (!agent) {
187
+ throw new Error(`Agent "${input.agentId}" not found.`)
188
+ }
189
+
190
+ // Use cached sessions if available (batch/swarm pass this to avoid N reads)
191
+ const sessions = (context._sessions ?? loadSessions()) as Record<string, Record<string, unknown>>
192
+ const depth = getSessionDepth(context.sessionId, maxDepth, sessions)
193
+ if (depth >= maxDepth) {
194
+ throw new Error(`Max subagent depth (${maxDepth}) reached.`)
195
+ }
196
+
197
+ // 1. Create delegation job
198
+ const job = createDelegationJob({
199
+ kind: 'subagent',
200
+ parentSessionId: context.sessionId || null,
201
+ agentId: input.agentId,
202
+ task: input.message,
203
+ cwd: input.cwd || context.cwd,
204
+ })
205
+ appendDelegationCheckpoint(job.id, `Initializing subagent ${agent.name}`, 'queued')
206
+
207
+ // 2. Create child session
208
+ const sid = genId()
209
+ const now = Date.now()
210
+ const parent = context.sessionId ? sessions[context.sessionId] : null
211
+ const browserProfileId = resolveSubagentBrowserProfileId(
212
+ parent,
213
+ sid,
214
+ input.shareBrowserProfile === true,
215
+ )
216
+
217
+ const agentPlugins: string[] = (agent.plugins || agent.tools || []) as string[]
218
+ const effectivePlugins = input.inheritPlugins === false
219
+ ? agentPlugins
220
+ : mergePlugins(agentPlugins, parent)
221
+
222
+ const nextSession = {
223
+ id: sid,
224
+ name: `subagent-${agent.name}`,
225
+ cwd: input.cwd || context.cwd,
226
+ user: 'agent',
227
+ provider: agent.provider,
228
+ model: agent.model,
229
+ credentialId: agent.credentialId || null,
230
+ messages: [],
231
+ createdAt: now,
232
+ lastActiveAt: now,
233
+ sessionType: 'orchestrated',
234
+ agentId: agent.id,
235
+ parentSessionId: context.sessionId || null,
236
+ plugins: effectivePlugins,
237
+ browserProfileId,
238
+ }
239
+ sessions[sid] = applyResolvedRoute(nextSession, resolvePrimaryAgentRoute(agent))
240
+ saveSessions(sessions)
241
+
242
+ // 3. Create lineage node (starts in 'initializing')
243
+ const lineageNode = createLineageNode({
244
+ sessionId: sid,
245
+ agentId: agent.id,
246
+ agentName: agent.name,
247
+ parentSessionId: context.sessionId || null,
248
+ jobId: job.id,
249
+ task: input.message,
250
+ cwd: input.cwd || context.cwd,
251
+ })
252
+
253
+ // 4. Transition: initializing → ready
254
+ transitionState(lineageNode.id, 'READY')
255
+
256
+ // 5. Start delegation job
257
+ startDelegationJob(job.id, {
258
+ childSessionId: sid,
259
+ agentId: agent.id,
260
+ agentName: agent.name,
261
+ cwd: input.cwd || context.cwd,
262
+ })
263
+ appendDelegationCheckpoint(job.id, `Created child session ${sid}`, 'running')
264
+
265
+ // 6. Transition: ready → running
266
+ transitionState(lineageNode.id, 'START')
267
+
268
+ // 7. Enqueue session run (native execution — no CLI)
269
+ const run = enqueueSessionRun({
270
+ sessionId: sid,
271
+ message: input.message,
272
+ internal: true,
273
+ source: 'subagent',
274
+ mode: 'followup',
275
+ })
276
+
277
+ // 8. Register runtime handle for cancellation
278
+ registerDelegationRuntime(job.id, {
279
+ cancel: () => {
280
+ run.abort()
281
+ const node = getLineageNode(lineageNode.id)
282
+ if (node && !isTerminalState(node.status)) {
283
+ cancelLineageNode(lineageNode.id)
284
+ }
285
+ },
286
+ })
287
+
288
+ // 9. Build result promise
289
+ const resultPromise = run.promise
290
+ .then((result): SubagentResult => {
291
+ const latest = getDelegationJob(job.id)
292
+ const node = getLineageNode(lineageNode.id)
293
+ if (latest?.status === 'cancelled' || node?.status === 'cancelled') {
294
+ return buildResult(job.id, sid, lineageNode, agent, 'cancelled', null, null)
295
+ }
296
+
297
+ const responseText = (result.text || '').slice(0, 32_000)
298
+ completeLineageNode(lineageNode.id, responseText.slice(0, 1000))
299
+ appendDelegationCheckpoint(job.id, 'Child session completed', 'completed')
300
+ completeDelegationJob(job.id, responseText, { childSessionId: sid })
301
+
302
+ return buildResult(job.id, sid, lineageNode, agent, 'completed', responseText, null)
303
+ })
304
+ .catch((err: unknown): SubagentResult => {
305
+ const message = errorMessage(err)
306
+ const latest = getDelegationJob(job.id)
307
+ const node = getLineageNode(lineageNode.id)
308
+ if (latest?.status === 'cancelled' || node?.status === 'cancelled') {
309
+ return buildResult(job.id, sid, lineageNode, agent, 'cancelled', null, null)
310
+ }
311
+
312
+ failLineageNode(lineageNode.id, message)
313
+ appendDelegationCheckpoint(job.id, `Child session failed: ${message}`, 'failed')
314
+ failDelegationJob(job.id, message, { childSessionId: sid })
315
+
316
+ return buildResult(job.id, sid, lineageNode, agent, 'failed', null, message)
317
+ })
318
+
319
+ const handle: SubagentHandle = {
320
+ jobId: job.id,
321
+ sessionId: sid,
322
+ lineageId: lineageNode.id,
323
+ agentId: agent.id,
324
+ agentName: agent.name,
325
+ run,
326
+ promise: resultPromise,
327
+ }
328
+
329
+ // Register handle for promise-based waiting
330
+ handleRegistry.set(job.id, handle)
331
+
332
+ return handle
333
+ }
334
+
335
+ // ---------------------------------------------------------------------------
336
+ // Result Builder
337
+ // ---------------------------------------------------------------------------
338
+
339
+ function buildResult(
340
+ jobId: string,
341
+ sessionId: string,
342
+ lineageNode: LineageNode,
343
+ agent: Record<string, unknown>,
344
+ status: SubagentResult['status'],
345
+ response: string | null,
346
+ error: string | null,
347
+ ): SubagentResult {
348
+ const children = getChildren(lineageNode.id)
349
+ return {
350
+ jobId,
351
+ sessionId,
352
+ lineageId: lineageNode.id,
353
+ agentId: String(agent.id ?? ''),
354
+ agentName: String(agent.name ?? ''),
355
+ status,
356
+ response,
357
+ error,
358
+ depth: lineageNode.depth,
359
+ parentSessionId: lineageNode.parentSessionId,
360
+ childCount: children.length,
361
+ durationMs: Date.now() - lineageNode.createdAt,
362
+ }
363
+ }
364
+
365
+ // ---------------------------------------------------------------------------
366
+ // Query helpers (re-exported for convenience)
367
+ // ---------------------------------------------------------------------------
368
+
369
+ export {
370
+ getLineageNodeBySession,
371
+ getAncestors,
372
+ getChildren,
373
+ getDescendants,
374
+ buildLineageTree,
375
+ cancelSubtree,
376
+ mergePlugins as _mergePlugins,
377
+ }
378
+
379
+ export type {
380
+ LineageNode,
381
+ LineageTree,
382
+ SubagentState,
383
+ }
384
+
385
+ // ---------------------------------------------------------------------------
386
+ // Cancel a running subagent by session ID
387
+ // ---------------------------------------------------------------------------
388
+
389
+ export function cancelSubagentBySession(sessionId: string): boolean {
390
+ const node = getLineageNodeBySession(sessionId)
391
+ if (!node) return false
392
+
393
+ if (!isTerminalState(node.status)) {
394
+ cancelLineageNode(node.id)
395
+ }
396
+
397
+ cancelSubtree(node.id)
398
+ return true
399
+ }
400
+
401
+ // ---------------------------------------------------------------------------
402
+ // Cleanup finished subagents (call periodically)
403
+ // ---------------------------------------------------------------------------
404
+
405
+ export function cleanupFinishedSubagents(maxAgeMs = 30 * 60_000): number {
406
+ const removedIds = cleanupTerminalNodes(maxAgeMs)
407
+ const removedSet = new Set(removedIds)
408
+ // Clean up handle registry entries for removed lineage nodes
409
+ // Also purge stale handles whose lineage nodes no longer exist (TTL safety net)
410
+ for (const [jobId, handle] of handleRegistry.entries()) {
411
+ if (removedSet.has(handle.lineageId)) {
412
+ handleRegistry.delete(jobId)
413
+ } else if (!getLineageNode(handle.lineageId)) {
414
+ // Lineage node already gone — handle is orphaned, clean it up
415
+ handleRegistry.delete(jobId)
416
+ }
417
+ }
418
+ return removedIds.length
419
+ }