@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
@@ -1,6 +1,8 @@
1
- import { describe, expect, test } from "bun:test";
1
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
2
 
3
+ import type { CesClient } from "../credential-execution/client.js";
3
4
  import { RiskLevel } from "../permissions/types.js";
5
+ import { setCesClient } from "../security/secure-keys.js";
4
6
  import { makeAuthenticatedRequestTool } from "../tools/credential-execution/make-authenticated-request.js";
5
7
  import { manageSecureCommandTool } from "../tools/credential-execution/manage-secure-command-tool.js";
6
8
  import { runAuthenticatedCommandTool } from "../tools/credential-execution/run-authenticated-command.js";
@@ -168,6 +170,11 @@ describe("CES tool execution without client", () => {
168
170
  trustClass: "guardian" as const,
169
171
  };
170
172
 
173
+ // The CES tools resolve the client via the module-level getCesClient()
174
+ // resolver, so ensure none is injected for the "absent client" cases.
175
+ beforeEach(() => setCesClient(undefined));
176
+ afterEach(() => setCesClient(undefined));
177
+
171
178
  test("make_authenticated_request fails gracefully when CES client is absent", async () => {
172
179
  const result = await makeAuthenticatedRequestTool.execute(
173
180
  {
@@ -218,19 +225,24 @@ describe("CES tool execution without client", () => {
218
225
  // ---------------------------------------------------------------------------
219
226
 
220
227
  describe("manage_secure_command_tool input validation", () => {
221
- const contextWithMockCes = {
228
+ const minimalContext = {
222
229
  workingDir: "/tmp",
223
230
  conversationId: "test-conversation",
224
231
  trustClass: "guardian" as const,
225
- cesClient: {
226
- isReady: () => true,
227
- handshake: async () => ({ accepted: true }),
228
- call: async () => ({ success: true }),
229
- updateAssistantApiKey: async () => ({ updated: true }),
230
- close: () => {},
231
- },
232
232
  };
233
233
 
234
+ // Input validation runs only after the client readiness check passes, so
235
+ // inject a ready mock client via the resolver for these cases.
236
+ const mockCesClient = {
237
+ isReady: () => true,
238
+ handshake: async () => ({ accepted: true }),
239
+ call: async () => ({ success: true }),
240
+ updateAssistantApiKey: async () => ({ updated: true }),
241
+ close: () => {},
242
+ } as unknown as CesClient;
243
+ beforeEach(() => setCesClient(mockCesClient));
244
+ afterEach(() => setCesClient(undefined));
245
+
234
246
  test("rejects register without required bundle metadata", async () => {
235
247
  const result = await manageSecureCommandTool.execute(
236
248
  {
@@ -238,7 +250,7 @@ describe("manage_secure_command_tool input validation", () => {
238
250
  toolName: "test-tool",
239
251
  // Missing bundleId, version, sourceUrl, sha256, credentialHandle
240
252
  },
241
- contextWithMockCes,
253
+ minimalContext,
242
254
  );
243
255
  expect(result.isError).toBe(true);
244
256
  expect(result.content).toContain("bundleId");
@@ -270,7 +282,7 @@ describe("manage_secure_command_tool input validation", () => {
270
282
  egressMode: "no_network",
271
283
  },
272
284
  },
273
- contextWithMockCes,
285
+ minimalContext,
274
286
  );
275
287
  expect(result.isError).toBe(true);
276
288
  expect(result.content).toContain("HTTPS");
@@ -216,6 +216,7 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
216
216
  "media/image-credentials.ts", // shared image-gen credential resolver (provider API key lookup)
217
217
  "memory/embedding-backend.ts", // embedding backend API key lookup
218
218
  "memory/llm-request-log-source-clickhouse.ts", // ClickHouse read source — lazy lookup of clickhouse:url + clickhouse:password + vellum:platform_assistant_id for self-scoped mirror reads
219
+ "memory/compaction-log-writer-clickhouse.ts", // ClickHouse compaction log writer — lazy lookup of clickhouse:url + clickhouse:password + vellum:platform_assistant_id for self-scoped event writes
219
220
  "daemon/providers-setup.ts", // provider initialization API key lookup
220
221
  "workspace/migrations/006-services-config.ts", // services config migration reads provider API keys
221
222
  "workspace/migrations/018-rekey-compound-credential-keys.ts", // re-key compound credential storage keys
@@ -230,7 +231,7 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
230
231
  "runtime/routes/platform-routes.ts", // CLI platform connect/disconnect/status routes (CLI-migrated to IPC)
231
232
  "ipc/skill-routes/providers.ts", // host.providers.secureKeys.getProviderKey IPC route (out-of-process SkillHost companion)
232
233
  "daemon/external-plugins-bootstrap.ts", // reads credentials at plugin init (manifest.requiresCredential) via the CES-mediated getSecureKeyAsync path
233
- "plugins/external-api.ts", // globalThis runtime bridge that exposes getSecureKeyAsync to dynamically-imported workspace plugins (compiled-binary plugin loading)
234
+ "plugin-api/index.ts", // public @vellumai/plugin-api surface re-exports getSecureKeyAsync to dynamically-imported workspace plugins via the boot-time shim (compiled-binary plugin loading)
234
235
  "inbound/platform-callback-registration.ts", // managed credential lookup for platform base URL, assistant ID, and API key
235
236
  "tts/providers/elevenlabs-provider.ts", // ElevenLabs TTS API key lookup
236
237
  "tts/providers/deepgram-provider.ts", // Deepgram TTS API key lookup
@@ -242,6 +243,10 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
242
243
  "cli/commands/oauth/connect.ts", // CLI OAuth connect stored-secret verification
243
244
  "runtime/routes/chatgpt-subscription-auth-routes.ts", // ChatGPT subscription OAuth token storage
244
245
  "runtime/routes/identity-routes.ts", // health/readyz endpoint checks CES connectivity via getCesClient
246
+ "tools/credential-execution/run-authenticated-command.ts", // resolves the CES RPC client via getCesClient
247
+ "tools/credential-execution/make-authenticated-request.ts", // resolves the CES RPC client via getCesClient
248
+ "tools/credential-execution/manage-secure-command-tool.ts", // resolves the CES RPC client via getCesClient
249
+ "tools/executor.ts", // CES approval bridge resolves the CES RPC client via getCesClient
245
250
  ]);
246
251
 
247
252
  const thisDir = dirname(fileURLToPath(import.meta.url));
@@ -4,6 +4,7 @@ import { describe, expect, test } from "bun:test";
4
4
  import { eq } from "drizzle-orm";
5
5
  import { drizzle } from "drizzle-orm/bun-sqlite";
6
6
 
7
+ import { migrateScheduleDescription } from "../memory/migrations/270-schedule-description.js";
7
8
  import { migrateScheduleSourceConversation } from "../memory/migrations/270-schedule-source-conversation.js";
8
9
  import * as schema from "../memory/schema.js";
9
10
  import { scheduleJobs } from "../memory/schema.js";
@@ -50,6 +51,7 @@ describe("schedule_syntax column migration", () => {
50
51
  script TEXT,
51
52
  wake_conversation_id TEXT,
52
53
  timeout_ms INTEGER,
54
+ description TEXT NOT NULL DEFAULT '',
53
55
  created_at INTEGER NOT NULL,
54
56
  updated_at INTEGER NOT NULL
55
57
  )
@@ -137,6 +139,7 @@ describe("schedule_syntax column migration", () => {
137
139
  /* already exists */
138
140
  }
139
141
  migrateScheduleSourceConversation(db);
142
+ migrateScheduleDescription(db);
140
143
 
141
144
  const row = db
142
145
  .select()
@@ -202,6 +205,8 @@ describe("schedule_syntax column migration", () => {
202
205
  }
203
206
  migrateScheduleSourceConversation(db);
204
207
  migrateScheduleSourceConversation(db);
208
+ migrateScheduleDescription(db);
209
+ migrateScheduleDescription(db);
205
210
 
206
211
  const now = Date.now();
207
212
  raw.exec(
@@ -214,4 +219,79 @@ describe("schedule_syntax column migration", () => {
214
219
  .get();
215
220
  expect(row!.scheduleSyntax).toBe("cron");
216
221
  });
222
+
223
+ test("schedule description migration backfills non-defer rows once", () => {
224
+ const db = createTestDb();
225
+ const raw = getRawSqlite(db);
226
+
227
+ raw.exec(/*sql*/ `
228
+ CREATE TABLE IF NOT EXISTS cron_jobs (
229
+ id TEXT PRIMARY KEY,
230
+ name TEXT NOT NULL,
231
+ enabled INTEGER NOT NULL DEFAULT 1,
232
+ cron_expression TEXT,
233
+ schedule_syntax TEXT NOT NULL DEFAULT 'cron',
234
+ timezone TEXT,
235
+ message TEXT NOT NULL,
236
+ next_run_at INTEGER NOT NULL,
237
+ retry_count INTEGER NOT NULL DEFAULT 0,
238
+ created_by TEXT NOT NULL,
239
+ created_at INTEGER NOT NULL,
240
+ updated_at INTEGER NOT NULL
241
+ )
242
+ `);
243
+
244
+ const now = Date.now();
245
+ raw
246
+ .query(
247
+ `INSERT INTO cron_jobs (id, name, cron_expression, message, next_run_at, created_by, created_at, updated_at)
248
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
249
+ )
250
+ .run(
251
+ "legacy-schedule",
252
+ "Legacy report",
253
+ "0 9 * * *",
254
+ "compile report",
255
+ now + 60_000,
256
+ "agent",
257
+ now,
258
+ now,
259
+ );
260
+ raw
261
+ .query(
262
+ `INSERT INTO cron_jobs (id, name, cron_expression, message, next_run_at, created_by, created_at, updated_at)
263
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
264
+ )
265
+ .run(
266
+ "legacy-defer",
267
+ "Deferred wake",
268
+ null,
269
+ "resume later",
270
+ now + 60_000,
271
+ "defer",
272
+ now,
273
+ now,
274
+ );
275
+
276
+ migrateScheduleDescription(db);
277
+
278
+ const rows = raw
279
+ .query("SELECT id, description FROM cron_jobs ORDER BY id")
280
+ .all() as Array<{ id: string; description: string }>;
281
+ expect(rows).toEqual([
282
+ { id: "legacy-defer", description: "" },
283
+ { id: "legacy-schedule", description: "Legacy report" },
284
+ ]);
285
+
286
+ raw
287
+ .query("UPDATE cron_jobs SET description = ? WHERE id = ?")
288
+ .run("", "legacy-schedule");
289
+
290
+ migrateScheduleDescription(db);
291
+
292
+ const description = raw
293
+ .query("SELECT description FROM cron_jobs WHERE id = ?")
294
+ .get("legacy-schedule") as { description: string };
295
+ expect(description.description).toBe("");
296
+ });
217
297
  });
@@ -1,4 +1,12 @@
1
- import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ mkdtempSync,
5
+ readdirSync,
6
+ readFileSync,
7
+ rmSync,
8
+ writeFileSync,
9
+ } from "node:fs";
2
10
  import { tmpdir } from "node:os";
3
11
  import { join } from "node:path";
4
12
  import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
@@ -16,11 +24,13 @@ import { getDeviceId, resetDeviceIdCache } from "../util/device-id.js";
16
24
  const originalVellumEnvironment = process.env.VELLUM_ENVIRONMENT;
17
25
  const originalXdgConfigHome = process.env.XDG_CONFIG_HOME;
18
26
  const originalIsContainerized = process.env.IS_CONTAINERIZED;
27
+ const originalVellumDeviceId = process.env.VELLUM_DEVICE_ID;
19
28
 
20
29
  let tempDir: string;
21
30
 
22
31
  beforeEach(() => {
23
32
  tempDir = mkdtempSync(join(tmpdir(), "vellum-device-id-test-"));
33
+ delete process.env.VELLUM_DEVICE_ID;
24
34
  resetDeviceIdCache();
25
35
  });
26
36
 
@@ -42,6 +52,11 @@ afterEach(() => {
42
52
  } else {
43
53
  process.env.IS_CONTAINERIZED = originalIsContainerized;
44
54
  }
55
+ if (originalVellumDeviceId == null) {
56
+ delete process.env.VELLUM_DEVICE_ID;
57
+ } else {
58
+ process.env.VELLUM_DEVICE_ID = originalVellumDeviceId;
59
+ }
45
60
 
46
61
  try {
47
62
  rmSync(tempDir, { recursive: true, force: true });
@@ -110,3 +125,57 @@ describe("getDeviceId env-awareness", () => {
110
125
  expect(existsSync(xdgPath)).toBe(false);
111
126
  });
112
127
  });
128
+
129
+ describe("getDeviceId VELLUM_DEVICE_ID precedence", () => {
130
+ beforeEach(() => {
131
+ delete process.env.IS_CONTAINERIZED;
132
+ process.env.VELLUM_ENVIRONMENT = "dev";
133
+ process.env.XDG_CONFIG_HOME = tempDir;
134
+ });
135
+
136
+ test("env var set returns that value without writing device.json", () => {
137
+ process.env.VELLUM_DEVICE_ID = "abc-123";
138
+
139
+ expect(getDeviceId()).toBe("abc-123");
140
+ // Nothing written anywhere under the XDG tempdir.
141
+ expect(readdirSync(tempDir)).toEqual([]);
142
+ });
143
+
144
+ test("env var with surrounding whitespace returns the trimmed value", () => {
145
+ process.env.VELLUM_DEVICE_ID = " abc-123 ";
146
+
147
+ expect(getDeviceId()).toBe("abc-123");
148
+ });
149
+
150
+ test("empty/whitespace-only env var falls through to file resolution", () => {
151
+ process.env.VELLUM_DEVICE_ID = " ";
152
+
153
+ const id = getDeviceId();
154
+ expect(id.length).toBeGreaterThan(0);
155
+ expect(existsSync(join(tempDir, "vellum-dev", "device.json"))).toBe(true);
156
+ });
157
+
158
+ test("env var wins over an existing device.json without overwriting it", () => {
159
+ const dir = join(tempDir, "vellum-dev");
160
+ mkdirSync(dir, { recursive: true });
161
+ const filePath = join(dir, "device.json");
162
+ writeFileSync(filePath, JSON.stringify({ deviceId: "file-id" }));
163
+ process.env.VELLUM_DEVICE_ID = "env-id";
164
+
165
+ expect(getDeviceId()).toBe("env-id");
166
+ expect(JSON.parse(readFileSync(filePath, "utf-8")).deviceId).toBe(
167
+ "file-id",
168
+ );
169
+ });
170
+
171
+ test("env-resolved value stays cached until resetDeviceIdCache", () => {
172
+ process.env.VELLUM_DEVICE_ID = "env-id";
173
+ expect(getDeviceId()).toBe("env-id");
174
+
175
+ delete process.env.VELLUM_DEVICE_ID;
176
+ expect(getDeviceId()).toBe("env-id");
177
+
178
+ resetDeviceIdCache();
179
+ expect(getDeviceId()).not.toBe("env-id");
180
+ });
181
+ });
@@ -2,8 +2,7 @@
2
2
  * Tests for managed proxy Gemini embedding backend selection.
3
3
  *
4
4
  * Verifies that selectEmbeddingBackend correctly routes through the
5
- * managed proxy when the feature flag is enabled and managed proxy
6
- * prerequisites are satisfied.
5
+ * managed proxy when managed proxy prerequisites are satisfied.
7
6
  */
8
7
 
9
8
  import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
@@ -42,13 +41,9 @@ mock.module("../security/secure-keys.js", () => ({
42
41
  },
43
42
  }));
44
43
 
45
- // Feature flag mock
46
- const mockFeatureFlags: Record<string, boolean> = {};
47
-
44
+ // Feature flag mock — always returns true (flag is GA'ed)
48
45
  mock.module("../config/assistant-feature-flags.js", () => ({
49
- isAssistantFeatureFlagEnabled: (key: string, _config: unknown) => {
50
- return mockFeatureFlags[key] ?? false;
51
- },
46
+ isAssistantFeatureFlagEnabled: () => true,
52
47
  }));
53
48
 
54
49
  import type { AssistantConfig } from "../config/types.js";
@@ -75,14 +70,6 @@ function disableManagedProxy() {
75
70
  mockAssistantApiKey = null;
76
71
  }
77
72
 
78
- function enableFlag() {
79
- mockFeatureFlags["managed-gemini-embeddings-enabled"] = true;
80
- }
81
-
82
- function disableFlag() {
83
- mockFeatureFlags["managed-gemini-embeddings-enabled"] = false;
84
- }
85
-
86
73
  function makeConfig(
87
74
  overrides: {
88
75
  provider?: string;
@@ -116,7 +103,6 @@ function makeConfig(
116
103
 
117
104
  beforeEach(() => {
118
105
  disableManagedProxy();
119
- disableFlag();
120
106
  mockProviderKeys = {};
121
107
  clearEmbeddingBackendCache();
122
108
  });
@@ -126,9 +112,8 @@ afterEach(() => {
126
112
  });
127
113
 
128
114
  describe("managed proxy Gemini embedding selection", () => {
129
- test("selects managed proxy Gemini when flag enabled and proxy context available", async () => {
115
+ test("selects managed proxy Gemini when proxy context available", async () => {
130
116
  enableManagedProxy();
131
- enableFlag();
132
117
  const config = makeConfig();
133
118
 
134
119
  const { backend, reason } = await selectEmbeddingBackend(config);
@@ -141,7 +126,6 @@ describe("managed proxy Gemini embedding selection", () => {
141
126
 
142
127
  test("managed proxy backend uses default 3072 dimensions when geminiDimensions not set", async () => {
143
128
  enableManagedProxy();
144
- enableFlag();
145
129
  const config = makeConfig();
146
130
 
147
131
  const { backend } = await selectEmbeddingBackend(config);
@@ -155,7 +139,6 @@ describe("managed proxy Gemini embedding selection", () => {
155
139
 
156
140
  test("managed proxy backend uses explicit geminiDimensions when set", async () => {
157
141
  enableManagedProxy();
158
- enableFlag();
159
142
  const config = makeConfig({ geminiDimensions: 768 });
160
143
 
161
144
  const { backend } = await selectEmbeddingBackend(config);
@@ -168,7 +151,6 @@ describe("managed proxy Gemini embedding selection", () => {
168
151
 
169
152
  test("managed proxy backend uses managedBaseUrl (not direct Google API)", async () => {
170
153
  enableManagedProxy();
171
- enableFlag();
172
154
  const config = makeConfig();
173
155
 
174
156
  const { backend } = await selectEmbeddingBackend(config);
@@ -179,32 +161,19 @@ describe("managed proxy Gemini embedding selection", () => {
179
161
  expect(managedBaseUrl).toBe(`${PLATFORM_BASE}/v1/runtime-proxy/gemini`);
180
162
  });
181
163
 
182
- test("falls back to local when flag is disabled (no managed proxy)", async () => {
183
- enableManagedProxy();
184
- disableFlag();
185
- const config = makeConfig();
186
-
187
- const { backend } = await selectEmbeddingBackend(config);
188
-
189
- // With auto and no provider keys, falls through to local
190
- expect(backend).not.toBeNull();
191
- expect(backend!.provider).toBe("local");
192
- });
193
-
194
164
  test("falls back to local when managed proxy context unavailable", async () => {
195
165
  disableManagedProxy();
196
- enableFlag();
197
166
  const config = makeConfig();
198
167
 
199
168
  const { backend } = await selectEmbeddingBackend(config);
200
169
 
170
+ // With auto and no provider keys or proxy, falls through to local
201
171
  expect(backend).not.toBeNull();
202
172
  expect(backend!.provider).toBe("local");
203
173
  });
204
174
 
205
175
  test("selects managed proxy when provider is explicitly gemini", async () => {
206
176
  enableManagedProxy();
207
- enableFlag();
208
177
  const config = makeConfig({ provider: "gemini" });
209
178
 
210
179
  const { backend } = await selectEmbeddingBackend(config);
@@ -217,7 +186,6 @@ describe("managed proxy Gemini embedding selection", () => {
217
186
 
218
187
  test("does not use managed proxy when provider is explicitly local", async () => {
219
188
  enableManagedProxy();
220
- enableFlag();
221
189
  const config = makeConfig({ provider: "local" });
222
190
 
223
191
  const { backend } = await selectEmbeddingBackend(config);
@@ -228,7 +196,6 @@ describe("managed proxy Gemini embedding selection", () => {
228
196
 
229
197
  test("does not use managed proxy when provider is explicitly openai", async () => {
230
198
  enableManagedProxy();
231
- enableFlag();
232
199
  mockProviderKeys[credentialKey("openai", "api_key")] = "user-openai-key";
233
200
  const config = makeConfig({ provider: "openai" });
234
201
 
@@ -238,9 +205,8 @@ describe("managed proxy Gemini embedding selection", () => {
238
205
  expect(backend!.provider).toBe("openai");
239
206
  });
240
207
 
241
- test("direct Gemini key still works when flag is off", async () => {
208
+ test("direct Gemini key still works without managed proxy", async () => {
242
209
  disableManagedProxy();
243
- disableFlag();
244
210
  mockProviderKeys[credentialKey("gemini", "api_key")] = "user-gemini-key";
245
211
  const config = makeConfig({ provider: "gemini" });
246
212