vellum 0.2.1 → 0.2.2

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 (349) hide show
  1. package/README.md +15 -2
  2. package/bun.lock +5 -2
  3. package/package.json +4 -2
  4. package/scripts/capture-x-graphql.ts +562 -0
  5. package/scripts/ipc/check-swift-decoder-drift.ts +2 -1
  6. package/scripts/test.sh +5 -0
  7. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +133 -34
  8. package/src/__tests__/account-registry.test.ts +2 -1
  9. package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
  10. package/src/__tests__/asset-materialize-tool.test.ts +16 -15
  11. package/src/__tests__/asset-search-tool.test.ts +23 -22
  12. package/src/__tests__/attachments-store.test.ts +56 -127
  13. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +5 -4
  14. package/src/__tests__/browser-skill-endstate.test.ts +4 -3
  15. package/src/__tests__/call-bridge.test.ts +385 -0
  16. package/src/__tests__/call-constants.test.ts +40 -0
  17. package/src/__tests__/call-orchestrator.test.ts +130 -4
  18. package/src/__tests__/call-recovery.test.ts +518 -0
  19. package/src/__tests__/call-routes-http.test.ts +459 -0
  20. package/src/__tests__/call-state-machine.test.ts +143 -0
  21. package/src/__tests__/call-store.test.ts +216 -1
  22. package/src/__tests__/cli-discover.test.ts +1 -1
  23. package/src/__tests__/commit-message-enrichment-service.test.ts +148 -7
  24. package/src/__tests__/compaction.benchmark.test.ts +176 -0
  25. package/src/__tests__/computer-use-tools.test.ts +250 -0
  26. package/src/__tests__/config-schema.test.ts +299 -3
  27. package/src/__tests__/conflict-store.test.ts +2 -1
  28. package/src/__tests__/contacts-tools.test.ts +331 -0
  29. package/src/__tests__/conversation-store.test.ts +30 -32
  30. package/src/__tests__/credential-security-invariants.test.ts +4 -0
  31. package/src/__tests__/date-context.test.ts +373 -0
  32. package/src/__tests__/db-schedule-syntax-migration.test.ts +129 -0
  33. package/src/__tests__/fixtures/media-reuse-fixtures.ts +3 -3
  34. package/src/__tests__/followup-tools.test.ts +303 -0
  35. package/src/__tests__/handlers-twitter-config.test.ts +718 -0
  36. package/src/__tests__/intent-routing.test.ts +64 -57
  37. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
  38. package/src/__tests__/ipc-snapshot.test.ts +62 -28
  39. package/src/__tests__/llm-usage-store.test.ts +3 -8
  40. package/src/__tests__/media-generate-image.test.ts +1 -1
  41. package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
  42. package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
  43. package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
  44. package/src/__tests__/playbook-tools.test.ts +342 -0
  45. package/src/__tests__/profile-compiler.test.ts +2 -1
  46. package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
  47. package/src/__tests__/recurrence-engine-rruleset.test.ts +78 -0
  48. package/src/__tests__/recurrence-engine.test.ts +69 -0
  49. package/src/__tests__/recurrence-types.test.ts +71 -0
  50. package/src/__tests__/registry.test.ts +5 -3
  51. package/src/__tests__/relay-server.test.ts +633 -0
  52. package/src/__tests__/reminder-store.test.ts +6 -3
  53. package/src/__tests__/reminder.test.ts +43 -77
  54. package/src/__tests__/run-orchestrator-assistant-events.test.ts +8 -4
  55. package/src/__tests__/run-orchestrator.test.ts +4 -4
  56. package/src/__tests__/runtime-attachment-metadata.test.ts +7 -6
  57. package/src/__tests__/runtime-runs-http.test.ts +4 -4
  58. package/src/__tests__/runtime-runs.test.ts +4 -4
  59. package/src/__tests__/schedule-store.test.ts +482 -0
  60. package/src/__tests__/schedule-tools.test.ts +700 -0
  61. package/src/__tests__/scheduler-recurrence.test.ts +329 -0
  62. package/src/__tests__/server-history-render.test.ts +14 -13
  63. package/src/__tests__/session-error.test.ts +28 -0
  64. package/src/__tests__/session-init.benchmark.test.ts +462 -0
  65. package/src/__tests__/session-queue.test.ts +71 -48
  66. package/src/__tests__/session-runtime-assembly.test.ts +161 -0
  67. package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
  68. package/src/__tests__/signup-e2e.test.ts +2 -1
  69. package/src/__tests__/skill-projection.benchmark.test.ts +328 -0
  70. package/src/__tests__/skill-script-runner.test.ts +159 -0
  71. package/src/__tests__/speaker-identification.test.ts +52 -0
  72. package/src/__tests__/subagent-manager-notify.test.ts +42 -10
  73. package/src/__tests__/subagent-tools.test.ts +141 -41
  74. package/src/__tests__/task-compiler.test.ts +2 -1
  75. package/src/__tests__/task-runner.test.ts +2 -1
  76. package/src/__tests__/task-scheduler.test.ts +2 -1
  77. package/src/__tests__/task-tools.test.ts +49 -56
  78. package/src/__tests__/tool-audit-listener.test.ts +1 -0
  79. package/src/__tests__/tool-domain-event-publisher.test.ts +2 -0
  80. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
  81. package/src/__tests__/tool-executor.test.ts +13 -17
  82. package/src/__tests__/turn-commit.test.ts +218 -3
  83. package/src/__tests__/twilio-provider.test.ts +143 -0
  84. package/src/__tests__/twilio-routes.test.ts +789 -0
  85. package/src/__tests__/twitter-auth-handler.test.ts +581 -0
  86. package/src/__tests__/view-image-tool.test.ts +217 -0
  87. package/src/__tests__/workspace-git-service.test.ts +186 -0
  88. package/src/__tests__/workspace-heartbeat-service.test.ts +13 -3
  89. package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
  90. package/src/bundler/app-bundler.ts +12 -8
  91. package/src/calls/call-bridge.ts +95 -0
  92. package/src/calls/call-constants.ts +43 -5
  93. package/src/calls/call-domain.ts +276 -0
  94. package/src/calls/call-orchestrator.ts +43 -17
  95. package/src/calls/call-recovery.ts +207 -0
  96. package/src/calls/call-state-machine.ts +68 -0
  97. package/src/calls/call-store.ts +192 -5
  98. package/src/calls/relay-server.ts +41 -4
  99. package/src/calls/speaker-identification.ts +213 -0
  100. package/src/calls/twilio-provider.ts +10 -6
  101. package/src/calls/twilio-routes.ts +90 -76
  102. package/src/calls/types.ts +1 -1
  103. package/src/cli/config-commands.ts +334 -0
  104. package/src/cli/core-commands.ts +776 -0
  105. package/src/cli/doordash.ts +251 -1
  106. package/src/cli/ipc-client.ts +82 -0
  107. package/src/cli/map.ts +246 -0
  108. package/src/cli/twitter.ts +575 -0
  109. package/src/cli.ts +7 -5
  110. package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
  111. package/src/commands/cc-command-registry.ts +209 -0
  112. package/src/config/bundled-skills/contacts/SKILL.md +39 -0
  113. package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
  114. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +9 -0
  115. package/src/config/bundled-skills/contacts/tools/contact-search.ts +9 -0
  116. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +9 -0
  117. package/src/config/bundled-skills/document/SKILL.md +18 -0
  118. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  119. package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
  120. package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
  121. package/src/config/bundled-skills/doordash/SKILL.md +82 -23
  122. package/src/config/bundled-skills/followups/SKILL.md +32 -0
  123. package/src/config/bundled-skills/followups/TOOLS.json +100 -0
  124. package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
  125. package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
  126. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
  127. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -23
  128. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -1
  129. package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
  130. package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
  131. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +9 -0
  132. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +9 -0
  133. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +9 -0
  134. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +9 -0
  135. package/src/config/bundled-skills/reminder/SKILL.md +20 -0
  136. package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
  137. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
  138. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
  139. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
  140. package/src/config/bundled-skills/schedule/SKILL.md +74 -0
  141. package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
  142. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
  143. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
  144. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
  145. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
  146. package/src/config/bundled-skills/subagent/SKILL.md +25 -0
  147. package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
  148. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
  149. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
  150. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
  151. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
  152. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
  153. package/src/config/bundled-skills/tasks/SKILL.md +28 -0
  154. package/src/config/bundled-skills/tasks/TOOLS.json +256 -0
  155. package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
  156. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
  157. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
  158. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
  159. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
  160. package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
  161. package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
  162. package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
  163. package/src/config/bundled-skills/twitter/SKILL.md +134 -0
  164. package/src/config/bundled-skills/watcher/SKILL.md +27 -0
  165. package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
  166. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
  167. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
  168. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
  169. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
  170. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
  171. package/src/config/defaults.ts +33 -0
  172. package/src/config/loader.ts +4 -1
  173. package/src/config/schema.ts +161 -1
  174. package/src/config/system-prompt.ts +61 -16
  175. package/src/config/templates/IDENTITY.md +7 -0
  176. package/src/config/types.ts +4 -0
  177. package/src/contacts/contact-store.ts +4 -4
  178. package/src/daemon/assistant-attachments.ts +10 -0
  179. package/src/daemon/classifier.ts +3 -1
  180. package/src/daemon/computer-use-session.ts +3 -1
  181. package/src/daemon/date-context.ts +136 -0
  182. package/src/daemon/handlers/apps.ts +16 -1
  183. package/src/daemon/handlers/browser.ts +54 -0
  184. package/src/daemon/handlers/computer-use.ts +7 -1
  185. package/src/daemon/handlers/config.ts +163 -5
  186. package/src/daemon/handlers/diagnostics.ts +5 -1
  187. package/src/daemon/handlers/documents.ts +18 -29
  188. package/src/daemon/handlers/home-base.ts +5 -1
  189. package/src/daemon/handlers/index.ts +40 -277
  190. package/src/daemon/handlers/misc.ts +9 -1
  191. package/src/daemon/handlers/publish.ts +6 -1
  192. package/src/daemon/handlers/sessions.ts +65 -12
  193. package/src/daemon/handlers/shared.ts +36 -1
  194. package/src/daemon/handlers/signing.ts +37 -0
  195. package/src/daemon/handlers/skills.ts +20 -6
  196. package/src/daemon/handlers/subagents.ts +8 -3
  197. package/src/daemon/handlers/twitter-auth.ts +169 -0
  198. package/src/daemon/handlers/work-items.ts +384 -68
  199. package/src/daemon/ipc-contract-inventory.json +28 -4
  200. package/src/daemon/ipc-contract.ts +133 -37
  201. package/src/daemon/ipc-protocol.ts +7 -2
  202. package/src/daemon/lifecycle.ts +21 -0
  203. package/src/daemon/main.ts +10 -4
  204. package/src/daemon/ride-shotgun-handler.ts +74 -10
  205. package/src/daemon/server.ts +143 -26
  206. package/src/daemon/session-agent-loop.ts +887 -0
  207. package/src/daemon/session-attachments.ts +28 -5
  208. package/src/daemon/session-error.ts +24 -3
  209. package/src/daemon/session-lifecycle.ts +147 -0
  210. package/src/daemon/session-media-retry.ts +147 -0
  211. package/src/daemon/session-messaging.ts +145 -0
  212. package/src/daemon/session-notifiers.ts +164 -0
  213. package/src/daemon/session-process.ts +2 -2
  214. package/src/daemon/session-queue-manager.ts +1 -0
  215. package/src/daemon/session-runtime-assembly.ts +52 -0
  216. package/src/daemon/session-skill-tools.ts +124 -5
  217. package/src/daemon/session-slash.ts +3 -0
  218. package/src/daemon/session-surfaces.ts +77 -2
  219. package/src/daemon/session-tool-setup.ts +216 -2
  220. package/src/daemon/session-usage.ts +0 -2
  221. package/src/daemon/session.ts +114 -1404
  222. package/src/daemon/video-thumbnail.ts +60 -0
  223. package/src/doordash/client.ts +121 -27
  224. package/src/doordash/queries.ts +1 -2
  225. package/src/export/formatter.ts +3 -1
  226. package/src/followups/followup-store.ts +4 -2
  227. package/src/followups/types.ts +6 -0
  228. package/src/hooks/templates.ts +1 -1
  229. package/src/index.ts +32 -1153
  230. package/src/memory/attachments-store.ts +28 -83
  231. package/src/memory/channel-delivery-store.ts +7 -21
  232. package/src/memory/clarification-resolver.ts +6 -5
  233. package/src/memory/contradiction-checker.ts +3 -2
  234. package/src/memory/conversation-key-store.ts +10 -29
  235. package/src/memory/conversation-store.ts +2 -1
  236. package/src/memory/db.ts +96 -2
  237. package/src/memory/entity-extractor.ts +6 -3
  238. package/src/memory/items-extractor.ts +5 -4
  239. package/src/memory/jobs-store.ts +3 -2
  240. package/src/memory/llm-usage-store.ts +1 -2
  241. package/src/memory/runs-store.ts +1 -2
  242. package/src/memory/schema.ts +23 -2
  243. package/src/messaging/style-analyzer.ts +3 -2
  244. package/src/messaging/thread-summarizer.ts +8 -12
  245. package/src/messaging/triage-engine.ts +4 -2
  246. package/src/providers/openrouter/client.ts +20 -0
  247. package/src/providers/registry.ts +8 -0
  248. package/src/runtime/http-server.ts +108 -20
  249. package/src/runtime/routes/attachment-routes.ts +2 -3
  250. package/src/runtime/routes/call-routes.ts +140 -0
  251. package/src/runtime/routes/channel-routes.ts +5 -10
  252. package/src/runtime/routes/conversation-routes.ts +5 -5
  253. package/src/runtime/routes/run-routes.ts +2 -2
  254. package/src/runtime/run-orchestrator.ts +9 -3
  255. package/src/schedule/recurrence-engine.ts +138 -0
  256. package/src/schedule/recurrence-types.ts +67 -0
  257. package/src/schedule/schedule-store.ts +102 -57
  258. package/src/schedule/scheduler.ts +9 -6
  259. package/src/security/oauth2.ts +29 -4
  260. package/src/security/secret-allowlist.ts +46 -0
  261. package/src/skills/clawhub.ts +1 -1
  262. package/src/subagent/manager.ts +40 -8
  263. package/src/swarm/backend-claude-code.ts +64 -9
  264. package/src/swarm/worker-prompts.ts +2 -1
  265. package/src/tasks/SPEC.md +34 -28
  266. package/src/tasks/ephemeral-permissions.ts +16 -7
  267. package/src/tasks/task-compiler.ts +5 -4
  268. package/src/tasks/task-runner.ts +10 -5
  269. package/src/tasks/task-scheduler.ts +1 -1
  270. package/src/tasks/tool-sanitizer.ts +36 -0
  271. package/src/tools/assets/search.ts +4 -4
  272. package/src/tools/browser/api-map.ts +220 -0
  273. package/src/tools/browser/auto-navigate.ts +270 -0
  274. package/src/tools/browser/browser-execution.ts +2 -1
  275. package/src/tools/browser/browser-manager.ts +2 -2
  276. package/src/tools/browser/network-recorder.ts +5 -4
  277. package/src/tools/browser/x-auto-navigate.ts +207 -0
  278. package/src/tools/calls/call-end.ts +17 -67
  279. package/src/tools/calls/call-start.ts +24 -85
  280. package/src/tools/calls/call-status.ts +35 -51
  281. package/src/tools/claude-code/claude-code.ts +77 -11
  282. package/src/tools/contacts/contact-merge.ts +46 -78
  283. package/src/tools/contacts/contact-search.ts +35 -79
  284. package/src/tools/contacts/contact-upsert.ts +35 -108
  285. package/src/tools/credentials/vault.ts +20 -4
  286. package/src/tools/document/document-tool.ts +71 -144
  287. package/src/tools/executor.ts +129 -10
  288. package/src/tools/followups/followup_create.ts +46 -88
  289. package/src/tools/followups/followup_list.ts +34 -74
  290. package/src/tools/followups/followup_resolve.ts +31 -66
  291. package/src/tools/host-terminal/cli-discover.ts +2 -1
  292. package/src/tools/host-terminal/host-shell.ts +10 -0
  293. package/src/tools/memory/handlers.ts +5 -4
  294. package/src/tools/network/__tests__/web-search.test.ts +427 -0
  295. package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
  296. package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
  297. package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
  298. package/src/tools/network/web-fetch.ts +18 -6
  299. package/src/tools/playbooks/index.ts +4 -5
  300. package/src/tools/playbooks/playbook-create.ts +3 -47
  301. package/src/tools/playbooks/playbook-delete.ts +1 -25
  302. package/src/tools/playbooks/playbook-list.ts +1 -28
  303. package/src/tools/playbooks/playbook-update.ts +3 -51
  304. package/src/tools/reminder/reminder.ts +5 -78
  305. package/src/tools/schedule/create.ts +69 -74
  306. package/src/tools/schedule/delete.ts +21 -47
  307. package/src/tools/schedule/list.ts +55 -74
  308. package/src/tools/schedule/update.ts +77 -84
  309. package/src/tools/subagent/abort.ts +29 -58
  310. package/src/tools/subagent/message.ts +30 -63
  311. package/src/tools/subagent/read.ts +53 -84
  312. package/src/tools/subagent/spawn.ts +43 -82
  313. package/src/tools/subagent/status.ts +42 -71
  314. package/src/tools/swarm/delegate.ts +2 -1
  315. package/src/tools/tasks/index.ts +8 -8
  316. package/src/tools/tasks/task-delete.ts +60 -88
  317. package/src/tools/tasks/task-list.ts +31 -52
  318. package/src/tools/tasks/task-run.ts +72 -108
  319. package/src/tools/tasks/task-save.ts +33 -65
  320. package/src/tools/tasks/work-item-enqueue.ts +183 -215
  321. package/src/tools/tasks/work-item-list.ts +33 -63
  322. package/src/tools/tasks/work-item-remove.ts +45 -97
  323. package/src/tools/tasks/work-item-update.ts +91 -163
  324. package/src/tools/terminal/backends/native.ts +3 -1
  325. package/src/tools/tool-manifest.ts +0 -62
  326. package/src/tools/types.ts +6 -0
  327. package/src/tools/ui-surface/definitions.ts +3 -1
  328. package/src/tools/watch/screen-watch.ts +3 -1
  329. package/src/tools/watcher/create.ts +52 -98
  330. package/src/tools/watcher/delete.ts +20 -46
  331. package/src/tools/watcher/digest.ts +36 -70
  332. package/src/tools/watcher/list.ts +49 -79
  333. package/src/tools/watcher/update.ts +45 -91
  334. package/src/twitter/client.ts +690 -0
  335. package/src/twitter/session.ts +91 -0
  336. package/src/usage/types.ts +0 -1
  337. package/src/util/truncate.ts +6 -0
  338. package/src/watcher/providers/slack.ts +2 -1
  339. package/src/watcher/watcher-store.ts +3 -2
  340. package/src/work-items/work-item-store.ts +27 -2
  341. package/src/workspace/commit-message-enrichment-service.ts +31 -7
  342. package/src/workspace/git-service.ts +87 -22
  343. package/src/workspace/provider-commit-message-generator.ts +242 -0
  344. package/src/workspace/turn-commit.ts +62 -3
  345. package/src/tools/contacts/index.ts +0 -4
  346. package/src/tools/document/index.ts +0 -5
  347. package/src/tools/followups/index.ts +0 -3
  348. package/src/tools/subagent/index.ts +0 -5
  349. /package/src/__tests__/{memory-context-benchmark.test.ts → memory-context-benchmark.benchmark.test.ts} +0 -0
@@ -1,62 +1,33 @@
1
- /**
2
- * subagent_abort tool — abort a running subagent.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager } from '../../subagent/index.js';
9
3
 
10
- const definition: ToolDefinition = {
11
- name: 'subagent_abort',
12
- description: 'Abort a running subagent by ID.',
13
- input_schema: {
14
- type: 'object',
15
- properties: {
16
- subagent_id: {
17
- type: 'string',
18
- description: 'The ID of the subagent to abort.',
19
- },
20
- },
21
- required: ['subagent_id'],
22
- },
23
- };
24
-
25
- export const subagentAbortTool: Tool = {
26
- name: 'subagent_abort',
27
- description: definition.description,
28
- category: 'orchestration',
29
- defaultRiskLevel: RiskLevel.Low,
30
-
31
- getDefinition(): ToolDefinition {
32
- return definition;
33
- },
34
-
35
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
36
- const subagentId = input.subagent_id as string;
37
- if (!subagentId) {
38
- return { content: '"subagent_id" is required.', isError: true };
39
- }
40
-
41
- const manager = getSubagentManager();
42
- const sendToClient = context.sendToClient as ((msg: unknown) => void) | undefined;
43
- const aborted = manager.abort(
44
- subagentId,
45
- sendToClient as ((msg: unknown) => void) | undefined,
46
- context.sessionId,
47
- { suppressNotification: true },
48
- );
49
-
50
- if (!aborted) {
51
- return {
52
- content: `Could not abort subagent "${subagentId}". It may not exist or already be in a terminal state.`,
53
- isError: true,
54
- };
55
- }
56
-
4
+ export async function executeSubagentAbort(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ const subagentId = input.subagent_id as string;
9
+ if (!subagentId) {
10
+ return { content: '"subagent_id" is required.', isError: true };
11
+ }
12
+
13
+ const manager = getSubagentManager();
14
+ const sendToClient = context.sendToClient as ((msg: unknown) => void) | undefined;
15
+ const aborted = manager.abort(
16
+ subagentId,
17
+ sendToClient as ((msg: unknown) => void) | undefined,
18
+ context.sessionId,
19
+ { suppressNotification: true },
20
+ );
21
+
22
+ if (!aborted) {
57
23
  return {
58
- content: JSON.stringify({ subagentId, status: 'aborted', message: 'Subagent aborted successfully.' }),
59
- isError: false,
24
+ content: `Could not abort subagent "${subagentId}". It may not exist or already be in a terminal state.`,
25
+ isError: true,
60
26
  };
61
- },
62
- };
27
+ }
28
+
29
+ return {
30
+ content: JSON.stringify({ subagentId, status: 'aborted', message: 'Subagent aborted successfully.' }),
31
+ isError: false,
32
+ };
33
+ }
@@ -1,72 +1,39 @@
1
- /**
2
- * subagent_message tool — send a follow-up message to a running subagent.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager } from '../../subagent/index.js';
9
3
 
10
- const definition: ToolDefinition = {
11
- name: 'subagent_message',
12
- description: 'Send a follow-up message to a running subagent.',
13
- input_schema: {
14
- type: 'object',
15
- properties: {
16
- subagent_id: {
17
- type: 'string',
18
- description: 'The ID of the subagent to send a message to.',
19
- },
20
- content: {
21
- type: 'string',
22
- description: 'The message content to send to the subagent.',
23
- },
24
- },
25
- required: ['subagent_id', 'content'],
26
- },
27
- };
28
-
29
- export const subagentMessageTool: Tool = {
30
- name: 'subagent_message',
31
- description: definition.description,
32
- category: 'orchestration',
33
- defaultRiskLevel: RiskLevel.Low,
34
-
35
- getDefinition(): ToolDefinition {
36
- return definition;
37
- },
38
-
39
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
40
- const subagentId = input.subagent_id as string;
41
- const content = input.content as string;
4
+ export async function executeSubagentMessage(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ const subagentId = input.subagent_id as string;
9
+ const content = input.content as string;
42
10
 
43
- if (!subagentId || !content) {
44
- return { content: 'Both "subagent_id" and "content" are required.', isError: true };
45
- }
11
+ if (!subagentId || !content) {
12
+ return { content: 'Both "subagent_id" and "content" are required.', isError: true };
13
+ }
46
14
 
47
- const manager = getSubagentManager();
15
+ const manager = getSubagentManager();
48
16
 
49
- // Ownership check: only the parent session can message a subagent.
50
- const state = manager.getState(subagentId);
51
- if (!state || state.config.parentSessionId !== context.sessionId) {
52
- return {
53
- content: `Could not send message to subagent "${subagentId}". It may not exist or be in a terminal state.`,
54
- isError: true,
55
- };
56
- }
57
-
58
- const sent = manager.sendMessage(subagentId, content);
17
+ // Ownership check: only the parent session can message a subagent.
18
+ const state = manager.getState(subagentId);
19
+ if (!state || state.config.parentSessionId !== context.sessionId) {
20
+ return {
21
+ content: `Could not send message to subagent "${subagentId}". It may not exist or be in a terminal state.`,
22
+ isError: true,
23
+ };
24
+ }
59
25
 
60
- if (!sent) {
61
- return {
62
- content: `Could not send message to subagent "${subagentId}". It may not exist or be in a terminal state.`,
63
- isError: true,
64
- };
65
- }
26
+ const sent = manager.sendMessage(subagentId, content);
66
27
 
28
+ if (!sent) {
67
29
  return {
68
- content: JSON.stringify({ subagentId, message: 'Message sent to subagent.' }),
69
- isError: false,
30
+ content: `Could not send message to subagent "${subagentId}". It may not exist or be in a terminal state.`,
31
+ isError: true,
70
32
  };
71
- },
72
- };
33
+ }
34
+
35
+ return {
36
+ content: JSON.stringify({ subagentId, message: 'Message sent to subagent.' }),
37
+ isError: false,
38
+ };
39
+ }
@@ -1,98 +1,67 @@
1
- /**
2
- * subagent_read tool — read the full output from a completed subagent's conversation.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager, TERMINAL_STATUSES } from '../../subagent/index.js';
9
3
  import { getMessages } from '../../memory/conversation-store.js';
10
4
 
11
- const definition: ToolDefinition = {
12
- name: 'subagent_read',
13
- description:
14
- 'Read the full conversation output from a subagent. ' +
15
- 'Use this after a subagent completes to retrieve its full work product.',
16
- input_schema: {
17
- type: 'object',
18
- properties: {
19
- subagent_id: {
20
- type: 'string',
21
- description: 'The ID of the subagent whose output to read.',
22
- },
23
- },
24
- required: ['subagent_id'],
25
- },
26
- };
27
-
28
- export const subagentReadTool: Tool = {
29
- name: 'subagent_read',
30
- description: definition.description,
31
- category: 'orchestration',
32
- defaultRiskLevel: RiskLevel.Low,
33
-
34
- getDefinition(): ToolDefinition {
35
- return definition;
36
- },
37
-
38
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
39
- const subagentId = input.subagent_id as string;
40
- if (!subagentId) {
41
- return { content: '"subagent_id" is required.', isError: true };
42
- }
5
+ export async function executeSubagentRead(
6
+ input: Record<string, unknown>,
7
+ context: ToolContext,
8
+ ): Promise<ToolExecutionResult> {
9
+ const subagentId = input.subagent_id as string;
10
+ if (!subagentId) {
11
+ return { content: '"subagent_id" is required.', isError: true };
12
+ }
43
13
 
44
- const manager = getSubagentManager();
45
- const state = manager.getState(subagentId);
46
- if (!state) {
47
- return { content: `No subagent found with ID "${subagentId}".`, isError: true };
48
- }
14
+ const manager = getSubagentManager();
15
+ const state = manager.getState(subagentId);
16
+ if (!state) {
17
+ return { content: `No subagent found with ID "${subagentId}".`, isError: true };
18
+ }
49
19
 
50
- // Ownership check: only the parent session can read a subagent's output.
51
- if (state.config.parentSessionId !== context.sessionId) {
52
- return { content: `No subagent found with ID "${subagentId}".`, isError: true };
53
- }
20
+ // Ownership check: only the parent session can read a subagent's output.
21
+ if (state.config.parentSessionId !== context.sessionId) {
22
+ return { content: `No subagent found with ID "${subagentId}".`, isError: true };
23
+ }
54
24
 
55
- if (!TERMINAL_STATUSES.has(state.status)) {
56
- return {
57
- content: `Subagent "${state.config.label}" is still ${state.status}. Wait for it to finish.`,
58
- isError: false,
59
- };
60
- }
25
+ if (!TERMINAL_STATUSES.has(state.status)) {
26
+ return {
27
+ content: `Subagent "${state.config.label}" is still ${state.status}. Wait for it to finish.`,
28
+ isError: false,
29
+ };
30
+ }
61
31
 
62
- // Read the subagent's conversation messages from DB.
63
- const dbMessages = getMessages(state.conversationId);
64
- if (!dbMessages || dbMessages.length === 0) {
65
- return { content: 'No messages found in subagent conversation.', isError: true };
66
- }
32
+ // Read the subagent's conversation messages from DB.
33
+ const dbMessages = getMessages(state.conversationId);
34
+ if (!dbMessages || dbMessages.length === 0) {
35
+ return { content: 'No messages found in subagent conversation.', isError: true };
36
+ }
67
37
 
68
- // Extract assistant messages only — that's the subagent's output.
69
- const output: string[] = [];
70
- for (const msg of dbMessages) {
71
- if (msg.role !== 'assistant') continue;
72
- try {
73
- const content = JSON.parse(msg.content);
74
- if (Array.isArray(content)) {
75
- for (const block of content) {
76
- if (block.type === 'text' && typeof block.text === 'string') {
77
- output.push(block.text);
78
- }
38
+ // Extract assistant messages only — that's the subagent's output.
39
+ const output: string[] = [];
40
+ for (const msg of dbMessages) {
41
+ if (msg.role !== 'assistant') continue;
42
+ try {
43
+ const content = JSON.parse(msg.content);
44
+ if (Array.isArray(content)) {
45
+ for (const block of content) {
46
+ if (block.type === 'text' && typeof block.text === 'string') {
47
+ output.push(block.text);
79
48
  }
80
- } else if (typeof content === 'string') {
81
- output.push(content);
82
49
  }
83
- } catch {
84
- // Content might be plain text.
85
- output.push(msg.content);
50
+ } else if (typeof content === 'string') {
51
+ output.push(content);
86
52
  }
53
+ } catch {
54
+ // Content might be plain text.
55
+ output.push(msg.content);
87
56
  }
57
+ }
88
58
 
89
- if (output.length === 0) {
90
- return { content: 'Subagent produced no text output.', isError: false };
91
- }
59
+ if (output.length === 0) {
60
+ return { content: 'Subagent produced no text output.', isError: false };
61
+ }
92
62
 
93
- return {
94
- content: output.join('\n\n'),
95
- isError: false,
96
- };
97
- },
98
- };
63
+ return {
64
+ content: output.join('\n\n'),
65
+ isError: false,
66
+ };
67
+ }
@@ -1,85 +1,46 @@
1
- /**
2
- * subagent_spawn tool — lets the parent LLM spawn an autonomous subagent.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager } from '../../subagent/index.js';
9
3
 
10
- const definition: ToolDefinition = {
11
- name: 'subagent_spawn',
12
- description:
13
- 'Spawn an independent subagent to work on a task in parallel. ' +
14
- 'The subagent runs autonomously and its results are reported back when complete.',
15
- input_schema: {
16
- type: 'object',
17
- properties: {
18
- label: {
19
- type: 'string',
20
- description: 'Short human-readable label for this subagent (e.g. "Research competitor pricing")',
21
- },
22
- objective: {
23
- type: 'string',
24
- description: 'The task objective — what the subagent should accomplish',
25
- },
26
- context: {
27
- type: 'string',
28
- description: 'Optional additional context to pass to the subagent',
4
+ export async function executeSubagentSpawn(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ const label = input.label as string;
9
+ const objective = input.objective as string;
10
+ const extraContext = input.context as string | undefined;
11
+
12
+ if (!label || !objective) {
13
+ return { content: 'Both "label" and "objective" are required.', isError: true };
14
+ }
15
+
16
+ const manager = getSubagentManager();
17
+ const sendToClient = context.sendToClient as ((msg: { type: string; [key: string]: unknown }) => void) | undefined;
18
+ if (!sendToClient) {
19
+ return { content: 'No IPC client connected — cannot spawn subagent.', isError: true };
20
+ }
21
+
22
+ try {
23
+ const subagentId = await manager.spawn(
24
+ {
25
+ parentSessionId: context.sessionId,
26
+ label,
27
+ objective,
28
+ context: extraContext,
29
29
  },
30
- },
31
- required: ['label', 'objective'],
32
- },
33
- };
34
-
35
- export const subagentSpawnTool: Tool = {
36
- name: 'subagent_spawn',
37
- description: definition.description,
38
- category: 'orchestration',
39
- defaultRiskLevel: RiskLevel.Low,
40
-
41
- getDefinition(): ToolDefinition {
42
- return definition;
43
- },
44
-
45
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
46
- const label = input.label as string;
47
- const objective = input.objective as string;
48
- const extraContext = input.context as string | undefined;
49
-
50
- if (!label || !objective) {
51
- return { content: 'Both "label" and "objective" are required.', isError: true };
52
- }
53
-
54
- const manager = getSubagentManager();
55
- const sendToClient = context.sendToClient as ((msg: { type: string; [key: string]: unknown }) => void) | undefined;
56
- if (!sendToClient) {
57
- return { content: 'No IPC client connected — cannot spawn subagent.', isError: true };
58
- }
59
-
60
- try {
61
- const subagentId = await manager.spawn(
62
- {
63
- parentSessionId: context.sessionId,
64
- label,
65
- objective,
66
- context: extraContext,
67
- },
68
- sendToClient as (msg: unknown) => void,
69
- );
70
-
71
- return {
72
- content: JSON.stringify({
73
- subagentId,
74
- label,
75
- status: 'pending',
76
- message: `Subagent "${label}" spawned. You will be notified automatically when it completes or fails — do NOT poll subagent_status. Continue the conversation normally.`,
77
- }),
78
- isError: false,
79
- };
80
- } catch (err) {
81
- const msg = err instanceof Error ? err.message : String(err);
82
- return { content: `Failed to spawn subagent: ${msg}`, isError: true };
83
- }
84
- },
85
- };
30
+ sendToClient as (msg: unknown) => void,
31
+ );
32
+
33
+ return {
34
+ content: JSON.stringify({
35
+ subagentId,
36
+ label,
37
+ status: 'pending',
38
+ message: `Subagent "${label}" spawned. You will be notified automatically when it completes or fails — do NOT poll subagent_status. Continue the conversation normally.`,
39
+ }),
40
+ isError: false,
41
+ };
42
+ } catch (err) {
43
+ const msg = err instanceof Error ? err.message : String(err);
44
+ return { content: `Failed to spawn subagent: ${msg}`, isError: true };
45
+ }
46
+ }
@@ -1,74 +1,45 @@
1
- /**
2
- * subagent_status tool — query the status of one or all subagents.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager } from '../../subagent/index.js';
9
3
 
10
- const definition: ToolDefinition = {
11
- name: 'subagent_status',
12
- description: 'Get the status of a specific subagent or list all subagents for the current session. Only use this when the user explicitly asks about subagent status — do NOT poll automatically, as you will be notified when subagents complete.',
13
- input_schema: {
14
- type: 'object',
15
- properties: {
16
- subagent_id: {
17
- type: 'string',
18
- description: 'Optional subagent ID to query. If omitted, returns all subagents for this session.',
19
- },
20
- },
21
- required: [],
22
- },
23
- };
24
-
25
- export const subagentStatusTool: Tool = {
26
- name: 'subagent_status',
27
- description: definition.description,
28
- category: 'orchestration',
29
- defaultRiskLevel: RiskLevel.Low,
30
-
31
- getDefinition(): ToolDefinition {
32
- return definition;
33
- },
34
-
35
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
36
- const subagentId = input.subagent_id as string | undefined;
37
- const manager = getSubagentManager();
38
-
39
- if (subagentId) {
40
- const state = manager.getState(subagentId);
41
- if (!state || state.config.parentSessionId !== context.sessionId) {
42
- return { content: `No subagent found with ID "${subagentId}".`, isError: true };
43
- }
44
- return {
45
- content: JSON.stringify({
46
- subagentId: state.config.id,
47
- label: state.config.label,
48
- status: state.status,
49
- error: state.error,
50
- createdAt: state.createdAt,
51
- startedAt: state.startedAt,
52
- completedAt: state.completedAt,
53
- usage: state.usage,
54
- }),
55
- isError: false,
56
- };
4
+ export async function executeSubagentStatus(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ const subagentId = input.subagent_id as string | undefined;
9
+ const manager = getSubagentManager();
10
+
11
+ if (subagentId) {
12
+ const state = manager.getState(subagentId);
13
+ if (!state || state.config.parentSessionId !== context.sessionId) {
14
+ return { content: `No subagent found with ID "${subagentId}".`, isError: true };
57
15
  }
58
-
59
- // List all subagents for this parent session.
60
- const children = manager.getChildrenOf(context.sessionId);
61
- if (children.length === 0) {
62
- return { content: 'No subagents found for this session.', isError: false };
63
- }
64
-
65
- const summary = children.map((s) => ({
66
- subagentId: s.config.id,
67
- label: s.config.label,
68
- status: s.status,
69
- error: s.error,
70
- }));
71
-
72
- return { content: JSON.stringify(summary), isError: false };
73
- },
74
- };
16
+ return {
17
+ content: JSON.stringify({
18
+ subagentId: state.config.id,
19
+ label: state.config.label,
20
+ status: state.status,
21
+ error: state.error,
22
+ createdAt: state.createdAt,
23
+ startedAt: state.startedAt,
24
+ completedAt: state.completedAt,
25
+ usage: state.usage,
26
+ }),
27
+ isError: false,
28
+ };
29
+ }
30
+
31
+ // List all subagents for this parent session.
32
+ const children = manager.getChildrenOf(context.sessionId);
33
+ if (children.length === 0) {
34
+ return { content: 'No subagents found for this session.', isError: false };
35
+ }
36
+
37
+ const summary = children.map((s) => ({
38
+ subagentId: s.config.id,
39
+ label: s.config.label,
40
+ status: s.status,
41
+ error: s.error,
42
+ }));
43
+
44
+ return { content: JSON.stringify(summary), isError: false };
45
+ }
@@ -3,6 +3,7 @@ import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
3
3
  import type { ToolDefinition } from '../../providers/types.js';
4
4
  import { getConfig } from '../../config/loader.js';
5
5
  import { getLogger } from '../../util/logger.js';
6
+ import { truncate } from '../../util/truncate.js';
6
7
  import { getFailoverProvider } from '../../providers/registry.js';
7
8
  import { resolveSwarmLimits } from '../../swarm/limits.js';
8
9
  import { generatePlan } from '../../swarm/router-planner.js';
@@ -94,7 +95,7 @@ export const swarmDelegateTool: Tool = {
94
95
 
95
96
  context.onOutput?.(`Plan: ${plan.tasks.length} tasks\n`);
96
97
  for (const task of plan.tasks) {
97
- context.onOutput?.(` - [${task.role}] ${task.id}: ${task.objective.slice(0, 80)}\n`);
98
+ context.onOutput?.(` - [${task.role}] ${task.id}: ${truncate(task.objective, 80)}\n`);
98
99
  }
99
100
  context.onOutput?.('\nExecuting...\n');
100
101
 
@@ -17,11 +17,11 @@
17
17
  * comments, logs, and developer-facing docs.
18
18
  */
19
19
 
20
- export { taskSaveTool } from './task-save.js';
21
- export { taskRunTool } from './task-run.js';
22
- export { taskListTool } from './task-list.js';
23
- export { taskDeleteTool } from './task-delete.js';
24
- export { taskListShowTool } from './work-item-list.js';
25
- export { taskListAddTool } from './work-item-enqueue.js';
26
- export { taskListUpdateTool } from './work-item-update.js';
27
- export { taskListRemoveTool } from './work-item-remove.js';
20
+ export { executeTaskSave } from './task-save.js';
21
+ export { executeTaskRun } from './task-run.js';
22
+ export { executeTaskList } from './task-list.js';
23
+ export { executeTaskDelete } from './task-delete.js';
24
+ export { executeTaskListShow } from './work-item-list.js';
25
+ export { executeTaskListAdd } from './work-item-enqueue.js';
26
+ export { executeTaskListUpdate } from './work-item-update.js';
27
+ export { executeTaskListRemove } from './work-item-remove.js';