@vellumai/assistant 0.8.8 → 0.8.9-staging.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 (360) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/examples/plugins/echo/README.md +61 -60
  4. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  5. package/examples/plugins/echo/hooks/stop.ts +16 -0
  6. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  7. package/examples/plugins/echo/package.json +1 -2
  8. package/examples/plugins/echo/src/emit.ts +19 -0
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  10. package/openapi.yaml +235 -6
  11. package/package.json +2 -2
  12. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  13. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  14. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  15. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  17. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  18. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  19. package/src/__tests__/agent-loop.test.ts +441 -96
  20. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  21. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  22. package/src/__tests__/anthropic-provider.test.ts +1 -1
  23. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  24. package/src/__tests__/app-control-flow.test.ts +1 -1
  25. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  26. package/src/__tests__/app-executors.test.ts +132 -0
  27. package/src/__tests__/approval-cascade.test.ts +5 -4
  28. package/src/__tests__/approval-routes-http.test.ts +4 -1
  29. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  30. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  31. package/src/__tests__/channel-approvals.test.ts +1 -1
  32. package/src/__tests__/compaction-circuit.test.ts +258 -0
  33. package/src/__tests__/compaction-direct.test.ts +132 -0
  34. package/src/__tests__/compaction-events.test.ts +5 -5
  35. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  36. package/src/__tests__/context-overflow-reducer.test.ts +1 -1
  37. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
  38. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  39. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  40. package/src/__tests__/conversation-agent-loop-overflow.test.ts +142 -218
  41. package/src/__tests__/conversation-agent-loop.test.ts +297 -586
  42. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  43. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
  44. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  45. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  46. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
  47. package/src/__tests__/conversation-process-callsite.test.ts +14 -14
  48. package/src/__tests__/conversation-provider-retry-repair.test.ts +70 -65
  49. package/src/__tests__/conversation-queue.test.ts +9 -9
  50. package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
  51. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  52. package/src/__tests__/conversation-slash-queue.test.ts +6 -4
  53. package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
  54. package/src/__tests__/conversation-speed-override.test.ts +10 -9
  55. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  56. package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
  57. package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
  58. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
  59. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  60. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  61. package/src/__tests__/db-acp-history.test.ts +101 -0
  62. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  63. package/src/__tests__/empty-response-hook.test.ts +1 -1
  64. package/src/__tests__/file-write-tool.test.ts +63 -0
  65. package/src/__tests__/gateway-only-guard.test.ts +12 -2
  66. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  67. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  68. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  69. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  70. package/src/__tests__/heartbeat-service.test.ts +1 -0
  71. package/src/__tests__/history-repair-hook.test.ts +1 -1
  72. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  73. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  74. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  75. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  76. package/src/__tests__/injector-background-turn.test.ts +13 -23
  77. package/src/__tests__/injector-chain.test.ts +268 -44
  78. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  79. package/src/__tests__/injector-document-comments.test.ts +97 -114
  80. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  81. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  82. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  83. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  84. package/src/__tests__/memory-retrieval-hook.test.ts +131 -26
  85. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  86. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  87. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  88. package/src/__tests__/plugin-bootstrap.test.ts +12 -23
  89. package/src/__tests__/plugin-registry.test.ts +3 -49
  90. package/src/__tests__/plugin-types.test.ts +0 -70
  91. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  92. package/src/__tests__/reaction-persistence.test.ts +1 -1
  93. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  94. package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
  95. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  96. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  97. package/src/__tests__/subagent-detail.test.ts +25 -7
  98. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  99. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  100. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  101. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  102. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  103. package/src/__tests__/title-generate-hook.test.ts +1 -1
  104. package/src/__tests__/tool-error-hook.test.ts +1 -1
  105. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  106. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  107. package/src/acp/__tests__/agent-process.test.ts +161 -0
  108. package/src/acp/__tests__/client-handler.test.ts +40 -0
  109. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  110. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  111. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  112. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  113. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  114. package/src/acp/agent-process.ts +61 -1
  115. package/src/acp/auto-install.test.ts +280 -0
  116. package/src/acp/auto-install.ts +232 -0
  117. package/src/acp/client-handler.ts +31 -0
  118. package/src/acp/feature-gate.test.ts +48 -0
  119. package/src/acp/feature-gate.ts +34 -0
  120. package/src/acp/prepare-agent-env.ts +80 -27
  121. package/src/acp/resolve-agent.test.ts +225 -9
  122. package/src/acp/resolve-agent.ts +122 -17
  123. package/src/acp/resume-hint.ts +23 -0
  124. package/src/acp/session-manager.ts +507 -73
  125. package/src/agent/compaction-circuit.ts +60 -102
  126. package/src/agent/loop.ts +414 -248
  127. package/src/api/responses/conversation-message.ts +14 -1
  128. package/src/approvals/guardian-request-resolvers.ts +1 -1
  129. package/src/background-wake/next-wake.ts +1 -0
  130. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  131. package/src/cli/commands/plugins.ts +43 -37
  132. package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
  133. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  134. package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
  135. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
  136. package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
  137. package/src/cli/lib/install-from-github.ts +464 -55
  138. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  139. package/src/cli/lib/plugin-details.ts +409 -0
  140. package/src/cli/lib/plugin-marketplace.ts +197 -0
  141. package/src/cli/lib/search-plugins.ts +195 -29
  142. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  143. package/src/config/acp-defaults.test.ts +10 -0
  144. package/src/config/acp-defaults.ts +6 -0
  145. package/src/config/bundled-skills/acp/SKILL.md +85 -33
  146. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  147. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  148. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  149. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  150. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  151. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  152. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  153. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  154. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  155. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  156. package/src/config/bundled-tool-registry.ts +4 -0
  157. package/src/config/call-site-defaults.ts +0 -2
  158. package/src/config/feature-flag-registry.json +15 -6
  159. package/src/config/schemas/call-site-catalog.ts +0 -14
  160. package/src/config/schemas/heartbeat.ts +9 -0
  161. package/src/config/schemas/llm.ts +0 -2
  162. package/src/context/compactor.ts +22 -4
  163. package/src/context/strip-injections.ts +8 -2
  164. package/src/context/window-manager.ts +27 -13
  165. package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
  166. package/src/daemon/conversation-agent-loop.ts +175 -1055
  167. package/src/daemon/conversation-lifecycle.ts +11 -255
  168. package/src/daemon/conversation-process.ts +8 -136
  169. package/src/daemon/conversation-registry.ts +159 -0
  170. package/src/daemon/conversation-runtime-assembly.ts +293 -392
  171. package/src/daemon/conversation-store.ts +9 -90
  172. package/src/daemon/conversation-surfaces.ts +24 -8
  173. package/src/daemon/conversation-workspace.ts +17 -0
  174. package/src/daemon/conversation.ts +404 -57
  175. package/src/daemon/disk-pressure-policy.ts +0 -1
  176. package/src/daemon/external-plugins-bootstrap.ts +14 -19
  177. package/src/daemon/handlers/conversations.ts +3 -1
  178. package/src/daemon/handlers/skills.ts +4 -1
  179. package/src/daemon/host-proxy-preactivation.ts +1 -3
  180. package/src/daemon/lifecycle.ts +21 -7
  181. package/src/daemon/server.ts +2 -0
  182. package/src/daemon/wake-conversation-ops.ts +269 -0
  183. package/src/embedded/plugin-api.ts +2 -2
  184. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  185. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  186. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  187. package/src/heartbeat/heartbeat-service.ts +26 -0
  188. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  189. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  190. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  191. package/src/ipc/skill-routes/memory.ts +4 -2
  192. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  193. package/src/memory/conversation-crud.ts +29 -19
  194. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  195. package/src/memory/db-init.ts +2 -0
  196. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  197. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  198. package/src/memory/jobs-worker.ts +25 -1
  199. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  200. package/src/memory/migrations/index.ts +1 -0
  201. package/src/memory/schema/acp.ts +4 -0
  202. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  203. package/src/memory/v2/consolidation-job.ts +13 -4
  204. package/src/plugin-api/constants.ts +4 -0
  205. package/src/plugin-api/index.ts +6 -5
  206. package/src/plugin-api/types.ts +75 -0
  207. package/src/plugins/defaults/compaction/compact.ts +59 -0
  208. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +7 -7
  209. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  210. package/src/plugins/defaults/compaction/package.json +1 -2
  211. package/src/plugins/defaults/empty-response/package.json +0 -1
  212. package/src/plugins/defaults/history-repair/package.json +0 -1
  213. package/src/plugins/defaults/index.ts +135 -26
  214. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  215. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +184 -74
  216. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  217. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  218. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  219. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
  220. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +9 -6
  221. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
  222. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +8 -5
  223. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
  224. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
  225. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +10 -5
  226. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
  227. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +5 -5
  228. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
  229. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
  230. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
  231. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
  232. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  233. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  234. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  235. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
  236. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
  237. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  238. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
  239. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
  240. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
  241. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
  242. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +5 -5
  243. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
  244. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +7 -7
  245. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
  246. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
  247. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
  248. package/src/plugins/defaults/title-generate/package.json +0 -1
  249. package/src/plugins/defaults/tool-error/package.json +0 -1
  250. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  251. package/src/plugins/pipeline.ts +6 -293
  252. package/src/plugins/registry.ts +9 -37
  253. package/src/plugins/types.ts +76 -381
  254. package/src/plugins/user-loader.ts +30 -127
  255. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  256. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
  257. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  258. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  259. package/src/runtime/agent-wake.ts +108 -209
  260. package/src/runtime/assistant-event-hub.ts +1 -1
  261. package/src/runtime/channel-approvals.ts +1 -1
  262. package/src/runtime/interactive-ui.ts +1 -1
  263. package/src/runtime/routes/__tests__/acp-routes.test.ts +315 -55
  264. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  265. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  266. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  267. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  268. package/src/runtime/routes/acp-routes.test.ts +89 -25
  269. package/src/runtime/routes/acp-routes.ts +81 -29
  270. package/src/runtime/routes/approval-routes.ts +1 -1
  271. package/src/runtime/routes/browser-routes.ts +1 -1
  272. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  273. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  274. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  275. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  276. package/src/runtime/routes/conversation-routes.ts +28 -2
  277. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  278. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  279. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  280. package/src/runtime/routes/host-cu-routes.ts +1 -1
  281. package/src/runtime/routes/identity-routes.ts +18 -3
  282. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  283. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  284. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  285. package/src/runtime/routes/memory-v3-routes.ts +16 -6
  286. package/src/runtime/routes/playground/helpers.ts +1 -1
  287. package/src/runtime/routes/plugins-routes.ts +337 -35
  288. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  289. package/src/runtime/routes/work-items-routes.ts +2 -4
  290. package/src/runtime/services/conversation-serializer.ts +1 -1
  291. package/src/signals/cancel.ts +2 -4
  292. package/src/subagent/manager.ts +21 -5
  293. package/src/tools/acp/context.ts +20 -0
  294. package/src/tools/acp/list-agents.test.ts +8 -2
  295. package/src/tools/acp/spawn.test.ts +176 -195
  296. package/src/tools/acp/spawn.ts +37 -172
  297. package/src/tools/acp/steer.test.ts +105 -8
  298. package/src/tools/acp/steer.ts +48 -17
  299. package/src/tools/apps/executors.ts +166 -50
  300. package/src/tools/filesystem/write.ts +34 -0
  301. package/src/tools/subagent/spawn.ts +2 -4
  302. package/src/tools/ui-surface/definitions.ts +25 -5
  303. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  304. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  305. package/docs/plugins.md +0 -832
  306. package/examples/plugins/echo/register.ts +0 -143
  307. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  308. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  309. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  310. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  311. package/src/__tests__/pipeline-runner.test.ts +0 -554
  312. package/src/__tests__/plugin-external-api.test.ts +0 -68
  313. package/src/daemon/wake-target-adapter.ts +0 -253
  314. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  315. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  316. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  317. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  318. package/src/plugins/defaults/compaction/register.ts +0 -35
  319. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  320. package/src/plugins/defaults/empty-response/register.ts +0 -23
  321. package/src/plugins/defaults/history-repair/register.ts +0 -24
  322. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  323. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  324. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  325. package/src/plugins/defaults/title-generate/register.ts +0 -35
  326. package/src/plugins/defaults/tool-error/register.ts +0 -23
  327. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  328. package/src/plugins/external-api.ts +0 -104
  329. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  330. package/src/proactive-artifact/decision.test.ts +0 -226
  331. package/src/proactive-artifact/decision.ts +0 -165
  332. package/src/proactive-artifact/index.ts +0 -7
  333. package/src/proactive-artifact/job.test.ts +0 -962
  334. package/src/proactive-artifact/job.ts +0 -372
  335. package/src/proactive-artifact/message-copy.ts +0 -58
  336. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  337. package/src/proactive-artifact/trigger-state.ts +0 -123
  338. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
  339. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
  340. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  341. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  342. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +0 -0
  343. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
  344. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/provider-blocks.test.ts +0 -0
  345. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
  346. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
  347. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  348. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  349. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
  350. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  351. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  352. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  353. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  354. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  355. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  356. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
  357. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
  358. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
  359. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
  360. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
@@ -1,13 +1,24 @@
1
1
  /**
2
- * Tests for `GET /v1/acp/sessions`.
2
+ * Tests for ACP route handlers.
3
3
  *
4
- * The handler merges in-memory `AcpSessionManager.getStatus()` output with
5
- * persisted `acp_session_history` rows, deduping by id (in-memory wins),
6
- * filtering by `?conversationId`, sorting newest-first, and truncating to
7
- * `?limit` (default 50, max 500).
4
+ * `GET /v1/acp/sessions`: the handler merges in-memory
5
+ * `AcpSessionManager.getStatus()` output with persisted
6
+ * `acp_session_history` rows, deduping by id (in-memory wins), filtering by
7
+ * `?conversationId`, sorting newest-first, and truncating to `?limit`
8
+ * (default 50, max 500).
9
+ *
10
+ * `POST /v1/acp/spawn`: when the adapter binary is missing, the handler
11
+ * silently auto-installs allowlisted adapter packages via a sandboxed `bun`
12
+ * global install before failing with the install hint. `execFile` is stubbed
13
+ * via the shared `installExecFileStub` helper so tests can script
14
+ * `bun add --global` outcomes.
8
15
  */
9
16
 
10
- import { beforeEach, describe, expect, mock, test } from "bun:test";
17
+ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
18
+
19
+ import { installAcpConfigStub } from "../../../acp/__tests__/helpers/acp-config-stub.js";
20
+ import { installExecFileStub } from "../../../acp/__tests__/helpers/exec-file-stub.js";
21
+ import { installWhichStub } from "../../../acp/__tests__/helpers/which-stub.js";
11
22
 
12
23
  mock.module("../../../util/logger.js", () => ({
13
24
  getLogger: () =>
@@ -16,6 +27,12 @@ mock.module("../../../util/logger.js", () => ({
16
27
  }),
17
28
  }));
18
29
 
30
+ const {
31
+ execScripts,
32
+ execFileMock,
33
+ reset: resetExecFileStub,
34
+ } = installExecFileStub();
35
+
19
36
  // ---------------------------------------------------------------------------
20
37
  // Stub the ACP session manager so tests control the in-memory side without
21
38
  // spawning real child processes. The route handler imports
@@ -37,64 +54,61 @@ interface FakeSessionState {
37
54
 
38
55
  let fakeInMemorySessions: FakeSessionState[] = [];
39
56
 
57
+ const spawnMock = mock(async () => ({
58
+ acpSessionId: "acp-route-session",
59
+ protocolSessionId: "proto-route-session",
60
+ }));
61
+
62
+ const defaultSteerOrResumeImpl = async (
63
+ _id: string,
64
+ _instruction: string,
65
+ ): Promise<{ resumed: boolean }> => ({ resumed: false });
66
+ let steerOrResumeImpl: (
67
+ id: string,
68
+ instruction: string,
69
+ ) => Promise<{ resumed: boolean }> = defaultSteerOrResumeImpl;
70
+ const steerOrResumeMock = mock(
71
+ (id: string, instruction: string, _send: unknown) =>
72
+ steerOrResumeImpl(id, instruction),
73
+ );
74
+
40
75
  mock.module("../../../acp/index.js", () => ({
41
76
  getAcpSessionManager: () => ({
42
77
  getStatus: () => fakeInMemorySessions,
78
+ spawn: spawnMock,
79
+ steerOrResume: steerOrResumeMock,
43
80
  }),
44
81
  }));
45
82
 
46
- import { getSqlite } from "../../../memory/db-connection.js";
83
+ // Identity env-prep: the credential-broker plumbing it wraps is exercised in
84
+ // its own suite; spawn tests here only care about the resolve/install flow.
85
+ mock.module("../../../acp/prepare-agent-env.js", () => ({
86
+ prepareAgentEnv: async (agentConfig: unknown) => agentConfig,
87
+ }));
88
+
89
+ const config = await installAcpConfigStub();
90
+ const which = installWhichStub();
91
+
92
+ import {
93
+ clearHistory,
94
+ insertHistoryRow,
95
+ } from "../../../acp/__tests__/helpers/acp-history-db.js";
96
+ import {
97
+ AcpResumeError,
98
+ AcpSessionNotFoundError,
99
+ } from "../../../acp/session-manager.js";
47
100
  import { initializeDb } from "../../../memory/db-init.js";
48
- import { ROUTES } from "../acp-routes.js";
101
+ import { FailedDependencyError, NotFoundError } from "../errors.js";
49
102
 
50
- initializeDb();
103
+ const { ROUTES } = await import("../acp-routes.js");
104
+ const { _resetAdapterInstallCacheForTests } =
105
+ await import("../../../acp/auto-install.js");
51
106
 
52
- function clearHistory(): void {
53
- getSqlite().run("DELETE FROM acp_session_history");
54
- }
107
+ initializeDb();
55
108
 
56
- function insertHistoryRow(row: {
57
- id: string;
58
- agentId: string;
59
- acpSessionId: string;
60
- parentConversationId: string;
61
- startedAt: number;
62
- completedAt?: number | null;
63
- status: string;
64
- stopReason?: string | null;
65
- error?: string | null;
66
- eventLogJson?: string;
67
- }): void {
68
- getSqlite()
69
- .query(
70
- /*sql*/ `
71
- INSERT INTO acp_session_history (
72
- id,
73
- agent_id,
74
- acp_session_id,
75
- parent_conversation_id,
76
- started_at,
77
- completed_at,
78
- status,
79
- stop_reason,
80
- error,
81
- event_log_json
82
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
83
- `,
84
- )
85
- .run(
86
- row.id,
87
- row.agentId,
88
- row.acpSessionId,
89
- row.parentConversationId,
90
- row.startedAt,
91
- row.completedAt ?? null,
92
- row.status,
93
- row.stopReason ?? null,
94
- row.error ?? null,
95
- row.eventLogJson ?? "[]",
96
- );
97
- }
109
+ afterAll(() => {
110
+ which.restore();
111
+ });
98
112
 
99
113
  function getSessionsHandler() {
100
114
  const route = ROUTES.find(
@@ -122,6 +136,13 @@ interface ResponseShape {
122
136
  beforeEach(() => {
123
137
  fakeInMemorySessions = [];
124
138
  clearHistory();
139
+ resetExecFileStub();
140
+ spawnMock.mockClear();
141
+ steerOrResumeMock.mockClear();
142
+ steerOrResumeImpl = defaultSteerOrResumeImpl;
143
+ _resetAdapterInstallCacheForTests();
144
+ config.setConfig({});
145
+ which.setWhich((cmd) => `/usr/local/bin/${cmd}`);
125
146
  });
126
147
 
127
148
  describe("GET /v1/acp/sessions — merged in-memory + history", () => {
@@ -306,7 +327,9 @@ describe("GET /v1/acp/sessions — merged in-memory + history", () => {
306
327
  });
307
328
 
308
329
  const handler = getSessionsHandler();
309
- const body = (await handler({ queryParams: { limit: "2" } })) as ResponseShape;
330
+ const body = (await handler({
331
+ queryParams: { limit: "2" },
332
+ })) as ResponseShape;
310
333
  expect(body.sessions).toHaveLength(2);
311
334
  expect(body.sessions.map((s) => s.id)).toEqual(["live-newest", "hist-mid"]);
312
335
  });
@@ -392,3 +415,240 @@ describe("GET /v1/acp/sessions — merged in-memory + history", () => {
392
415
  expect(body.sessions).toHaveLength(3);
393
416
  });
394
417
  });
418
+
419
+ // ---------------------------------------------------------------------------
420
+ // POST /v1/acp/spawn: auto-install on missing adapter binary
421
+ // ---------------------------------------------------------------------------
422
+
423
+ function getSpawnHandler() {
424
+ const route = ROUTES.find(
425
+ (r) => r.endpoint === "acp/spawn" && r.method === "POST",
426
+ );
427
+ if (!route) throw new Error("acp/spawn POST route not found");
428
+ return route.handler;
429
+ }
430
+
431
+ const SPAWN_BODY = {
432
+ agent: "claude",
433
+ task: "do something",
434
+ conversationId: "conv-1",
435
+ };
436
+
437
+ const BUN_BIN = "/usr/local/bin/bun";
438
+ const BUN_ADD_KEY = `${BUN_BIN} add`;
439
+
440
+ describe("POST /v1/acp/spawn: sandboxed bun auto-install on missing binary", () => {
441
+ test("known command + bun present: installs via bun, then spawns the real binary", async () => {
442
+ // Binary appears on PATH only after `bun add --global` runs, simulating a
443
+ // successful global install that links the adapter bin onto PATH.
444
+ let binaryOnPath = false;
445
+ which.setWhich((cmd) => {
446
+ if (cmd === "bun") return BUN_BIN;
447
+ if (binaryOnPath) return `/usr/local/bin/${cmd}`;
448
+ return null;
449
+ });
450
+ execScripts.set(BUN_ADD_KEY, {
451
+ stdout: "",
452
+ onCall: () => {
453
+ binaryOnPath = true;
454
+ },
455
+ });
456
+
457
+ const handler = getSpawnHandler();
458
+ const body = (await handler({ body: SPAWN_BODY })) as Record<
459
+ string,
460
+ unknown
461
+ >;
462
+
463
+ expect(body).toEqual({
464
+ acpSessionId: "acp-route-session",
465
+ protocolSessionId: "proto-route-session",
466
+ agent: "claude",
467
+ });
468
+ expect(spawnMock).toHaveBeenCalledTimes(1);
469
+ // The real adapter binary is spawned, not a `bun x` wrapper.
470
+ const agentConfigArg = (spawnMock.mock.calls[0] as unknown[])[1] as {
471
+ command: string;
472
+ };
473
+ expect(agentConfigArg.command).toBe("claude-agent-acp");
474
+ // Exactly one install, and it was `bun add --global` (never npm).
475
+ expect(execFileMock).toHaveBeenCalledTimes(1);
476
+ const [command, args] = execFileMock.mock.calls[0];
477
+ expect(command).toBe(BUN_BIN);
478
+ expect(args).toEqual([
479
+ "add",
480
+ "--global",
481
+ "@agentclientprotocol/claude-agent-acp",
482
+ ]);
483
+ });
484
+
485
+ test("install runs in a temp dir (not the task cwd) with secrets stripped", async () => {
486
+ let binaryOnPath = false;
487
+ which.setWhich((cmd) => {
488
+ if (cmd === "bun") return BUN_BIN;
489
+ if (binaryOnPath) return `/usr/local/bin/${cmd}`;
490
+ return null;
491
+ });
492
+ execScripts.set(BUN_ADD_KEY, {
493
+ stdout: "",
494
+ onCall: () => {
495
+ binaryOnPath = true;
496
+ },
497
+ });
498
+
499
+ const handler = getSpawnHandler();
500
+ await handler({ body: { ...SPAWN_BODY, cwd: "/untrusted/project" } });
501
+
502
+ const options = execFileMock.mock.calls[0][2] as {
503
+ cwd?: string;
504
+ env?: NodeJS.ProcessEnv;
505
+ };
506
+ expect(options.cwd).not.toBe("/untrusted/project");
507
+ expect(options.cwd).toContain("vellum-acp-install-");
508
+ expect(options.env?.CLAUDE_CODE_OAUTH_TOKEN).toBeUndefined();
509
+ expect(options.env?.GEMINI_API_KEY).toBeUndefined();
510
+ expect(options.env?.BUN_CONFIG_REGISTRY).toBe(
511
+ "https://registry.npmjs.org/",
512
+ );
513
+ });
514
+
515
+ test("bun absent: no install attempted, FailedDependencyError with the hint", async () => {
516
+ which.setWhich({}); // neither bun nor the adapter on PATH
517
+
518
+ const handler = getSpawnHandler();
519
+ const promise = handler({ body: SPAWN_BODY });
520
+ await expect(promise).rejects.toBeInstanceOf(FailedDependencyError);
521
+ await expect(promise).rejects.toThrow(
522
+ /claude-agent-acp is not on PATH.*bun add -g @agentclientprotocol\/claude-agent-acp/,
523
+ );
524
+ expect(execFileMock).not.toHaveBeenCalled();
525
+ expect(spawnMock).not.toHaveBeenCalled();
526
+ });
527
+
528
+ test("install failure: FailedDependencyError carries hint and failure reason, never npm", async () => {
529
+ which.setWhich({ bun: BUN_BIN });
530
+ execScripts.set(BUN_ADD_KEY, {
531
+ error: new Error("EACCES: permission denied"),
532
+ });
533
+
534
+ const handler = getSpawnHandler();
535
+ const promise = handler({ body: SPAWN_BODY });
536
+ await expect(promise).rejects.toBeInstanceOf(FailedDependencyError);
537
+ await expect(promise).rejects.toThrow(
538
+ /claude-agent-acp is not on PATH.*bun add -g @agentclientprotocol\/claude-agent-acp.*auto-install failed.*EACCES/,
539
+ );
540
+ for (const call of execFileMock.mock.calls) {
541
+ expect(call[0]).not.toBe("npm");
542
+ }
543
+ expect(spawnMock).not.toHaveBeenCalled();
544
+ });
545
+
546
+ test("unknown command: plain hint maps to FailedDependencyError", async () => {
547
+ // The allowlist itself (no npm invocation for unmapped commands) is
548
+ // pinned in auto-install.test.ts and spawn.test.ts; this asserts only
549
+ // the route's transport mapping of the plain-hint failure.
550
+ config.setConfig({
551
+ agents: { custom: { command: "custom-bin", args: [] } },
552
+ });
553
+ which.setWhich({});
554
+
555
+ const handler = getSpawnHandler();
556
+ const promise = handler({ body: { ...SPAWN_BODY, agent: "custom" } });
557
+ await expect(promise).rejects.toBeInstanceOf(FailedDependencyError);
558
+ await expect(promise).rejects.toThrow(
559
+ "custom-bin is not on PATH. Install 'custom-bin' and ensure it is on PATH.",
560
+ );
561
+ });
562
+ });
563
+
564
+ // ---------------------------------------------------------------------------
565
+ // POST /v1/acp/:id/steer: transparent resume of sessions not in memory
566
+ // ---------------------------------------------------------------------------
567
+
568
+ function getSteerHandler() {
569
+ const route = ROUTES.find(
570
+ (r) => r.endpoint === "acp/:id/steer" && r.method === "POST",
571
+ );
572
+ if (!route) throw new Error("acp/:id/steer POST route not found");
573
+ return route.handler;
574
+ }
575
+
576
+ describe("POST /v1/acp/:id/steer: resume fallback", () => {
577
+ test("in-memory session steers without a resume", async () => {
578
+ const handler = getSteerHandler();
579
+ const body = await handler({
580
+ pathParams: { id: "live-1" },
581
+ body: { instruction: "redirect" },
582
+ });
583
+
584
+ expect(body).toEqual({ acpSessionId: "live-1", steered: true });
585
+ expect(steerOrResumeMock).toHaveBeenCalledTimes(1);
586
+ expect(steerOrResumeMock.mock.calls[0][0]).toBe("live-1");
587
+ expect(steerOrResumeMock.mock.calls[0][1]).toBe("redirect");
588
+ expect(typeof steerOrResumeMock.mock.calls[0][2]).toBe("function");
589
+ });
590
+
591
+ test("resumed session reports the resumed flag", async () => {
592
+ steerOrResumeImpl = async () => ({ resumed: true });
593
+
594
+ const handler = getSteerHandler();
595
+ const body = await handler({
596
+ pathParams: { id: "gone-1" },
597
+ body: { instruction: "keep going" },
598
+ });
599
+
600
+ expect(body).toEqual({
601
+ acpSessionId: "gone-1",
602
+ steered: true,
603
+ resumed: true,
604
+ });
605
+ });
606
+
607
+ test("typed not-found (no session, no history row) maps to NotFoundError", async () => {
608
+ steerOrResumeImpl = async (id) => {
609
+ throw new AcpSessionNotFoundError(id);
610
+ };
611
+
612
+ const handler = getSteerHandler();
613
+ const promise = handler({
614
+ pathParams: { id: "missing-1" },
615
+ body: { instruction: "go" },
616
+ });
617
+ await expect(promise).rejects.toBeInstanceOf(NotFoundError);
618
+ });
619
+
620
+ test("resume failure surfaces as FailedDependencyError with the actionable hint", async () => {
621
+ steerOrResumeImpl = async (id) => {
622
+ throw new AcpResumeError(
623
+ new Error(
624
+ `ACP session "${id}" was recorded before resume support ` +
625
+ `(no working directory persisted) and cannot be resumed. ` +
626
+ `Spawn a new session instead.`,
627
+ ),
628
+ );
629
+ };
630
+
631
+ const handler = getSteerHandler();
632
+ const promise = handler({
633
+ pathParams: { id: "legacy-1" },
634
+ body: { instruction: "go" },
635
+ });
636
+ await expect(promise).rejects.toBeInstanceOf(FailedDependencyError);
637
+ await expect(promise).rejects.toThrow(/recorded before resume support/);
638
+ });
639
+
640
+ test("plain steer errors map to NotFoundError", async () => {
641
+ steerOrResumeImpl = async (id) => {
642
+ throw new Error(
643
+ `ACP session "${id}" is not running (status: initializing)`,
644
+ );
645
+ };
646
+
647
+ const handler = getSteerHandler();
648
+ const promise = handler({
649
+ pathParams: { id: "init-1" },
650
+ body: { instruction: "go" },
651
+ });
652
+ await expect(promise).rejects.toBeInstanceOf(NotFoundError);
653
+ });
654
+ });
@@ -23,7 +23,7 @@ mock.module("../../assistant-event-hub.js", () => ({
23
23
  broadcastMessage: () => {},
24
24
  }));
25
25
 
26
- import { findConversation } from "../../../daemon/conversation-store.js";
26
+ import { findConversation } from "../../../daemon/conversation-registry.js";
27
27
  import { createConversation } from "../../../memory/conversation-crud.js";
28
28
  import { getDb } from "../../../memory/db-connection.js";
29
29
  import { initializeDb } from "../../../memory/db-init.js";