@vellumai/assistant 0.8.4 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -21,7 +21,10 @@ import {
21
21
  isValidConversationStarterText,
22
22
  } from "../../memory/conversation-starter-validation.js";
23
23
  import { getDb } from "../../memory/db-connection.js";
24
- import { enqueueMemoryJob } from "../../memory/jobs-store.js";
24
+ import {
25
+ enqueueMemoryJob,
26
+ isMemoryEnabled,
27
+ } from "../../memory/jobs-store.js";
25
28
  import { conversationStarters, memoryJobs } from "../../memory/schema.js";
26
29
  import { NotFoundError } from "./errors.js";
27
30
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
@@ -203,7 +206,7 @@ function handleListConversationStarters({
203
206
  checkpointAhead ||
204
207
  (invalidItemCount > 0 && totalActive > 0 && !withinCooldown);
205
208
 
206
- if (shouldRefresh && !hasActiveJob) {
209
+ if (shouldRefresh && !hasActiveJob && isMemoryEnabled()) {
207
210
  enqueueMemoryJob("generate_conversation_starters", { scopeId });
208
211
  hasActiveJob = true;
209
212
  }
@@ -225,7 +228,7 @@ function handleListConversationStarters({
225
228
 
226
229
  const existing = hasActiveConversationStarterJob(db, scopeId);
227
230
 
228
- if (!existing) {
231
+ if (!existing && isMemoryEnabled()) {
229
232
  enqueueMemoryJob("generate_conversation_starters", { scopeId });
230
233
  }
231
234
 
@@ -2,7 +2,11 @@ import { eq } from "drizzle-orm";
2
2
  import { z } from "zod";
3
3
 
4
4
  import { getConfig } from "../../config/loader.js";
5
- import { addMessage, createConversation } from "../../memory/conversation-crud.js";
5
+ import {
6
+ addMessage,
7
+ createConversation,
8
+ type MessageRole,
9
+ } from "../../memory/conversation-crud.js";
6
10
  import {
7
11
  getConversationByKey,
8
12
  setConversationKey,
@@ -22,7 +26,7 @@ const log = getLogger("conversations-import-routes");
22
26
  // -- Types --
23
27
 
24
28
  interface ImportMessage {
25
- role: string;
29
+ role: MessageRole;
26
30
  content: string | Array<{ type: string; text: string }>;
27
31
  createdAt?: number;
28
32
  }
@@ -59,7 +63,10 @@ function resolveTimestamps(conv: ImportConversation): {
59
63
  // -- Handler --
60
64
 
61
65
  async function handleConversationsImport({ body }: RouteHandlerArgs) {
62
- if (!body || !Array.isArray((body as Record<string, unknown>).conversations)) {
66
+ if (
67
+ !body ||
68
+ !Array.isArray((body as Record<string, unknown>).conversations)
69
+ ) {
63
70
  throw new BadRequestError("conversations array required");
64
71
  }
65
72
 
@@ -70,7 +77,8 @@ async function handleConversationsImport({ body }: RouteHandlerArgs) {
70
77
  let imported = 0;
71
78
  let skipped = 0;
72
79
  let totalMessages = 0;
73
- const errors: Array<{ index: number; sourceKey?: string; error: string }> = [];
80
+ const errors: Array<{ index: number; sourceKey?: string; error: string }> =
81
+ [];
74
82
 
75
83
  for (let idx = 0; idx < payload.conversations.length; idx++) {
76
84
  const conv = payload.conversations[idx];
@@ -90,7 +98,8 @@ async function handleConversationsImport({ body }: RouteHandlerArgs) {
90
98
  }
91
99
  }
92
100
 
93
- const { convCreatedAt, convUpdatedAt, messageTimestamps } = resolveTimestamps(conv);
101
+ const { convCreatedAt, convUpdatedAt, messageTimestamps } =
102
+ resolveTimestamps(conv);
94
103
 
95
104
  const conversation = createConversation(conv.title);
96
105
 
@@ -122,7 +131,11 @@ async function handleConversationsImport({ body }: RouteHandlerArgs) {
122
131
  .orderBy(messagesTable.createdAt)
123
132
  .all();
124
133
 
125
- for (let i = 0; i < dbMessages.length && i < messageTimestamps.length; i++) {
134
+ for (
135
+ let i = 0;
136
+ i < dbMessages.length && i < messageTimestamps.length;
137
+ i++
138
+ ) {
126
139
  db.update(messagesTable)
127
140
  .set({ createdAt: messageTimestamps[i] })
128
141
  .where(eq(messagesTable.id, dbMessages[i].id))
@@ -11,7 +11,7 @@ import type { RouteDefinition } from "./types.js";
11
11
 
12
12
  const DiskPressureStatusSchema = z.object({
13
13
  enabled: z.boolean(),
14
- state: z.enum(["disabled", "ok", "critical", "unknown"]),
14
+ state: z.enum(["disabled", "ok", "warning", "critical", "unknown"]),
15
15
  locked: z.boolean(),
16
16
  acknowledged: z.boolean(),
17
17
  overrideActive: z.boolean(),
@@ -82,7 +82,16 @@ export const ROUTES: RouteDefinition[] = [
82
82
  },
83
83
  ],
84
84
  responseBody: z.object({
85
- documents: z.array(z.unknown()).describe("Document summary objects"),
85
+ documents: z.array(
86
+ z.object({
87
+ surfaceId: z.string(),
88
+ conversationId: z.string(),
89
+ title: z.string(),
90
+ wordCount: z.number(),
91
+ createdAt: z.number(),
92
+ updatedAt: z.number(),
93
+ }),
94
+ ),
86
95
  }),
87
96
  handler: ({ queryParams }) => {
88
97
  const conversationId = queryParams?.conversationId ?? undefined;
@@ -35,7 +35,10 @@ async function requireClient(): Promise<VellumPlatformClient> {
35
35
  // ── Handlers ──────────────────────────────────────────────────────────
36
36
 
37
37
  async function handleDomainRegister({ body = {} }: RouteHandlerArgs) {
38
- const { subdomain } = body as { subdomain?: string };
38
+ const { subdomain, email_username } = body as {
39
+ subdomain?: string;
40
+ email_username?: string;
41
+ };
39
42
  const client = await requireClient();
40
43
  const apexDomain = getApexDomain();
41
44
 
@@ -43,6 +46,9 @@ async function handleDomainRegister({ body = {} }: RouteHandlerArgs) {
43
46
  if (subdomain) {
44
47
  reqBody.subdomain = subdomain;
45
48
  }
49
+ if (email_username) {
50
+ reqBody.email_username = email_username;
51
+ }
46
52
 
47
53
  const response = await client.fetch(
48
54
  `/v1/assistants/${client.platformAssistantId}/domains/`,
@@ -58,12 +64,18 @@ async function handleDomainRegister({ body = {} }: RouteHandlerArgs) {
58
64
  string,
59
65
  unknown
60
66
  >;
67
+ const firstFieldError = ["subdomain", "email_username"].reduce<
68
+ string | undefined
69
+ >(
70
+ (found, field) =>
71
+ found ??
72
+ (Array.isArray(respBody[field])
73
+ ? (respBody[field][0] as string)
74
+ : undefined),
75
+ undefined,
76
+ );
61
77
  const detail =
62
- respBody.detail ??
63
- (Array.isArray(respBody.subdomain)
64
- ? respBody.subdomain[0]
65
- : undefined) ??
66
- `HTTP ${response.status}`;
78
+ respBody.detail ?? firstFieldError ?? `HTTP ${response.status}`;
67
79
  throw new BadRequestError(String(detail));
68
80
  }
69
81
 
@@ -71,10 +83,9 @@ async function handleDomainRegister({ body = {} }: RouteHandlerArgs) {
71
83
  id: string;
72
84
  subdomain?: string;
73
85
  domain?: string;
74
- status?: string;
75
- verified?: boolean;
76
86
  created_at?: string;
77
87
  created?: string;
88
+ email_error?: { detail: string; code: string };
78
89
  };
79
90
 
80
91
  // Persist the subdomain to config so getAssistantDomain() can use it
@@ -117,8 +128,6 @@ async function handleDomainStatus(_args: RouteHandlerArgs) {
117
128
  id: string;
118
129
  subdomain?: string;
119
130
  domain?: string;
120
- status?: string;
121
- verified?: boolean;
122
131
  created_at?: string;
123
132
  created?: string;
124
133
  }[];
@@ -145,6 +154,39 @@ async function handleDomainStatus(_args: RouteHandlerArgs) {
145
154
  return data;
146
155
  }
147
156
 
157
+ async function handleDomainVerificationStatus({
158
+ body = {},
159
+ }: RouteHandlerArgs) {
160
+ const { domain_id } = body as { domain_id?: string };
161
+ if (!domain_id) {
162
+ throw new BadRequestError("domain_id is required");
163
+ }
164
+ const client = await requireClient();
165
+
166
+ const response = await client.fetch(
167
+ `/v1/assistants/${client.platformAssistantId}/domains/${domain_id}/verification-status/`,
168
+ );
169
+
170
+ if (!response.ok) {
171
+ const respBody = (await response.json().catch(() => ({}))) as Record<
172
+ string,
173
+ unknown
174
+ >;
175
+ const detail = respBody.detail ?? `HTTP ${response.status}`;
176
+ throw new RouteError(
177
+ String(detail),
178
+ "VERIFICATION_STATUS_FAILED",
179
+ response.status,
180
+ );
181
+ }
182
+
183
+ return (await response.json()) as {
184
+ domain: string;
185
+ status: string;
186
+ message: string;
187
+ };
188
+ }
189
+
148
190
  // ── Route definitions ─────────────────────────────────────────────────
149
191
 
150
192
  export const ROUTES: RouteDefinition[] = [
@@ -164,4 +206,12 @@ export const ROUTES: RouteDefinition[] = [
164
206
  summary: "Show domain registration and health",
165
207
  tags: ["domain"],
166
208
  },
209
+ {
210
+ operationId: "domain_verification_status",
211
+ endpoint: "domain/verification-status",
212
+ method: "POST",
213
+ handler: handleDomainVerificationStatus,
214
+ summary: "Get live DNS verification status for a domain",
215
+ tags: ["domain"],
216
+ },
167
217
  ];
@@ -277,13 +277,16 @@ async function handleEmailSend({ body = {} }: RouteHandlerArgs) {
277
277
 
278
278
  const fromAddress = addresses[0].address;
279
279
 
280
+ // LLMs often produce literal "\n" escape sequences instead of real newlines.
281
+ const normalizedText = text?.replace(/\\n/g, "\n") ?? "";
282
+
280
283
  // Auto-generate HTML from text if not provided
281
- const resolvedHtml = html ?? markdownToEmailHtml(text);
284
+ const resolvedHtml = html ?? markdownToEmailHtml(normalizedText);
282
285
 
283
286
  const payload: Record<string, unknown> = {
284
287
  to,
285
288
  from_address: fromAddress,
286
- text,
289
+ text: normalizedText,
287
290
  };
288
291
  if (subject) payload.subject = subject;
289
292
  if (resolvedHtml) payload.html = resolvedHtml;
@@ -26,6 +26,7 @@ import { z } from "zod";
26
26
  import type { HostProxyCapability } from "../../channels/types.js";
27
27
  import { parseInterfaceId, supportsHostProxy } from "../../channels/types.js";
28
28
  import { emitContactChange } from "../../contacts/contact-events.js";
29
+ import { getConversation } from "../../memory/conversation-crud.js";
29
30
  import { getOrCreateConversation } from "../../memory/conversation-key-store.js";
30
31
  import { getLogger } from "../../util/logger.js";
31
32
  import { formatSseFrame, formatSseHeartbeat } from "../assistant-event.js";
@@ -39,7 +40,11 @@ import {
39
40
  assistantEventHub,
40
41
  } from "../assistant-event-hub.js";
41
42
  import { resolveActorPrincipalIdForLocalGuardian } from "../local-actor-identity.js";
42
- import { BadRequestError, ServiceUnavailableError } from "./errors.js";
43
+ import {
44
+ BadRequestError,
45
+ NotFoundError,
46
+ ServiceUnavailableError,
47
+ } from "./errors.js";
43
48
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
44
49
 
45
50
  const log = getLogger("events-routes");
@@ -220,9 +225,17 @@ const defaultSseShedReporter: SseShedReporter = (reason, inst) => {
220
225
  * Stream assistant events as Server-Sent Events.
221
226
  *
222
227
  * Query params:
223
- * conversationKey -- optional; when provided, scopes the stream to one
224
- * conversation. When omitted, the stream delivers events
225
- * from ALL conversations for this assistant.
228
+ * conversationId -- optional; assistant-minted internal conversation id.
229
+ * When provided, the stream is scoped to that one
230
+ * conversation; the daemon 404s if no such conversation
231
+ * exists (clients must obtain the id from a prior
232
+ * response).
233
+ * conversationKey -- optional; external key (non-vellum channels) or the
234
+ * web idempotency key. Resolved via the conversation
235
+ * keys table; materializes a row on first use.
236
+ * Ignored when `conversationId` is also provided.
237
+ * When both are omitted, the stream delivers events from ALL
238
+ * conversations for this assistant.
226
239
  *
227
240
  * Headers (optional):
228
241
  * X-Vellum-Client-Id -- stable per-install UUID identifying this client.
@@ -248,8 +261,18 @@ export function handleSubscribeAssistantEvents(
248
261
  ): ReadableStream<Uint8Array> {
249
262
  const { queryParams, headers, abortSignal } = args;
250
263
 
251
- const conversationKey = queryParams?.conversationKey;
252
- if ("conversationKey" in (queryParams ?? {}) && !conversationKey?.trim()) {
264
+ const rawConversationId = queryParams?.conversationId;
265
+ const rawConversationKey = queryParams?.conversationKey;
266
+ if (
267
+ "conversationId" in (queryParams ?? {}) &&
268
+ !rawConversationId?.trim()
269
+ ) {
270
+ throw new BadRequestError("conversationId must not be empty");
271
+ }
272
+ if (
273
+ "conversationKey" in (queryParams ?? {}) &&
274
+ !rawConversationKey?.trim()
275
+ ) {
253
276
  throw new BadRequestError("conversationKey must not be empty");
254
277
  }
255
278
 
@@ -293,10 +316,25 @@ export function handleSubscribeAssistantEvents(
293
316
  "host_browser",
294
317
  ];
295
318
 
319
+ // Resolve the scope. `conversationId` (when supplied) is the
320
+ // assistant-minted internal id — looked up directly; 404 if absent.
321
+ // Otherwise fall through to `conversationKey`, which is treated as an
322
+ // external key and resolved via the conversation_keys table
323
+ // (materialized on first use, preserving the existing subscribe-time
324
+ // create behavior for the web idempotency flow).
296
325
  const filter: AssistantEventFilter = {};
297
- if (conversationKey) {
298
- const mapping = getOrCreateConversation(conversationKey);
326
+ let scopeConversationKey: string | null = null;
327
+ if (rawConversationId) {
328
+ const existing = getConversation(rawConversationId);
329
+ if (!existing) {
330
+ throw new NotFoundError(`Conversation ${rawConversationId} not found`);
331
+ }
332
+ filter.conversationId = existing.id;
333
+ scopeConversationKey = existing.id;
334
+ } else if (rawConversationKey) {
335
+ const mapping = getOrCreateConversation(rawConversationKey);
299
336
  filter.conversationId = mapping.conversationId;
337
+ scopeConversationKey = rawConversationKey;
300
338
  }
301
339
 
302
340
  const encoder = new TextEncoder();
@@ -316,7 +354,7 @@ export function handleSubscribeAssistantEvents(
316
354
  heartbeatsSent: 0,
317
355
  clientId,
318
356
  interfaceId,
319
- conversationKey: conversationKey ?? null,
357
+ conversationKey: scopeConversationKey,
320
358
  };
321
359
 
322
360
  ensureEventLoopDelayMonitorStarted();
@@ -470,9 +508,15 @@ export const ROUTES: RouteDefinition[] = [
470
508
  description: "Stream assistant events as Server-Sent Events (SSE).",
471
509
  tags: ["events"],
472
510
  queryParams: [
511
+ {
512
+ name: "conversationId",
513
+ description:
514
+ "Scope to a single conversation by its assistant-minted internal id. 404s if no such conversation exists.",
515
+ },
473
516
  {
474
517
  name: "conversationKey",
475
- description: "Scope to a single conversation",
518
+ description:
519
+ "Scope to a single conversation by an external key (non-vellum channels) or the web idempotency key. Materializes a row on first use. Ignored when conversationId is also provided.",
476
520
  },
477
521
  ],
478
522
  responseHeaders: {
@@ -22,6 +22,13 @@ import { publishConversationListChanged } from "../sync/resource-sync-events.js"
22
22
  import { BadRequestError, ForbiddenError, NotFoundError } from "./errors.js";
23
23
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
24
24
 
25
+ const groupSchema = z.object({
26
+ id: z.string(),
27
+ name: z.string(),
28
+ sortPosition: z.number(),
29
+ isSystemGroup: z.boolean(),
30
+ });
31
+
25
32
  function serializeGroup(group: ReturnType<typeof getGroup>) {
26
33
  if (!group) return null;
27
34
  return {
@@ -41,14 +48,17 @@ function handleListGroups() {
41
48
  return { groups: groups.map(serializeGroup) };
42
49
  }
43
50
 
44
- function handleCreateGroup({ body = {} }: RouteHandlerArgs) {
51
+ function handleCreateGroup({ body = {}, headers }: RouteHandlerArgs) {
45
52
  const name = body.name;
46
53
  if (!name || typeof name !== "string") {
47
54
  throw new BadRequestError("Missing or invalid name");
48
55
  }
49
56
  try {
50
57
  const group = createGroup(name);
51
- publishConversationListChanged("created");
58
+ publishConversationListChanged(
59
+ "created",
60
+ headers?.["x-vellum-client-id"]?.trim() || undefined,
61
+ );
52
62
  return serializeGroup(group);
53
63
  } catch (err) {
54
64
  if (
@@ -63,7 +73,11 @@ function handleCreateGroup({ body = {} }: RouteHandlerArgs) {
63
73
  }
64
74
  }
65
75
 
66
- function handleUpdateGroup({ pathParams = {}, body = {} }: RouteHandlerArgs) {
76
+ function handleUpdateGroup({
77
+ pathParams = {},
78
+ body = {},
79
+ headers,
80
+ }: RouteHandlerArgs) {
67
81
  const groupId = pathParams.groupId;
68
82
  const existing = getGroup(groupId);
69
83
  if (!existing) {
@@ -92,11 +106,14 @@ function handleUpdateGroup({ pathParams = {}, body = {} }: RouteHandlerArgs) {
92
106
  if (!updated) {
93
107
  throw new NotFoundError("Group not found");
94
108
  }
95
- publishConversationListChanged("reordered");
109
+ publishConversationListChanged(
110
+ "reordered",
111
+ headers?.["x-vellum-client-id"]?.trim() || undefined,
112
+ );
96
113
  return serializeGroup(updated);
97
114
  }
98
115
 
99
- function handleDeleteGroup({ pathParams = {} }: RouteHandlerArgs) {
116
+ function handleDeleteGroup({ pathParams = {}, headers }: RouteHandlerArgs) {
100
117
  const groupId = pathParams.groupId;
101
118
  const existing = getGroup(groupId);
102
119
  if (!existing) {
@@ -106,10 +123,13 @@ function handleDeleteGroup({ pathParams = {} }: RouteHandlerArgs) {
106
123
  throw new ForbiddenError("System groups cannot be deleted");
107
124
  }
108
125
  deleteGroup(groupId);
109
- publishConversationListChanged("reordered");
126
+ publishConversationListChanged(
127
+ "reordered",
128
+ headers?.["x-vellum-client-id"]?.trim() || undefined,
129
+ );
110
130
  }
111
131
 
112
- function handleReorderGroups({ body = {} }: RouteHandlerArgs) {
132
+ function handleReorderGroups({ body = {}, headers }: RouteHandlerArgs) {
113
133
  const updates = body.updates as
114
134
  | Array<{ groupId: string; sortPosition: number }>
115
135
  | undefined;
@@ -135,7 +155,10 @@ function handleReorderGroups({ body = {} }: RouteHandlerArgs) {
135
155
  }
136
156
  }
137
157
  reorderGroups(updates);
138
- publishConversationListChanged("reordered");
158
+ publishConversationListChanged(
159
+ "reordered",
160
+ headers?.["x-vellum-client-id"]?.trim() || undefined,
161
+ );
139
162
  return { ok: true };
140
163
  }
141
164
 
@@ -153,6 +176,7 @@ export const ROUTES: RouteDefinition[] = [
153
176
  summary: "List groups",
154
177
  description: "Return all conversation groups.",
155
178
  tags: ["groups"],
179
+ responseBody: z.object({ groups: z.array(groupSchema) }),
156
180
  },
157
181
  {
158
182
  operationId: "groups_create",
@@ -168,6 +192,7 @@ export const ROUTES: RouteDefinition[] = [
168
192
  requestBody: z.object({
169
193
  name: z.string().describe("Group name"),
170
194
  }),
195
+ responseBody: groupSchema,
171
196
  additionalResponses: {
172
197
  "400": {
173
198
  description:
@@ -188,6 +213,7 @@ export const ROUTES: RouteDefinition[] = [
188
213
  name: z.string().optional(),
189
214
  sortPosition: z.number().optional(),
190
215
  }),
216
+ responseBody: groupSchema,
191
217
  additionalResponses: {
192
218
  "403": {
193
219
  description: "System group sort position cannot be changed",
@@ -235,6 +261,7 @@ export const ROUTES: RouteDefinition[] = [
235
261
  )
236
262
  .describe("Array of { groupId, sortPosition } objects"),
237
263
  }),
264
+ responseBody: z.object({ ok: z.boolean() }),
238
265
  additionalResponses: {
239
266
  "403": {
240
267
  description: "Cannot reorder system groups",
@@ -62,6 +62,32 @@ const patchFeedItemRequestSchema = z.object({
62
62
  status: z.enum(["new", "seen", "acted_on", "dismissed"]),
63
63
  });
64
64
 
65
+ const listHomeFeedRequestSchema = z.object({
66
+ includeDismissed: z.boolean().optional(),
67
+ statuses: z
68
+ .array(z.enum(["new", "seen", "acted_on", "dismissed"]))
69
+ .optional(),
70
+ before: z.string().optional(),
71
+ after: z.string().optional(),
72
+ urgencies: z.array(z.enum(["low", "medium", "high", "critical"])).optional(),
73
+ categories: z
74
+ .array(z.enum(["security", "scheduling", "background", "email", "system"]))
75
+ .optional(),
76
+ conversationId: z.string().optional(),
77
+ fromAssistant: z.boolean().optional(),
78
+ noteworthy: z.boolean().optional(),
79
+ limit: z.number().int().positive().max(200).optional(),
80
+ offset: z.number().int().nonnegative().optional(),
81
+ });
82
+
83
+ const listHomeFeedResponseSchema = z.object({
84
+ items: z.array(feedItemSchema),
85
+ total: z.number().int().nonnegative(),
86
+ returned: z.number().int().nonnegative(),
87
+ hasMore: z.boolean(),
88
+ updatedAt: z.string(),
89
+ });
90
+
65
91
  // ---------------------------------------------------------------------------
66
92
  // Pure helpers (exported for direct testing)
67
93
  // ---------------------------------------------------------------------------
@@ -183,6 +209,97 @@ export async function handlePatchFeedItem({
183
209
  return updated as unknown as Record<string, unknown>;
184
210
  }
185
211
 
212
+ export function handleListHomeFeed({
213
+ body = {},
214
+ }: RouteHandlerArgs): Record<string, unknown> {
215
+ const parsed = listHomeFeedRequestSchema.safeParse(body);
216
+ if (!parsed.success) {
217
+ throw new BadRequestError(
218
+ `Invalid list request: ${parsed.error.issues
219
+ .map((i) => `${i.path.join(".")} ${i.message}`)
220
+ .join("; ")}`,
221
+ );
222
+ }
223
+ const params = parsed.data;
224
+
225
+ const beforeMs =
226
+ params.before !== undefined ? Date.parse(params.before) : undefined;
227
+ if (beforeMs !== undefined && Number.isNaN(beforeMs)) {
228
+ throw new BadRequestError(
229
+ `Invalid 'before' timestamp; expected ISO-8601 (got "${params.before}")`,
230
+ );
231
+ }
232
+ const afterMs =
233
+ params.after !== undefined ? Date.parse(params.after) : undefined;
234
+ if (afterMs !== undefined && Number.isNaN(afterMs)) {
235
+ throw new BadRequestError(
236
+ `Invalid 'after' timestamp; expected ISO-8601 (got "${params.after}")`,
237
+ );
238
+ }
239
+
240
+ // `statuses` is the explicit override. Otherwise default to excluding
241
+ // dismissed unless includeDismissed=true — the assistant's primary use
242
+ // case is "what's still outstanding", so dismissed items are noise
243
+ // unless explicitly requested.
244
+ const statusFilter: Set<FeedItemStatus> | null = params.statuses
245
+ ? new Set(params.statuses)
246
+ : params.includeDismissed
247
+ ? null
248
+ : new Set<FeedItemStatus>(["new", "seen", "acted_on"]);
249
+
250
+ const urgencySet = params.urgencies ? new Set(params.urgencies) : null;
251
+ const categorySet = params.categories ? new Set(params.categories) : null;
252
+
253
+ const feed = readHomeFeed();
254
+
255
+ const filtered = feed.items.filter((item) => {
256
+ if (statusFilter && !statusFilter.has(item.status)) return false;
257
+ if (urgencySet) {
258
+ if (!item.urgency || !urgencySet.has(item.urgency)) return false;
259
+ }
260
+ if (categorySet) {
261
+ if (!item.category || !categorySet.has(item.category)) return false;
262
+ }
263
+ if (
264
+ params.conversationId !== undefined &&
265
+ item.conversationId !== params.conversationId
266
+ )
267
+ return false;
268
+ if (
269
+ params.fromAssistant !== undefined &&
270
+ (item.fromAssistant ?? false) !== params.fromAssistant
271
+ )
272
+ return false;
273
+ if (
274
+ params.noteworthy !== undefined &&
275
+ (item.noteworthy ?? false) !== params.noteworthy
276
+ )
277
+ return false;
278
+
279
+ if (beforeMs !== undefined || afterMs !== undefined) {
280
+ const createdMs = Date.parse(item.createdAt);
281
+ if (Number.isNaN(createdMs)) return false;
282
+ if (beforeMs !== undefined && createdMs >= beforeMs) return false;
283
+ if (afterMs !== undefined && createdMs <= afterMs) return false;
284
+ }
285
+
286
+ return true;
287
+ });
288
+
289
+ const total = filtered.length;
290
+ const offset = params.offset ?? 0;
291
+ const limit = params.limit ?? 20;
292
+ const items = filtered.slice(offset, offset + limit);
293
+
294
+ return {
295
+ items,
296
+ total,
297
+ returned: items.length,
298
+ hasMore: total > offset + items.length,
299
+ updatedAt: feed.updatedAt,
300
+ };
301
+ }
302
+
186
303
  export async function handlePostFeedAction({
187
304
  pathParams = {},
188
305
  }: RouteHandlerArgs): Promise<Record<string, unknown>> {
@@ -261,6 +378,18 @@ export const ROUTES: RouteDefinition[] = [
261
378
  "500": { description: "Failed to persist feed item status" },
262
379
  },
263
380
  },
381
+ {
382
+ operationId: "list_home_feed",
383
+ endpoint: "home/feed/query",
384
+ method: "POST",
385
+ handler: handleListHomeFeed,
386
+ summary: "List home feed items with filters",
387
+ description:
388
+ "Return home feed items filtered by status, urgency, category, conversation, and date range. Defaults to excluding dismissed items. Used by the assistant CLI to inspect what notifications have been surfaced to the user.",
389
+ tags: ["home"],
390
+ requestBody: listHomeFeedRequestSchema,
391
+ responseBody: listHomeFeedResponseSchema,
392
+ },
264
393
  {
265
394
  operationId: "trigger_home_feed_action",
266
395
  endpoint: "home/feed/:id/actions/:actionId",
@@ -223,8 +223,9 @@ export type HostBrowserSessionInvalidatedResolution =
223
223
  export function resolveHostBrowserSessionInvalidated(frame: {
224
224
  targetId?: unknown;
225
225
  reason?: unknown;
226
+ clientId?: unknown;
226
227
  }): HostBrowserSessionInvalidatedResolution {
227
- const { targetId, reason } = frame;
228
+ const { targetId, reason, clientId } = frame;
228
229
 
229
230
  if (targetId !== undefined && typeof targetId !== "string") {
230
231
  return {
@@ -235,6 +236,9 @@ export function resolveHostBrowserSessionInvalidated(frame: {
235
236
  };
236
237
  }
237
238
 
239
+ const resolvedClientId =
240
+ typeof clientId === "string" && clientId.length > 0 ? clientId : undefined;
241
+
238
242
  if (typeof targetId === "string" && targetId.length > 0) {
239
243
  markTargetInvalidated(
240
244
  targetId,
@@ -245,7 +249,7 @@ export function resolveHostBrowserSessionInvalidated(frame: {
245
249
  // Without this, a user closing the pinned tab manually would see
246
250
  // their next browser command fail with a `cdp_session_not_found`
247
251
  // until the daemon process restarts.
248
- clearPinnedTabByTabId(targetId);
252
+ clearPinnedTabByTabId(targetId, resolvedClientId);
249
253
  }
250
254
 
251
255
  return { ok: true };
@@ -387,6 +391,10 @@ export const ROUTES: RouteDefinition[] = [
387
391
  .optional()
388
392
  .describe("CDP target that was detached"),
389
393
  reason: z.string().optional().describe("Detach reason"),
394
+ clientId: z
395
+ .string()
396
+ .optional()
397
+ .describe("Extension client ID that reported the invalidation"),
390
398
  }),
391
399
  responseBody: z.object({
392
400
  accepted: z.boolean(),