@vellumai/assistant 0.8.0 → 0.8.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 (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -43,6 +43,17 @@ describe("WebSearchTool", () => {
43
43
  expect(result.isError).toBe(true);
44
44
  expect(result.content).toContain("No web search API key configured");
45
45
  });
46
+
47
+ test("returns error when no API key is configured (tavily)", async () => {
48
+ delete process.env.TAVILY_API_KEY;
49
+ const result = await executeWebSearch(
50
+ { query: "test" },
51
+ undefined,
52
+ "tavily",
53
+ );
54
+ expect(result.isError).toBe(true);
55
+ expect(result.content).toContain("No web search API key configured");
56
+ });
46
57
  });
47
58
 
48
59
  describe("input validation", () => {
@@ -508,6 +519,159 @@ describe("WebSearchTool", () => {
508
519
  expect(result.content).toContain("Network unreachable");
509
520
  });
510
521
  });
522
+
523
+ describe("Tavily API responses", () => {
524
+ test("formats results", async () => {
525
+ const mockResponse = {
526
+ results: [
527
+ {
528
+ title: "Tavily Result",
529
+ url: "https://example.com/tavily",
530
+ content: "A Tavily search snippet.",
531
+ score: 0.9234,
532
+ },
533
+ ],
534
+ };
535
+
536
+ globalThis.fetch = (async () =>
537
+ new Response(JSON.stringify(mockResponse), {
538
+ status: 200,
539
+ headers: { "Content-Type": "application/json" },
540
+ })) as unknown as typeof fetch;
541
+
542
+ const result = await executeWebSearch(
543
+ { query: "test" },
544
+ "tvly-key",
545
+ "tavily",
546
+ );
547
+ expect(result.isError).toBe(false);
548
+ expect(result.content).toContain("Tavily Result");
549
+ expect(result.content).toContain("https://example.com/tavily");
550
+ expect(result.content).toContain("A Tavily search snippet");
551
+ expect(result.content).toContain("Score: 0.923");
552
+ });
553
+
554
+ test("handles empty response", async () => {
555
+ globalThis.fetch = (async () =>
556
+ new Response(JSON.stringify({ results: [] }), {
557
+ status: 200,
558
+ headers: { "Content-Type": "application/json" },
559
+ })) as unknown as typeof fetch;
560
+
561
+ const result = await executeWebSearch(
562
+ { query: "noresults" },
563
+ "tvly-key",
564
+ "tavily",
565
+ );
566
+ expect(result.isError).toBe(false);
567
+ expect(result.content).toContain("No results found");
568
+ });
569
+
570
+ test("maps count and freshness into Tavily request body", async () => {
571
+ let capturedHeaders: Record<string, string> = {};
572
+ let capturedBody: Record<string, unknown> = {};
573
+ globalThis.fetch = (async (_url: string, init: RequestInit) => {
574
+ capturedHeaders = Object.fromEntries(
575
+ Object.entries(init.headers as Record<string, string>),
576
+ );
577
+ capturedBody = JSON.parse(init.body as string);
578
+ return new Response(JSON.stringify({ results: [] }), {
579
+ status: 200,
580
+ headers: { "Content-Type": "application/json" },
581
+ });
582
+ }) as unknown as typeof fetch;
583
+
584
+ await executeWebSearch(
585
+ { query: "test query", count: 50, freshness: "pw" },
586
+ "tvly-my-key",
587
+ "tavily",
588
+ );
589
+ expect(capturedHeaders.Authorization).toBe("Bearer tvly-my-key");
590
+ expect(capturedHeaders["Content-Type"]).toBe("application/json");
591
+ expect(capturedBody.query).toBe("test query");
592
+ expect(capturedBody.search_depth).toBe("advanced");
593
+ expect(capturedBody.max_results).toBe(20);
594
+ expect(capturedBody.time_range).toBe("week");
595
+ });
596
+
597
+ test("omits invalid freshness values", async () => {
598
+ let capturedBody: Record<string, unknown> = {};
599
+ globalThis.fetch = (async (_url: string, init: RequestInit) => {
600
+ capturedBody = JSON.parse(init.body as string);
601
+ return new Response(JSON.stringify({ results: [] }), {
602
+ status: 200,
603
+ headers: { "Content-Type": "application/json" },
604
+ });
605
+ }) as unknown as typeof fetch;
606
+
607
+ await executeWebSearch(
608
+ { query: "test query", freshness: "invalid" },
609
+ "tvly-my-key",
610
+ "tavily",
611
+ );
612
+ expect(capturedBody.time_range).toBeUndefined();
613
+ });
614
+
615
+ test("handles 401 unauthorized", async () => {
616
+ globalThis.fetch = (async () =>
617
+ new Response("Unauthorized", {
618
+ status: 401,
619
+ })) as unknown as typeof fetch;
620
+
621
+ const result = await executeWebSearch(
622
+ { query: "test" },
623
+ "bad-key",
624
+ "tavily",
625
+ );
626
+ expect(result.isError).toBe(true);
627
+ expect(result.content).toContain("Invalid or expired");
628
+ });
629
+
630
+ test("retries on 429 and succeeds", async () => {
631
+ let callCount = 0;
632
+ globalThis.fetch = (async () => {
633
+ callCount++;
634
+ if (callCount <= 2) {
635
+ return new Response("Too Many Requests", { status: 429 });
636
+ }
637
+ return new Response(
638
+ JSON.stringify({
639
+ results: [
640
+ {
641
+ title: "Found it",
642
+ url: "https://example.com/found",
643
+ content: "Found it with Tavily",
644
+ },
645
+ ],
646
+ }),
647
+ { status: 200, headers: { "Content-Type": "application/json" } },
648
+ );
649
+ }) as unknown as typeof fetch;
650
+
651
+ const result = await executeWebSearch(
652
+ { query: "test" },
653
+ "tvly-key",
654
+ "tavily",
655
+ );
656
+ expect(result.isError).toBe(false);
657
+ expect(result.content).toContain("Found it with Tavily");
658
+ expect(callCount).toBe(3);
659
+ });
660
+
661
+ test("handles network errors", async () => {
662
+ globalThis.fetch = (async () => {
663
+ throw new Error("Network unreachable");
664
+ }) as unknown as typeof fetch;
665
+
666
+ const result = await executeWebSearch(
667
+ { query: "test" },
668
+ "tvly-key",
669
+ "tavily",
670
+ );
671
+ expect(result.isError).toBe(true);
672
+ expect(result.content).toContain("Network unreachable");
673
+ });
674
+ });
511
675
  });
512
676
 
513
677
  interface BraveSearchResult {
@@ -527,6 +691,17 @@ interface PerplexityResponse {
527
691
  citations?: string[];
528
692
  }
529
693
 
694
+ interface TavilySearchResult {
695
+ title?: string;
696
+ url?: string;
697
+ content?: string;
698
+ score?: number;
699
+ }
700
+
701
+ interface TavilySearchResponse {
702
+ results?: TavilySearchResult[];
703
+ }
704
+
530
705
  /**
531
706
  * Helper that exercises the web search logic directly, bypassing module
532
707
  * registration concerns. This replicates the core execute path from
@@ -535,7 +710,7 @@ interface PerplexityResponse {
535
710
  async function executeWebSearch(
536
711
  input: Record<string, unknown>,
537
712
  apiKey?: string,
538
- provider: "brave" | "perplexity" = "brave",
713
+ provider: "brave" | "perplexity" | "tavily" = "brave",
539
714
  ): Promise<{ content: string; isError: boolean }> {
540
715
  const query = input.query;
541
716
  if (!query || typeof query !== "string") {
@@ -548,7 +723,7 @@ async function executeWebSearch(
548
723
  if (!apiKey) {
549
724
  return {
550
725
  content:
551
- "Error: No web search API key configured. Set it via `keys set perplexity <key>` or `keys set brave <key>`, or configure it from the Settings page under API Keys.",
726
+ "Error: No web search API key configured. Set it via `keys set perplexity <key>`, `keys set brave <key>`, or `keys set tavily <key>`, or configure it from the Settings page under API Keys.",
552
727
  isError: true,
553
728
  };
554
729
  }
@@ -557,6 +732,10 @@ async function executeWebSearch(
557
732
  return executePerplexitySearchHelper(query as string, apiKey);
558
733
  }
559
734
 
735
+ if (provider === "tavily") {
736
+ return executeTavilySearchHelper(input, query as string, apiKey);
737
+ }
738
+
560
739
  return executeBraveSearchHelper(input, query as string, apiKey);
561
740
  }
562
741
 
@@ -764,3 +943,125 @@ async function executePerplexitySearchHelper(
764
943
  return { content: `Error: Web search failed: ${msg}`, isError: true };
765
944
  }
766
945
  }
946
+
947
+ function tavilyTimeRangeForFreshness(
948
+ freshness: string | undefined,
949
+ ): "day" | "week" | "month" | "year" | undefined {
950
+ switch (freshness) {
951
+ case "pd":
952
+ return "day";
953
+ case "pw":
954
+ return "week";
955
+ case "pm":
956
+ return "month";
957
+ case "py":
958
+ return "year";
959
+ default:
960
+ return undefined;
961
+ }
962
+ }
963
+
964
+ async function executeTavilySearchHelper(
965
+ input: Record<string, unknown>,
966
+ query: string,
967
+ apiKey: string,
968
+ ): Promise<{ content: string; isError: boolean }> {
969
+ const count =
970
+ typeof input.count === "number"
971
+ ? Math.min(20, Math.max(1, Math.round(input.count)))
972
+ : 10;
973
+ const timeRange = tavilyTimeRangeForFreshness(
974
+ typeof input.freshness === "string" ? input.freshness : undefined,
975
+ );
976
+ const body: Record<string, unknown> = {
977
+ query,
978
+ search_depth: "advanced",
979
+ max_results: count,
980
+ };
981
+ if (timeRange) body.time_range = timeRange;
982
+
983
+ const MAX_RETRIES = 3;
984
+ const BASE_DELAY_MS = 1;
985
+
986
+ try {
987
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
988
+ const response = await fetch("https://api.tavily.com/search", {
989
+ method: "POST",
990
+ headers: {
991
+ "Content-Type": "application/json",
992
+ Authorization: `Bearer ${apiKey}`,
993
+ "X-Client-Source": "vellum-assistant",
994
+ },
995
+ body: JSON.stringify(body),
996
+ });
997
+
998
+ if (response.ok) {
999
+ const data = (await response.json()) as TavilySearchResponse;
1000
+ const results = data.results ?? [];
1001
+
1002
+ if (results.length === 0) {
1003
+ return {
1004
+ content: `No results found for "${query}".`,
1005
+ isError: false,
1006
+ };
1007
+ }
1008
+
1009
+ const lines: string[] = [`Web search results for "${query}":\n`];
1010
+
1011
+ for (let i = 0; i < results.length; i++) {
1012
+ const r = results[i];
1013
+ const title = r.title?.trim() || r.url?.trim() || "Untitled result";
1014
+ lines.push(`${i + 1}. ${title}`);
1015
+ if (r.url) lines.push(` URL: ${r.url}`);
1016
+ if (r.content) lines.push(` ${r.content}`);
1017
+ if (typeof r.score === "number") {
1018
+ lines.push(` Score: ${r.score.toFixed(3)}`);
1019
+ }
1020
+ lines.push("");
1021
+ }
1022
+
1023
+ return { content: lines.join("\n"), isError: false };
1024
+ }
1025
+
1026
+ await response.text();
1027
+
1028
+ if (response.status === 401 || response.status === 403) {
1029
+ return {
1030
+ content: "Error: Invalid or expired Tavily API key",
1031
+ isError: true,
1032
+ };
1033
+ }
1034
+
1035
+ if (response.status === 429 && attempt < MAX_RETRIES) {
1036
+ const retryAfter = response.headers.get("retry-after");
1037
+ const delayMs =
1038
+ retryAfter && !isNaN(Number(retryAfter))
1039
+ ? Number(retryAfter) * 1000
1040
+ : BASE_DELAY_MS * Math.pow(2, attempt);
1041
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
1042
+ continue;
1043
+ }
1044
+
1045
+ if (response.status === 429) {
1046
+ return {
1047
+ content:
1048
+ "Error: Tavily Search rate limit exceeded after retries. Try again shortly.",
1049
+ isError: true,
1050
+ };
1051
+ }
1052
+ return {
1053
+ content: `Error: Tavily Search API returned status ${response.status}`,
1054
+ isError: true,
1055
+ };
1056
+ }
1057
+
1058
+ return {
1059
+ content:
1060
+ "Error: Tavily Search rate limit exceeded after retries. Try again shortly.",
1061
+ isError: true,
1062
+ };
1063
+ } catch (err) {
1064
+ const msg = err instanceof Error ? err.message : String(err);
1065
+ return { content: `Error: Web search failed: ${msg}`, isError: true };
1066
+ }
1067
+ }
@@ -176,11 +176,10 @@ describe("039-drop-legacy-llm-keys migration", () => {
176
176
  expect(config.contextWindow).toBeUndefined();
177
177
  expect(config.pricingOverrides).toBeUndefined();
178
178
 
179
- // services.inference: provider/model stripped, mode preserved
179
+ // services.inference: provider/model stripped
180
180
  const services = config.services as { inference: Record<string, unknown> };
181
181
  expect(services.inference.provider).toBeUndefined();
182
182
  expect(services.inference.model).toBeUndefined();
183
- expect(services.inference.mode).toBe("your-own");
184
183
 
185
184
  // heartbeat / filing
186
185
  const heartbeat = config.heartbeat as Record<string, unknown>;
@@ -248,31 +247,12 @@ describe("039-drop-legacy-llm-keys migration", () => {
248
247
  expect(config.speed).toBeUndefined();
249
248
  const services = config.services as { inference: Record<string, unknown> };
250
249
  expect(services.inference.provider).toBeUndefined();
251
- expect(services.inference.mode).toBe("managed");
252
250
  expect(
253
251
  (config.notifications as Record<string, unknown>).decisionModelIntent,
254
252
  ).toBeUndefined();
255
253
  expect(config.maxStepsPerSession).toBe(50);
256
254
  });
257
255
 
258
- // ─── services.inference.mode preservation ──────────────────────────────
259
-
260
- test("preserves services.inference.mode while stripping provider/model", () => {
261
- writeConfig({
262
- services: {
263
- inference: { mode: "your-own", provider: "openai", model: "gpt-5.4" },
264
- },
265
- });
266
-
267
- dropLegacyLlmKeysMigration.run(workspaceDir);
268
-
269
- const config = readConfig();
270
- const services = config.services as { inference: Record<string, unknown> };
271
- expect(services.inference.mode).toBe("your-own");
272
- expect(services.inference.provider).toBeUndefined();
273
- expect(services.inference.model).toBeUndefined();
274
- });
275
-
276
256
  // ─── Idempotency ───────────────────────────────────────────────────────
277
257
 
278
258
  test("idempotency: re-running the migration yields no further mutation", () => {
@@ -217,6 +217,64 @@ describe("057-repair-stale-gemini-model-ids migration", () => {
217
217
  expect(config.llm.profiles.balanced.model).toBe("gemini-3-flash-preview");
218
218
  });
219
219
 
220
+ test("does not rewrite blocks whose effective provider is not Gemini", () => {
221
+ writeConfig({
222
+ llm: {
223
+ default: {
224
+ provider: "ollama",
225
+ model: "gemini-3-flash",
226
+ },
227
+ callSites: {
228
+ analyzeConversation: {
229
+ provider: "openrouter",
230
+ model: "gemini-3-flash",
231
+ },
232
+ recall: {
233
+ model: "gemini-3-flash",
234
+ },
235
+ },
236
+ profiles: {
237
+ custom: {
238
+ provider: "ollama",
239
+ model: "gemini-3-flash",
240
+ },
241
+ },
242
+ },
243
+ });
244
+ const before = readFileSync(configPath(), "utf-8");
245
+
246
+ repairStaleGeminiModelIdsMigration.run(workspaceDir);
247
+
248
+ expect(readFileSync(configPath(), "utf-8")).toBe(before);
249
+ });
250
+
251
+ test("rewrites call-site/profile blocks without local provider when default is Gemini", () => {
252
+ writeConfig({
253
+ llm: {
254
+ default: { provider: "gemini", model: "gemini-3-flash-preview" },
255
+ callSites: {
256
+ memoryRetrieval: { model: "gemini-3-flash" },
257
+ },
258
+ profiles: {
259
+ balanced: { model: "gemini-3-flash" },
260
+ },
261
+ },
262
+ });
263
+
264
+ repairStaleGeminiModelIdsMigration.run(workspaceDir);
265
+
266
+ const config = readConfig() as {
267
+ llm: {
268
+ callSites: Record<string, { model: string }>;
269
+ profiles: Record<string, { model: string }>;
270
+ };
271
+ };
272
+ expect(config.llm.callSites.memoryRetrieval.model).toBe(
273
+ "gemini-3.1-flash-lite-preview",
274
+ );
275
+ expect(config.llm.profiles.balanced.model).toBe("gemini-3-flash-preview");
276
+ });
277
+
220
278
  test("no-ops when config.json is missing or invalid", () => {
221
279
  repairStaleGeminiModelIdsMigration.run(workspaceDir);
222
280
  expect(existsSync(configPath())).toBe(false);
@@ -2,8 +2,11 @@
2
2
  * Tests for workspace migration `069-seed-onboarding-threads`.
3
3
  *
4
4
  * The migration writes onboarding bullet content to `memory/threads.md` only
5
- * when the file exists and is empty (or whitespace-only). It must preserve
6
- * any existing content and must be idempotent.
5
+ * for newly-created workspaces (`ctx.isNewWorkspace === true`) when the file
6
+ * exists and is empty (or whitespace-only). For upgrading workspaces it must
7
+ * be a no-op even if `threads.md` is currently empty (the user may have
8
+ * cleaned it up themselves). It must preserve any existing content and be
9
+ * idempotent.
7
10
  */
8
11
 
9
12
  import {
@@ -20,6 +23,10 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
20
23
 
21
24
  import { memoryV2InitMigration } from "../workspace/migrations/060-memory-v2-init.js";
22
25
  import { seedOnboardingThreadsMigration } from "../workspace/migrations/069-seed-onboarding-threads.js";
26
+ import type { MigrationRunContext } from "../workspace/migrations/types.js";
27
+
28
+ const NEW_WORKSPACE_CTX: MigrationRunContext = { isNewWorkspace: true };
29
+ const UPGRADE_CTX: MigrationRunContext = { isNewWorkspace: false };
23
30
 
24
31
  let workspaceDir: string;
25
32
 
@@ -48,18 +55,44 @@ describe("069-seed-onboarding-threads migration", () => {
48
55
  test.each([
49
56
  ["empty file", ""],
50
57
  ["whitespace-only file", " \n\n"],
51
- ])("seeds onboarding bullets when memory/threads.md is %s", (_, initial) => {
52
- mkdirSync(join(workspaceDir, "memory"), { recursive: true });
53
- writeFileSync(join(workspaceDir, "memory", "threads.md"), initial, "utf-8");
58
+ ])(
59
+ "seeds onboarding bullets when new workspace and memory/threads.md is %s",
60
+ (_, initial) => {
61
+ mkdirSync(join(workspaceDir, "memory"), { recursive: true });
62
+ writeFileSync(
63
+ join(workspaceDir, "memory", "threads.md"),
64
+ initial,
65
+ "utf-8",
66
+ );
67
+
68
+ seedOnboardingThreadsMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
69
+
70
+ const content = readThreads();
71
+ expect(content).toContain("Figure out what kind of personality");
72
+ expect(content).toContain("data/avatar/avatar-image.png");
73
+ expect(content).toContain("ChatGPT, Claude");
74
+ expect(content).toContain("Slack or Telegram");
75
+ },
76
+ );
54
77
 
55
- seedOnboardingThreadsMigration.run(workspaceDir);
56
-
57
- const content = readThreads();
58
- expect(content).toContain("Figure out what kind of personality");
59
- expect(content).toContain("data/avatar/avatar-image.png");
60
- expect(content).toContain("ChatGPT, Claude");
61
- expect(content).toContain("Slack or Telegram");
62
- });
78
+ test.each([
79
+ ["empty file", ""],
80
+ ["whitespace-only file", " \n\n"],
81
+ ])(
82
+ "no-op on upgrade when memory/threads.md is %s (user may have cleared it)",
83
+ (_, initial) => {
84
+ mkdirSync(join(workspaceDir, "memory"), { recursive: true });
85
+ writeFileSync(
86
+ join(workspaceDir, "memory", "threads.md"),
87
+ initial,
88
+ "utf-8",
89
+ );
90
+
91
+ seedOnboardingThreadsMigration.run(workspaceDir, UPGRADE_CTX);
92
+
93
+ expect(readThreads()).toBe(initial);
94
+ },
95
+ );
63
96
 
64
97
  test("preserves existing content when memory/threads.md is non-empty", () => {
65
98
  mkdirSync(join(workspaceDir, "memory"), { recursive: true });
@@ -70,13 +103,13 @@ describe("069-seed-onboarding-threads migration", () => {
70
103
  "utf-8",
71
104
  );
72
105
 
73
- seedOnboardingThreadsMigration.run(workspaceDir);
106
+ seedOnboardingThreadsMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
74
107
 
75
108
  expect(readThreads()).toBe(existing);
76
109
  });
77
110
 
78
111
  test("no-op when memory/threads.md does not exist", () => {
79
- seedOnboardingThreadsMigration.run(workspaceDir);
112
+ seedOnboardingThreadsMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
80
113
  expect(existsSync(join(workspaceDir, "memory", "threads.md"))).toBe(false);
81
114
  });
82
115
 
@@ -84,18 +117,18 @@ describe("069-seed-onboarding-threads migration", () => {
84
117
  mkdirSync(join(workspaceDir, "memory"), { recursive: true });
85
118
  writeFileSync(join(workspaceDir, "memory", "threads.md"), "", "utf-8");
86
119
 
87
- seedOnboardingThreadsMigration.run(workspaceDir);
120
+ seedOnboardingThreadsMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
88
121
  const afterFirst = readThreads();
89
122
 
90
- seedOnboardingThreadsMigration.run(workspaceDir);
123
+ seedOnboardingThreadsMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
91
124
  const afterSecond = readThreads();
92
125
 
93
126
  expect(afterSecond).toBe(afterFirst);
94
127
  });
95
128
 
96
129
  test("composes with 060: fresh workspace -> 060 -> 069 produces seeded threads.md", () => {
97
- memoryV2InitMigration.run(workspaceDir);
98
- seedOnboardingThreadsMigration.run(workspaceDir);
130
+ memoryV2InitMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
131
+ seedOnboardingThreadsMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
99
132
 
100
133
  expect(readThreads()).toContain("Figure out what kind of personality");
101
134
  // The other v2 prose files are untouched (still empty).
@@ -110,7 +143,7 @@ describe("069-seed-onboarding-threads migration", () => {
110
143
  mkdirSync(join(workspaceDir, "memory"), { recursive: true });
111
144
  writeFileSync(join(workspaceDir, "memory", "threads.md"), "", "utf-8");
112
145
 
113
- seedOnboardingThreadsMigration.run(workspaceDir);
146
+ seedOnboardingThreadsMigration.run(workspaceDir, NEW_WORKSPACE_CTX);
114
147
  const seeded = readThreads();
115
148
 
116
149
  seedOnboardingThreadsMigration.down(workspaceDir);