@vellumai/assistant 0.8.5 → 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 (544) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +1 -1
  3. package/bunfig.toml +6 -1
  4. package/docs/credential-execution-service.md +6 -6
  5. package/docs/plugins.md +4 -3
  6. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  7. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  9. package/openapi.yaml +1900 -166
  10. package/package.json +1 -1
  11. package/src/__tests__/actor-token-service.test.ts +3 -2
  12. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  13. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  14. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  15. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  16. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  17. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  18. package/src/__tests__/approval-cascade.test.ts +1 -0
  19. package/src/__tests__/approval-routes-http.test.ts +9 -13
  20. package/src/__tests__/assert-not-live-db.ts +79 -0
  21. package/src/__tests__/assistant-feature-flags-integration.test.ts +9 -25
  22. package/src/__tests__/audit-log-rotation.test.ts +2 -2
  23. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  24. package/src/__tests__/background-workers-disk-pressure.test.ts +5 -8
  25. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  26. package/src/__tests__/btw-routes.test.ts +3 -2
  27. package/src/__tests__/call-controller.test.ts +3 -2
  28. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  29. package/src/__tests__/channel-guardian.test.ts +3 -2
  30. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  31. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  32. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  33. package/src/__tests__/checker.test.ts +12 -12
  34. package/src/__tests__/compaction-events.test.ts +1 -0
  35. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  36. package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
  37. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  38. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
  39. package/src/__tests__/computer-use-tools.test.ts +12 -14
  40. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  41. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  42. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  43. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  44. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  45. package/src/__tests__/config-schema.test.ts +10 -10
  46. package/src/__tests__/connection-model-compat.test.ts +83 -0
  47. package/src/__tests__/contacts-tools.test.ts +3 -2
  48. package/src/__tests__/context-token-estimator.test.ts +22 -0
  49. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  50. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
  51. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  52. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
  53. package/src/__tests__/conversation-agent-loop-overflow.test.ts +34 -0
  54. package/src/__tests__/conversation-agent-loop.test.ts +488 -2
  55. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  56. package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
  57. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  58. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  59. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  60. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  61. package/src/__tests__/conversation-error.test.ts +30 -0
  62. package/src/__tests__/conversation-fork-crud.test.ts +69 -8
  63. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  64. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  65. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  66. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  67. package/src/__tests__/conversation-lifecycle.test.ts +1 -0
  68. package/src/__tests__/conversation-list-source.test.ts +3 -2
  69. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  70. package/src/__tests__/conversation-load-history-stripped.test.ts +1 -0
  71. package/src/__tests__/conversation-pairing.test.ts +53 -0
  72. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  73. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  74. package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -0
  75. package/src/__tests__/conversation-queue.test.ts +333 -291
  76. package/src/__tests__/conversation-routes-disk-view.test.ts +3 -18
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  78. package/src/__tests__/conversation-routes-slash-commands.test.ts +33 -2
  79. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  80. package/src/__tests__/conversation-skill-tools.test.ts +38 -142
  81. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  82. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  83. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  84. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  85. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  86. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  87. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  88. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  89. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  90. package/src/__tests__/conversation-sync-tags.test.ts +128 -12
  91. package/src/__tests__/conversation-title-service.test.ts +1 -0
  92. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  93. package/src/__tests__/conversation-usage.test.ts +1 -0
  94. package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
  95. package/src/__tests__/conversation-workspace-injection.test.ts +5 -0
  96. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -0
  97. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  98. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  99. package/src/__tests__/credential-execution-client.test.ts +72 -1
  100. package/src/__tests__/credential-execution-feature-gates.test.ts +10 -12
  101. package/src/__tests__/credential-health-service.test.ts +252 -3
  102. package/src/__tests__/credential-security-invariants.test.ts +5 -5
  103. package/src/__tests__/credential-vault-unit.test.ts +19 -19
  104. package/src/__tests__/credential-vault.test.ts +5 -5
  105. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  106. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  107. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  108. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  109. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  110. package/src/__tests__/db-test-helpers.ts +58 -0
  111. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  112. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  113. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  114. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  115. package/src/__tests__/dm-persistence.test.ts +26 -40
  116. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  117. package/src/__tests__/document-find-replace.test.ts +3 -2
  118. package/src/__tests__/document-tool-security.test.ts +81 -2
  119. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  120. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  121. package/src/__tests__/encrypted-store.test.ts +11 -9
  122. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  123. package/src/__tests__/filing-service.test.ts +1 -0
  124. package/src/__tests__/first-greeting.test.ts +62 -12
  125. package/src/__tests__/gateway-flag-listener.test.ts +0 -1
  126. package/src/__tests__/gemini-provider.test.ts +26 -0
  127. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  128. package/src/__tests__/guardian-outbound-http.test.ts +3 -2
  129. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  130. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -0
  131. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  132. package/src/__tests__/heartbeat-service.test.ts +1 -0
  133. package/src/__tests__/helpers/mock-logger.ts +26 -0
  134. package/src/__tests__/host-bash-routes.test.ts +1 -0
  135. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  136. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  137. package/src/__tests__/host-shell-tool.test.ts +5 -4
  138. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  139. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  140. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  141. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  142. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  143. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  144. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  145. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  146. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  147. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  148. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  149. package/src/__tests__/llm-resolver.test.ts +331 -0
  150. package/src/__tests__/llm-schema.test.ts +1 -1
  151. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  152. package/src/__tests__/mcp-abort-signal.test.ts +14 -0
  153. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  154. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  155. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  156. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  157. package/src/__tests__/model-intents.test.ts +3 -3
  158. package/src/__tests__/native-web-search.test.ts +30 -2
  159. package/src/__tests__/notification-deep-link.test.ts +62 -0
  160. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  161. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  162. package/src/__tests__/oauth-store.test.ts +3 -2
  163. package/src/__tests__/onboarding-template-contract.test.ts +3 -2
  164. package/src/__tests__/openai-provider.test.ts +8 -9
  165. package/src/__tests__/openai-responses-provider.test.ts +70 -10
  166. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  167. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  168. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  169. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  170. package/src/__tests__/plugin-bootstrap.test.ts +9 -11
  171. package/src/__tests__/plugin-tool-contribution.test.ts +41 -38
  172. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  173. package/src/__tests__/process-message-display-content.test.ts +19 -22
  174. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  175. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  176. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  177. package/src/__tests__/recording-handler.test.ts +1 -0
  178. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  179. package/src/__tests__/registry.test.ts +82 -76
  180. package/src/__tests__/relay-server.test.ts +10 -10
  181. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  182. package/src/__tests__/schedule-store.test.ts +16 -1
  183. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  184. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  185. package/src/__tests__/secure-keys.test.ts +3 -3
  186. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  187. package/src/__tests__/server-history-render.test.ts +4 -1
  188. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  189. package/src/__tests__/skill-feature-flags.test.ts +14 -16
  190. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  191. package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
  192. package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
  193. package/src/__tests__/skill-tool-factory.test.ts +96 -95
  194. package/src/__tests__/slack-channel-config.test.ts +3 -3
  195. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  196. package/src/__tests__/subagent-disposal.test.ts +27 -8
  197. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  198. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  199. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  200. package/src/__tests__/subagent-notify-parent.test.ts +5 -4
  201. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  202. package/src/__tests__/subagent-tools.test.ts +2 -1
  203. package/src/__tests__/suggestion-routes.test.ts +1 -0
  204. package/src/__tests__/system-prompt.test.ts +38 -0
  205. package/src/__tests__/test-preload-verifier.ts +68 -0
  206. package/src/__tests__/test-preload.ts +32 -39
  207. package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
  208. package/src/__tests__/tool-executor.test.ts +55 -10
  209. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  210. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  211. package/src/__tests__/twilio-routes.test.ts +3 -2
  212. package/src/__tests__/validate-input.test.ts +381 -0
  213. package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
  214. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  215. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  216. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  217. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  218. package/src/acp/session-manager.ts +5 -6
  219. package/src/agent/loop.ts +80 -0
  220. package/src/api/README.md +124 -2
  221. package/src/api/constants/call-sites.ts +27 -0
  222. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  223. package/src/api/events/assistant-text-delta.ts +32 -0
  224. package/src/api/events/assistant-turn-start.ts +33 -0
  225. package/src/api/events/document-comment-created.ts +48 -0
  226. package/src/api/events/document-comment-deleted.ts +24 -0
  227. package/src/api/events/document-comment-reopened.ts +25 -0
  228. package/src/api/events/document-comment-resolved.ts +27 -0
  229. package/src/api/events/generation-cancelled.ts +24 -0
  230. package/src/api/events/generation-handoff.ts +41 -0
  231. package/src/api/events/message-complete.ts +42 -0
  232. package/src/api/events/open-url.ts +30 -0
  233. package/src/{events → api/events}/relationship-state-updated.ts +3 -3
  234. package/src/api/events/tool-use-start.ts +32 -0
  235. package/src/api/index.ts +128 -3
  236. package/src/api/responses/llm-context-response.ts +39 -0
  237. package/src/api/responses/llm-request-log-entry.ts +93 -0
  238. package/src/api/responses/memory-recall-log.ts +65 -0
  239. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  240. package/src/background-wake/background-wake-routes.test.ts +687 -52
  241. package/src/background-wake/platform-client.test.ts +308 -0
  242. package/src/background-wake/platform-client.ts +167 -0
  243. package/src/background-wake/publisher.ts +91 -0
  244. package/src/background-wake/runtime-registry.ts +2 -2
  245. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  246. package/src/calls/guardian-dispatch.ts +1 -0
  247. package/src/calls/voice-session-bridge.ts +4 -4
  248. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  249. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  250. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  251. package/src/cli/commands/channels/index.ts +229 -0
  252. package/src/cli/commands/memory-v3-render.ts +147 -0
  253. package/src/cli/commands/memory-v3.ts +255 -4
  254. package/src/cli/commands/notifications.ts +365 -55
  255. package/src/cli/lib/open-browser.ts +7 -2
  256. package/src/cli/program.ts +2 -0
  257. package/src/config/assistant-feature-flags.ts +23 -42
  258. package/src/config/bundled-skills/document-editor/SKILL.md +5 -1
  259. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  260. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  261. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  262. package/src/config/call-site-defaults.ts +1 -1
  263. package/src/config/feature-flag-cache.ts +86 -0
  264. package/src/config/feature-flag-registry.json +17 -17
  265. package/src/config/llm-context-resolution.ts +10 -1
  266. package/src/config/llm-resolver.ts +121 -15
  267. package/src/config/loader.ts +4 -5
  268. package/src/config/schemas/__tests__/memory-v2.test.ts +15 -0
  269. package/src/config/schemas/heartbeat.ts +1 -1
  270. package/src/config/schemas/llm.ts +90 -1
  271. package/src/config/schemas/memory-v2.ts +26 -0
  272. package/src/config/schemas/services.ts +6 -2
  273. package/src/config/seed-inference-profiles.ts +36 -16
  274. package/src/context/token-estimator.ts +10 -5
  275. package/src/credential-execution/executable-discovery.ts +40 -0
  276. package/src/credential-execution/process-manager.ts +6 -2
  277. package/src/credential-health/credential-health-service.ts +125 -40
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  279. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  280. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -2
  281. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  282. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  283. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  284. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  285. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  286. package/src/daemon/conversation-agent-loop-handlers.ts +389 -68
  287. package/src/daemon/conversation-agent-loop.ts +132 -28
  288. package/src/daemon/conversation-error.ts +33 -5
  289. package/src/daemon/conversation-messaging.ts +84 -43
  290. package/src/daemon/conversation-process.ts +74 -37
  291. package/src/daemon/conversation-runtime-assembly.ts +29 -9
  292. package/src/daemon/conversation-skill-tools.ts +14 -30
  293. package/src/daemon/conversation-surfaces.ts +69 -34
  294. package/src/daemon/conversation-tool-setup.ts +33 -48
  295. package/src/daemon/conversation.ts +26 -46
  296. package/src/daemon/daemon-control.ts +1 -1
  297. package/src/daemon/daemon-skill-host.ts +9 -2
  298. package/src/daemon/disk-pressure-guard.ts +27 -29
  299. package/src/daemon/first-greeting.ts +31 -13
  300. package/src/daemon/handlers/shared.ts +6 -1
  301. package/src/daemon/lifecycle.ts +12 -12
  302. package/src/daemon/mcp-reload-service.ts +1 -1
  303. package/src/daemon/meet-manifest-loader.ts +10 -17
  304. package/src/daemon/message-types/conversations.ts +20 -22
  305. package/src/daemon/message-types/document-comments.ts +8 -44
  306. package/src/daemon/message-types/home.ts +2 -2
  307. package/src/daemon/message-types/integrations.ts +2 -7
  308. package/src/daemon/message-types/messages.ts +23 -38
  309. package/src/daemon/message-types/subagents.ts +6 -0
  310. package/src/daemon/process-message.ts +9 -9
  311. package/src/daemon/providers-setup.ts +1 -1
  312. package/src/daemon/server.ts +16 -0
  313. package/src/daemon/switch-inference-profile-tool.ts +13 -3
  314. package/src/daemon/tool-setup-types.ts +0 -6
  315. package/src/daemon/wake-target-adapter.ts +10 -0
  316. package/src/documents/document-store.ts +38 -0
  317. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  318. package/src/heartbeat/__tests__/heartbeat-service.test.ts +29 -0
  319. package/src/heartbeat/heartbeat-service.ts +63 -0
  320. package/src/home/__tests__/feed-writer.test.ts +161 -0
  321. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  322. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  323. package/src/home/feed-writer.ts +146 -7
  324. package/src/home/suggested-prompts.ts +27 -145
  325. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  326. package/src/ipc/gateway-client.test.ts +4 -1
  327. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  328. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  329. package/src/ipc/skill-routes/memory.ts +4 -3
  330. package/src/ipc/skill-routes/registries.ts +28 -29
  331. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +1 -0
  332. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  333. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  334. package/src/memory/__tests__/memory-retrospective-job.test.ts +1 -0
  335. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  336. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  337. package/src/memory/conversation-attention-store.ts +17 -3
  338. package/src/memory/conversation-crud.ts +352 -112
  339. package/src/memory/db-connection.ts +29 -19
  340. package/src/memory/db-init.ts +4 -0
  341. package/src/memory/db-singleton.ts +77 -0
  342. package/src/memory/delivery-channels.ts +82 -0
  343. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  344. package/src/memory/graph/retriever.test.ts +3 -3
  345. package/src/memory/job-handlers/embedding.test.ts +3 -2
  346. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  347. package/src/memory/jobs-worker.ts +12 -1
  348. package/src/memory/llm-request-log-source-clickhouse.ts +80 -0
  349. package/src/memory/llm-request-log-source-local.ts +24 -0
  350. package/src/memory/llm-request-log-source.ts +31 -0
  351. package/src/memory/llm-request-log-store.ts +188 -3
  352. package/src/memory/memory-v2-activation-log-store.ts +95 -1
  353. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  354. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  355. package/src/memory/migrations/index.ts +2 -0
  356. package/src/memory/schema/conversations.ts +9 -1
  357. package/src/memory/schema/inference.ts +0 -1
  358. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  359. package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
  360. package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
  361. package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
  362. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  363. package/src/memory/v2/harness/metrics.ts +5 -1
  364. package/src/memory/v2/harness/replay-input.ts +19 -3
  365. package/src/memory/v2/harness/runner.ts +6 -0
  366. package/src/memory/v2/harness/trace.ts +6 -0
  367. package/src/memory/v3/__tests__/consolidation-job.test.ts +2 -4
  368. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  369. package/src/memory/v3/__tests__/edges.test.ts +144 -1
  370. package/src/memory/v3/__tests__/filter.test.ts +48 -0
  371. package/src/memory/v3/__tests__/gate.test.ts +96 -33
  372. package/src/memory/v3/__tests__/index-composition.test.ts +58 -0
  373. package/src/memory/v3/__tests__/loop.test.ts +250 -5
  374. package/src/memory/v3/__tests__/scouts.test.ts +49 -0
  375. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  376. package/src/memory/v3/__tests__/shadow-middleware.test.ts +88 -2
  377. package/src/memory/v3/__tests__/traversal.test.ts +39 -0
  378. package/src/memory/v3/__tests__/tree-walk.test.ts +77 -0
  379. package/src/memory/v3/__tests__/validate.test.ts +32 -0
  380. package/src/memory/v3/coretrieval-seed.ts +240 -0
  381. package/src/memory/v3/edges.ts +58 -21
  382. package/src/memory/v3/filter.ts +27 -22
  383. package/src/memory/v3/gate.ts +51 -36
  384. package/src/memory/v3/index-composition.ts +18 -5
  385. package/src/memory/v3/loop.ts +65 -17
  386. package/src/memory/v3/scouts.ts +15 -4
  387. package/src/memory/v3/shadow-diff.ts +287 -0
  388. package/src/memory/v3/shadow-middleware.ts +44 -2
  389. package/src/memory/v3/traversal.ts +6 -1
  390. package/src/memory/v3/tree-walk.ts +6 -1
  391. package/src/memory/v3/validate.ts +56 -33
  392. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  393. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  394. package/src/notifications/adapters/slack.ts +45 -11
  395. package/src/notifications/broadcaster.ts +114 -63
  396. package/src/notifications/conversation-pairing.ts +23 -3
  397. package/src/notifications/decisions-store.ts +32 -1
  398. package/src/notifications/deliveries-store.ts +45 -0
  399. package/src/notifications/edit-notification.ts +201 -0
  400. package/src/notifications/emit-signal.ts +11 -1
  401. package/src/notifications/signal.ts +10 -0
  402. package/src/notifications/types.ts +37 -0
  403. package/src/oauth/byo-connection.test.ts +67 -3
  404. package/src/oauth/byo-connection.ts +32 -5
  405. package/src/oauth/connect-orchestrator.ts +9 -0
  406. package/src/oauth/connection-resolver.test.ts +76 -0
  407. package/src/oauth/connection-resolver.ts +49 -10
  408. package/src/oauth/manual-token-connection.ts +51 -3
  409. package/src/oauth/seed-providers.ts +3 -0
  410. package/src/permissions/approval-policy.test.ts +19 -5
  411. package/src/permissions/approval-policy.ts +14 -3
  412. package/src/permissions/checker.ts +21 -8
  413. package/src/platform/client.test.ts +24 -1
  414. package/src/platform/client.ts +8 -0
  415. package/src/platform/feature-gate.ts +15 -0
  416. package/src/plugins/defaults/injectors.ts +2 -8
  417. package/src/plugins/defaults/persistence.ts +25 -6
  418. package/src/plugins/types.ts +57 -13
  419. package/src/proactive-artifact/job.test.ts +1 -0
  420. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  421. package/src/prompts/system-prompt.ts +38 -40
  422. package/src/prompts/template-detection.ts +10 -4
  423. package/src/prompts/templates/BOOTSTRAP.md +7 -11
  424. package/src/prompts/templates/IDENTITY.md +0 -2
  425. package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
  426. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  427. package/src/providers/call-site-routing.ts +33 -9
  428. package/src/providers/connection-model-compat.ts +23 -0
  429. package/src/providers/connection-resolution.ts +39 -20
  430. package/src/providers/fireworks/client.ts +1 -0
  431. package/src/providers/gemini/client.ts +24 -3
  432. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  433. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  434. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  435. package/src/providers/inference/auth.ts +0 -8
  436. package/src/providers/inference/connections.ts +3 -66
  437. package/src/providers/inference/resolve-auth.ts +2 -3
  438. package/src/providers/model-catalog.ts +35 -1
  439. package/src/providers/model-intents.ts +3 -3
  440. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  441. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  442. package/src/providers/openai/chat-completions-provider.ts +110 -12
  443. package/src/providers/openai/codex-models.ts +2 -0
  444. package/src/providers/openai/responses-provider.ts +53 -53
  445. package/src/providers/openrouter/client.ts +13 -8
  446. package/src/providers/provider-send-message.ts +18 -9
  447. package/src/providers/registry.ts +48 -8
  448. package/src/providers/retry.ts +16 -4
  449. package/src/providers/search-provider-catalog.ts +17 -9
  450. package/src/providers/types.ts +9 -0
  451. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  452. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  453. package/src/runtime/access-request-helper.ts +1 -0
  454. package/src/runtime/auth/route-policy.ts +10 -0
  455. package/src/runtime/channel-readiness-service.ts +68 -0
  456. package/src/runtime/channel-reply-delivery.ts +23 -0
  457. package/src/runtime/channel-retry-sweep.ts +47 -14
  458. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  459. package/src/runtime/migrations/vbundle-builder.ts +3 -2
  460. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  461. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  462. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
  463. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  464. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  465. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  466. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +51 -3
  467. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  468. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  469. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  470. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  471. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  472. package/src/runtime/routes/app-management-routes.ts +111 -4
  473. package/src/runtime/routes/background-wake-routes.ts +188 -20
  474. package/src/runtime/routes/btw-routes.ts +4 -4
  475. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  476. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  477. package/src/runtime/routes/conversation-list-routes.ts +147 -0
  478. package/src/runtime/routes/conversation-management-routes.ts +39 -14
  479. package/src/runtime/routes/conversation-query-routes.ts +60 -10
  480. package/src/runtime/routes/conversation-routes.ts +186 -140
  481. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  482. package/src/runtime/routes/documents-routes.ts +10 -1
  483. package/src/runtime/routes/group-routes.ts +11 -0
  484. package/src/runtime/routes/home-feed-routes.ts +129 -0
  485. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  486. package/src/runtime/routes/identity-routes.ts +30 -9
  487. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  488. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  489. package/src/runtime/routes/index.ts +2 -0
  490. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  491. package/src/runtime/routes/integrations/vercel.ts +15 -0
  492. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  493. package/src/runtime/routes/memory-v3-routes.ts +160 -2
  494. package/src/runtime/routes/migration-routes.ts +20 -13
  495. package/src/runtime/routes/notification-routes.ts +63 -1
  496. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  497. package/src/runtime/routes/surface-action-routes.ts +1 -38
  498. package/src/runtime/routes/surface-content-routes.ts +12 -5
  499. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  500. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  501. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  502. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  503. package/src/runtime/sync/resource-sync-events.ts +1 -1
  504. package/src/runtime/tool-grant-request-helper.ts +1 -0
  505. package/src/schedule/schedule-store.ts +8 -1
  506. package/src/schedule/scheduler.ts +111 -15
  507. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  508. package/src/security/encrypted-store.ts +7 -16
  509. package/src/security/store-path-override.ts +61 -0
  510. package/src/signals/user-message.ts +5 -8
  511. package/src/skills/validate-input.ts +177 -0
  512. package/src/subagent/manager.ts +13 -13
  513. package/src/subagent/types.ts +6 -0
  514. package/src/tasks/tool-sanitizer.ts +2 -2
  515. package/src/tools/apps/definitions.ts +35 -21
  516. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  517. package/src/tools/computer-use/definitions.ts +268 -266
  518. package/src/tools/document/document-tool.ts +131 -8
  519. package/src/tools/execution-target.ts +2 -5
  520. package/src/tools/executor.ts +18 -55
  521. package/src/tools/host-filesystem/edit.test.ts +1 -0
  522. package/src/tools/host-filesystem/read.test.ts +1 -0
  523. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  524. package/src/tools/host-filesystem/write.test.ts +1 -0
  525. package/src/tools/mcp/mcp-tool-factory.ts +0 -2
  526. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  527. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  528. package/src/tools/network/managed-search-proxy.ts +183 -0
  529. package/src/tools/network/web-search.ts +199 -44
  530. package/src/tools/policy-context.ts +3 -1
  531. package/src/tools/registry.ts +146 -103
  532. package/src/tools/schedule/create.ts +1 -1
  533. package/src/tools/skills/skill-tool-factory.ts +17 -36
  534. package/src/tools/subagent/spawn.ts +3 -0
  535. package/src/tools/tool-approval-handler.ts +10 -4
  536. package/src/tools/tool-name-aliases.ts +72 -14
  537. package/src/tools/types.ts +17 -15
  538. package/src/tools/ui-surface/definitions.ts +98 -86
  539. package/src/types/onboarding-context.ts +6 -0
  540. package/src/usage/attribution.ts +32 -1
  541. package/src/util/browser.ts +7 -2
  542. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  543. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  544. package/src/workspace/migrations/registry.ts +4 -0
@@ -7,6 +7,8 @@
7
7
  * GET /v1/conversations/:id — conversation detail
8
8
  */
9
9
 
10
+ import { z } from "zod";
11
+
10
12
  import {
11
13
  type Confidence,
12
14
  getAttentionStateByConversationIds,
@@ -43,6 +45,112 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
43
45
 
44
46
  const log = getLogger("conversation-list-routes");
45
47
 
48
+ // ---------------------------------------------------------------------------
49
+ // Response schemas
50
+ // ---------------------------------------------------------------------------
51
+
52
+ const channelIdSchema = z.enum([
53
+ "telegram",
54
+ "phone",
55
+ "vellum",
56
+ "whatsapp",
57
+ "slack",
58
+ "email",
59
+ "platform",
60
+ "a2a",
61
+ ]);
62
+
63
+ const assistantAttentionSchema = z.object({
64
+ hasUnseenLatestAssistantMessage: z.boolean(),
65
+ latestAssistantMessageAt: z.number().optional(),
66
+ lastSeenAssistantMessageAt: z.number().optional(),
67
+ lastSeenConfidence: z.enum(["explicit", "inferred"]).optional(),
68
+ lastSeenSignalType: z
69
+ .enum([
70
+ "macos_notification_view",
71
+ "macos_conversation_opened",
72
+ "ios_conversation_opened",
73
+ "telegram_inbound_message",
74
+ "telegram_callback",
75
+ "slack_inbound_message",
76
+ "slack_callback",
77
+ ])
78
+ .optional(),
79
+ });
80
+
81
+ const slackThreadSchema = z.object({
82
+ channelId: z.string(),
83
+ threadTs: z.string(),
84
+ link: z
85
+ .object({
86
+ appUrl: z.string().optional(),
87
+ webUrl: z.string().optional(),
88
+ })
89
+ .optional(),
90
+ });
91
+
92
+ const slackChannelSchema = z.object({
93
+ channelId: z.string(),
94
+ name: z.string().optional(),
95
+ link: z.object({ webUrl: z.string() }).optional(),
96
+ });
97
+
98
+ const channelBindingSchema = z.object({
99
+ sourceChannel: z.string(),
100
+ externalChatId: z.string(),
101
+ externalChatName: z.string().optional(),
102
+ externalThreadId: z.string().optional(),
103
+ externalUserId: z.string().nullable(),
104
+ displayName: z.string().nullable(),
105
+ username: z.string().nullable(),
106
+ slackThread: slackThreadSchema.optional(),
107
+ slackChannel: slackChannelSchema.optional(),
108
+ });
109
+
110
+ const forkParentSchema = z.object({
111
+ conversationId: z.string(),
112
+ messageId: z.string(),
113
+ title: z.string(),
114
+ });
115
+
116
+ export const conversationSummarySchema = z.object({
117
+ id: z.string(),
118
+ title: z.string(),
119
+ createdAt: z.number(),
120
+ updatedAt: z.number(),
121
+ lastMessageAt: z.number().nullable(),
122
+ conversationType: z.enum(["standard", "background", "scheduled"]),
123
+ source: z.string(),
124
+ scheduleJobId: z.string().optional(),
125
+ channelBinding: channelBindingSchema.optional(),
126
+ conversationOriginChannel: channelIdSchema.nullable().optional(),
127
+ assistantAttention: assistantAttentionSchema.optional(),
128
+ isPinned: z.literal(true).optional(),
129
+ displayOrder: z.number().nullable().optional(),
130
+ groupId: z.string().nullable(),
131
+ forkParent: forkParentSchema.optional(),
132
+ archivedAt: z.number().optional(),
133
+ inferenceProfile: z.string().optional(),
134
+ });
135
+
136
+ const groupSummarySchema = z.object({
137
+ id: z.string(),
138
+ name: z.string(),
139
+ sortPosition: z.number(),
140
+ isSystemGroup: z.boolean(),
141
+ });
142
+
143
+ const listConversationsResponseSchema = z.object({
144
+ conversations: z.array(conversationSummarySchema),
145
+ nextOffset: z.number(),
146
+ hasMore: z.boolean(),
147
+ groups: z.array(groupSummarySchema).optional(),
148
+ });
149
+
150
+ const conversationDetailResponseSchema = z.object({
151
+ conversation: conversationSummarySchema,
152
+ });
153
+
46
154
  // ---------------------------------------------------------------------------
47
155
  // Helpers
48
156
  // ---------------------------------------------------------------------------
@@ -204,6 +312,29 @@ export const ROUTES: RouteDefinition[] = [
204
312
  description:
205
313
  "Paginated list of conversations with attention state and display metadata.",
206
314
  tags: ["conversations"],
315
+ queryParams: [
316
+ {
317
+ name: "limit",
318
+ type: "integer",
319
+ required: false,
320
+ description: "Maximum number of conversations to return (default 50).",
321
+ },
322
+ {
323
+ name: "offset",
324
+ type: "integer",
325
+ required: false,
326
+ description: "Number of conversations to skip (default 0).",
327
+ },
328
+ {
329
+ name: "conversationType",
330
+ type: "string",
331
+ required: false,
332
+ description:
333
+ 'Filter by conversation type. Pass "background" to list only background/scheduled conversations.',
334
+ schema: { type: "string", enum: ["background"] },
335
+ },
336
+ ],
337
+ responseBody: listConversationsResponseSchema,
207
338
  handler: handleListConversations,
208
339
  },
209
340
  {
@@ -214,6 +345,17 @@ export const ROUTES: RouteDefinition[] = [
214
345
  summary: "Record a seen signal",
215
346
  description: "Mark a conversation as seen, advancing the attention cursor.",
216
347
  tags: ["conversations"],
348
+ requestBody: z.object({
349
+ conversationId: z.string(),
350
+ sourceChannel: z.string().optional(),
351
+ signalType: z.string().optional(),
352
+ confidence: z.enum(["explicit", "inferred"]).optional(),
353
+ source: z.string().optional(),
354
+ evidenceText: z.string().optional(),
355
+ metadata: z.record(z.string(), z.unknown()).optional(),
356
+ observedAt: z.number().optional(),
357
+ }),
358
+ responseBody: z.object({ ok: z.boolean() }),
217
359
  handler: handleRecordSeen,
218
360
  },
219
361
  {
@@ -224,6 +366,10 @@ export const ROUTES: RouteDefinition[] = [
224
366
  summary: "Mark conversation unread",
225
367
  description: "Reset the seen cursor so the conversation appears unread.",
226
368
  tags: ["conversations"],
369
+ requestBody: z.object({
370
+ conversationId: z.string(),
371
+ }),
372
+ responseBody: z.object({ ok: z.boolean() }),
227
373
  handler: handleMarkUnread,
228
374
  },
229
375
  {
@@ -234,6 +380,7 @@ export const ROUTES: RouteDefinition[] = [
234
380
  summary: "Get conversation detail",
235
381
  description: "Retrieve a single conversation with full metadata.",
236
382
  tags: ["conversations"],
383
+ responseBody: conversationDetailResponseSchema,
237
384
  handler: handleGetConversation,
238
385
  },
239
386
  ];
@@ -28,6 +28,7 @@ import {
28
28
  undoLastMessage,
29
29
  } from "../../daemon/handlers/conversations.js";
30
30
  import { normalizeConversationType } from "../../daemon/message-types/shared.js";
31
+ import { stripConversationIds } from "../../home/feed-writer.js";
31
32
  import {
32
33
  archiveConversation,
33
34
  batchSetDisplayOrders,
@@ -54,6 +55,7 @@ import {
54
55
  publishConversationListChanged,
55
56
  publishConversationTitleChanged,
56
57
  } from "../sync/resource-sync-events.js";
58
+ import { conversationSummarySchema } from "./conversation-list-routes.js";
57
59
  import { BadRequestError, InternalError, NotFoundError } from "./errors.js";
58
60
  import { setInferenceProfileSession } from "./inference-profile-session-handler.js";
59
61
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
@@ -114,7 +116,10 @@ function handleCreateConversation({ body = {}, headers }: RouteHandlerArgs) {
114
116
  };
115
117
  }
116
118
 
117
- async function handleForkConversation({ body = {}, headers }: RouteHandlerArgs) {
119
+ async function handleForkConversation({
120
+ body = {},
121
+ headers,
122
+ }: RouteHandlerArgs) {
118
123
  const conversationId = body.conversationId as string | undefined;
119
124
  if (!conversationId || typeof conversationId !== "string") {
120
125
  throw new BadRequestError("Missing conversationId");
@@ -223,9 +228,7 @@ function handleRenameConversation({
223
228
  return { ok: true };
224
229
  }
225
230
 
226
- async function handleClearAllConversations({
227
- headers = {},
228
- }: RouteHandlerArgs) {
231
+ async function handleClearAllConversations({ headers = {} }: RouteHandlerArgs) {
229
232
  const confirm = headers["x-confirm-destructive"];
230
233
  if (confirm !== "clear-all-conversations") {
231
234
  throw new BadRequestError(
@@ -241,7 +244,10 @@ async function handleClearAllConversations({
241
244
  return undefined;
242
245
  }
243
246
 
244
- function handleWipeConversation({ pathParams = {}, headers }: RouteHandlerArgs) {
247
+ function handleWipeConversation({
248
+ pathParams = {},
249
+ headers,
250
+ }: RouteHandlerArgs) {
245
251
  const resolvedId = resolveOrThrow(pathParams.id!);
246
252
 
247
253
  cancelScheduleIfLast(resolvedId);
@@ -273,6 +279,9 @@ function handleWipeConversation({ pathParams = {}, headers }: RouteHandlerArgs)
273
279
  resolvedId,
274
280
  headers?.["x-vellum-client-id"]?.trim() || undefined,
275
281
  );
282
+
283
+ void stripConversationIds(resolvedId);
284
+
276
285
  return {
277
286
  wiped: true,
278
287
  unsupersededItems: 0,
@@ -311,6 +320,8 @@ function handleDeleteConversation({
311
320
  headers?.["x-vellum-client-id"]?.trim() || undefined,
312
321
  );
313
322
 
323
+ void stripConversationIds(resolvedId);
324
+
314
325
  return undefined;
315
326
  }
316
327
 
@@ -400,7 +411,7 @@ function handleReorderConversations({ body = {}, headers }: RouteHandlerArgs) {
400
411
  updates.map((u) => ({
401
412
  id: u.conversationId,
402
413
  displayOrder: u.displayOrder ?? null,
403
- isPinned: u.isPinned ?? false,
414
+ isPinned: u.isPinned,
404
415
  groupId: u.groupId,
405
416
  })),
406
417
  );
@@ -445,9 +456,7 @@ export const ROUTES: RouteDefinition[] = [
445
456
  ),
446
457
  conversationKey: z
447
458
  .string()
448
- .describe(
449
- "Echo of the optional external key supplied by the client.",
450
- ),
459
+ .describe("Echo of the optional external key supplied by the client."),
451
460
  conversationType: z.string(),
452
461
  created: z.boolean(),
453
462
  }),
@@ -469,6 +478,9 @@ export const ROUTES: RouteDefinition[] = [
469
478
  .describe("Truncate the fork at this message")
470
479
  .optional(),
471
480
  }),
481
+ responseBody: z.object({
482
+ conversation: conversationSummarySchema,
483
+ }),
472
484
  handler: handleForkConversation,
473
485
  },
474
486
  {
@@ -538,6 +550,7 @@ export const ROUTES: RouteDefinition[] = [
538
550
  requestBody: z.object({
539
551
  name: z.string(),
540
552
  }),
553
+ responseBody: z.object({ ok: z.boolean() }),
541
554
  handler: handleRenameConversation,
542
555
  },
543
556
  {
@@ -590,6 +603,10 @@ export const ROUTES: RouteDefinition[] = [
590
603
  description: "Move a conversation to the archived state.",
591
604
  tags: ["conversations"],
592
605
  pathParams: [{ name: "id", type: "uuid" }],
606
+ responseBody: z.object({
607
+ ok: z.boolean(),
608
+ conversationId: z.string(),
609
+ }),
593
610
  handler: handleArchiveConversation,
594
611
  },
595
612
  {
@@ -602,6 +619,10 @@ export const ROUTES: RouteDefinition[] = [
602
619
  "Restore an archived conversation back to the default sidebar.",
603
620
  tags: ["conversations"],
604
621
  pathParams: [{ name: "id", type: "uuid" }],
622
+ responseBody: z.object({
623
+ ok: z.boolean(),
624
+ conversationId: z.string(),
625
+ }),
605
626
  handler: handleUnarchiveConversation,
606
627
  },
607
628
  {
@@ -659,12 +680,16 @@ export const ROUTES: RouteDefinition[] = [
659
680
  description: "Batch-update display order and pin state for conversations.",
660
681
  tags: ["conversations"],
661
682
  requestBody: z.object({
662
- updates: z
663
- .array(z.unknown())
664
- .describe(
665
- "Array of { conversationId, displayOrder?, isPinned? } objects",
666
- ),
683
+ updates: z.array(
684
+ z.object({
685
+ conversationId: z.string(),
686
+ displayOrder: z.number().optional(),
687
+ isPinned: z.boolean().optional(),
688
+ groupId: z.string().nullable().optional(),
689
+ }),
690
+ ),
667
691
  }),
692
+ responseBody: z.object({ ok: z.boolean() }),
668
693
  handler: handleReorderConversations,
669
694
  },
670
695
  ];
@@ -67,7 +67,7 @@ import { getConversationByKey } from "../../memory/conversation-key-store.js";
67
67
  import { getDb } from "../../memory/db-connection.js";
68
68
  import { clearEmbeddingBackendCache } from "../../memory/embedding-backend.js";
69
69
  import { getLlmRequestLogSource } from "../../memory/llm-request-log-source.js";
70
- import type { LogRow } from "../../memory/llm-request-log-store.js";
70
+ import { type LogRow } from "../../memory/llm-request-log-store.js";
71
71
  import { getMemoryRecallLogByMessageIds } from "../../memory/memory-recall-log-store.js";
72
72
  import { getMemoryV2ActivationLogByMessageIds } from "../../memory/memory-v2-activation-log-store.js";
73
73
  import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../memory/v2/constants.js";
@@ -239,6 +239,7 @@ function normalizeLlmContextLog(log: LogRow): LlmContextRouteResult & {
239
239
  responsePayload: null;
240
240
  createdAt: number;
241
241
  agentLoopExitReason: string | null;
242
+ callSite: string | null;
242
243
  } {
243
244
  let requestPayload: unknown;
244
245
  try {
@@ -257,7 +258,10 @@ function normalizeLlmContextLog(log: LogRow): LlmContextRouteResult & {
257
258
  responsePayload,
258
259
  createdAt: log.createdAt,
259
260
  });
260
- const result = applyStoredProviderToLlmContextResult(normalized, log.provider);
261
+ const result = applyStoredProviderToLlmContextResult(
262
+ normalized,
263
+ log.provider,
264
+ );
261
265
  return {
262
266
  id: log.id,
263
267
  requestPayload: null,
@@ -269,6 +273,12 @@ function normalizeLlmContextLog(log: LogRow): LlmContextRouteResult & {
269
273
  // terminal call in each loop iteration carries a value; non-terminal calls
270
274
  // land here as `null`.
271
275
  agentLoopExitReason: log.agentLoopExitReason ?? null,
276
+ // Logical call site (`mainAgent`, `compactionAgent`,
277
+ // `syntheticAgentErrorMessage`, …). Exposed to the inspector so synthetic
278
+ // rows can be rendered distinctly without re-deriving the kind from
279
+ // other fields — the frontend branches on this value alone, and the
280
+ // existing `agent_loop_exit_reason` column tells it WHICH error fired.
281
+ callSite: log.callSite ?? null,
272
282
  ...result,
273
283
  };
274
284
  }
@@ -700,15 +710,57 @@ async function handleReplaceInferenceProfile({
700
710
  );
701
711
  }
702
712
  }
703
- // When the UI sends provider but no provider_connection ("Any active X
704
- // connection"), derive the connection now so the config deep-merge doesn't
705
- // inherit a stale connection from the default layer.
713
+ // Mix profiles reference other profiles by name. `ProfileEntry.safeParse`
714
+ // above validates the fragment in isolation, so the cross-profile integrity
715
+ // rules `LLMSchema.superRefine` enforces on full-config load (every arm
716
+ // exists, no nesting, no self-reference, no config fields) must be checked
717
+ // here against the live profile set — otherwise an invalid mix would persist
718
+ // and break the next full config reparse.
719
+ if (parsed.data.mix != null) {
720
+ const MIX_ALLOWED_KEYS = new Set([
721
+ "mix",
722
+ "label",
723
+ "description",
724
+ "status",
725
+ "source",
726
+ ]);
727
+ const extraneous = Object.keys(parsed.data).filter(
728
+ (k) => !MIX_ALLOWED_KEYS.has(k),
729
+ );
730
+ if (extraneous.length > 0) {
731
+ throw new BadRequestError(
732
+ `Mix profile "${name}" cannot also set [${extraneous.join(", ")}] — a mix only references other profiles plus metadata (label, description, status).`,
733
+ );
734
+ }
735
+ const existingProfiles = getConfig().llm.profiles ?? {};
736
+ parsed.data.mix.forEach((arm, index) => {
737
+ if (arm.profile === name) {
738
+ throw new BadRequestError(
739
+ `Mix profile "${name}" cannot reference itself (arm ${index}).`,
740
+ );
741
+ }
742
+ const target = existingProfiles[arm.profile];
743
+ if (target == null) {
744
+ throw new BadRequestError(
745
+ `Mix profile "${name}" references profile "${arm.profile}" which is not defined.`,
746
+ );
747
+ }
748
+ if (target.mix != null) {
749
+ throw new BadRequestError(
750
+ `Mix profile "${name}" references another mix profile "${arm.profile}" — mixes cannot be nested; constituents must be standard profiles.`,
751
+ );
752
+ }
753
+ });
754
+ }
755
+
756
+ // When the UI sends provider but no provider_connection, derive the connection
757
+ // now so the config deep-merge doesn't inherit a stale connection from the
758
+ // default layer.
706
759
  const fragment = parsed.data as Record<string, unknown>;
707
760
  if (!isManaged && fragment.provider && !fragment.provider_connection) {
708
761
  const provider = fragment.provider as string;
709
762
  const db = getDb();
710
- const candidates = listConnections(db, { provider });
711
- const active = candidates.find((c) => c.status === "active");
763
+ const [active] = listConnections(db, { provider });
712
764
  if (active) {
713
765
  fragment.provider_connection = active.name;
714
766
  } else if (!PROVIDERS_REQUIRING_BASE_URL_AND_MODELS.has(provider)) {
@@ -1002,9 +1054,7 @@ function handleSteerToMessage({
1002
1054
  ? (body as Record<string, unknown>).conversationId
1003
1055
  : undefined);
1004
1056
  if (!conversationId || typeof conversationId !== "string") {
1005
- throw new BadRequestError(
1006
- "Missing required parameter: conversationId",
1007
- );
1057
+ throw new BadRequestError("Missing required parameter: conversationId");
1008
1058
  }
1009
1059
  const result = steerToMessage(conversationId, pathParams.id ?? "");
1010
1060
  if (result.steered) {