@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
@@ -56,10 +56,18 @@ describe("AgentLoop", () => {
56
56
  // 1. Basic text response
57
57
  test("returns history with assistant message for simple text response", async () => {
58
58
  const { provider } = createMockProvider([textResponse("Hi there!")]);
59
- const loop = new AgentLoop(provider, "system prompt");
59
+ const loop = new AgentLoop({
60
+ provider: provider,
61
+ systemPrompt: "system prompt",
62
+ conversationId: "test-conversation",
63
+ });
60
64
 
61
65
  const events: AgentEvent[] = [];
62
- const { history } = await loop.run([userMessage], collectEvents(events));
66
+ const { history } = await loop.run({
67
+ messages: [userMessage],
68
+ onEvent: collectEvents(events),
69
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
70
+ });
63
71
 
64
72
  // History should contain original user message + assistant response
65
73
  expect(history).toHaveLength(2);
@@ -85,12 +93,19 @@ describe("AgentLoop", () => {
85
93
  return { content: "file data here", isError: false };
86
94
  };
87
95
 
88
- const loop = new AgentLoop(provider, "system", {
96
+ const loop = new AgentLoop({
97
+ provider: provider,
98
+ systemPrompt: "system",
99
+ conversationId: "test-conversation",
89
100
  tools: dummyTools,
90
101
  toolExecutor: toolExecutor,
91
102
  });
92
103
  const events: AgentEvent[] = [];
93
- const { history } = await loop.run([userMessage], collectEvents(events));
104
+ const { history } = await loop.run({
105
+ messages: [userMessage],
106
+ onEvent: collectEvents(events),
107
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
108
+ });
94
109
 
95
110
  // Tool executor was called with correct args
96
111
  expect(toolCalls).toHaveLength(1);
@@ -134,12 +149,18 @@ describe("AgentLoop", () => {
134
149
  overrideProfile = "quality-optimized";
135
150
  return { content: "ok", isError: false };
136
151
  };
137
- const loop = new AgentLoop(provider, "system", {
152
+ const loop = new AgentLoop({
153
+ provider: provider,
154
+ systemPrompt: "system",
155
+ conversationId: "test-conversation",
138
156
  tools: dummyTools,
139
157
  toolExecutor: toolExecutor,
140
158
  });
141
159
 
142
- await loop.run([userMessage], collectEvents([]), {
160
+ await loop.run({
161
+ messages: [userMessage],
162
+ onEvent: collectEvents([]),
163
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
143
164
  requestId: "req-1",
144
165
  callSite: "mainAgent",
145
166
  resolveOverrideProfile: () => overrideProfile,
@@ -163,12 +184,18 @@ describe("AgentLoop", () => {
163
184
  maxInputTokens = 10_000;
164
185
  return { content: toolOutput, isError: false };
165
186
  };
166
- const loop = new AgentLoop(provider, "system", {
187
+ const loop = new AgentLoop({
188
+ provider: provider,
189
+ systemPrompt: "system",
190
+ conversationId: "test-conversation",
167
191
  tools: dummyTools,
168
192
  toolExecutor: toolExecutor,
169
193
  });
170
194
 
171
- await loop.run([userMessage], collectEvents([]), {
195
+ await loop.run({
196
+ messages: [userMessage],
197
+ onEvent: collectEvents([]),
198
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
172
199
  requestId: "req-1",
173
200
  callSite: "mainAgent",
174
201
  resolveContextWindow: () => ({
@@ -204,11 +231,18 @@ describe("AgentLoop", () => {
204
231
  };
205
232
  };
206
233
 
207
- const loop = new AgentLoop(provider, "system", {
234
+ const loop = new AgentLoop({
235
+ provider: provider,
236
+ systemPrompt: "system",
237
+ conversationId: "test-conversation",
208
238
  tools: dummyTools,
209
239
  toolExecutor: toolExecutor,
210
240
  });
211
- const { history } = await loop.run([userMessage], () => {});
241
+ const { history } = await loop.run({
242
+ messages: [userMessage],
243
+ onEvent: () => {},
244
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
245
+ });
212
246
 
213
247
  // Provider called 3 times (two tool rounds + final text)
214
248
  expect(calls).toHaveLength(3);
@@ -227,8 +261,17 @@ describe("AgentLoop", () => {
227
261
  ]);
228
262
 
229
263
  // No tool executor provided
230
- const loop = new AgentLoop(provider, "system", { tools: dummyTools });
231
- const { history } = await loop.run([userMessage], () => {});
264
+ const loop = new AgentLoop({
265
+ provider: provider,
266
+ systemPrompt: "system",
267
+ conversationId: "test-conversation",
268
+ tools: dummyTools,
269
+ });
270
+ const { history } = await loop.run({
271
+ messages: [userMessage],
272
+ onEvent: () => {},
273
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
274
+ });
232
275
 
233
276
  // Should stop after first response (no executor to handle tool use)
234
277
  expect(history).toHaveLength(2);
@@ -245,9 +288,17 @@ describe("AgentLoop", () => {
245
288
  },
246
289
  };
247
290
 
248
- const loop = new AgentLoop(provider, "system");
291
+ const loop = new AgentLoop({
292
+ provider: provider,
293
+ systemPrompt: "system",
294
+ conversationId: "test-conversation",
295
+ });
249
296
  const events: AgentEvent[] = [];
250
- const { history } = await loop.run([userMessage], collectEvents(events));
297
+ const { history } = await loop.run({
298
+ messages: [userMessage],
299
+ onEvent: collectEvents(events),
300
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
301
+ });
251
302
 
252
303
  // Only the original message remains (no assistant message added on error)
253
304
  expect(history).toHaveLength(1);
@@ -266,8 +317,15 @@ describe("AgentLoop", () => {
266
317
  controller.abort(); // abort immediately
267
318
 
268
319
  const { provider } = createMockProvider([textResponse("Should not reach")]);
269
- const loop = new AgentLoop(provider, "system");
270
- const { history } = await loop.run([userMessage], () => {}, {
320
+ const loop = new AgentLoop({
321
+ provider: provider,
322
+ systemPrompt: "system",
323
+ conversationId: "test-conversation",
324
+ });
325
+ const { history } = await loop.run({
326
+ messages: [userMessage],
327
+ onEvent: () => {},
328
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
271
329
  signal: controller.signal,
272
330
  });
273
331
 
@@ -294,11 +352,17 @@ describe("AgentLoop", () => {
294
352
  return { content: "data", isError: false };
295
353
  };
296
354
 
297
- const loop = new AgentLoop(provider, "system", {
355
+ const loop = new AgentLoop({
356
+ provider: provider,
357
+ systemPrompt: "system",
358
+ conversationId: "test-conversation",
298
359
  tools: dummyTools,
299
360
  toolExecutor: toolExecutor,
300
361
  });
301
- const { history } = await loop.run([userMessage], () => {}, {
362
+ const { history } = await loop.run({
363
+ messages: [userMessage],
364
+ onEvent: () => {},
365
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
302
366
  signal: controller.signal,
303
367
  });
304
368
 
@@ -340,12 +404,18 @@ describe("AgentLoop", () => {
340
404
  return { content: "should never return", isError: false };
341
405
  };
342
406
 
343
- const loop = new AgentLoop(provider, "system", {
407
+ const loop = new AgentLoop({
408
+ provider: provider,
409
+ systemPrompt: "system",
410
+ conversationId: "test-conversation",
344
411
  tools: dummyTools,
345
412
  toolExecutor: toolExecutor,
346
413
  });
347
414
  const start = Date.now();
348
- const { history } = await loop.run([userMessage], () => {}, {
415
+ const { history } = await loop.run({
416
+ messages: [userMessage],
417
+ onEvent: () => {},
418
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
349
419
  signal: controller.signal,
350
420
  });
351
421
  const elapsed = Date.now() - start;
@@ -384,10 +454,18 @@ describe("AgentLoop", () => {
384
454
  // 7. Events — verify text_delta and other events are emitted
385
455
  test("emits text_delta events during streaming", async () => {
386
456
  const { provider } = createMockProvider([textResponse("Hello world")]);
387
- const loop = new AgentLoop(provider, "system");
457
+ const loop = new AgentLoop({
458
+ provider: provider,
459
+ systemPrompt: "system",
460
+ conversationId: "test-conversation",
461
+ });
388
462
 
389
463
  const events: AgentEvent[] = [];
390
- await loop.run([userMessage], collectEvents(events));
464
+ await loop.run({
465
+ messages: [userMessage],
466
+ onEvent: collectEvents(events),
467
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
468
+ });
391
469
 
392
470
  const textDeltas = events.filter((e) => e.type === "text_delta");
393
471
  expect(textDeltas).toHaveLength(1);
@@ -398,10 +476,18 @@ describe("AgentLoop", () => {
398
476
 
399
477
  test("emits usage events", async () => {
400
478
  const { provider } = createMockProvider([textResponse("Hi")]);
401
- const loop = new AgentLoop(provider, "system");
479
+ const loop = new AgentLoop({
480
+ provider: provider,
481
+ systemPrompt: "system",
482
+ conversationId: "test-conversation",
483
+ });
402
484
 
403
485
  const events: AgentEvent[] = [];
404
- await loop.run([userMessage], collectEvents(events));
486
+ await loop.run({
487
+ messages: [userMessage],
488
+ onEvent: collectEvents(events),
489
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
490
+ });
405
491
 
406
492
  const usageEvents = events.filter((e) => e.type === "usage");
407
493
  expect(usageEvents).toHaveLength(1);
@@ -416,10 +502,18 @@ describe("AgentLoop", () => {
416
502
 
417
503
  test("emits message_complete events", async () => {
418
504
  const { provider } = createMockProvider([textResponse("Done")]);
419
- const loop = new AgentLoop(provider, "system");
505
+ const loop = new AgentLoop({
506
+ provider: provider,
507
+ systemPrompt: "system",
508
+ conversationId: "test-conversation",
509
+ });
420
510
 
421
511
  const events: AgentEvent[] = [];
422
- await loop.run([userMessage], collectEvents(events));
512
+ await loop.run({
513
+ messages: [userMessage],
514
+ onEvent: collectEvents(events),
515
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
516
+ });
423
517
 
424
518
  const completeEvents = events.filter((e) => e.type === "message_complete");
425
519
  expect(completeEvents).toHaveLength(1);
@@ -436,13 +530,20 @@ describe("AgentLoop", () => {
436
530
  ]);
437
531
 
438
532
  const toolExecutor = async () => ({ content: "file data", isError: false });
439
- const loop = new AgentLoop(provider, "system", {
533
+ const loop = new AgentLoop({
534
+ provider: provider,
535
+ systemPrompt: "system",
536
+ conversationId: "test-conversation",
440
537
  tools: dummyTools,
441
538
  toolExecutor: toolExecutor,
442
539
  });
443
540
 
444
541
  const events: AgentEvent[] = [];
445
- await loop.run([userMessage], collectEvents(events));
542
+ await loop.run({
543
+ messages: [userMessage],
544
+ onEvent: collectEvents(events),
545
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
546
+ });
446
547
 
447
548
  const toolUseEvents = events.filter((e) => e.type === "tool_use");
448
549
  expect(toolUseEvents).toHaveLength(1);
@@ -480,12 +581,19 @@ describe("AgentLoop", () => {
480
581
  content: "ENOENT: file not found",
481
582
  isError: true,
482
583
  });
483
- const loop = new AgentLoop(provider, "system", {
584
+ const loop = new AgentLoop({
585
+ provider: provider,
586
+ systemPrompt: "system",
587
+ conversationId: "test-conversation",
484
588
  tools: dummyTools,
485
589
  toolExecutor: toolExecutor,
486
590
  });
487
591
 
488
- await loop.run([userMessage], () => {});
592
+ await loop.run({
593
+ messages: [userMessage],
594
+ onEvent: () => {},
595
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
596
+ });
489
597
 
490
598
  const secondCallMessages = calls[1].messages;
491
599
  const lastMsg = secondCallMessages[secondCallMessages.length - 1];
@@ -515,12 +623,19 @@ describe("AgentLoop", () => {
515
623
  return { content: "full output", isError: false };
516
624
  };
517
625
 
518
- const loop = new AgentLoop(provider, "system", {
626
+ const loop = new AgentLoop({
627
+ provider: provider,
628
+ systemPrompt: "system",
629
+ conversationId: "test-conversation",
519
630
  tools: dummyTools,
520
631
  toolExecutor: toolExecutor,
521
632
  });
522
633
  const events: AgentEvent[] = [];
523
- await loop.run([userMessage], collectEvents(events));
634
+ await loop.run({
635
+ messages: [userMessage],
636
+ onEvent: collectEvents(events),
637
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
638
+ });
524
639
 
525
640
  const chunkEvents = events.filter((e) => e.type === "tool_output_chunk");
526
641
  expect(chunkEvents).toHaveLength(2);
@@ -537,11 +652,18 @@ describe("AgentLoop", () => {
537
652
  // 11. System prompt and tools are passed to provider
538
653
  test("passes system prompt and tools to provider", async () => {
539
654
  const { provider, calls } = createMockProvider([textResponse("Hi")]);
540
- const loop = new AgentLoop(provider, "My system prompt", {
655
+ const loop = new AgentLoop({
656
+ provider: provider,
657
+ systemPrompt: "My system prompt",
658
+ conversationId: "test-conversation",
541
659
  tools: dummyTools,
542
660
  });
543
661
 
544
- await loop.run([userMessage], () => {});
662
+ await loop.run({
663
+ messages: [userMessage],
664
+ onEvent: () => {},
665
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
666
+ });
545
667
 
546
668
  expect(calls[0].systemPrompt).toBe("My system prompt");
547
669
  expect(calls[0].tools).toEqual(dummyTools);
@@ -550,9 +672,17 @@ describe("AgentLoop", () => {
550
672
  // 12. No tools configured — tools are not passed to provider
551
673
  test("does not pass tools to provider when none are configured", async () => {
552
674
  const { provider, calls } = createMockProvider([textResponse("Hi")]);
553
- const loop = new AgentLoop(provider, "system");
675
+ const loop = new AgentLoop({
676
+ provider: provider,
677
+ systemPrompt: "system",
678
+ conversationId: "test-conversation",
679
+ });
554
680
 
555
- await loop.run([userMessage], () => {});
681
+ await loop.run({
682
+ messages: [userMessage],
683
+ onEvent: () => {},
684
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
685
+ });
556
686
 
557
687
  expect(calls[0].tools).toBeUndefined();
558
688
  });
@@ -605,12 +735,19 @@ describe("AgentLoop", () => {
605
735
  };
606
736
  };
607
737
 
608
- const loop = new AgentLoop(provider, "system", {
738
+ const loop = new AgentLoop({
739
+ provider: provider,
740
+ systemPrompt: "system",
741
+ conversationId: "test-conversation",
609
742
  tools: dummyTools,
610
743
  toolExecutor: toolExecutor,
611
744
  });
612
745
  const events: AgentEvent[] = [];
613
- const { history } = await loop.run([userMessage], collectEvents(events));
746
+ const { history } = await loop.run({
747
+ messages: [userMessage],
748
+ onEvent: collectEvents(events),
749
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
750
+ });
614
751
 
615
752
  // All 3 tools should have been called
616
753
  expect(executionLog).toHaveLength(3);
@@ -699,12 +836,18 @@ describe("AgentLoop", () => {
699
836
  return { content: "data", isError: false };
700
837
  };
701
838
 
702
- const loop = new AgentLoop(provider, "system", {
839
+ const loop = new AgentLoop({
840
+ provider: provider,
841
+ systemPrompt: "system",
842
+ conversationId: "test-conversation",
703
843
  tools: dummyTools,
704
844
  toolExecutor: toolExecutor,
705
845
  });
706
846
  const events: AgentEvent[] = [];
707
- const { history } = await loop.run([userMessage], collectEvents(events), {
847
+ const { history } = await loop.run({
848
+ messages: [userMessage],
849
+ onEvent: collectEvents(events),
850
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
708
851
  signal: controller.signal,
709
852
  });
710
853
 
@@ -773,12 +916,19 @@ describe("AgentLoop", () => {
773
916
  return { content: `contents of ${path}`, isError: false };
774
917
  };
775
918
 
776
- const loop = new AgentLoop(provider, "system", {
919
+ const loop = new AgentLoop({
920
+ provider: provider,
921
+ systemPrompt: "system",
922
+ conversationId: "test-conversation",
777
923
  tools: dummyTools,
778
924
  toolExecutor: toolExecutor,
779
925
  });
780
926
  const events: AgentEvent[] = [];
781
- await loop.run([userMessage], collectEvents(events));
927
+ await loop.run({
928
+ messages: [userMessage],
929
+ onEvent: collectEvents(events),
930
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
931
+ });
782
932
 
783
933
  // Collect tool_result events in order
784
934
  const toolResultEvents = events.filter(
@@ -805,7 +955,10 @@ describe("AgentLoop", () => {
805
955
  ]);
806
956
 
807
957
  const toolExecutor = async () => ({ content: "file data", isError: false });
808
- const loop = new AgentLoop(provider, "system", {
958
+ const loop = new AgentLoop({
959
+ provider: provider,
960
+ systemPrompt: "system",
961
+ conversationId: "test-conversation",
809
962
  tools: dummyTools,
810
963
  toolExecutor: toolExecutor,
811
964
  });
@@ -816,7 +969,12 @@ describe("AgentLoop", () => {
816
969
  return "continue";
817
970
  };
818
971
 
819
- await loop.run([userMessage], () => {}, { onCheckpoint });
972
+ await loop.run({
973
+ messages: [userMessage],
974
+ onEvent: () => {},
975
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
976
+ onCheckpoint,
977
+ });
820
978
 
821
979
  expect(checkpoints).toHaveLength(1);
822
980
  expect(checkpoints[0]).toMatchObject({
@@ -837,14 +995,20 @@ describe("AgentLoop", () => {
837
995
  ]);
838
996
 
839
997
  const toolExecutor = async () => ({ content: "data", isError: false });
840
- const loop = new AgentLoop(provider, "system", {
998
+ const loop = new AgentLoop({
999
+ provider: provider,
1000
+ systemPrompt: "system",
1001
+ conversationId: "test-conversation",
841
1002
  tools: dummyTools,
842
1003
  toolExecutor: toolExecutor,
843
1004
  });
844
1005
 
845
1006
  const onCheckpoint = (): CheckpointDecision => "continue";
846
1007
 
847
- const { history } = await loop.run([userMessage], () => {}, {
1008
+ const { history } = await loop.run({
1009
+ messages: [userMessage],
1010
+ onEvent: () => {},
1011
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
848
1012
  onCheckpoint,
849
1013
  });
850
1014
 
@@ -864,14 +1028,20 @@ describe("AgentLoop", () => {
864
1028
  ]);
865
1029
 
866
1030
  const toolExecutor = async () => ({ content: "data", isError: false });
867
- const loop = new AgentLoop(provider, "system", {
1031
+ const loop = new AgentLoop({
1032
+ provider: provider,
1033
+ systemPrompt: "system",
1034
+ conversationId: "test-conversation",
868
1035
  tools: dummyTools,
869
1036
  toolExecutor: toolExecutor,
870
1037
  });
871
1038
 
872
1039
  const onCheckpoint = (): CheckpointDecision => "budget";
873
1040
 
874
- const { history } = await loop.run([userMessage], () => {}, {
1041
+ const { history } = await loop.run({
1042
+ messages: [userMessage],
1043
+ onEvent: () => {},
1044
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
875
1045
  onCheckpoint,
876
1046
  });
877
1047
 
@@ -891,12 +1061,19 @@ describe("AgentLoop", () => {
891
1061
  ]);
892
1062
 
893
1063
  const toolExecutor = async () => ({ content: "data", isError: false });
894
- const loop = new AgentLoop(provider, "system", {
1064
+ const loop = new AgentLoop({
1065
+ provider: provider,
1066
+ systemPrompt: "system",
1067
+ conversationId: "test-conversation",
895
1068
  tools: dummyTools,
896
1069
  toolExecutor: toolExecutor,
897
1070
  });
898
1071
 
899
- const { history } = await loop.run([userMessage], () => {});
1072
+ const { history } = await loop.run({
1073
+ messages: [userMessage],
1074
+ onEvent: () => {},
1075
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1076
+ });
900
1077
 
901
1078
  // Normal behavior: 2 provider calls, full history
902
1079
  expect(calls).toHaveLength(2);
@@ -914,7 +1091,10 @@ describe("AgentLoop", () => {
914
1091
  ]);
915
1092
 
916
1093
  const toolExecutor = async () => ({ content: "data", isError: false });
917
- const loop = new AgentLoop(provider, "system", {
1094
+ const loop = new AgentLoop({
1095
+ provider: provider,
1096
+ systemPrompt: "system",
1097
+ conversationId: "test-conversation",
918
1098
  tools: dummyTools,
919
1099
  toolExecutor: toolExecutor,
920
1100
  });
@@ -925,7 +1105,12 @@ describe("AgentLoop", () => {
925
1105
  return "continue";
926
1106
  };
927
1107
 
928
- await loop.run([userMessage], () => {}, { onCheckpoint });
1108
+ await loop.run({
1109
+ messages: [userMessage],
1110
+ onEvent: () => {},
1111
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1112
+ onCheckpoint,
1113
+ });
929
1114
 
930
1115
  expect(checkpoints).toHaveLength(3);
931
1116
  expect(checkpoints[0].turnIndex).toBe(0);
@@ -938,7 +1123,12 @@ describe("AgentLoop", () => {
938
1123
  const { provider } = createMockProvider([
939
1124
  textResponse("Just a text response"),
940
1125
  ]);
941
- const loop = new AgentLoop(provider, "system", { tools: dummyTools });
1126
+ const loop = new AgentLoop({
1127
+ provider: provider,
1128
+ systemPrompt: "system",
1129
+ conversationId: "test-conversation",
1130
+ tools: dummyTools,
1131
+ });
942
1132
 
943
1133
  const checkpoints: CheckpointInfo[] = [];
944
1134
  const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
@@ -946,7 +1136,10 @@ describe("AgentLoop", () => {
946
1136
  return "continue";
947
1137
  };
948
1138
 
949
- const { history } = await loop.run([userMessage], () => {}, {
1139
+ const { history } = await loop.run({
1140
+ messages: [userMessage],
1141
+ onEvent: () => {},
1142
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
950
1143
  onCheckpoint,
951
1144
  });
952
1145
 
@@ -991,7 +1184,10 @@ describe("AgentLoop", () => {
991
1184
  ]);
992
1185
 
993
1186
  const toolExecutor = async () => ({ content: "data", isError: false });
994
- const loop = new AgentLoop(provider, "system", {
1187
+ const loop = new AgentLoop({
1188
+ provider: provider,
1189
+ systemPrompt: "system",
1190
+ conversationId: "test-conversation",
995
1191
  tools: dummyTools,
996
1192
  toolExecutor: toolExecutor,
997
1193
  });
@@ -1002,7 +1198,12 @@ describe("AgentLoop", () => {
1002
1198
  return "continue";
1003
1199
  };
1004
1200
 
1005
- await loop.run([userMessage], () => {}, { onCheckpoint });
1201
+ await loop.run({
1202
+ messages: [userMessage],
1203
+ onEvent: () => {},
1204
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1205
+ onCheckpoint,
1206
+ });
1006
1207
 
1007
1208
  expect(checkpoints).toHaveLength(1);
1008
1209
  expect(checkpoints[0].toolCount).toBe(3);
@@ -1022,7 +1223,10 @@ describe("AgentLoop", () => {
1022
1223
 
1023
1224
  const { provider, calls } = createMockProvider(responses);
1024
1225
  const toolExecutor = async () => ({ content: "data", isError: false });
1025
- const loop = new AgentLoop(provider, "system", {
1226
+ const loop = new AgentLoop({
1227
+ provider: provider,
1228
+ systemPrompt: "system",
1229
+ conversationId: "test-conversation",
1026
1230
  tools: dummyTools,
1027
1231
  toolExecutor: toolExecutor,
1028
1232
  });
@@ -1035,7 +1239,10 @@ describe("AgentLoop", () => {
1035
1239
  };
1036
1240
 
1037
1241
  const events: AgentEvent[] = [];
1038
- const { history } = await loop.run([userMessage], collectEvents(events), {
1242
+ const { history } = await loop.run({
1243
+ messages: [userMessage],
1244
+ onEvent: collectEvents(events),
1245
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1039
1246
  onCheckpoint,
1040
1247
  });
1041
1248
 
@@ -1091,7 +1298,10 @@ describe("AgentLoop", () => {
1091
1298
  ]);
1092
1299
 
1093
1300
  const toolExecutor = async () => ({ content: "data", isError: false });
1094
- const loop = new AgentLoop(provider, "system", {
1301
+ const loop = new AgentLoop({
1302
+ provider: provider,
1303
+ systemPrompt: "system",
1304
+ conversationId: "test-conversation",
1095
1305
  tools: dummyTools,
1096
1306
  toolExecutor: toolExecutor,
1097
1307
  });
@@ -1101,7 +1311,10 @@ describe("AgentLoop", () => {
1101
1311
  return checkpoint.turnIndex === 1 ? "budget" : "continue";
1102
1312
  };
1103
1313
 
1104
- const { history } = await loop.run([userMessage], () => {}, {
1314
+ const { history } = await loop.run({
1315
+ messages: [userMessage],
1316
+ onEvent: () => {},
1317
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1105
1318
  onCheckpoint,
1106
1319
  });
1107
1320
 
@@ -1118,9 +1331,18 @@ describe("AgentLoop", () => {
1118
1331
  // 25. Without resolveTools, static tools are used
1119
1332
  test("without resolveTools, static tools are passed to provider", async () => {
1120
1333
  const { provider, calls } = createMockProvider([textResponse("Hi")]);
1121
- const loop = new AgentLoop(provider, "system", { tools: dummyTools });
1334
+ const loop = new AgentLoop({
1335
+ provider: provider,
1336
+ systemPrompt: "system",
1337
+ conversationId: "test-conversation",
1338
+ tools: dummyTools,
1339
+ });
1122
1340
 
1123
- await loop.run([userMessage], () => {});
1341
+ await loop.run({
1342
+ messages: [userMessage],
1343
+ onEvent: () => {},
1344
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1345
+ });
1124
1346
 
1125
1347
  expect(calls[0].tools).toEqual(dummyTools);
1126
1348
  });
@@ -1151,11 +1373,18 @@ describe("AgentLoop", () => {
1151
1373
  return resolvedTools;
1152
1374
  };
1153
1375
 
1154
- const loop = new AgentLoop(provider, "system", {
1376
+ const loop = new AgentLoop({
1377
+ provider: provider,
1378
+ systemPrompt: "system",
1379
+ conversationId: "test-conversation",
1155
1380
  toolExecutor: toolExecutor,
1156
1381
  resolveTools: resolveTools,
1157
1382
  });
1158
- await loop.run([userMessage], () => {});
1383
+ await loop.run({
1384
+ messages: [userMessage],
1385
+ onEvent: () => {},
1386
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1387
+ });
1159
1388
 
1160
1389
  // resolveTools should be called once per provider turn (2 turns total)
1161
1390
  expect(resolverCalls).toHaveLength(2);
@@ -1183,11 +1412,18 @@ describe("AgentLoop", () => {
1183
1412
  const resolveTools = (): ToolDefinition[] => dynamicTools;
1184
1413
 
1185
1414
  // Pass different static tools to verify they are overridden
1186
- const loop = new AgentLoop(provider, "system", {
1415
+ const loop = new AgentLoop({
1416
+ provider: provider,
1417
+ systemPrompt: "system",
1418
+ conversationId: "test-conversation",
1187
1419
  tools: dummyTools,
1188
1420
  resolveTools: resolveTools,
1189
1421
  });
1190
- await loop.run([userMessage], () => {});
1422
+ await loop.run({
1423
+ messages: [userMessage],
1424
+ onEvent: () => {},
1425
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1426
+ });
1191
1427
 
1192
1428
  // Provider should receive the dynamically resolved tools, not the static ones
1193
1429
  expect(calls[0].tools).toEqual(dynamicTools);
@@ -1240,11 +1476,18 @@ describe("AgentLoop", () => {
1240
1476
  ]);
1241
1477
 
1242
1478
  const toolExecutor = async () => ({ content: "ok", isError: false });
1243
- const loop = new AgentLoop(provider, "system", {
1479
+ const loop = new AgentLoop({
1480
+ provider: provider,
1481
+ systemPrompt: "system",
1482
+ conversationId: "test-conversation",
1244
1483
  toolExecutor: toolExecutor,
1245
1484
  resolveTools: resolveTools,
1246
1485
  });
1247
- await loop.run([userMessage], () => {});
1486
+ await loop.run({
1487
+ messages: [userMessage],
1488
+ onEvent: () => {},
1489
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1490
+ });
1248
1491
 
1249
1492
  // Provider should have been called 3 times
1250
1493
  expect(calls).toHaveLength(3);
@@ -1263,11 +1506,18 @@ describe("AgentLoop", () => {
1263
1506
  textResponse("No tools available"),
1264
1507
  ]);
1265
1508
 
1266
- const loop = new AgentLoop(provider, "system", {
1509
+ const loop = new AgentLoop({
1510
+ provider: provider,
1511
+ systemPrompt: "system",
1512
+ conversationId: "test-conversation",
1267
1513
  tools: dummyTools,
1268
1514
  resolveTools: resolveTools,
1269
1515
  });
1270
- await loop.run([userMessage], () => {});
1516
+ await loop.run({
1517
+ messages: [userMessage],
1518
+ onEvent: () => {},
1519
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1520
+ });
1271
1521
 
1272
1522
  // Empty array should result in undefined tools (same as no-tools behavior)
1273
1523
  expect(calls[0].tools).toBeUndefined();
@@ -1291,13 +1541,20 @@ describe("AgentLoop", () => {
1291
1541
  return { content: largeContent, isError: false };
1292
1542
  };
1293
1543
 
1294
- const loop = new AgentLoop(provider, "system", {
1544
+ const loop = new AgentLoop({
1545
+ provider: provider,
1546
+ systemPrompt: "system",
1547
+ conversationId: "test-conversation",
1295
1548
  config: { maxInputTokens: 180_000 },
1296
1549
  tools: dummyTools,
1297
1550
  toolExecutor: toolExecutor,
1298
1551
  });
1299
1552
  const events: AgentEvent[] = [];
1300
- const { history } = await loop.run([userMessage], collectEvents(events));
1553
+ const { history } = await loop.run({
1554
+ messages: [userMessage],
1555
+ onEvent: collectEvents(events),
1556
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1557
+ });
1301
1558
 
1302
1559
  // The tool result user message is at index 2 in history
1303
1560
  const toolResultMsg = history[2];
@@ -1340,13 +1597,20 @@ describe("AgentLoop", () => {
1340
1597
  return { content: smallContent, isError: false };
1341
1598
  };
1342
1599
 
1343
- const loop = new AgentLoop(provider, "system", {
1600
+ const loop = new AgentLoop({
1601
+ provider: provider,
1602
+ systemPrompt: "system",
1603
+ conversationId: "test-conversation",
1344
1604
  config: { maxInputTokens: 180_000 },
1345
1605
  tools: dummyTools,
1346
1606
  toolExecutor: toolExecutor,
1347
1607
  });
1348
1608
  const events: AgentEvent[] = [];
1349
- const { history } = await loop.run([userMessage], collectEvents(events));
1609
+ const { history } = await loop.run({
1610
+ messages: [userMessage],
1611
+ onEvent: collectEvents(events),
1612
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1613
+ });
1350
1614
 
1351
1615
  // The tool result user message is at index 2 in history
1352
1616
  const toolResultMsg = history[2];
@@ -1398,12 +1662,19 @@ describe("AgentLoop", () => {
1398
1662
  ],
1399
1663
  });
1400
1664
 
1401
- const loop = new AgentLoop(provider, "system", {
1665
+ const loop = new AgentLoop({
1666
+ provider: provider,
1667
+ systemPrompt: "system",
1668
+ conversationId: "test-conversation",
1402
1669
  tools: dummyTools,
1403
1670
  toolExecutor: toolExecutor,
1404
1671
  });
1405
1672
  const events: AgentEvent[] = [];
1406
- const { history } = await loop.run([userMessage], collectEvents(events));
1673
+ const { history } = await loop.run({
1674
+ messages: [userMessage],
1675
+ onEvent: collectEvents(events),
1676
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1677
+ });
1407
1678
 
1408
1679
  // The final assistant message in HISTORY should retain placeholders
1409
1680
  // (so the model never sees real values on subsequent turns)
@@ -1464,12 +1735,19 @@ describe("AgentLoop", () => {
1464
1735
  ],
1465
1736
  });
1466
1737
 
1467
- const loop = new AgentLoop(provider, "system", {
1738
+ const loop = new AgentLoop({
1739
+ provider: provider,
1740
+ systemPrompt: "system",
1741
+ conversationId: "test-conversation",
1468
1742
  tools: dummyTools,
1469
1743
  toolExecutor: toolExecutor,
1470
1744
  });
1471
1745
  const events: AgentEvent[] = [];
1472
- await loop.run([userMessage], collectEvents(events));
1746
+ await loop.run({
1747
+ messages: [userMessage],
1748
+ onEvent: collectEvents(events),
1749
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1750
+ });
1473
1751
 
1474
1752
  // Collect all text_delta events from the final turn (after tool result)
1475
1753
  const textDeltas = events.filter(
@@ -1496,12 +1774,19 @@ describe("AgentLoop", () => {
1496
1774
  // No sensitiveBindings
1497
1775
  });
1498
1776
 
1499
- const loop = new AgentLoop(provider, "system", {
1777
+ const loop = new AgentLoop({
1778
+ provider: provider,
1779
+ systemPrompt: "system",
1780
+ conversationId: "test-conversation",
1500
1781
  tools: dummyTools,
1501
1782
  toolExecutor: toolExecutor,
1502
1783
  });
1503
1784
  const events: AgentEvent[] = [];
1504
- const { history } = await loop.run([userMessage], collectEvents(events));
1785
+ const { history } = await loop.run({
1786
+ messages: [userMessage],
1787
+ onEvent: collectEvents(events),
1788
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1789
+ });
1505
1790
 
1506
1791
  const lastAssistant = history[history.length - 1];
1507
1792
  const textBlock = lastAssistant.content.find(
@@ -1540,11 +1825,18 @@ describe("AgentLoop", () => {
1540
1825
  return { content: "file contents", isError: false };
1541
1826
  };
1542
1827
 
1543
- const loop = new AgentLoop(provider, "system", {
1828
+ const loop = new AgentLoop({
1829
+ provider: provider,
1830
+ systemPrompt: "system",
1831
+ conversationId: "test-conversation",
1544
1832
  tools: dummyTools,
1545
1833
  toolExecutor: toolExecutor,
1546
1834
  });
1547
- await loop.run([userMessage], () => {});
1835
+ await loop.run({
1836
+ messages: [userMessage],
1837
+ onEvent: () => {},
1838
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1839
+ });
1548
1840
 
1549
1841
  // Provider should have been called 3 times (error -> retry -> final text)
1550
1842
  expect(calls).toHaveLength(3);
@@ -1598,11 +1890,18 @@ describe("AgentLoop", () => {
1598
1890
  return { content: "service unavailable", isError: true };
1599
1891
  };
1600
1892
 
1601
- const loop = new AgentLoop(provider, "system", {
1893
+ const loop = new AgentLoop({
1894
+ provider: provider,
1895
+ systemPrompt: "system",
1896
+ conversationId: "test-conversation",
1602
1897
  tools: dummyTools,
1603
1898
  toolExecutor: toolExecutor,
1604
1899
  });
1605
- await loop.run([userMessage], () => {});
1900
+ await loop.run({
1901
+ messages: [userMessage],
1902
+ onEvent: () => {},
1903
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1904
+ });
1606
1905
 
1607
1906
  expect(calls).toHaveLength(5);
1608
1907
 
@@ -1644,12 +1943,19 @@ describe("AgentLoop", () => {
1644
1943
  isError: false,
1645
1944
  });
1646
1945
 
1647
- const loop = new AgentLoop(provider, "system", {
1946
+ const loop = new AgentLoop({
1947
+ provider: provider,
1948
+ systemPrompt: "system",
1949
+ conversationId: "test-conversation",
1648
1950
  tools: dummyTools,
1649
1951
  toolExecutor: toolExecutor,
1650
1952
  });
1651
1953
  const events: AgentEvent[] = [];
1652
- const { history } = await loop.run([userMessage], collectEvents(events));
1954
+ const { history } = await loop.run({
1955
+ messages: [userMessage],
1956
+ onEvent: collectEvents(events),
1957
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
1958
+ });
1653
1959
 
1654
1960
  // Provider should be called 3 times: initial, empty response, retry
1655
1961
  expect(calls).toHaveLength(3);
@@ -1719,12 +2025,19 @@ describe("AgentLoop", () => {
1719
2025
  isError: false,
1720
2026
  });
1721
2027
 
1722
- const loop = new AgentLoop(provider, "system", {
2028
+ const loop = new AgentLoop({
2029
+ provider: provider,
2030
+ systemPrompt: "system",
2031
+ conversationId: "test-conversation",
1723
2032
  tools: dummyTools,
1724
2033
  toolExecutor: toolExecutor,
1725
2034
  });
1726
2035
  const events: AgentEvent[] = [];
1727
- const { history } = await loop.run([userMessage], collectEvents(events));
2036
+ const { history } = await loop.run({
2037
+ messages: [userMessage],
2038
+ onEvent: collectEvents(events),
2039
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
2040
+ });
1728
2041
 
1729
2042
  // Provider called exactly 2 times: initial [text+tool_use], then empty.
1730
2043
  // No third (retry) call because the prior turn had visible text.
@@ -1778,12 +2091,19 @@ describe("AgentLoop", () => {
1778
2091
  isError: false,
1779
2092
  });
1780
2093
 
1781
- const loop = new AgentLoop(provider, "system", {
2094
+ const loop = new AgentLoop({
2095
+ provider: provider,
2096
+ systemPrompt: "system",
2097
+ conversationId: "test-conversation",
1782
2098
  tools: dummyTools,
1783
2099
  toolExecutor: toolExecutor,
1784
2100
  });
1785
2101
  const events: AgentEvent[] = [];
1786
- const { history } = await loop.run([userMessage], collectEvents(events));
2102
+ const { history } = await loop.run({
2103
+ messages: [userMessage],
2104
+ onEvent: collectEvents(events),
2105
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
2106
+ });
1787
2107
 
1788
2108
  // Provider called 3 times: initial, empty, retry (also empty)
1789
2109
  expect(calls).toHaveLength(3);
@@ -1812,9 +2132,17 @@ describe("AgentLoop", () => {
1812
2132
 
1813
2133
  const { provider, calls } = createMockProvider([emptyResponse]);
1814
2134
 
1815
- const loop = new AgentLoop(provider, "system");
2135
+ const loop = new AgentLoop({
2136
+ provider: provider,
2137
+ systemPrompt: "system",
2138
+ conversationId: "test-conversation",
2139
+ });
1816
2140
  const events: AgentEvent[] = [];
1817
- const { history } = await loop.run([userMessage], collectEvents(events));
2141
+ const { history } = await loop.run({
2142
+ messages: [userMessage],
2143
+ onEvent: collectEvents(events),
2144
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
2145
+ });
1818
2146
 
1819
2147
  // Should NOT retry — this is the first turn with no tool use history
1820
2148
  expect(calls).toHaveLength(1);
@@ -1827,8 +2155,17 @@ describe("AgentLoop", () => {
1827
2155
  test("threads callSite from AgentLoop.run() into per-call provider config", async () => {
1828
2156
  const { provider, calls } = createMockProvider([textResponse("ok")]);
1829
2157
 
1830
- const loop = new AgentLoop(provider, "system");
1831
- await loop.run([userMessage], () => {}, { callSite: "heartbeatAgent" });
2158
+ const loop = new AgentLoop({
2159
+ provider: provider,
2160
+ systemPrompt: "system",
2161
+ conversationId: "test-conversation",
2162
+ });
2163
+ await loop.run({
2164
+ messages: [userMessage],
2165
+ onEvent: () => {},
2166
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
2167
+ callSite: "heartbeatAgent",
2168
+ });
1832
2169
 
1833
2170
  expect(calls).toHaveLength(1);
1834
2171
  expect(calls[0].options?.config?.callSite).toBe("heartbeatAgent");
@@ -1837,8 +2174,16 @@ describe("AgentLoop", () => {
1837
2174
  test("omits callSite from provider config when not supplied", async () => {
1838
2175
  const { provider, calls } = createMockProvider([textResponse("ok")]);
1839
2176
 
1840
- const loop = new AgentLoop(provider, "system");
1841
- await loop.run([userMessage], () => {});
2177
+ const loop = new AgentLoop({
2178
+ provider: provider,
2179
+ systemPrompt: "system",
2180
+ conversationId: "test-conversation",
2181
+ });
2182
+ await loop.run({
2183
+ messages: [userMessage],
2184
+ onEvent: () => {},
2185
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
2186
+ });
1842
2187
 
1843
2188
  expect(calls).toHaveLength(1);
1844
2189
  expect(calls[0].options?.config?.callSite).toBeUndefined();