@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
@@ -34,6 +34,7 @@ const USAGE_ATTRIBUTION_HEADER_NAMES = {
34
34
  inferenceProfileSource: "X-Vellum-Inference-Profile-Source",
35
35
  resolvedProvider: "X-Vellum-Resolved-Provider",
36
36
  resolvedModel: "X-Vellum-Resolved-Model",
37
+ resolvedMixArm: "X-Vellum-Resolved-Mix-Arm",
37
38
  } as const;
38
39
 
39
40
  /** Providers that support the `effort` config (extended thinking / reasoning). */
@@ -47,9 +48,18 @@ const EFFORT_SUPPORTED_PROVIDERS = new Set([
47
48
  /**
48
49
  * Providers that consume the `thinking` config. Anthropic uses it directly on
49
50
  * the wire; OpenRouter either forwards it to its Anthropic-compatible path or
50
- * translates it into the unified `reasoning` parameter on OpenAI-compat calls.
51
+ * translates it into the unified `reasoning` parameter on OpenAI-compat calls;
52
+ * Gemini reads `thinking.level` to populate `thinkingConfig.thinkingLevel`.
51
53
  */
52
- const THINKING_AWARE_PROVIDERS = new Set(["anthropic", "openrouter"]);
54
+ const THINKING_AWARE_PROVIDERS = new Set(["anthropic", "openrouter", "gemini"]);
55
+
56
+ /**
57
+ * Providers that consume Gemini-only thinking extras (`level`,
58
+ * `streamThinking`). For other thinking-aware providers, we scrub these from
59
+ * the normalized wire payload because Anthropic's SDK rejects unknown keys
60
+ * inside the `thinking` object with "Extra inputs are not permitted".
61
+ */
62
+ const THINKING_EXTRA_FIELDS_AWARE_PROVIDERS = new Set(["gemini"]);
53
63
 
54
64
  /**
55
65
  * Providers that consume the `verbosity` config. Currently OpenAI (mapped to
@@ -186,19 +196,23 @@ function normalizeSendMessageOptions(
186
196
  delete nextConfig.usageAttributionHeaders;
187
197
  delete nextConfig.usageTracking;
188
198
 
189
- // `overrideProfile` is a routing/resolution-time concern (consumed by the
190
- // resolver below and `CallSiteRoutingProvider`'s provider selection); it is
191
- // not a wire-format field. Strip unconditionally so it never leaks into
192
- // provider request bodies even when callers set it without a `callSite`.
199
+ // `overrideProfile` and `selectionSeed` are routing/resolution-time concerns
200
+ // (consumed by the resolver below and `CallSiteRoutingProvider`'s provider
201
+ // selection); neither is a wire-format field. Strip unconditionally so they
202
+ // never leak into provider request bodies even when callers set them without
203
+ // a `callSite`.
193
204
  delete nextConfig.overrideProfile;
205
+ delete nextConfig.selectionSeed;
194
206
 
195
207
  if (config.callSite !== undefined) {
196
208
  const resolved = resolveCallSiteConfig(config.callSite, getConfig().llm, {
197
209
  overrideProfile: config.overrideProfile,
210
+ selectionSeed: config.selectionSeed,
198
211
  });
199
212
  const attribution = resolveUsageAttribution({
200
213
  callSite: config.callSite,
201
214
  overrideProfile: config.overrideProfile,
215
+ selectionSeed: config.selectionSeed,
202
216
  });
203
217
 
204
218
  const explicitModel =
@@ -216,6 +230,7 @@ function normalizeSendMessageOptions(
216
230
  profileSource: attribution.profileSource,
217
231
  resolvedProvider: attribution.resolvedProvider,
218
232
  resolvedModel: attribution.resolvedModel,
233
+ resolvedMixArm: attribution.resolvedMixArm,
219
234
  });
220
235
  if (Object.keys(usageAttributionHeaders).length > 0) {
221
236
  nextConfig.usageAttributionHeaders = usageAttributionHeaders;
@@ -289,7 +304,8 @@ function normalizeSendMessageOptions(
289
304
  }
290
305
 
291
306
  // thinking is Anthropic-specific on the wire; OpenRouter reads it as a
292
- // signal for its unified reasoning parameter. Strip it for other providers.
307
+ // signal for its unified reasoning parameter; Gemini reads `level` from it.
308
+ // Strip it for other providers.
293
309
  if (
294
310
  !THINKING_AWARE_PROVIDERS.has(providerName) &&
295
311
  nextConfig.thinking !== undefined
@@ -297,6 +313,27 @@ function normalizeSendMessageOptions(
297
313
  delete nextConfig.thinking;
298
314
  }
299
315
 
316
+ // Strip Gemini-only extras (`level`, `streamThinking`) from the wire
317
+ // `thinking` object for providers that don't read them. Anthropic in
318
+ // particular rejects unknown keys inside `thinking` with "Extra inputs are
319
+ // not permitted"; the OpenRouter Anthropic-compat path hits the same SDK.
320
+ if (
321
+ nextConfig.thinking !== undefined &&
322
+ !THINKING_EXTRA_FIELDS_AWARE_PROVIDERS.has(providerName) &&
323
+ typeof nextConfig.thinking === "object" &&
324
+ nextConfig.thinking !== null
325
+ ) {
326
+ const wire = nextConfig.thinking as Record<string, unknown>;
327
+ if (wire.level !== undefined || wire.streamThinking !== undefined) {
328
+ const scrubbed: Record<string, unknown> = {};
329
+ for (const [key, value] of Object.entries(wire)) {
330
+ if (key === "level" || key === "streamThinking") continue;
331
+ scrubbed[key] = value;
332
+ }
333
+ nextConfig.thinking = scrubbed;
334
+ }
335
+ }
336
+
300
337
  // Anthropic (and OpenRouter fronting Anthropic) rejects requests that
301
338
  // combine extended thinking with forced tool use (`tool_choice.type` of
302
339
  // `"tool"` or `"any"`). Strip thinking when both are present so the
@@ -415,6 +452,7 @@ function buildUsageAttributionHeaders(input: {
415
452
  profileSource: string;
416
453
  resolvedProvider: string;
417
454
  resolvedModel: string;
455
+ resolvedMixArm: string | null;
418
456
  }): Record<string, string> {
419
457
  const headers: Record<string, string> = {};
420
458
  addSanitizedHeader(
@@ -444,6 +482,11 @@ function buildUsageAttributionHeaders(input: {
444
482
  USAGE_ATTRIBUTION_HEADER_NAMES.resolvedModel,
445
483
  input.resolvedModel,
446
484
  );
485
+ addSanitizedHeader(
486
+ headers,
487
+ USAGE_ATTRIBUTION_HEADER_NAMES.resolvedMixArm,
488
+ input.resolvedMixArm,
489
+ );
447
490
  return headers;
448
491
  }
449
492
 
@@ -42,8 +42,17 @@ export interface SearchProviderCatalogEntry {
42
42
  * privacy notices). Defaults to {@link displayName} when omitted.
43
43
  */
44
44
  readonly displayNameLong?: string;
45
- /** Authentication style. `managed` providers are routed through the
46
- * inference provider; `byok` providers require a user-supplied key. */
45
+ /**
46
+ * Authentication style for the search provider choice.
47
+ *
48
+ * `managed` means the choice does not require a user-supplied search API key.
49
+ * For `inference-provider-native`, the daemon uses the inference API's native
50
+ * hosted web-search tool only when the selected inference provider/model
51
+ * supports it. Managed non-native inference providers keep the app-executed
52
+ * `web_search` tool, which can route through the platform search proxy.
53
+ *
54
+ * `byok` providers require a user-supplied key in Your Own mode.
55
+ */
47
56
  readonly kind: SearchProviderKind;
48
57
  /** Placeholder shown in the API-key input. BYOK providers only. */
49
58
  readonly apiKeyPrefix?: string;
@@ -99,19 +108,18 @@ export const SEARCH_PROVIDER_CATALOG: readonly SearchProviderCatalogEntry[] = [
99
108
  ];
100
109
 
101
110
  /** Provider ids accepted by the web-search config schema. */
102
- export const SEARCH_PROVIDER_IDS: readonly string[] = SEARCH_PROVIDER_CATALOG.map(
103
- (p) => p.id,
104
- );
111
+ export const SEARCH_PROVIDER_IDS: readonly string[] =
112
+ SEARCH_PROVIDER_CATALOG.map((p) => p.id);
105
113
 
106
114
  /** Catalog entries that store an API key under their bare provider name. */
107
115
  export const BYOK_SEARCH_PROVIDERS: readonly SearchProviderCatalogEntry[] =
108
116
  SEARCH_PROVIDER_CATALOG.filter((p) => p.kind === "byok");
109
117
 
110
118
  /** BYOK provider ids, ordered by `fallbackOrder` (ascending). */
111
- export const SEARCH_PROVIDER_FALLBACK_ORDER: readonly string[] = BYOK_SEARCH_PROVIDERS
112
- .slice()
113
- .sort((a, b) => (a.fallbackOrder ?? 0) - (b.fallbackOrder ?? 0))
114
- .map((p) => p.id);
119
+ export const SEARCH_PROVIDER_FALLBACK_ORDER: readonly string[] =
120
+ BYOK_SEARCH_PROVIDERS.slice()
121
+ .sort((a, b) => (a.fallbackOrder ?? 0) - (b.fallbackOrder ?? 0))
122
+ .map((p) => p.id);
115
123
 
116
124
  /** Look up a single catalog entry by id. Returns `undefined` if unknown. */
117
125
  export function getSearchProvider(
@@ -1,20 +1,45 @@
1
+ import { THINKING_LEVELS, type ThinkingLevel } from "../config/schemas/llm.js";
2
+
1
3
  type ThinkingConfigRecord = Record<string, unknown>;
2
4
 
5
+ const THINKING_LEVEL_SET: ReadonlySet<string> = new Set(THINKING_LEVELS);
6
+
3
7
  function isRecord(value: unknown): value is ThinkingConfigRecord {
4
8
  return typeof value === "object" && value !== null && !Array.isArray(value);
5
9
  }
6
10
 
11
+ function pickGeminiExtras(thinking: ThinkingConfigRecord): {
12
+ level?: ThinkingLevel;
13
+ streamThinking?: boolean;
14
+ } {
15
+ const extras: { level?: ThinkingLevel; streamThinking?: boolean } = {};
16
+ if (
17
+ typeof thinking.level === "string" &&
18
+ THINKING_LEVEL_SET.has(thinking.level)
19
+ ) {
20
+ extras.level = thinking.level as ThinkingLevel;
21
+ }
22
+ if (typeof thinking.streamThinking === "boolean") {
23
+ extras.streamThinking = thinking.streamThinking;
24
+ }
25
+ return extras;
26
+ }
27
+
7
28
  export function normalizeThinkingConfigForWire(
8
29
  thinking: unknown,
9
30
  ): ThinkingConfigRecord | undefined {
10
31
  if (!isRecord(thinking)) return undefined;
11
32
 
33
+ // Already in wire shape — preserve as-is so re-normalization is idempotent
34
+ // and Gemini-only fields stay attached for the Gemini provider to read.
12
35
  if (typeof thinking.type === "string") {
13
36
  return thinking;
14
37
  }
15
38
 
39
+ const extras = pickGeminiExtras(thinking);
40
+
16
41
  if (thinking.enabled === true) {
17
- return { type: "adaptive" };
42
+ return { type: "adaptive", ...extras };
18
43
  }
19
44
 
20
45
  if (thinking.enabled === false) {
@@ -182,6 +182,15 @@ export interface SendMessageConfig {
182
182
  * silently fall through.
183
183
  */
184
184
  overrideProfile?: string;
185
+ /**
186
+ * Per-conversation seed for deterministic `mix`-profile expansion. The agent
187
+ * loop sets this to the conversation id so every resolver call this send
188
+ * triggers — provider/transport selection, wire-param normalization, usage
189
+ * attribution — picks the same mix constituent, stable across the
190
+ * conversation's turns and retries. A resolution/routing-time concern only;
191
+ * stripped before any provider wire request.
192
+ */
193
+ selectionSeed?: string;
185
194
  /**
186
195
  * Internal per-request HTTP headers for managed-proxy usage attribution.
187
196
  * Provider clients may pass these through SDK request options only when the
@@ -2,6 +2,7 @@ import { recordUsageEvent } from "../memory/llm-usage-store.js";
2
2
  import { resolveUsageAttribution } from "../usage/attribution.js";
3
3
  import {
4
4
  buildPricingUsageFromResponse,
5
+ extractRawUsage,
5
6
  resolveStructuredPricing,
6
7
  } from "../usage/pricing.js";
7
8
  import { getLogger } from "../util/logger.js";
@@ -76,6 +77,7 @@ export class UsageTrackingProvider implements Provider {
76
77
  outputTokens: pricingUsage.outputTokens,
77
78
  cacheCreationInputTokens: pricingUsage.cacheCreationInputTokens,
78
79
  cacheReadInputTokens: pricingUsage.cacheReadInputTokens,
80
+ rawUsage: extractRawUsage(response.rawResponse),
79
81
  conversationId: null,
80
82
  runId: null,
81
83
  requestId: null,
@@ -161,10 +161,10 @@ All `/v1/*` endpoints share a per-client-IP sliding-window rate limiter (`middle
161
161
 
162
162
  When the limit is exceeded, the limiter returns 429 and logs a structured warning (module: `rate-limiter`) with the denied endpoint and a breakdown of which endpoints consumed the budget in the current window. This makes it easy to identify whether the cause is rapid conversation switching, polling, or unexpected request volume.
163
163
 
164
- Logs are written to `~/.vellum/workspace/data/logs/vellum.log` by default. If `logFile.dir` is configured, logs rotate daily as `assistant-YYYY-MM-DD.log` in that directory. To watch rate limit events in real time:
164
+ Logs rotate daily into `$VELLUM_WORKSPACE_DIR/data/logs/assistant-YYYY-MM-DD.log` (or into the directory configured via `logFile.dir`). To watch rate limit events in real time:
165
165
 
166
166
  ```bash
167
- tail -f ~/.vellum/workspace/data/logs/vellum.log | grep rate-limit
167
+ tail -f "$VELLUM_WORKSPACE_DIR/data/logs/assistant-$(date -u +%Y-%m-%d).log" | grep rate-limit
168
168
  ```
169
169
 
170
170
  The provider-level rate limiter (`providers/ratelimit.ts`) also logs warnings (module: `rate-limit`) when request rate or token budget limits are enforced.
@@ -29,6 +29,7 @@ import type { DiskPressureStatus } from "../../daemon/disk-pressure-guard.js";
29
29
  mock.module("../../memory/conversation-crud.js", () => ({
30
30
  getConversationOverrideProfile: () => undefined,
31
31
  getConversation: () => ({ archivedAt: null }),
32
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
32
33
  }));
33
34
 
34
35
  const mockGetOrCreateConversationCalls: Array<{
@@ -40,6 +40,7 @@ mock.module("../../memory/conversation-crud.js", () => ({
40
40
  addMessageCalls.push({ conversationId, role, content });
41
41
  return { id: `msg-${addMessageCalls.length}` };
42
42
  },
43
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
43
44
  }));
44
45
 
45
46
  let processMessageImpl: (
@@ -217,6 +217,7 @@ export function notifyGuardianOfAccessRequest(
217
217
  sourceEventName: "ingress.access_request",
218
218
  sourceChannel: sourceChannel as NotificationSourceChannel,
219
219
  sourceContextId: `access-req-${sourceChannel}-${actorExternalId}`,
220
+ requiresConversation: true,
220
221
  ...(sameChannelOnly ? { routingIntent: "single_channel" as const } : {}),
221
222
  attentionHints: {
222
223
  requiresAction: true,
@@ -640,6 +640,7 @@ export async function wakeAgentForOpportunity(
640
640
  JSON.stringify(record.rawResponse),
641
641
  undefined,
642
642
  record.provider,
643
+ "mainAgent",
643
644
  );
644
645
  } catch (err) {
645
646
  log.warn(
@@ -247,6 +247,10 @@ export class AssistantEventHub {
247
247
  * Publish an event to all matching subscribers.
248
248
  *
249
249
  * Matching rules:
250
+ * - if `excludeClientId` is set, the subscriber with that clientId is
251
+ * skipped regardless of every other rule (self-echo suppression — the
252
+ * client that originated the mutation does not receive its own
253
+ * invalidation back through the hub).
250
254
  * - if `targetClientId` is set, deliver only to the subscriber with that
251
255
  * clientId, bypassing the conversation-id filter entirely (the web-origin
252
256
  * event's conversationId differs from the macOS client's subscribed
@@ -255,6 +259,11 @@ export class AssistantEventHub {
255
259
  * `event.conversationId` must equal it
256
260
  * - if `targetCapability` is set, only subscribers whose capabilities include
257
261
  * it receive the event; untargeted events go to all
262
+ * - if `targetInterfaceId` is set, only client subscribers whose
263
+ * `interfaceId` matches receive the event; process subscribers and
264
+ * non-matching clients are skipped. Used to narrow legacy
265
+ * broadcasts (e.g. `conversation_list_invalidated`) to a specific
266
+ * client surface during a migration window.
258
267
  *
259
268
  * Fanout is isolated: a throwing or rejecting subscriber does not abort
260
269
  * delivery to remaining subscribers.
@@ -264,6 +273,15 @@ export class AssistantEventHub {
264
273
  options?: {
265
274
  targetCapability?: HostProxyCapability;
266
275
  targetClientId?: string;
276
+ targetInterfaceId?: InterfaceId;
277
+ /**
278
+ * Skip the subscriber with this `clientId`. Used for self-echo
279
+ * suppression on `sync_changed`: the route handler echoes the
280
+ * originating tab's `X-Vellum-Client-Id` back on the event, and the
281
+ * hub uses it here to avoid re-delivering the invalidation to the
282
+ * tab that already mutated its own optimistic state.
283
+ */
284
+ excludeClientId?: string;
267
285
  },
268
286
  ): Promise<void> {
269
287
  if (event.conversationId) {
@@ -276,12 +294,33 @@ export class AssistantEventHub {
276
294
 
277
295
  const targetCapability = options?.targetCapability;
278
296
  const targetClientId = options?.targetClientId;
297
+ const targetInterfaceId = options?.targetInterfaceId;
298
+ const excludeClientId = options?.excludeClientId;
279
299
  const snapshot = Array.from(this.subscribers);
280
300
  const errors: unknown[] = [];
281
301
 
282
302
  for (const entry of snapshot) {
283
303
  if (!entry.active) continue;
284
304
 
305
+ // Self-echo suppression: the originating client never receives the
306
+ // event back. Checked before every other rule so it composes with
307
+ // both targeted and untargeted broadcasts.
308
+ if (
309
+ excludeClientId != null &&
310
+ entry.type === "client" &&
311
+ entry.clientId === excludeClientId
312
+ ) {
313
+ continue;
314
+ }
315
+
316
+ // Interface targeting: skip any subscriber that is not a client of
317
+ // the requested interface. Composes with `targetClientId` and
318
+ // `targetCapability` below.
319
+ if (targetInterfaceId != null) {
320
+ if (entry.type !== "client" || entry.interfaceId !== targetInterfaceId)
321
+ continue;
322
+ }
323
+
285
324
  if (targetClientId != null) {
286
325
  // Targeted: bypass conversation filter, deliver only to the named client.
287
326
  if (entry.type !== "client" || entry.clientId !== targetClientId)
@@ -519,10 +558,11 @@ let _hubChain = Promise.resolve();
519
558
  export function broadcastMessage(
520
559
  msg: ServerMessage,
521
560
  conversationId?: string,
522
- options?: { targetClientId?: string },
561
+ options?: { targetClientId?: string; targetInterfaceId?: InterfaceId },
523
562
  ): void {
524
563
  const resolvedConversationId = conversationId ?? extractConversationId(msg);
525
564
  const targetClientId = options?.targetClientId;
565
+ const targetInterfaceId = options?.targetInterfaceId;
526
566
 
527
567
  // Confirmation-request side effects: canonical guardian request creation.
528
568
  // The home-feed `activity.failed` notification side-effect lives in the
@@ -539,16 +579,45 @@ export function broadcastMessage(
539
579
  : resolvedConversationId;
540
580
  const event = buildAssistantEvent(msg, scopedConversationId);
541
581
  const targetCapability = capabilityForMessageType(msg.type);
582
+ // Self-echo suppression: a `sync_changed` carrying an `originClientId`
583
+ // means a specific client just mutated the resource. The hub must not
584
+ // re-deliver the invalidation to that client — it already updated its
585
+ // optimistic state locally and a redundant invalidation would clobber it
586
+ // with a flash of stale-then-fresh data. Assistant-internal emits (agent
587
+ // loop, FS watcher, cron) leave `originClientId` unset and the event
588
+ // fans out to every subscriber as before.
589
+ const excludeClientId =
590
+ msg.type === "sync_changed" &&
591
+ typeof msg.originClientId === "string" &&
592
+ msg.originClientId.length > 0
593
+ ? msg.originClientId
594
+ : undefined;
542
595
  const publishOptions =
543
- targetCapability != null || targetClientId != null
544
- ? { targetCapability, targetClientId }
596
+ targetCapability != null ||
597
+ targetClientId != null ||
598
+ targetInterfaceId != null ||
599
+ excludeClientId != null
600
+ ? {
601
+ targetCapability,
602
+ targetClientId,
603
+ targetInterfaceId,
604
+ excludeClientId,
605
+ }
545
606
  : undefined;
546
607
  _hubChain = _hubChain
547
608
  .then(() => assistantEventHub.publish(event, publishOptions))
548
609
  .then(() => {
549
- // When a conversation title changes, also broadcast an unscoped
550
- // `conversation_list_invalidated` so every connected client's sidebar
551
- // refreshes not just the client viewing this conversation.
610
+ // When a conversation title changes, also publish a
611
+ // `conversation_list_invalidated` so the macOS sidebar refreshes
612
+ // its row ordering for the renamed conversation. Web consumes the
613
+ // paired `sync_changed` with `conversation:<id>:metadata` tag
614
+ // emitted by `publishConversationTitleChanged` and patches the
615
+ // single row in place, so the broadcast is scoped to macOS only.
616
+ //
617
+ // TODO(electron-cutover): remove this emission once macOS migrates
618
+ // to the Electron client and consumes `sync_changed` directly. At
619
+ // that point `conversation_list_invalidated` has no remaining
620
+ // consumers and the message type can be retired.
552
621
  if (msg.type === "conversation_title_updated") {
553
622
  return assistantEventHub
554
623
  .publish(
@@ -556,6 +625,7 @@ export function broadcastMessage(
556
625
  type: "conversation_list_invalidated",
557
626
  reason: "renamed",
558
627
  }),
628
+ { targetInterfaceId: "macos" },
559
629
  )
560
630
  .catch((err: unknown) => {
561
631
  log.warn(
@@ -209,6 +209,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
209
209
  { endpoint: "identity/intro", scopes: ["settings.read"] },
210
210
  { endpoint: "home/state", scopes: ["settings.read"] },
211
211
  { endpoint: "home/feed", scopes: ["settings.read"] },
212
+ { endpoint: "home/feed/query", scopes: ["settings.read"] },
212
213
  { endpoint: "home/feed:PATCH", scopes: ["settings.write"] },
213
214
  { endpoint: "home/feed/actions", scopes: ["settings.write"] },
214
215
  { endpoint: "brain-graph", scopes: ["settings.read"] },
@@ -417,6 +418,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
417
418
 
418
419
  // LLM call site catalog
419
420
  { endpoint: "config/llm/call-sites:GET", scopes: ["settings.read"] },
421
+ { endpoint: "config/llm/profiles:GET", scopes: ["settings.read"] },
420
422
 
421
423
  // Conversation management
422
424
  { endpoint: "conversations:DELETE", scopes: ["chat.write"] },
@@ -440,6 +442,8 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
440
442
  // Message content
441
443
  { endpoint: "messages/content", scopes: ["chat.read"] },
442
444
  { endpoint: "messages/llm-context", scopes: ["chat.read"] },
445
+ { endpoint: "conversations/llm-context", scopes: ["chat.read"] },
446
+ { endpoint: "conversations/compaction", scopes: ["chat.read"] },
443
447
  { endpoint: "llm-request-logs/payload", scopes: ["chat.read"] },
444
448
  { endpoint: "messages/tts", scopes: ["chat.read"] },
445
449
  { endpoint: "tts/synthesize", scopes: ["chat.read"] },
@@ -458,6 +462,11 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
458
462
  { endpoint: "skills:DELETE", scopes: ["settings.write"] },
459
463
  { endpoint: "skills:PATCH", scopes: ["settings.write"] },
460
464
 
465
+ // Plugins (read-only for now — install / uninstall stay CLI-side)
466
+ { endpoint: "plugins:GET", scopes: ["settings.read"] },
467
+ { endpoint: "plugins/search:GET", scopes: ["settings.read"] },
468
+ { endpoint: "plugins:DELETE", scopes: ["settings.write"] },
469
+
461
470
  // Memory items
462
471
  { endpoint: "memory-items:GET", scopes: ["settings.read"] },
463
472
  { endpoint: "memory-items:POST", scopes: ["settings.write"] },
@@ -471,6 +480,20 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
471
480
  { endpoint: "memory/v2/concept-frequency:POST", scopes: ["settings.read"] },
472
481
  { endpoint: "memory/v2/ema-scores:POST", scopes: ["settings.read"] },
473
482
  { endpoint: "memory/v2/simulate-router:POST", scopes: ["settings.read"] },
483
+ {
484
+ endpoint: "memory/v2/compare-retrievers:POST",
485
+ scopes: ["settings.read"],
486
+ },
487
+ {
488
+ endpoint: "memory/v2/router-prompt-template:GET",
489
+ scopes: ["settings.read"],
490
+ },
491
+ { endpoint: "memory/v2/now-text:GET", scopes: ["settings.read"] },
492
+ { endpoint: "memory/v3/validate:POST", scopes: ["settings.read"] },
493
+ { endpoint: "memory/v3/tree:POST", scopes: ["settings.read"] },
494
+ { endpoint: "memory/v3/simulate:POST", scopes: ["settings.read"] },
495
+ { endpoint: "memory/v3/shadow-diff:POST", scopes: ["settings.read"] },
496
+ { endpoint: "memory/v3/seed-edges:POST", scopes: ["settings.write"] },
474
497
 
475
498
  // Trust rule listing
476
499
  { endpoint: "trust-rules/manage:GET", scopes: ["settings.read"] },
@@ -665,6 +688,12 @@ registerPolicy("channels/inbound", {
665
688
  allowedPrincipalTypes: ["svc_gateway"],
666
689
  });
667
690
 
691
+ // Background wake control-plane calls from the platform.
692
+ registerPolicy("background-wake", {
693
+ requiredScopes: ["internal.write"],
694
+ allowedPrincipalTypes: ["svc_gateway"],
695
+ });
696
+
668
697
  // Internal forwarding endpoints: gateway-only
669
698
  const INTERNAL_ENDPOINTS = [
670
699
  "internal/twilio/voice-webhook",
@@ -843,6 +872,12 @@ registerPolicy("notifications/events", {
843
872
  allowedPrincipalTypes: ["local"],
844
873
  });
845
874
 
875
+ // Edit an already-sent notification: local-only (CLI / IPC callers)
876
+ registerPolicy("notifications/edit", {
877
+ requiredScopes: ["settings.write"],
878
+ allowedPrincipalTypes: ["local"],
879
+ });
880
+
846
881
  // Defer operations: local-only (CLI / IPC callers)
847
882
  registerPolicy("defer/create", {
848
883
  requiredScopes: ["settings.write"],
@@ -887,6 +922,12 @@ registerPolicy("browser/execute", {
887
922
  allowedPrincipalTypes: ["local"],
888
923
  });
889
924
 
925
+ // Browser tabs operations (list/select/new/close): local-only (CLI / IPC callers)
926
+ registerPolicy("browser/tabs", {
927
+ requiredScopes: ["settings.write"],
928
+ allowedPrincipalTypes: ["local"],
929
+ });
930
+
890
931
  // Background tools: local-only (CLI / IPC callers)
891
932
  registerPolicy("background-tools", {
892
933
  requiredScopes: ["settings.read"],
@@ -922,6 +963,11 @@ registerPolicy("domain/status", {
922
963
  allowedPrincipalTypes: ["local"],
923
964
  });
924
965
 
966
+ registerPolicy("domain/verification-status", {
967
+ requiredScopes: ["settings.read"],
968
+ allowedPrincipalTypes: ["local"],
969
+ });
970
+
925
971
  // Email management (IPC-local)
926
972
  registerPolicy("email/register", {
927
973
  requiredScopes: ["settings.write"],
@@ -40,9 +40,6 @@ export interface RunBtwSidechainParams {
40
40
  signal?: AbortSignal;
41
41
  timeoutMs?: number;
42
42
  onEvent?: (event: ProviderEvent) => void;
43
- userPersona?: string | null;
44
- channelPersona?: string | null;
45
- userSlug?: string | null;
46
43
  }
47
44
 
48
45
  export interface RunBtwSidechainResult {
@@ -79,9 +76,6 @@ export async function runBtwSidechain(
79
76
  : buildSystemPrompt({
80
77
  excludeBootstrap: true,
81
78
  excludeCustomPrefix: true,
82
- userPersona: params.userPersona,
83
- channelPersona: params.channelPersona,
84
- userSlug: params.userSlug,
85
79
  }));
86
80
 
87
81
  const { signal: timeoutSignal, cleanup } = createTimeout(
@@ -282,6 +282,74 @@ const slackProbe: ChannelProbe = {
282
282
  ),
283
283
  ];
284
284
  },
285
+ async runRemoteChecks(): Promise<ReadinessCheckResult[]> {
286
+ const botToken = await getSecureKeyAsync(
287
+ credentialKey("slack_channel", "bot_token"),
288
+ );
289
+ if (!botToken) {
290
+ return [
291
+ check(
292
+ "auth_test",
293
+ false,
294
+ "Slack auth.test ok",
295
+ "Skipped: no bot_token stored",
296
+ ),
297
+ ];
298
+ }
299
+ try {
300
+ const res = await fetch("https://slack.com/api/auth.test", {
301
+ method: "POST",
302
+ headers: { Authorization: `Bearer ${botToken}` },
303
+ });
304
+ const data = (await res.json()) as {
305
+ ok: boolean;
306
+ error?: string;
307
+ team_id?: string;
308
+ team?: string;
309
+ user?: string;
310
+ };
311
+ if (!data.ok) {
312
+ return [
313
+ check(
314
+ "auth_test",
315
+ false,
316
+ "Slack auth.test ok",
317
+ `Slack auth.test rejected bot_token: ${data.error ?? "unknown error"}`,
318
+ ),
319
+ ];
320
+ }
321
+ const raw = loadRawConfig();
322
+ const storedTeamId = getNestedValue(raw, "slack.teamId");
323
+ const teamMatches =
324
+ typeof storedTeamId !== "string" ||
325
+ storedTeamId.length === 0 ||
326
+ storedTeamId === data.team_id;
327
+ return [
328
+ check(
329
+ "auth_test",
330
+ true,
331
+ `Slack auth.test ok (workspace ${data.team ?? data.team_id ?? "unknown"}, bot ${data.user ?? "unknown"})`,
332
+ "Slack auth.test ok",
333
+ ),
334
+ check(
335
+ "workspace_match",
336
+ teamMatches,
337
+ "Stored workspace matches bot token",
338
+ `Stored workspace ${storedTeamId} does not match bot token's workspace ${data.team_id ?? "unknown"} — run 'assistant channels slack reconnect' to refresh metadata`,
339
+ ),
340
+ ];
341
+ } catch (err) {
342
+ const message = err instanceof Error ? err.message : String(err);
343
+ return [
344
+ check(
345
+ "auth_test",
346
+ false,
347
+ "Slack auth.test ok",
348
+ `Failed to reach Slack auth.test: ${message}`,
349
+ ),
350
+ ];
351
+ }
352
+ },
285
353
  };
286
354
 
287
355
  // ── Service ─────────────────────────────────────────────────────────────────