@vellumai/assistant 0.8.10 → 0.8.11-staging.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. package/bun.lock +62 -1
  2. package/docs/workspace-tools.md +196 -0
  3. package/examples/plugins/echo/README.md +3 -3
  4. package/knip.json +1 -0
  5. package/openapi.yaml +460 -128
  6. package/package.json +2 -1
  7. package/scripts/build-plugin-api.ts +299 -0
  8. package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
  9. package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
  10. package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
  11. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
  12. package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
  13. package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
  14. package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
  15. package/src/__tests__/agent-loop-thinking.test.ts +4 -0
  16. package/src/__tests__/agent-loop.test.ts +578 -5
  17. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
  18. package/src/__tests__/approval-cascade.test.ts +1 -0
  19. package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
  20. package/src/__tests__/btw-routes.test.ts +0 -1
  21. package/src/__tests__/build-persisted-content.test.ts +75 -1
  22. package/src/__tests__/catalog-install-normalize.test.ts +141 -0
  23. package/src/__tests__/ces-startup-timeout.test.ts +60 -0
  24. package/src/__tests__/compaction-events.test.ts +1 -0
  25. package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
  26. package/src/__tests__/context-overflow-reducer.test.ts +264 -124
  27. package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
  28. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
  29. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
  30. package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
  31. package/src/__tests__/conversation-agent-loop.test.ts +131 -551
  32. package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
  33. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  34. package/src/__tests__/conversation-fork-crud.test.ts +259 -0
  35. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  36. package/src/__tests__/conversation-lifecycle.test.ts +257 -1
  37. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  38. package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
  39. package/src/__tests__/conversation-queue.test.ts +1 -39
  40. package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
  41. package/src/__tests__/conversation-skill-tools.test.ts +491 -5
  42. package/src/__tests__/conversation-slash-queue.test.ts +1 -1
  43. package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
  44. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  45. package/src/__tests__/conversation-store.test.ts +74 -0
  46. package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
  47. package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
  48. package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
  49. package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
  50. package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
  51. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
  52. package/src/__tests__/corrected-target.test.ts +93 -0
  53. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
  54. package/src/__tests__/credential-execution-tools.test.ts +23 -11
  55. package/src/__tests__/credential-security-invariants.test.ts +6 -1
  56. package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
  57. package/src/__tests__/device-id.test.ts +70 -1
  58. package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
  59. package/src/__tests__/empty-response-hook.test.ts +242 -66
  60. package/src/__tests__/external-plugin-loader.test.ts +0 -31
  61. package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
  62. package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
  63. package/src/__tests__/history-repair-hook.test.ts +228 -3
  64. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  65. package/src/__tests__/host-browser-proxy.test.ts +254 -9
  66. package/src/__tests__/identity-routes.test.ts +1 -0
  67. package/src/__tests__/image-recovery-hook.test.ts +387 -0
  68. package/src/__tests__/injector-chain.test.ts +5 -4
  69. package/src/__tests__/injector-v3-suppression.test.ts +373 -47
  70. package/src/__tests__/intent-routing.test.ts +7 -0
  71. package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
  72. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  73. package/src/__tests__/oauth-store.test.ts +0 -85
  74. package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
  75. package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
  76. package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
  77. package/src/__tests__/persist-unsendable-image.test.ts +4 -4
  78. package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
  79. package/src/__tests__/plugin-bootstrap.test.ts +82 -73
  80. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  81. package/src/__tests__/plugin-types.test.ts +0 -8
  82. package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
  83. package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
  84. package/src/__tests__/registry.test.ts +240 -1
  85. package/src/__tests__/require-fresh-approval.test.ts +3 -0
  86. package/src/__tests__/schedule-routes.test.ts +116 -1
  87. package/src/__tests__/schedule-store.test.ts +28 -0
  88. package/src/__tests__/schedule-tools.test.ts +94 -1
  89. package/src/__tests__/server-history-render.test.ts +39 -0
  90. package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
  91. package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
  92. package/src/__tests__/skills.test.ts +202 -0
  93. package/src/__tests__/slim-skill-category.test.ts +195 -0
  94. package/src/__tests__/strip-memory-injections.test.ts +33 -39
  95. package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
  96. package/src/__tests__/title-generate-hook.test.ts +9 -7
  97. package/src/__tests__/tool-audit-listener.test.ts +264 -1
  98. package/src/__tests__/tool-error-hook.test.ts +4 -3
  99. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
  100. package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
  101. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
  102. package/src/__tests__/tool-start-timestamp.test.ts +218 -0
  103. package/src/__tests__/tools-get-route.test.ts +202 -0
  104. package/src/__tests__/workspace-tool-loader.test.ts +319 -0
  105. package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
  106. package/src/agent/loop.ts +569 -319
  107. package/src/api/events/tool-result.ts +9 -0
  108. package/src/api/events/tool-use-start.ts +7 -0
  109. package/src/api/index.ts +10 -0
  110. package/src/api/responses/conversation-message.ts +135 -27
  111. package/src/api/responses/memory-v3-selection-log.ts +4 -4
  112. package/src/approvals/guardian-request-resolvers.ts +26 -0
  113. package/src/browser-session/backends/host-bridge.ts +29 -0
  114. package/src/browser-session/index.ts +1 -0
  115. package/src/browser-session/types.ts +5 -1
  116. package/src/cli/commands/__tests__/schedules.test.ts +62 -4
  117. package/src/cli/commands/__tests__/skills.test.ts +53 -0
  118. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  119. package/src/cli/commands/inference-providers.ts +0 -8
  120. package/src/cli/commands/plugins.ts +2 -2
  121. package/src/cli/commands/schedules.ts +27 -4
  122. package/src/cli/commands/skills.ts +187 -146
  123. package/src/cli/commands/tools.ts +106 -0
  124. package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
  125. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
  126. package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
  127. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
  128. package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
  129. package/src/cli/lib/install-from-github.ts +187 -117
  130. package/src/cli/lib/plugin-catalog-cache.ts +9 -9
  131. package/src/cli/lib/plugin-details.ts +38 -68
  132. package/src/cli/lib/plugin-marketplace.ts +42 -14
  133. package/src/cli/lib/search-plugins.ts +29 -129
  134. package/src/cli/program.ts +2 -0
  135. package/src/config/bundled-skills/acp/SKILL.md +1 -0
  136. package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
  137. package/src/config/bundled-skills/app-control/SKILL.md +1 -0
  138. package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
  139. package/src/config/bundled-skills/contacts/SKILL.md +1 -0
  140. package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
  141. package/src/config/bundled-skills/followups/SKILL.md +1 -0
  142. package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
  143. package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
  144. package/src/config/bundled-skills/messaging/SKILL.md +1 -0
  145. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
  146. package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
  147. package/src/config/bundled-skills/schedule/SKILL.md +1 -0
  148. package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
  149. package/src/config/bundled-skills/sequences/SKILL.md +1 -0
  150. package/src/config/bundled-skills/settings/SKILL.md +1 -0
  151. package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
  152. package/src/config/bundled-skills/subagent/SKILL.md +1 -0
  153. package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
  154. package/src/config/env-registry.ts +23 -0
  155. package/src/config/feature-flag-registry.json +17 -81
  156. package/src/config/loader.ts +5 -22
  157. package/src/config/schema.ts +2 -0
  158. package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
  159. package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
  160. package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
  161. package/src/config/schemas/compaction-logs.ts +79 -0
  162. package/src/config/schemas/memory-v2.ts +0 -8
  163. package/src/config/schemas/memory-v3.ts +104 -33
  164. package/src/config/seed-inference-profiles.ts +1 -1
  165. package/src/config/skills.ts +117 -47
  166. package/src/context/compactor.ts +11 -0
  167. package/src/context/strip-injections.ts +38 -4
  168. package/src/credential-execution/feature-gates.ts +0 -21
  169. package/src/credential-execution/startup-timeout.ts +32 -4
  170. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
  171. package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
  172. package/src/daemon/conversation-agent-loop.ts +123 -658
  173. package/src/daemon/conversation-error.ts +6 -33
  174. package/src/daemon/conversation-lifecycle.ts +1 -1
  175. package/src/daemon/conversation-runtime-assembly.ts +183 -22
  176. package/src/daemon/conversation-skill-tools.ts +137 -8
  177. package/src/daemon/conversation-slash.ts +0 -14
  178. package/src/daemon/conversation-store.ts +2 -19
  179. package/src/daemon/conversation-tool-setup.ts +87 -1
  180. package/src/daemon/conversation.ts +119 -50
  181. package/src/daemon/external-plugins-bootstrap.ts +36 -95
  182. package/src/daemon/handlers/config-channels.ts +11 -2
  183. package/src/daemon/handlers/shared.ts +9 -1
  184. package/src/daemon/handlers/skills.ts +10 -4
  185. package/src/daemon/host-app-control-proxy.ts +72 -57
  186. package/src/daemon/host-browser-proxy.ts +117 -22
  187. package/src/daemon/lifecycle.ts +34 -5
  188. package/src/daemon/message-protocol.ts +0 -7
  189. package/src/daemon/message-types/schedules.ts +1 -0
  190. package/src/daemon/message-types/skills.ts +17 -0
  191. package/src/daemon/providers-setup.ts +3 -0
  192. package/src/daemon/server.ts +3 -3
  193. package/src/daemon/tool-setup-types.ts +9 -3
  194. package/src/daemon/trust-context.ts +23 -0
  195. package/src/daemon/workspace-tools-watcher.ts +324 -0
  196. package/src/events/tool-audit-listener.ts +78 -16
  197. package/src/events/tool-metrics-listener.ts +2 -5
  198. package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
  199. package/src/memory/__tests__/conversation-queries.test.ts +176 -0
  200. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
  201. package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
  202. package/src/memory/conversation-crud.ts +134 -3
  203. package/src/memory/conversation-queries.ts +64 -7
  204. package/src/memory/db-init.ts +14 -0
  205. package/src/memory/embedding-backend.test.ts +130 -1
  206. package/src/memory/embedding-backend.ts +79 -106
  207. package/src/memory/embedding-gemini.ts +5 -0
  208. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
  209. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
  210. package/src/memory/graph/conversation-graph-memory.ts +36 -25
  211. package/src/memory/graph/tool-handlers.ts +3 -0
  212. package/src/memory/job-handlers/cleanup.ts +3 -1
  213. package/src/memory/jobs-store.ts +0 -28
  214. package/src/memory/jobs-worker.ts +10 -22
  215. package/src/memory/memory-marker.ts +29 -0
  216. package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
  217. package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
  218. package/src/memory/migrations/270-schedule-description.ts +36 -0
  219. package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
  220. package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
  221. package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
  222. package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
  223. package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
  224. package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
  225. package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
  226. package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
  227. package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
  228. package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
  229. package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
  230. package/src/memory/migrations/index.ts +10 -0
  231. package/src/memory/migrations/registry.ts +8 -0
  232. package/src/memory/schema/conversations.ts +16 -0
  233. package/src/memory/schema/infrastructure.ts +26 -0
  234. package/src/memory/skill-loaded-events-store.test.ts +160 -0
  235. package/src/memory/skill-loaded-events-store.ts +95 -0
  236. package/src/memory/tool-executed-events-store.test.ts +219 -0
  237. package/src/memory/tool-executed-events-store.ts +102 -0
  238. package/src/memory/tool-usage-store.ts +15 -3
  239. package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
  240. package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
  241. package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
  242. package/src/memory/v2/__tests__/page-store.test.ts +33 -0
  243. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
  244. package/src/memory/v2/activation-store.ts +50 -1
  245. package/src/memory/v2/consolidation-job.ts +113 -29
  246. package/src/memory/v2/injected-block-slugs.ts +79 -0
  247. package/src/memory/v2/injection.ts +6 -1
  248. package/src/memory/v2/prompts/consolidation.ts +414 -13
  249. package/src/memory/v2/router.ts +2 -28
  250. package/src/memory/v2/static-context.ts +1 -1
  251. package/src/memory/v2/types.ts +16 -0
  252. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  253. package/src/notifications/access-request-copy.ts +298 -0
  254. package/src/notifications/adapters/slack.ts +3 -3
  255. package/src/notifications/adapters/telegram.ts +2 -1
  256. package/src/notifications/copy-composer.ts +49 -267
  257. package/src/notifications/decision-engine.ts +16 -35
  258. package/src/notifications/home-feed-side-effect.ts +1 -6
  259. package/src/oauth/oauth-store.ts +0 -9
  260. package/src/permissions/checker.test.ts +83 -1
  261. package/src/permissions/checker.ts +25 -2
  262. package/src/permissions/gateway-threshold-reader.test.ts +182 -0
  263. package/src/permissions/gateway-threshold-reader.ts +80 -0
  264. package/src/platform/client.ts +1 -3
  265. package/src/platform/feature-gate.ts +3 -12
  266. package/src/plugin-api/constants.ts +4 -2
  267. package/src/plugin-api/index.ts +63 -11
  268. package/src/plugin-api/types.ts +236 -71
  269. package/src/plugins/defaults/compaction/compact.ts +66 -2
  270. package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
  271. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  272. package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
  273. package/src/plugins/defaults/compaction/window-manager.ts +303 -1
  274. package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
  275. package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
  276. package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
  277. package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
  278. package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
  279. package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
  280. package/src/plugins/defaults/history-repair/terminal.ts +39 -2
  281. package/src/plugins/defaults/image-recovery/detect.ts +25 -0
  282. package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
  283. package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
  284. package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
  285. package/src/plugins/defaults/image-recovery/package.json +14 -0
  286. package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
  287. package/src/plugins/defaults/index.ts +71 -5
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
  289. package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
  290. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
  291. package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
  292. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  293. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
  297. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
  298. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
  299. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
  300. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
  301. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
  302. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
  303. package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
  304. package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
  305. package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
  306. package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
  307. package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
  308. package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
  309. package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
  310. package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
  311. package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
  312. package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
  313. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
  314. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
  315. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
  316. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
  317. package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
  318. package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
  319. package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
  320. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
  321. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
  322. package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
  323. package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
  324. package/src/plugins/pipeline.ts +8 -5
  325. package/src/plugins/types.ts +5 -51
  326. package/src/providers/cache-control.ts +26 -0
  327. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
  328. package/src/providers/model-catalog.ts +13 -1
  329. package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
  330. package/src/providers/openai/chat-completions-provider.ts +46 -0
  331. package/src/providers/openai/responses-provider.ts +45 -0
  332. package/src/providers/registry.ts +0 -8
  333. package/src/runtime/__tests__/agent-wake.test.ts +0 -1
  334. package/src/runtime/agent-wake.ts +13 -0
  335. package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
  336. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
  337. package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
  338. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
  339. package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
  340. package/src/runtime/routes/acp-routes.test.ts +106 -0
  341. package/src/runtime/routes/acp-routes.ts +248 -2
  342. package/src/runtime/routes/browser-tabs-routes.ts +1 -1
  343. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  344. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
  345. package/src/runtime/routes/consolidation-routes.ts +6 -82
  346. package/src/runtime/routes/conversation-list-routes.ts +6 -0
  347. package/src/runtime/routes/conversation-management-routes.ts +71 -0
  348. package/src/runtime/routes/identity-routes.ts +8 -0
  349. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  350. package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
  351. package/src/runtime/routes/plugins-routes.ts +34 -45
  352. package/src/runtime/routes/schedule-routes.ts +43 -5
  353. package/src/runtime/routes/settings-routes.ts +140 -15
  354. package/src/runtime/routes/skills-routes.ts +18 -6
  355. package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
  356. package/src/runtime/services/conversation-serializer.ts +38 -1
  357. package/src/runtime/verification-outbound-actions.ts +147 -2
  358. package/src/runtime/verification-templates.ts +29 -3
  359. package/src/schedule/schedule-store.ts +19 -0
  360. package/src/skills/catalog-install.ts +77 -13
  361. package/src/tasks/task-scheduler.ts +1 -0
  362. package/src/telemetry/types.ts +66 -1
  363. package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
  364. package/src/telemetry/usage-telemetry-reporter.ts +213 -20
  365. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
  366. package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
  367. package/src/tools/browser/browser-execution.ts +27 -9
  368. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
  369. package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
  370. package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
  371. package/src/tools/browser/cdp-client/factory.ts +217 -17
  372. package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
  373. package/src/tools/browser/cdp-client/types.ts +22 -2
  374. package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
  375. package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
  376. package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
  377. package/src/tools/executor.ts +39 -7
  378. package/src/tools/registry.ts +387 -5
  379. package/src/tools/schedule/create.ts +16 -0
  380. package/src/tools/schedule/list.ts +12 -4
  381. package/src/tools/schedule/update.ts +12 -0
  382. package/src/tools/skills/load.ts +11 -6
  383. package/src/tools/terminal/safe-env.ts +2 -0
  384. package/src/tools/types.ts +65 -9
  385. package/src/tools/workspace-tools/loader.ts +673 -0
  386. package/src/usage/attribution.ts +28 -0
  387. package/src/util/device-id.ts +17 -3
  388. package/src/util/platform.ts +16 -0
  389. package/tsconfig.plugin-api.json +13 -0
  390. package/src/__tests__/plugin-external-api.test.ts +0 -68
  391. package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
  392. package/src/daemon/message-types/browser.ts +0 -10
  393. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  394. package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
  395. package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
  396. package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
  397. package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
  398. package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
  399. package/src/plugins/external-api.ts +0 -114
  400. package/src/plugins/plugin-skill-contributions.ts +0 -292
@@ -13,7 +13,9 @@
13
13
  * Sites not exercised here (`aborted_via_error`) require deeper provider
14
14
  * fakery and are best covered by integration tests.
15
15
  */
16
- import { afterEach, describe, expect, mock, test } from "bun:test";
16
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
17
+
18
+ import type { PostCompactContext } from "@vellumai/plugin-api";
17
19
 
18
20
  import type {
19
21
  AgentEvent,
@@ -23,12 +25,16 @@ import type {
23
25
  import { AgentLoop, isMaxTokensStopReason } from "../agent/loop.js";
24
26
  import type { ContextWindowConfig } from "../config/types.js";
25
27
  import type { TrustContext } from "../daemon/trust-context.js";
28
+ import { HOOKS } from "../plugin-api/constants.js";
26
29
  import {
27
30
  createContextWindowManager,
28
31
  disposeContextWindowManager,
29
32
  getContextWindowManager,
30
33
  } from "../plugins/defaults/compaction/manager-store.js";
31
- import type { PostCompactContext } from "../plugins/defaults/memory-retrieval/hooks/post-compact.js";
34
+ import {
35
+ registerPlugin,
36
+ resetPluginRegistryForTests,
37
+ } from "../plugins/registry.js";
32
38
  import type {
33
39
  Message,
34
40
  Provider,
@@ -37,22 +43,25 @@ import type {
37
43
  ToolDefinition,
38
44
  } from "../providers/types.js";
39
45
 
40
- // The agent loop invokes the default post-compaction re-injection hook directly
41
- // when it compacts in place. Stub it so these unit tests can drive the
42
- // re-injection result without the daemon-level injector chain. Tests assign
43
- // `postCompactImpl` to observe the call or force a failure; when unset
44
- // the hook is a no-op that returns the history it was handed.
46
+ // The agent loop runs the default post-compaction re-injection through the
47
+ // `post-compact` hook chain when it compacts in place. Register a test hook on
48
+ // that chain so these unit tests can drive the re-injection result without the
49
+ // daemon-level injector. The hook writes the re-injected history back onto the
50
+ // context; tests assign `postCompactImpl` to observe the call or force a
51
+ // failure; when unset the hook leaves the history it was handed untouched.
45
52
  let postCompactImpl:
46
53
  | ((input: PostCompactContext) => Promise<Message[]>)
47
54
  | null = null;
48
- mock.module(
49
- "../plugins/defaults/memory-retrieval/hooks/post-compact.js",
50
- () => ({
51
- default: async (input: PostCompactContext) => ({
52
- messages: postCompactImpl ? await postCompactImpl(input) : input.history,
53
- }),
54
- }),
55
- );
55
+ const testPostCompactPlugin = {
56
+ manifest: { name: "test-post-compact", version: "0.0.0" },
57
+ hooks: {
58
+ [HOOKS.POST_COMPACT]: async (input: PostCompactContext): Promise<void> => {
59
+ input.history = postCompactImpl
60
+ ? await postCompactImpl(input)
61
+ : input.history;
62
+ },
63
+ },
64
+ };
56
65
 
57
66
  // ---------------------------------------------------------------------------
58
67
  // Helpers (mirrored from agent-loop.test.ts so this file is self-contained)
@@ -163,6 +172,14 @@ function countExitEvents(events: AgentEvent[]): number {
163
172
  // ---------------------------------------------------------------------------
164
173
 
165
174
  describe("AgentLoop exit-reason instrumentation", () => {
175
+ // Reset the plugin registry to a known state so ambient registrations from
176
+ // other test files (e.g. the default plugins) cannot leak into the
177
+ // post-compact hook chain these tests drive.
178
+ beforeEach(() => {
179
+ resetPluginRegistryForTests();
180
+ registerPlugin(testPostCompactPlugin);
181
+ });
182
+
166
183
  afterEach(() => {
167
184
  disposeContextWindowManager("test-conversation");
168
185
  });
@@ -186,6 +203,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
186
203
 
187
204
  const events: AgentEvent[] = [];
188
205
  await loop.run({
206
+ requestId: "test-request",
189
207
  messages: [userMessage],
190
208
  onEvent: (e) => {
191
209
  events.push(e);
@@ -208,6 +226,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
208
226
 
209
227
  const events: AgentEvent[] = [];
210
228
  await loop.run({
229
+ requestId: "test-request",
211
230
  messages: [userMessage],
212
231
  onEvent: (e) => {
213
232
  events.push(e);
@@ -219,6 +238,41 @@ describe("AgentLoop exit-reason instrumentation", () => {
219
238
  expect(events[events.length - 1].type).toBe("agent_loop_exit");
220
239
  });
221
240
 
241
+ test("emits agent_loop_exit even when a stop hook throws", async () => {
242
+ // A third-party teardown hook that rejects must not suppress the terminal
243
+ // exit: the loop isolates the stop chain, logs the failure, and still emits
244
+ // `agent_loop_exit` exactly once with the real reason.
245
+ registerPlugin({
246
+ manifest: { name: "throwing-stop", version: "0.0.0" },
247
+ hooks: {
248
+ [HOOKS.STOP]: async (): Promise<void> => {
249
+ throw new Error("teardown boom");
250
+ },
251
+ },
252
+ });
253
+
254
+ const { provider } = createMockProvider([textResponse("Hi there!")]);
255
+ const loop = new AgentLoop({
256
+ provider: provider,
257
+ systemPrompt: "system prompt",
258
+ conversationId: "test-conversation",
259
+ });
260
+
261
+ const events: AgentEvent[] = [];
262
+ await loop.run({
263
+ requestId: "test-request",
264
+ messages: [userMessage],
265
+ onEvent: (e) => {
266
+ events.push(e);
267
+ },
268
+ trust: { sourceChannel: "vellum", trustClass: "unknown" },
269
+ });
270
+
271
+ expect(countExitEvents(events)).toBe(1);
272
+ expect(lastExitEvent(events)?.reason).toBe("no_tool_calls");
273
+ expect(events[events.length - 1].type).toBe("agent_loop_exit");
274
+ });
275
+
222
276
  test("emits continuation surface event and exits on max_tokens", async () => {
223
277
  const { provider } = createMockProvider([
224
278
  maxTokensResponse("Partial answer"),
@@ -231,6 +285,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
231
285
 
232
286
  const events: AgentEvent[] = [];
233
287
  await loop.run({
288
+ requestId: "test-request",
234
289
  messages: [userMessage],
235
290
  onEvent: (e) => {
236
291
  events.push(e);
@@ -238,9 +293,14 @@ describe("AgentLoop exit-reason instrumentation", () => {
238
293
  trust: { sourceChannel: "vellum", trustClass: "unknown" },
239
294
  });
240
295
 
296
+ // The mock provider returns its content without streaming any text_delta
297
+ // live, so the loop surfaces the truncated reply once via a synthetic
298
+ // text_delta before stopping (a real provider streams the text live, where
299
+ // this emit is a no-op).
241
300
  expect(events.map((e) => e.type)).toEqual([
242
301
  "llm_call_started",
243
302
  "usage",
303
+ "text_delta",
244
304
  "max_tokens_reached",
245
305
  "message_complete",
246
306
  "agent_loop_exit",
@@ -275,6 +335,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
275
335
 
276
336
  const events: AgentEvent[] = [];
277
337
  const { history: result } = await loop.run({
338
+ requestId: "test-request",
278
339
  messages: [userMessage],
279
340
  onEvent: (e) => {
280
341
  events.push(e);
@@ -302,6 +363,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
302
363
 
303
364
  const events: AgentEvent[] = [];
304
365
  await loop.run({
366
+ requestId: "test-request",
305
367
  messages: [userMessage],
306
368
  onEvent: (e) => {
307
369
  events.push(e);
@@ -333,6 +395,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
333
395
 
334
396
  const events: AgentEvent[] = [];
335
397
  await loop.run({
398
+ requestId: "test-request",
336
399
  messages: [userMessage],
337
400
  onEvent: (e) => {
338
401
  events.push(e);
@@ -359,10 +422,11 @@ describe("AgentLoop exit-reason instrumentation", () => {
359
422
  });
360
423
 
361
424
  const onCheckpoint = (_info: CheckpointInfo): CheckpointDecision =>
362
- "budget";
425
+ "handoff";
363
426
 
364
427
  const events: AgentEvent[] = [];
365
428
  await loop.run({
429
+ requestId: "test-request",
366
430
  messages: [userMessage],
367
431
  onEvent: (e) => {
368
432
  events.push(e);
@@ -374,42 +438,9 @@ describe("AgentLoop exit-reason instrumentation", () => {
374
438
  expect(countExitEvents(events)).toBe(0);
375
439
  });
376
440
 
377
- test("yields with 'budget' when the in-loop budget gate trips", async () => {
378
- // GIVEN a provider that calls a tool (reaching a checkpoint) before it
379
- // would continue with a text response.
380
- const { provider } = createMockProvider([
381
- toolUseResponse("t1", "read_file", { path: "/a.txt" }),
382
- textResponse("never reached"),
383
- ]);
384
- const toolExecutor = async () => ({ content: "ok", isError: false });
385
- const loop = new AgentLoop({
386
- provider: provider,
387
- systemPrompt: "system",
388
- conversationId: "test-conversation",
389
- tools: dummyTools,
390
- toolExecutor: toolExecutor,
391
- });
392
-
393
- // AND an effective context window so small that any real token estimate
394
- // of the running history exceeds the mid-loop threshold.
395
- // WHEN the loop checkpoints after the tool results land
396
- const result = await loop.run({
397
- messages: [userMessage],
398
- onEvent: () => {},
399
- trust: { sourceChannel: "vellum", trustClass: "unknown" },
400
- resolveContextWindow: () => ({
401
- maxInputTokens: 10,
402
- overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
403
- }),
404
- });
405
-
406
- // THEN it yields for budget before issuing the next provider call.
407
- expect(result.exitReason).toBe("budget");
408
- });
409
-
410
- test("does not yield for budget when overflow recovery is disabled", async () => {
411
- // GIVEN the same tiny context window but overflow recovery disabled — the
412
- // agent-wake configuration, which must never yield for budget.
441
+ test("runs to a clean exit when overflow recovery is disabled", async () => {
442
+ // GIVEN a tiny context window but overflow recovery disabled — the
443
+ // agent-wake configuration, which must never compact mid-loop.
413
444
  const { provider } = createMockProvider([
414
445
  toolUseResponse("t1", "read_file", { path: "/a.txt" }),
415
446
  textResponse("done"),
@@ -425,6 +456,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
425
456
 
426
457
  // WHEN the loop runs to completion
427
458
  const result = await loop.run({
459
+ requestId: "test-request",
428
460
  messages: [userMessage],
429
461
  onEvent: () => {},
430
462
  trust: { sourceChannel: "vellum", trustClass: "unknown" },
@@ -434,8 +466,8 @@ describe("AgentLoop exit-reason instrumentation", () => {
434
466
  }),
435
467
  });
436
468
 
437
- // THEN it never yields for budget.
438
- expect(result.exitReason).not.toBe("budget");
469
+ // THEN it reaches a clean exit without pausing the loop.
470
+ expect(result.exitReason).toBeNull();
439
471
  });
440
472
 
441
473
  test("compacts in place and continues when the budget gate trips with a compaction hook", async () => {
@@ -463,6 +495,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
463
495
 
464
496
  // WHEN the in-loop budget gate trips at the checkpoint
465
497
  const result = await loop.run({
498
+ requestId: "test-request",
466
499
  messages: [userMessage],
467
500
  onEvent: (event) => {
468
501
  events.push(event);
@@ -479,52 +512,13 @@ describe("AgentLoop exit-reason instrumentation", () => {
479
512
  });
480
513
 
481
514
  // THEN the loop runs the compaction ceremony in place and continues to a
482
- // clean exit instead of yielding for budget. The durable commit is
483
- // signalled via a `compaction_completed` event rather than an injected hook.
515
+ // clean exit. The durable commit is signalled via a `compaction_completed`
516
+ // event rather than an injected hook.
484
517
  expect(events.some((event) => event.type === "compaction_completed")).toBe(
485
518
  true,
486
519
  );
487
520
  expect(reinjected).toBe(true);
488
- expect(result.exitReason).not.toBe("budget");
489
- });
490
-
491
- test("yields 'budget' when inline compaction reports exhausted", async () => {
492
- const { provider } = createMockProvider([
493
- toolUseResponse("t1", "read_file", { path: "/a.txt" }),
494
- textResponse("never reached"),
495
- ]);
496
- const toolExecutor = async () => ({ content: "ok", isError: false });
497
- const loop = new AgentLoop({
498
- provider: provider,
499
- systemPrompt: "system",
500
- conversationId: "test-conversation",
501
- tools: dummyTools,
502
- toolExecutor: toolExecutor,
503
- });
504
-
505
- postCompactImpl = async () => {
506
- throw new Error(
507
- "post-compaction re-injection must not run when exhausted",
508
- );
509
- };
510
-
511
- // WHEN compaction exhausts its retry budget
512
- const result = await loop.run({
513
- messages: [userMessage],
514
- onEvent: () => {},
515
- resolveContextWindow: () => ({
516
- maxInputTokens: 10,
517
- overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
518
- }),
519
- compactInPlace: true,
520
- ...fakeCompaction("test-conversation", {
521
- compacted: false,
522
- exhausted: true,
523
- }),
524
- });
525
-
526
- // THEN the loop yields for budget so the orchestrator can escalate.
527
- expect(result.exitReason).toBe("budget");
521
+ expect(result.exitReason).toBeNull();
528
522
  });
529
523
 
530
524
  test("emits 'error' when provider throws an unhandled error", async () => {
@@ -542,6 +536,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
542
536
 
543
537
  const events: AgentEvent[] = [];
544
538
  await loop.run({
539
+ requestId: "test-request",
545
540
  messages: [userMessage],
546
541
  onEvent: (e) => {
547
542
  events.push(e);
@@ -575,6 +570,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
575
570
 
576
571
  const events: AgentEvent[] = [];
577
572
  await loop.run({
573
+ requestId: "test-request",
578
574
  messages: [userMessage],
579
575
  onEvent: (e) => {
580
576
  events.push(e);
@@ -606,6 +602,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
606
602
 
607
603
  const events: AgentEvent[] = [];
608
604
  await loop.run({
605
+ requestId: "test-request",
609
606
  messages: [userMessage],
610
607
  onEvent: (e) => {
611
608
  events.push(e);
@@ -115,6 +115,7 @@ describe("AgentLoop.run — mutableLatestUserMessage from memory-v3-live", () =>
115
115
 
116
116
  // WHEN the loop runs
117
117
  await loop.run({
118
+ requestId: "test-request",
118
119
  messages: [userMessage],
119
120
  onEvent: () => {},
120
121
  trust: { sourceChannel: "vellum", trustClass: "unknown" },
@@ -143,6 +144,7 @@ describe("AgentLoop.run — mutableLatestUserMessage from memory-v3-live", () =>
143
144
 
144
145
  // WHEN the loop runs
145
146
  await loop.run({
147
+ requestId: "test-request",
146
148
  messages: [userMessage],
147
149
  onEvent: () => {},
148
150
  trust: { sourceChannel: "vellum", trustClass: "unknown" },