@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
@@ -76,7 +76,6 @@ function makeTarget(): Conversation {
76
76
  run: async ({ messages }: { messages: Message[] }) => ({
77
77
  history: messages,
78
78
  exitReason: null,
79
- appendedNewMessages: false,
80
79
  newMessages: [],
81
80
  }),
82
81
  },
@@ -183,6 +183,7 @@ mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
183
183
  async maybeCompact() {
184
184
  return { compacted: false };
185
185
  }
186
+ resetOverflowRecovery() {}
186
187
  },
187
188
  createContextSummaryMessage: () => ({
188
189
  role: "user",
@@ -167,7 +167,6 @@ const mockFailStalledJobs = mock(() => 0);
167
167
  const mockClaimMemoryJobs = mock(() => []);
168
168
  mock.module("../memory/jobs-store.js", () => ({
169
169
  claimMemoryJobs: mockClaimMemoryJobs,
170
- cancelPendingAutomaticConsolidationJobs: mock(() => 0),
171
170
  completeMemoryJob: mock(() => {}),
172
171
  deferMemoryJob: mock(() => "deferred"),
173
172
  EMBED_JOB_TYPES: [],
@@ -179,7 +178,6 @@ mock.module("../memory/jobs-store.js", () => ({
179
178
  failStalledJobs: mockFailStalledJobs,
180
179
  getMemoryJobCounts: mock(() => ({})),
181
180
  hasActiveJobOfType: mock(() => false),
182
- isAutomaticConsolidationJob: mock(() => true),
183
181
  isMemoryEnabled: () => true,
184
182
  MEMORY_V2_CONSOLIDATION_JOB_TRIGGERS: {
185
183
  automatic: "automatic",
@@ -114,7 +114,6 @@ mock.module("../daemon/conversation-store.js", () => ({
114
114
  mergeConversationOptions: () => {},
115
115
  deleteConversationOptions: () => {},
116
116
  clearConversationOptions: () => {},
117
- setCesClientPromise: () => {},
118
117
  }));
119
118
 
120
119
  // ---------------------------------------------------------------------------
@@ -54,7 +54,10 @@ mock.module("../memory/llm-request-log-store.js", () => ({
54
54
  }));
55
55
 
56
56
  // ── Imports (after mocks) ─────────────────────────────────────────────────────
57
- import { buildPersistedAssistantContent } from "../daemon/conversation-agent-loop-handlers.js";
57
+ import {
58
+ buildPersistedAssistantContent,
59
+ stampThinkingTiming,
60
+ } from "../daemon/conversation-agent-loop-handlers.js";
58
61
  import type { ToolActivityMetadata } from "../daemon/message-types/web-activity.js";
59
62
  import type { ContentBlock } from "../providers/types.js";
60
63
 
@@ -182,3 +185,74 @@ describe("buildPersistedAssistantContent — native activityMetadata", () => {
182
185
  expect(block._activityMetadata).toBeUndefined();
183
186
  });
184
187
  });
188
+
189
+ describe("stampThinkingTiming", () => {
190
+ test("stamps internal timing onto thinking blocks by position", () => {
191
+ // GIVEN a turn that interleaves text and two thinking blocks AND the
192
+ // per-block timing captured while streaming (one entry per thinking block,
193
+ // in stream order)
194
+ const content = [
195
+ { type: "thinking", thinking: "first", signature: "s1" },
196
+ { type: "text", text: "answer" },
197
+ { type: "thinking", thinking: "second", signature: "s2" },
198
+ ] as unknown as ContentBlock[];
199
+ const timings = [
200
+ { startedAt: 100, completedAt: 250 },
201
+ { startedAt: 400, completedAt: 480 },
202
+ ];
203
+
204
+ // WHEN the content is stamped before persistence
205
+ const stamped = stampThinkingTiming(content, timings) as unknown as Array<
206
+ Record<string, unknown>
207
+ >;
208
+
209
+ // THEN each thinking block carries the `_`-prefixed timing for its position
210
+ expect(stamped[0]).toMatchObject({
211
+ type: "thinking",
212
+ _startedAt: 100,
213
+ _completedAt: 250,
214
+ });
215
+ expect(stamped[2]).toMatchObject({
216
+ type: "thinking",
217
+ _startedAt: 400,
218
+ _completedAt: 480,
219
+ });
220
+ // AND the interleaved text block is left untouched
221
+ expect(stamped[1]).toEqual({ type: "text", text: "answer" });
222
+ });
223
+
224
+ test("leaves thinking blocks unstamped when no timing was captured", () => {
225
+ // GIVEN thinking content but an empty timing list (thinking streaming was
226
+ // disabled, so no per-block timing was recorded this turn)
227
+ const content = [
228
+ { type: "thinking", thinking: "first", signature: "s1" },
229
+ ] as unknown as ContentBlock[];
230
+
231
+ // WHEN the content is stamped with no timing
232
+ const stamped = stampThinkingTiming(content, []);
233
+
234
+ // THEN the original content is returned unchanged so the UI hides duration,
235
+ // exactly as a tool call with no timing
236
+ expect(stamped).toBe(content);
237
+ expect(stamped[0]).not.toHaveProperty("_startedAt");
238
+ });
239
+
240
+ test("stamps only the thinking blocks that have a matching timing entry", () => {
241
+ // GIVEN two thinking blocks but only one captured timing entry (e.g. the
242
+ // second block opened after the timing array was already finalized)
243
+ const content = [
244
+ { type: "thinking", thinking: "first", signature: "s1" },
245
+ { type: "thinking", thinking: "second", signature: "s2" },
246
+ ] as unknown as ContentBlock[];
247
+ const timings = [{ startedAt: 100, completedAt: 250 }];
248
+
249
+ // WHEN the content is stamped
250
+ const stamped = stampThinkingTiming(content, timings) as unknown as Array<
251
+ Record<string, unknown>
252
+ >;
253
+
254
+ // THEN the first block is stamped and the unmatched second block is left as-is
255
+ expect(stamped[0]).toMatchObject({ _startedAt: 100, _completedAt: 250 });
256
+ expect(stamped[1]).not.toHaveProperty("_startedAt");
257
+ });
258
+ });
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Regression tests for catalog entry normalization in catalog-install.ts.
3
+ *
4
+ * The platform `/v1/skills/` API flattens skill metadata into top-level
5
+ * fields (`category`, `display_name`, `icon`) rather than the nested
6
+ * `metadata.vellum.*` shape used by the local `catalog.json`. Both
7
+ * `fetchCatalog` (remote) and `readLocalCatalog` (local file) must produce a
8
+ * canonical `CatalogSkill` whose `metadata.vellum.category` is populated, so
9
+ * downstream category assignment doesn't fall back to "system" for every skill.
10
+ */
11
+
12
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { afterEach, describe, expect, mock, test } from "bun:test";
16
+
17
+ mock.module("../util/logger.js", () => ({
18
+ getLogger: () =>
19
+ new Proxy({} as Record<string, unknown>, {
20
+ get: () => () => {},
21
+ }),
22
+ }));
23
+
24
+ mock.module("../config/env.js", () => ({
25
+ getPlatformBaseUrl: () => "https://platform.example.com",
26
+ }));
27
+
28
+ import { fetchCatalog, readLocalCatalog } from "../skills/catalog-install.js";
29
+
30
+ const originalFetch = globalThis.fetch;
31
+
32
+ afterEach(() => {
33
+ globalThis.fetch = originalFetch;
34
+ });
35
+
36
+ /**
37
+ * Build a `fetch` stub that responds with `payload` serialized as JSON.
38
+ *
39
+ * `Object.assign` attaches the `preconnect` static that Bun's `fetch` type
40
+ * requires, so the stub satisfies `typeof fetch` without an `as unknown` cast.
41
+ */
42
+ function stubFetchJson(payload: unknown): typeof fetch {
43
+ const respond = async () =>
44
+ new Response(JSON.stringify(payload), {
45
+ status: 200,
46
+ headers: { "content-type": "application/json" },
47
+ });
48
+ return Object.assign(respond, { preconnect: () => {} });
49
+ }
50
+
51
+ describe("fetchCatalog normalization", () => {
52
+ test("re-nests the platform's flattened category under metadata.vellum", async () => {
53
+ globalThis.fetch = stubFetchJson({
54
+ skills: [
55
+ {
56
+ id: "amazon",
57
+ name: "amazon",
58
+ display_name: "Amazon",
59
+ description: "Shop on Amazon",
60
+ icon: "🛒",
61
+ category: "commerce",
62
+ updated_at: "2026-04-19T19:26:17Z",
63
+ },
64
+ ],
65
+ });
66
+
67
+ const catalog = await fetchCatalog();
68
+
69
+ expect(catalog).toHaveLength(1);
70
+ const [skill] = catalog;
71
+ expect(skill.id).toBe("amazon");
72
+ expect(skill.metadata?.vellum?.category).toBe("commerce");
73
+ expect(skill.metadata?.vellum?.["display-name"]).toBe("Amazon");
74
+ expect(skill.icon).toBe("🛒");
75
+ expect(skill.metadata?.icon).toBe("🛒");
76
+ expect(skill.updatedAt).toBe("2026-04-19T19:26:17Z");
77
+ });
78
+
79
+ test("leaves category undefined when the API omits it", async () => {
80
+ globalThis.fetch = stubFetchJson({
81
+ skills: [{ id: "no-cat", name: "no-cat", description: "d" }],
82
+ });
83
+
84
+ const catalog = await fetchCatalog();
85
+
86
+ expect(catalog).toHaveLength(1);
87
+ expect(catalog[0].metadata?.vellum?.category).toBeUndefined();
88
+ });
89
+
90
+ test("drops malformed entries without throwing", async () => {
91
+ globalThis.fetch = stubFetchJson({
92
+ skills: [
93
+ null,
94
+ undefined,
95
+ "not-an-object",
96
+ { name: "missing-id", description: "d" },
97
+ { id: 42 },
98
+ { id: "valid", name: "valid", description: "d", category: "email" },
99
+ ],
100
+ });
101
+
102
+ const catalog = await fetchCatalog();
103
+
104
+ expect(catalog).toHaveLength(1);
105
+ expect(catalog[0].id).toBe("valid");
106
+ expect(catalog[0].metadata?.vellum?.category).toBe("email");
107
+ });
108
+ });
109
+
110
+ describe("readLocalCatalog normalization", () => {
111
+ test("reads the nested metadata.vellum.category from catalog.json", () => {
112
+ const dir = mkdtempSync(join(tmpdir(), "vellum-catalog-"));
113
+ try {
114
+ writeFileSync(
115
+ join(dir, "catalog.json"),
116
+ JSON.stringify({
117
+ version: 1,
118
+ skills: [
119
+ {
120
+ id: "tasks",
121
+ name: "tasks",
122
+ description: "Task management",
123
+ metadata: {
124
+ icon: "✅",
125
+ vellum: { "display-name": "Tasks", category: "productivity" },
126
+ },
127
+ },
128
+ ],
129
+ }),
130
+ );
131
+
132
+ const catalog = readLocalCatalog(dir);
133
+
134
+ expect(catalog).toHaveLength(1);
135
+ expect(catalog[0].metadata?.vellum?.category).toBe("productivity");
136
+ expect(catalog[0].metadata?.vellum?.["display-name"]).toBe("Tasks");
137
+ } finally {
138
+ rmSync(dir, { recursive: true, force: true });
139
+ }
140
+ });
141
+ });
@@ -4,8 +4,23 @@ import type { CesClient } from "../credential-execution/client.js";
4
4
  import {
5
5
  awaitCesClientWithTimeout,
6
6
  DEFAULT_CES_STARTUP_TIMEOUT_MS,
7
+ injectCesClientWhenReady,
7
8
  } from "../credential-execution/startup-timeout.js";
8
9
 
10
+ function makeResolver(initial?: CesClient) {
11
+ let current = initial;
12
+ const setCesClient = mock((client: CesClient) => {
13
+ current = client;
14
+ });
15
+ return {
16
+ getCesClient: () => current,
17
+ setCesClient,
18
+ };
19
+ }
20
+
21
+ /** Wait for the microtask attached to the resolved promise to run. */
22
+ const flush = () => new Promise((resolve) => setTimeout(resolve, 0));
23
+
9
24
  describe("awaitCesClientWithTimeout", () => {
10
25
  test("clears the fallback timer when the CES client resolves first", async () => {
11
26
  const onTimeout = mock(() => {});
@@ -38,3 +53,48 @@ describe("awaitCesClientWithTimeout", () => {
38
53
  expect(DEFAULT_CES_STARTUP_TIMEOUT_MS).toBe(20_000);
39
54
  });
40
55
  });
56
+
57
+ describe("injectCesClientWhenReady", () => {
58
+ test("injects the client into an empty resolver once the handshake resolves", async () => {
59
+ const client = { isReady: () => true } as unknown as CesClient;
60
+ const resolver = makeResolver();
61
+
62
+ injectCesClientWhenReady(Promise.resolve(client), resolver);
63
+ await flush();
64
+
65
+ expect(resolver.setCesClient).toHaveBeenCalledTimes(1);
66
+ expect(resolver.getCesClient()).toBe(client);
67
+ });
68
+
69
+ test("does not overwrite a client installed by a reconnection", async () => {
70
+ const reconnected = { isReady: () => true } as unknown as CesClient;
71
+ const lateStartupClient = { isReady: () => true } as unknown as CesClient;
72
+ const resolver = makeResolver(reconnected);
73
+
74
+ injectCesClientWhenReady(Promise.resolve(lateStartupClient), resolver);
75
+ await flush();
76
+
77
+ expect(resolver.setCesClient).not.toHaveBeenCalled();
78
+ expect(resolver.getCesClient()).toBe(reconnected);
79
+ });
80
+
81
+ test("is a no-op when the handshake resolves without a client", async () => {
82
+ const resolver = makeResolver();
83
+
84
+ injectCesClientWhenReady(Promise.resolve(undefined), resolver);
85
+ await flush();
86
+
87
+ expect(resolver.setCesClient).not.toHaveBeenCalled();
88
+ expect(resolver.getCesClient()).toBeUndefined();
89
+ });
90
+
91
+ test("swallows a rejected handshake without injecting", async () => {
92
+ const resolver = makeResolver();
93
+
94
+ injectCesClientWhenReady(Promise.reject(new Error("aborted")), resolver);
95
+ await flush();
96
+
97
+ expect(resolver.setCesClient).not.toHaveBeenCalled();
98
+ expect(resolver.getCesClient()).toBeUndefined();
99
+ });
100
+ });
@@ -198,6 +198,7 @@ mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
198
198
  async maybeCompact(): Promise<ContextWindowResult> {
199
199
  return mockCompactResult;
200
200
  }
201
+ resetOverflowRecovery() {}
201
202
  },
202
203
  createContextSummaryMessage: () => ({
203
204
  role: "user",
@@ -57,17 +57,8 @@ mock.module("../util/logger.js", () => ({
57
57
  getLogger: () => makeLoggerStub(),
58
58
  }));
59
59
 
60
- // ---------------------------------------------------------------------------
61
- // Feature flag mock — controls whether managed-gemini-embeddings-enabled is on
62
- // ---------------------------------------------------------------------------
63
-
64
- let featureFlagEnabled = false;
65
-
66
60
  mock.module("../config/assistant-feature-flags.js", () => ({
67
- isAssistantFeatureFlagEnabled: (key: string) => {
68
- if (key === "managed-gemini-embeddings-enabled") return featureFlagEnabled;
69
- return true;
70
- },
61
+ isAssistantFeatureFlagEnabled: () => true,
71
62
  clearFeatureFlagOverridesCache: () => {},
72
63
  initFeatureFlagOverrides: async () => {},
73
64
  getAssistantFeatureFlagDefaults: () => ({}),
@@ -119,8 +110,6 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
119
110
  setStorePathForTesting(join(WORKSPACE_DIR, "keys.enc"));
120
111
  invalidateConfigCache();
121
112
 
122
- // Reset mock state
123
- featureFlagEnabled = false;
124
113
  originalIsPlatform = process.env.IS_PLATFORM;
125
114
  delete process.env.IS_PLATFORM;
126
115
  });
@@ -137,10 +126,9 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
137
126
  }
138
127
  });
139
128
 
140
- test("applies managed Gemini defaults when FF on + IS_PLATFORM + provider auto", () => {
129
+ test("applies managed Gemini defaults when IS_PLATFORM + provider auto", () => {
141
130
  writeConfig({});
142
131
 
143
- featureFlagEnabled = true;
144
132
  process.env.IS_PLATFORM = "true";
145
133
 
146
134
  const config = loadConfig();
@@ -162,22 +150,9 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
162
150
  expect(qdrantRaw.vectorSize).toBe(3072);
163
151
  });
164
152
 
165
- test("does NOT apply when feature flag is OFF", () => {
166
- writeConfig({});
167
-
168
- featureFlagEnabled = false;
169
- process.env.IS_PLATFORM = "true";
170
-
171
- const config = loadConfig();
172
-
173
- expect(config.memory.embeddings.provider).toBe("auto");
174
- expect(config.memory.qdrant.vectorSize).toBe(384);
175
- });
176
-
177
153
  test("does NOT apply when IS_PLATFORM is not set", () => {
178
154
  writeConfig({});
179
155
 
180
- featureFlagEnabled = true;
181
156
  delete process.env.IS_PLATFORM;
182
157
 
183
158
  const config = loadConfig();
@@ -191,7 +166,6 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
191
166
  memory: { embeddings: { provider: "local" } },
192
167
  });
193
168
 
194
- featureFlagEnabled = true;
195
169
  process.env.IS_PLATFORM = "true";
196
170
 
197
171
  const config = loadConfig();
@@ -204,7 +178,6 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
204
178
  memory: { embeddings: { provider: "openai" } },
205
179
  });
206
180
 
207
- featureFlagEnabled = true;
208
181
  process.env.IS_PLATFORM = "true";
209
182
 
210
183
  const config = loadConfig();
@@ -219,7 +192,6 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
219
192
  },
220
193
  });
221
194
 
222
- featureFlagEnabled = true;
223
195
  process.env.IS_PLATFORM = "true";
224
196
 
225
197
  const config = loadConfig();
@@ -235,7 +207,6 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
235
207
  memory: { embeddings: { provider: "ollama" } },
236
208
  });
237
209
 
238
- featureFlagEnabled = true;
239
210
  process.env.IS_PLATFORM = "true";
240
211
 
241
212
  const config = loadConfig();
@@ -245,7 +216,6 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
245
216
  test("is idempotent — second loadConfig is a no-op after migration", () => {
246
217
  writeConfig({});
247
218
 
248
- featureFlagEnabled = true;
249
219
  process.env.IS_PLATFORM = "true";
250
220
 
251
221
  const config = loadConfig();
@@ -274,7 +244,6 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
274
244
  },
275
245
  });
276
246
 
277
- featureFlagEnabled = true;
278
247
  process.env.IS_PLATFORM = "true";
279
248
 
280
249
  const config = loadConfig();
@@ -295,22 +264,9 @@ describe("managed Gemini embedding defaults (via loadConfig)", () => {
295
264
  expect(qdrantRaw.onDisk).toBe(false);
296
265
  });
297
266
 
298
- test("does NOT apply when both FF off and IS_PLATFORM not set", () => {
299
- writeConfig({});
300
-
301
- featureFlagEnabled = false;
302
- delete process.env.IS_PLATFORM;
303
-
304
- const config = loadConfig();
305
-
306
- expect(config.memory.embeddings.provider).toBe("auto");
307
- expect(config.memory.qdrant.vectorSize).toBe(384);
308
- });
309
-
310
267
  test("applies when IS_PLATFORM is '1'", () => {
311
268
  writeConfig({});
312
269
 
313
- featureFlagEnabled = true;
314
270
  process.env.IS_PLATFORM = "1";
315
271
 
316
272
  const config = loadConfig();