@vellumai/assistant 0.8.4 → 0.8.6

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 (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Module-level cache for resolved feature flag override values.
3
+ *
4
+ * Lives in its own module (rather than alongside the resolver in
5
+ * `assistant-feature-flags.ts`) so test code can read/write the cache
6
+ * without going through `assistant-feature-flags.ts` — which transitively
7
+ * pulls `util/logger.js` (pino) and the gateway IPC client. Stdlib-only
8
+ * by design: this file must remain safe to import from the test
9
+ * preload's load-time chain, where a broken `node_modules` symlink has
10
+ * historically tripped the env override (see DB ghost #3,
11
+ * /workspace/journal/2026-05-25-db-ghost-3-recovery.md).
12
+ *
13
+ * State is held on `globalThis.vellumAssistant.featureFlagCache` so test
14
+ * helpers in `__tests__/` can read/write it WITHOUT importing this
15
+ * module — they declare the same slot shape locally and access the
16
+ * globalThis namespace directly. See
17
+ * `__tests__/feature-flag-test-helpers.ts` for the test-side mirror;
18
+ * the slot shape MUST stay in sync between the two.
19
+ *
20
+ * Both `overrides` and `fromGateway` were previously module-level `let`
21
+ * bindings inside `assistant-feature-flags.ts`. The semantics are
22
+ * preserved exactly: `overrides === null` means "no fetch has populated
23
+ * the cache yet"; `fromGateway === true` means "the cache is
24
+ * authoritative — `initFeatureFlagOverrides()` should not clobber it".
25
+ *
26
+ * Consumers:
27
+ * - `assistant-feature-flags.ts` (resolver — reads/writes via gateway fetch)
28
+ * - `__tests__/feature-flag-test-helpers.ts` (seeds for tests, via globalThis)
29
+ */
30
+
31
+ type FlagSlot = {
32
+ overrides: Record<string, boolean> | null;
33
+ fromGateway: boolean;
34
+ };
35
+
36
+ type VellumAssistantNamespace = {
37
+ featureFlagCache?: FlagSlot;
38
+ };
39
+
40
+ function slot(): FlagSlot {
41
+ const g = globalThis as { vellumAssistant?: VellumAssistantNamespace };
42
+ const ns = (g.vellumAssistant ??= {});
43
+ return (ns.featureFlagCache ??= { overrides: null, fromGateway: false });
44
+ }
45
+
46
+ /** Read the current override cache. `null` means not yet populated. */
47
+ export function getCachedOverrides(): Record<string, boolean> | null {
48
+ return slot().overrides;
49
+ }
50
+
51
+ /**
52
+ * True when the cache was populated by either a gateway IPC fetch or by a
53
+ * test helper. Used by `initFeatureFlagOverrides()` to short-circuit a
54
+ * second fetch (e.g. when a CLI entry point runs after the daemon has
55
+ * already initialized) and by tests to prevent the retry loop from
56
+ * clobbering preseeded state.
57
+ */
58
+ export function isCachedFromGateway(): boolean {
59
+ return slot().fromGateway;
60
+ }
61
+
62
+ /**
63
+ * Replace the cache with a clone of `overrides`. The `fromGateway` flag
64
+ * is set by the caller — production callers pass `true` after a
65
+ * successful gateway fetch; test helpers also pass `true` so subsequent
66
+ * `initFeatureFlagOverrides()` calls are no-ops.
67
+ */
68
+ export function setCachedOverrides(
69
+ overrides: Record<string, boolean>,
70
+ options: { fromGateway: boolean },
71
+ ): void {
72
+ const s = slot();
73
+ s.overrides = { ...overrides };
74
+ s.fromGateway = options.fromGateway;
75
+ }
76
+
77
+ /**
78
+ * Drop the cache. The next `loadOverrides()` returns an empty record (so
79
+ * flag checks fall through to registry defaults) and the next
80
+ * `initFeatureFlagOverrides()` re-fetches from the gateway.
81
+ */
82
+ export function clearCachedOverrides(): void {
83
+ const s = slot();
84
+ s.overrides = null;
85
+ s.fromGateway = false;
86
+ }
@@ -25,6 +25,14 @@
25
25
  "description": "Enable user-hosted onboarding flow",
26
26
  "defaultEnabled": false
27
27
  },
28
+ {
29
+ "id": "prechat-onboarding-condensed-flow",
30
+ "scope": "client",
31
+ "key": "prechat-onboarding-condensed-flow",
32
+ "label": "Condensed Pre-chat Onboarding",
33
+ "description": "Enable the condensed pre-chat onboarding flow for a standard LaunchDarkly percentage rollout.",
34
+ "defaultEnabled": false
35
+ },
28
36
  {
29
37
  "id": "local-docker-enabled",
30
38
  "scope": "client",
@@ -190,7 +198,7 @@
190
198
  "scope": "assistant",
191
199
  "key": "fast-mode",
192
200
  "label": "Fast Mode",
193
- "description": "Enable Anthropic fast mode for Opus models (4.6, 4.7), delivering up to 2.5x higher output tokens per second at premium pricing",
201
+ "description": "Enable Anthropic fast mode for Opus models (4.6, 4.7, 4.8), delivering up to 2.5x higher output tokens per second at premium pricing",
194
202
  "defaultEnabled": false
195
203
  },
196
204
  {
@@ -281,14 +289,6 @@
281
289
  "description": "Expose the developer-only Compaction Playground tab in macOS Settings and enable the /playground/* HTTP endpoints for exercising compaction conditions. Dev-only; default off.",
282
290
  "defaultEnabled": false
283
291
  },
284
- {
285
- "id": "safe-storage-limits",
286
- "scope": "assistant",
287
- "key": "safe-storage-limits",
288
- "label": "Safe Storage Limits",
289
- "description": "Enable disk pressure protection flows that block background work and remote actors while storage is critically low.",
290
- "defaultEnabled": false
291
- },
292
292
  {
293
293
  "id": "account-deletion",
294
294
  "scope": "assistant",
@@ -313,14 +313,6 @@
313
313
  "description": "Show the 'Analyze' / 'Analyze conversation' option in conversation context menus and the conversation title actions dropdown.",
314
314
  "defaultEnabled": false
315
315
  },
316
- {
317
- "id": "pro-plan-adjust",
318
- "scope": "client",
319
- "key": "pro-plan-adjust",
320
- "label": "Pro Plan Adjust",
321
- "description": "Show the rich Plan card (current plan, features, Manage/Upgrade CTA) at the top of the macOS Settings \u2192 Billing tab.",
322
- "defaultEnabled": false
323
- },
324
316
  {
325
317
  "id": "external-plugins",
326
318
  "scope": "assistant",
@@ -393,6 +385,14 @@
393
385
  "description": "Enable the Notifications tab in settings.",
394
386
  "defaultEnabled": false
395
387
  },
388
+ {
389
+ "id": "preview-channel",
390
+ "scope": "client",
391
+ "key": "preview-channel",
392
+ "label": "Preview Channel",
393
+ "description": "Enable user-facing Preview release channel controls in assistant settings.",
394
+ "defaultEnabled": false
395
+ },
396
396
  {
397
397
  "id": "rollback-enabled",
398
398
  "scope": "assistant",
@@ -424,6 +424,22 @@
424
424
  "label": "Velvet",
425
425
  "description": "Enable the Velvet design theme.",
426
426
  "defaultEnabled": false
427
+ },
428
+ {
429
+ "id": "memory-router-playground",
430
+ "scope": "client",
431
+ "key": "memory-router-playground",
432
+ "label": "Memory Router Playground",
433
+ "description": "Expose the developer-only Memory Router Playground tab in macOS Settings and the /assistant/memory-router-playground web page for dry-running v4 router config overrides against the live page index. Dev-only; default off.",
434
+ "defaultEnabled": false
435
+ },
436
+ {
437
+ "id": "platform-features-in-local-mode",
438
+ "scope": "assistant",
439
+ "key": "platform-features-in-local-mode",
440
+ "label": "Platform Features in Local Mode",
441
+ "description": "When enabled, the assistant can call the Vellum platform API from local mode. When disabled, all platform API clients in the daemon, gateway, CES, and web UI no-op with a debug log instead of making outbound requests.",
442
+ "defaultEnabled": true
427
443
  }
428
444
  ]
429
445
  }
@@ -27,12 +27,21 @@ export function resolveEffectiveContextWindow({
27
27
  llm,
28
28
  callSite,
29
29
  overrideProfile,
30
+ selectionSeed,
30
31
  }: {
31
32
  llm: LLMConfig;
32
33
  callSite: LLMCallSite;
33
34
  overrideProfile?: string;
35
+ /**
36
+ * Per-conversation mix seed (the conversation id). Threaded so context-window
37
+ * sizing for a mix profile reflects the same arm the dispatch path picks.
38
+ */
39
+ selectionSeed?: string;
34
40
  }): EffectiveContextWindow {
35
- const resolved = resolveCallSiteConfig(callSite, llm, { overrideProfile });
41
+ const resolved = resolveCallSiteConfig(callSite, llm, {
42
+ overrideProfile,
43
+ selectionSeed,
44
+ });
36
45
  const catalogModel = PROVIDER_CATALOG.find(
37
46
  (provider) => provider.id === resolved.provider,
38
47
  )?.models.find((model) => model.id === resolved.model);
@@ -42,33 +42,60 @@ import {
42
42
  * resolver stays pure; schema validation in `LLMSchema.superRefine` catches
43
43
  * unknown `activeProfile` references at config-load time.
44
44
  *
45
- * Pure & synchronous: no I/O, no async work.
45
+ * A profile reference that points at a "mix" profile is expanded to one of its
46
+ * constituent profiles by a seeded weighted pick (see `resolveProfileFragment`
47
+ * and `opts.selectionSeed`). Expansion happens uniformly at every dereference
48
+ * spot, so a mix works as `activeProfile`, `overrideProfile`, or a call-site
49
+ * `profile`.
50
+ *
51
+ * Pure & synchronous: no I/O, no async work. (Random selection only occurs for
52
+ * mix profiles when no `selectionSeed` is supplied; with a seed the pick is
53
+ * deterministic.)
46
54
  */
55
+ export interface ResolveCallSiteOpts {
56
+ overrideProfile?: string;
57
+ /**
58
+ * Per-conversation seed for expanding `mix` profiles. The chosen constituent
59
+ * is a deterministic function of `selectionSeed` + the mix profile's own
60
+ * name, so every `resolveCallSiteConfig` call for the same conversation picks
61
+ * the SAME arm (stable across turns, retries, and restarts). Pass the
62
+ * conversation id. When absent, the resolver falls back to a fresh random
63
+ * pick per call — acceptable only for one-shot/background call sites that
64
+ * resolve config exactly once per invocation.
65
+ */
66
+ selectionSeed?: string;
67
+ /**
68
+ * Invoked once for each mix profile the resolver expands, reporting which
69
+ * constituent was chosen. Used by A/B-eval recording (usage attribution).
70
+ */
71
+ onMixSelected?: (info: { mixProfile: string; chosenProfile: string }) => void;
72
+ }
73
+
47
74
  export function resolveCallSiteConfig(
48
75
  callSite: LLMCallSite,
49
76
  llm: z.infer<typeof LLMSchema>,
50
- opts: { overrideProfile?: string } = {},
77
+ opts: ResolveCallSiteOpts = {},
51
78
  ): z.infer<typeof LLMConfigBase> {
52
79
  const layers: Mergeable[] = [llm.default as Mergeable];
53
80
 
54
- const activeFragment =
55
- llm.activeProfile != null ? llm.profiles?.[llm.activeProfile] : undefined;
56
- const overrideFragment =
57
- opts.overrideProfile != null
58
- ? llm.profiles?.[opts.overrideProfile]
59
- : undefined;
81
+ const activeFragment = resolveProfileFragment(llm.activeProfile, llm, opts);
82
+ const overrideFragment = resolveProfileFragment(
83
+ opts.overrideProfile,
84
+ llm,
85
+ opts,
86
+ );
60
87
  const site =
61
88
  llm.callSites?.[callSite] ??
62
89
  effectiveDefault(callSite, llm, opts.overrideProfile != null);
63
90
 
64
91
  if (callSite === "mainAgent") {
65
- appendCallSiteLayers(layers, callSite, llm, site);
92
+ appendCallSiteLayers(layers, callSite, llm, site, opts);
66
93
  appendProfileLayer(layers, activeFragment);
67
94
  appendProfileLayer(layers, overrideFragment);
68
95
  } else {
69
96
  appendProfileLayer(layers, activeFragment);
70
97
  appendProfileLayer(layers, overrideFragment);
71
- appendCallSiteLayers(layers, callSite, llm, site);
98
+ appendCallSiteLayers(layers, callSite, llm, site, opts);
72
99
  }
73
100
 
74
101
  return finalize(deepMerge(...layers.map(withImpliedProviderForKnownModel)));
@@ -80,6 +107,81 @@ export function resolveCallSiteConfig(
80
107
 
81
108
  type Mergeable = Record<string, unknown>;
82
109
 
110
+ /**
111
+ * FNV-1a 32-bit string hash → unit float in [0, 1). Deterministic and stable
112
+ * across runtimes — the mix-pick contract depends on identical output for
113
+ * identical input forever, so the constants must never change. (Mirrors the
114
+ * private hash in `memory/v2/page-index.ts`; intentionally re-declared here so
115
+ * the resolver's determinism contract is self-contained and cannot be broken
116
+ * by an unrelated edit to that module.)
117
+ */
118
+ function seededUnitFloat(seed: string): number {
119
+ let h = 0x811c9dc5;
120
+ for (let i = 0; i < seed.length; i++) {
121
+ h ^= seed.charCodeAt(i);
122
+ h = Math.imul(h, 0x01000193);
123
+ }
124
+ // `>>> 0` → unsigned 32-bit; divide by 2^32 to land in [0, 1).
125
+ return (h >>> 0) / 0x100000000;
126
+ }
127
+
128
+ /**
129
+ * Pick one entry from a weighted list given a unit float in [0, 1). Weights
130
+ * are relative and normalized by their sum. Assumes `entries` is non-empty
131
+ * with positive weights (guaranteed by `MixSchema`: `.min(2)` + positive).
132
+ */
133
+ function weightedPick<T extends { weight: number }>(
134
+ entries: readonly T[],
135
+ unit: number,
136
+ ): T {
137
+ const total = entries.reduce((sum, e) => sum + e.weight, 0);
138
+ // Defensive: a degenerate total (unreachable post-schema) → first arm.
139
+ if (!(total > 0)) return entries[0];
140
+ let threshold = unit * total;
141
+ for (const entry of entries) {
142
+ threshold -= entry.weight;
143
+ if (threshold < 0) return entry;
144
+ }
145
+ // Floating-point fall-through (unit ≈ 1): return the last arm.
146
+ return entries[entries.length - 1];
147
+ }
148
+
149
+ /**
150
+ * Dereference a profile name to its concrete `ProfileEntry`, expanding a mix
151
+ * profile by a seeded weighted pick. Returns `undefined` when the name is
152
+ * unknown (parity with the silent fall-through callers already rely on).
153
+ *
154
+ * Mix expansion is one level only — `LLMSchema.superRefine` guarantees arms
155
+ * are standard (non-mix) profiles, so this never recurses unboundedly. A
156
+ * chosen arm pointing at a missing profile (only reachable in hand-crafted,
157
+ * unparsed configs) falls through to `undefined`.
158
+ *
159
+ * Pure & synchronous (the only impurity is `Math.random()` in the no-seed
160
+ * fallback path).
161
+ */
162
+ function resolveProfileFragment(
163
+ name: string | undefined,
164
+ llm: z.infer<typeof LLMSchema>,
165
+ opts: ResolveCallSiteOpts,
166
+ ): ProfileEntry | undefined {
167
+ if (name == null) return undefined;
168
+ const entry = llm.profiles?.[name];
169
+ if (entry?.mix == null) return entry;
170
+
171
+ // Mix: pick one constituent. Seed by per-conversation seed + the mix's own
172
+ // name so two different mixes in the same conversation pick independently,
173
+ // but the same mix always resolves to the same arm within the conversation.
174
+ const unit =
175
+ opts.selectionSeed != null
176
+ ? seededUnitFloat(`${opts.selectionSeed}\u0000${name}`)
177
+ : Math.random();
178
+ const chosen = weightedPick(entry.mix, unit);
179
+ opts.onMixSelected?.({ mixProfile: name, chosenProfile: chosen.profile });
180
+
181
+ // The chosen arm must be a standard profile (enforced by superRefine).
182
+ return llm.profiles?.[chosen.profile];
183
+ }
184
+
83
185
  /**
84
186
  * Returns the effective default profile key the resolver would actually
85
187
  * select for a call site when no per-turn `overrideProfile` is supplied.
@@ -170,16 +272,16 @@ function appendCallSiteLayers(
170
272
  callSite: LLMCallSite,
171
273
  llm: z.infer<typeof LLMSchema>,
172
274
  site: z.infer<typeof LLMSchema>["callSites"][LLMCallSite] | undefined,
275
+ opts: ResolveCallSiteOpts,
173
276
  ): void {
174
277
  if (site != null) {
175
278
  if (site.profile != null) {
176
- const profileFragment: ProfileEntry | undefined =
177
- llm.profiles?.[site.profile];
279
+ const profileFragment = resolveProfileFragment(site.profile, llm, opts);
178
280
  if (profileFragment == null) {
179
281
  // Defensive: `LLMSchema.superRefine` already rejects unknown profile
180
- // references at config load, so this branch is unreachable for any
181
- // config that survived schema validation. Throw a clear error in case
182
- // a hand-crafted (un-parsed) config slips through.
282
+ // references (and unknown mix arms) at config load, so this branch is
283
+ // unreachable for any config that survived schema validation. Throw a
284
+ // clear error in case a hand-crafted (un-parsed) config slips through.
183
285
  throw new Error(
184
286
  `LLM call site "${callSite}" references undefined profile "${site.profile}"`,
185
287
  );
@@ -198,6 +300,10 @@ function profileConfigFragment(profile: ProfileEntry): Mergeable {
198
300
  source: _source,
199
301
  label: _label,
200
302
  description: _description,
303
+ // `mix` never reaches here in practice (a mix expands to a standard
304
+ // profile before this point), but strip it defensively so it can never
305
+ // leak into the merged `LLMConfigBase`.
306
+ mix: _mix,
201
307
  ...config
202
308
  } = profile;
203
309
  return config as Mergeable;
@@ -122,6 +122,9 @@ export function getDeploymentContextDefaults(): Record<string, unknown> {
122
122
  if (process.env.IS_PLATFORM !== "true" && process.env.IS_PLATFORM !== "1") {
123
123
  return {};
124
124
  }
125
+ // `web-search.mode = managed` enables platform-backed app-executed search
126
+ // for non-native inference providers while preserving provider-native hosted
127
+ // search for providers/models that support it.
125
128
  const managed = { mode: "managed" as const };
126
129
  return {
127
130
  services: {
@@ -161,11 +164,7 @@ export function fillContextDefaultsForMissingKeys(
161
164
  ): void {
162
165
  for (const [key, value] of Object.entries(contextDefaults)) {
163
166
  const fileVal = fileConfig[key];
164
- if (
165
- value !== null &&
166
- typeof value === "object" &&
167
- !Array.isArray(value)
168
- ) {
167
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
169
168
  const targetChild = readPlainObject(target[key]);
170
169
  const fileChild = readPlainObject(fileVal);
171
170
  if (targetChild) {
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
 
3
3
  import { MemoryConfigSchema } from "../memory.js";
4
- import { MemoryV2ConfigSchema } from "../memory-v2.js";
4
+ import { MemoryV2ConfigSchema, MemoryV3ConfigSchema } from "../memory-v2.js";
5
5
 
6
6
  describe("MemoryV2ConfigSchema", () => {
7
7
  test("parses an empty object to documented defaults", () => {
@@ -40,6 +40,8 @@ describe("MemoryV2ConfigSchema", () => {
40
40
  batch_size: null,
41
41
  tier1_size: null,
42
42
  tier2_size: null,
43
+ historical_pairs: 1,
44
+ historical_pairs_max_chars: null,
43
45
  },
44
46
  });
45
47
  });
@@ -210,6 +212,231 @@ describe("MemoryV2ConfigSchema", () => {
210
212
  });
211
213
  });
212
214
 
215
+ describe("MemoryV3ConfigSchema", () => {
216
+ test("parses an empty object to documented defaults", () => {
217
+ const parsed = MemoryV3ConfigSchema.parse({});
218
+ expect(parsed).toEqual({
219
+ enabled: false,
220
+ shadow: false,
221
+ passCap: 3,
222
+ breadthBudget: 6,
223
+ maxDepth: 6,
224
+ denseQuota: { activeDomain: 30, offDomain: 8 },
225
+ hotLimit: 50,
226
+ lanes: { hot: true, sparse: true, dense: true, tree: true, edges: true },
227
+ edges: { learnedAdjacencyThreshold: 0, maxPulls: 400 },
228
+ ks: [5, 10, 25, 50],
229
+ write: {
230
+ enabled: false,
231
+ consolidateIntervalMs: 3600000,
232
+ coactivation: false,
233
+ },
234
+ prompts: {
235
+ filter: { override: null, path: null },
236
+ descent: { override: null, path: null },
237
+ gate: { override: null, path: null },
238
+ },
239
+ gateCandidateSummaries: false,
240
+ });
241
+ });
242
+
243
+ test("parses undefined to the same defaults (top-level .default)", () => {
244
+ expect(MemoryV3ConfigSchema.parse(undefined)).toEqual(
245
+ MemoryV3ConfigSchema.parse({}),
246
+ );
247
+ });
248
+
249
+ test("defaults to disabled for backwards compatibility", () => {
250
+ expect(MemoryV3ConfigSchema.parse({}).enabled).toBe(false);
251
+ expect(MemoryV3ConfigSchema.parse({}).shadow).toBe(false);
252
+ });
253
+
254
+ test("accepts explicit scalar overrides", () => {
255
+ const parsed = MemoryV3ConfigSchema.parse({
256
+ enabled: true,
257
+ shadow: true,
258
+ passCap: 5,
259
+ breadthBudget: 10,
260
+ maxDepth: 8,
261
+ });
262
+ expect(parsed.enabled).toBe(true);
263
+ expect(parsed.shadow).toBe(true);
264
+ expect(parsed.passCap).toBe(5);
265
+ expect(parsed.breadthBudget).toBe(10);
266
+ expect(parsed.maxDepth).toBe(8);
267
+ });
268
+
269
+ test("accepts explicit denseQuota override", () => {
270
+ const parsed = MemoryV3ConfigSchema.parse({
271
+ denseQuota: { activeDomain: 50, offDomain: 12 },
272
+ });
273
+ expect(parsed.denseQuota).toEqual({ activeDomain: 50, offDomain: 12 });
274
+ });
275
+
276
+ test("accepts a partial denseQuota override and defaults the rest", () => {
277
+ // Overriding only one leaf must merge with defaults, not fail validation
278
+ // (which would discard the entire user config).
279
+ const onlyActive = MemoryV3ConfigSchema.parse({
280
+ denseQuota: { activeDomain: 50 },
281
+ });
282
+ expect(onlyActive.denseQuota).toEqual({ activeDomain: 50, offDomain: 8 });
283
+
284
+ const onlyOff = MemoryV3ConfigSchema.parse({
285
+ denseQuota: { offDomain: 12 },
286
+ });
287
+ expect(onlyOff.denseQuota).toEqual({ activeDomain: 30, offDomain: 12 });
288
+ });
289
+
290
+ test("accepts a partial lanes override and defaults the rest", () => {
291
+ const parsed = MemoryV3ConfigSchema.parse({ lanes: { dense: false } });
292
+ expect(parsed.lanes).toEqual({
293
+ hot: true,
294
+ sparse: true,
295
+ dense: false,
296
+ tree: true,
297
+ edges: true,
298
+ });
299
+ });
300
+
301
+ test("accepts an explicit ks override", () => {
302
+ const parsed = MemoryV3ConfigSchema.parse({ ks: [1, 3, 7] });
303
+ expect(parsed.ks).toEqual([1, 3, 7]);
304
+ });
305
+
306
+ test("rejects a non-boolean enabled", () => {
307
+ expect(() => MemoryV3ConfigSchema.parse({ enabled: "yes" })).toThrow();
308
+ });
309
+
310
+ test("rejects a non-integer passCap", () => {
311
+ expect(() => MemoryV3ConfigSchema.parse({ passCap: 2.5 })).toThrow();
312
+ });
313
+
314
+ test("rejects non-number ks entries", () => {
315
+ expect(() => MemoryV3ConfigSchema.parse({ ks: ["a"] })).toThrow();
316
+ });
317
+
318
+ test("parses the write subtree to safe off defaults when omitted", () => {
319
+ const parsed = MemoryV3ConfigSchema.parse({});
320
+ expect(parsed.write).toEqual({
321
+ enabled: false,
322
+ consolidateIntervalMs: 3600000,
323
+ coactivation: false,
324
+ });
325
+ });
326
+
327
+ test("accepts a partial write override and defaults the rest", () => {
328
+ const parsed = MemoryV3ConfigSchema.parse({ write: { enabled: true } });
329
+ expect(parsed.write).toEqual({
330
+ enabled: true,
331
+ consolidateIntervalMs: 3600000,
332
+ coactivation: false,
333
+ });
334
+ });
335
+
336
+ test("rejects a non-integer write.consolidateIntervalMs", () => {
337
+ expect(() =>
338
+ MemoryV3ConfigSchema.parse({ write: { consolidateIntervalMs: 1.5 } }),
339
+ ).toThrow();
340
+ });
341
+
342
+ test("rejects a non-positive write.consolidateIntervalMs", () => {
343
+ // 0 or negative would make the scheduler's `now - lastRun >= interval`
344
+ // check always true, flooding the queue with consolidation jobs.
345
+ expect(() =>
346
+ MemoryV3ConfigSchema.parse({ write: { consolidateIntervalMs: 0 } }),
347
+ ).toThrow();
348
+ expect(() =>
349
+ MemoryV3ConfigSchema.parse({ write: { consolidateIntervalMs: -1000 } }),
350
+ ).toThrow();
351
+ });
352
+
353
+ test("accepts a positive write.consolidateIntervalMs override", () => {
354
+ const parsed = MemoryV3ConfigSchema.parse({
355
+ write: { consolidateIntervalMs: 1800000 },
356
+ });
357
+ expect(parsed.write.consolidateIntervalMs).toBe(1800000);
358
+ });
359
+
360
+ test("parses the prompts subtree to null overrides when omitted", () => {
361
+ const parsed = MemoryV3ConfigSchema.parse({});
362
+ expect(parsed.prompts).toEqual({
363
+ filter: { override: null, path: null },
364
+ descent: { override: null, path: null },
365
+ gate: { override: null, path: null },
366
+ });
367
+ });
368
+
369
+ test("accepts a partial prompts override and defaults the rest", () => {
370
+ const parsed = MemoryV3ConfigSchema.parse({
371
+ prompts: { filter: { override: "custom filter prompt" } },
372
+ });
373
+ expect(parsed.prompts.filter).toEqual({
374
+ override: "custom filter prompt",
375
+ path: null,
376
+ });
377
+ // Lanes not mentioned keep their null defaults.
378
+ expect(parsed.prompts.descent).toEqual({ override: null, path: null });
379
+ expect(parsed.prompts.gate).toEqual({ override: null, path: null });
380
+ });
381
+
382
+ test("accepts a file path override for a prompt lane", () => {
383
+ const parsed = MemoryV3ConfigSchema.parse({
384
+ prompts: { gate: { path: "~/prompts/v3-gate.md" } },
385
+ });
386
+ expect(parsed.prompts.gate).toEqual({
387
+ override: null,
388
+ path: "~/prompts/v3-gate.md",
389
+ });
390
+ });
391
+
392
+ test("rejects a non-string prompts override", () => {
393
+ expect(() =>
394
+ MemoryV3ConfigSchema.parse({ prompts: { filter: { override: 42 } } }),
395
+ ).toThrow();
396
+ });
397
+
398
+ test("rejects a non-string prompts path", () => {
399
+ expect(() =>
400
+ MemoryV3ConfigSchema.parse({ prompts: { descent: { path: 7 } } }),
401
+ ).toThrow();
402
+ });
403
+ });
404
+
405
+ describe("MemoryConfigSchema integration with v3 block", () => {
406
+ test("includes a v3 block defaulting to disabled when v3 is omitted", () => {
407
+ const parsed = MemoryConfigSchema.parse({});
408
+ expect(parsed.v3).toBeDefined();
409
+ expect(parsed.v3.enabled).toBe(false);
410
+ expect(parsed.v3.shadow).toBe(false);
411
+ expect(parsed.v3.passCap).toBe(3);
412
+ expect(parsed.v3.lanes.dense).toBe(true);
413
+ expect(parsed.v3.ks).toEqual([5, 10, 25, 50]);
414
+ expect(parsed.v3.write).toEqual({
415
+ enabled: false,
416
+ consolidateIntervalMs: 3600000,
417
+ coactivation: false,
418
+ });
419
+ });
420
+
421
+ test("leaves pre-existing configs (no v3 key) otherwise unchanged", () => {
422
+ // A config authored before v3 existed parses fine and its v2 block is
423
+ // untouched; the v3 block is purely additive.
424
+ const parsed = MemoryConfigSchema.parse({ v2: { top_k: 50 } });
425
+ expect(parsed.v2.top_k).toBe(50);
426
+ expect(parsed.v3.enabled).toBe(false);
427
+ });
428
+
429
+ test("propagates v3 overrides through MemoryConfigSchema", () => {
430
+ const parsed = MemoryConfigSchema.parse({
431
+ v3: { enabled: true, passCap: 4 },
432
+ });
433
+ expect(parsed.v3.enabled).toBe(true);
434
+ expect(parsed.v3.passCap).toBe(4);
435
+ // Non-overridden v3 fields keep their defaults.
436
+ expect(parsed.v3.maxDepth).toBe(6);
437
+ });
438
+ });
439
+
213
440
  describe("MemoryConfigSchema integration with v2 block", () => {
214
441
  test("parses an empty memory config and includes a v2 block with defaults", () => {
215
442
  const parsed = MemoryConfigSchema.parse({});