@vellumai/assistant 0.9.1-staging.1 → 0.10.0-staging.2

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 (433) hide show
  1. package/docs/activation-funnel-telemetry.md +24 -18
  2. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
  3. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  4. package/node_modules/@vellumai/gateway-client/src/index.ts +15 -0
  5. package/openapi.yaml +852 -15
  6. package/package.json +1 -1
  7. package/src/__tests__/access-request-card-view.test.ts +98 -0
  8. package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
  9. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +59 -7
  10. package/src/__tests__/agent-loop-compaction-strip.test.ts +17 -16
  11. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
  12. package/src/__tests__/app-compiler.test.ts +15 -1
  13. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  14. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  15. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  16. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  17. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  18. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  19. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  20. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  21. package/src/__tests__/config-loader-backfill.test.ts +174 -30
  22. package/src/__tests__/config-schema.test.ts +35 -0
  23. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  24. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  25. package/src/__tests__/contacts-tools.test.ts +29 -0
  26. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  27. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  28. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  29. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  30. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  31. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  32. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  33. package/src/__tests__/conversation-title-service.test.ts +62 -0
  34. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  35. package/src/__tests__/credential-prompt-route.test.ts +1 -0
  36. package/src/__tests__/credential-security-invariants.test.ts +2 -0
  37. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  38. package/src/__tests__/disk-usage.test.ts +65 -0
  39. package/src/__tests__/dynamic-page-surface.test.ts +51 -0
  40. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  41. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  42. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  43. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  44. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  45. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  46. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  47. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  48. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  49. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  50. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  51. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  52. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  53. package/src/__tests__/invite-redemption-service.test.ts +0 -3
  54. package/src/__tests__/llm-catalog-parity.test.ts +30 -1
  55. package/src/__tests__/llm-resolver.test.ts +21 -0
  56. package/src/__tests__/llm-schema.test.ts +1 -0
  57. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  58. package/src/__tests__/mcp-health-check.test.ts +6 -7
  59. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  60. package/src/__tests__/path-policy.test.ts +34 -0
  61. package/src/__tests__/persona-resolver.test.ts +38 -0
  62. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  63. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  64. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  65. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  66. package/src/__tests__/reaction-persistence.test.ts +150 -29
  67. package/src/__tests__/relay-server.test.ts +285 -0
  68. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  69. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  70. package/src/__tests__/skill-execute-input.test.ts +5 -0
  71. package/src/__tests__/skills.test.ts +51 -0
  72. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  73. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  74. package/src/__tests__/subagent-tools.test.ts +150 -0
  75. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  76. package/src/__tests__/title-generate-hook.test.ts +100 -3
  77. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  78. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  79. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  80. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  81. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  82. package/src/__tests__/trusted-contact-verification.test.ts +2 -4
  83. package/src/__tests__/twilio-routes.test.ts +81 -1
  84. package/src/__tests__/voice-invite-redemption.test.ts +0 -1
  85. package/src/__tests__/weak-open-model.test.ts +30 -0
  86. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  87. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  88. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  89. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  90. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  91. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  92. package/src/agent/loop.ts +33 -33
  93. package/src/api/events/tool-result.ts +6 -0
  94. package/src/api/events/workflow-completed.ts +53 -0
  95. package/src/api/events/workflow-leaf-finished.ts +38 -0
  96. package/src/api/events/workflow-leaf-started.ts +35 -0
  97. package/src/api/events/workflow-progress.ts +32 -0
  98. package/src/api/events/workflow-started.ts +31 -0
  99. package/src/api/index.ts +40 -0
  100. package/src/api/responses/conversation-message.ts +26 -0
  101. package/src/api/responses/home.ts +26 -0
  102. package/src/api/responses/workflow-journal.ts +53 -0
  103. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  104. package/src/approvals/guardian-decision-primitive.ts +26 -3
  105. package/src/approvals/guardian-request-resolvers.ts +181 -78
  106. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  107. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  108. package/src/calls/call-pointer-messages.ts +10 -4
  109. package/src/calls/channel-admission-reader.ts +104 -0
  110. package/src/calls/guardian-dispatch.ts +17 -45
  111. package/src/calls/media-stream-server.ts +84 -2
  112. package/src/calls/relay-server.ts +66 -0
  113. package/src/calls/relay-setup-router.ts +82 -1
  114. package/src/calls/twilio-routes.ts +17 -8
  115. package/src/cli/commands/clients.ts +3 -0
  116. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  117. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  118. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  119. package/src/cli/commands/memory/index.ts +30 -0
  120. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  121. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  122. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  123. package/src/cli/commands/oauth/status.test.ts +36 -0
  124. package/src/cli/commands/oauth/status.ts +23 -3
  125. package/src/cli/commands/plugins.ts +57 -5
  126. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  127. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +134 -4
  128. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  129. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +53 -11
  130. package/src/cli/lib/inspect-plugin.ts +12 -1
  131. package/src/cli/lib/merge-plugin-tree.ts +149 -49
  132. package/src/cli/lib/plugin-surfaces.ts +104 -0
  133. package/src/cli/lib/upgrade-plugin.ts +64 -36
  134. package/src/cli/program.ts +2 -4
  135. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  136. package/src/config/assistant-feature-flags.ts +22 -7
  137. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  138. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  139. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  140. package/src/config/bundled-skills/workflows/SKILL.md +14 -7
  141. package/src/config/call-site-defaults.ts +3 -0
  142. package/src/config/feature-flag-registry.json +49 -18
  143. package/src/config/llm-resolver.ts +3 -0
  144. package/src/config/memory-v3-gate.ts +11 -0
  145. package/src/config/schema.ts +8 -6
  146. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  147. package/src/config/schemas/call-site-catalog.ts +7 -0
  148. package/src/config/schemas/channels.ts +11 -0
  149. package/src/config/schemas/llm.ts +31 -0
  150. package/src/config/schemas/memory-lifecycle.ts +3 -7
  151. package/src/config/schemas/memory-v3.ts +6 -0
  152. package/src/config/schemas/services.ts +18 -0
  153. package/src/config/seed-inference-profiles.ts +94 -34
  154. package/src/config/skills.ts +21 -0
  155. package/src/config/sync-gated-profiles.ts +220 -0
  156. package/src/contacts/contact-store.ts +2 -10
  157. package/src/contacts/contacts-write.ts +1 -2
  158. package/src/contacts/types.ts +0 -1
  159. package/src/context/compactor.ts +86 -52
  160. package/src/context/strip-injections.ts +58 -10
  161. package/src/context/token-estimator.ts +1 -1
  162. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  163. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  164. package/src/daemon/conversation-agent-loop.ts +100 -19
  165. package/src/daemon/conversation-history.ts +1 -1
  166. package/src/daemon/conversation-lifecycle.ts +3 -5
  167. package/src/daemon/conversation-process.ts +13 -5
  168. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  169. package/src/daemon/conversation-surfaces.ts +26 -0
  170. package/src/daemon/conversation-tool-setup.ts +16 -11
  171. package/src/daemon/conversation.ts +64 -14
  172. package/src/daemon/disk-pressure-policy.ts +5 -3
  173. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  174. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  175. package/src/daemon/handlers/config-a2a.ts +0 -2
  176. package/src/daemon/handlers/config-channels.ts +5 -10
  177. package/src/daemon/handlers/config-slack-channel.ts +20 -0
  178. package/src/daemon/handlers/conversations.ts +107 -0
  179. package/src/daemon/host-browser-proxy.ts +41 -0
  180. package/src/daemon/lifecycle.ts +55 -20
  181. package/src/daemon/message-provenance.ts +2 -0
  182. package/src/daemon/message-types/contacts.ts +0 -1
  183. package/src/daemon/message-types/web-activity.ts +7 -1
  184. package/src/daemon/message-types/workflows.ts +83 -1
  185. package/src/daemon/tool-setup-types.ts +4 -0
  186. package/src/daemon/trust-context.ts +1 -1
  187. package/src/events/tool-audit-listener.ts +2 -2
  188. package/src/home/feed-source-enrichment.test.ts +151 -0
  189. package/src/home/feed-source-enrichment.ts +176 -0
  190. package/src/instrument.ts +18 -6
  191. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  192. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  193. package/src/ipc/assistant-server.ts +37 -4
  194. package/src/ipc/gateway-flag-listener.ts +18 -2
  195. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  196. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  197. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  198. package/src/memory/__tests__/memory-retrospective-job.test.ts +34 -0
  199. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  200. package/src/memory/auth-fallback-events-store.ts +2 -2
  201. package/src/memory/auto-analysis-enqueue.ts +3 -5
  202. package/src/memory/canonical-guardian-store.ts +39 -1
  203. package/src/memory/conversation-crud.ts +9 -4
  204. package/src/memory/conversation-key-store.ts +17 -2
  205. package/src/memory/conversation-title-service.ts +64 -7
  206. package/src/memory/db-init.ts +10 -0
  207. package/src/memory/embedding-backend.ts +15 -1
  208. package/src/memory/jobs-worker.ts +2 -1
  209. package/src/memory/lifecycle-events-store.ts +2 -2
  210. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  211. package/src/memory/memory-retrospective-job.ts +9 -0
  212. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  213. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  214. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  215. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +10 -0
  216. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  217. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  218. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  219. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  220. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  221. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  222. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  223. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  224. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  225. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +30 -0
  226. package/src/memory/migrations/index.ts +5 -0
  227. package/src/memory/onboarding-events-store.ts +3 -3
  228. package/src/memory/schema/contacts.ts +0 -1
  229. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  230. package/src/memory/skill-loaded-events-store.ts +2 -2
  231. package/src/memory/tool-executed-events-store.test.ts +7 -7
  232. package/src/memory/turn-trace-store.test.ts +736 -0
  233. package/src/memory/turn-trace-store.ts +364 -0
  234. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  235. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  236. package/src/memory/v2/consolidation-job.ts +2 -2
  237. package/src/memory/v2/skill-content.ts +25 -7
  238. package/src/memory/v2/skill-store.ts +7 -1
  239. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  240. package/src/memory/v3-eval/eval-packets.ts +546 -0
  241. package/src/messaging/providers/slack/api.ts +31 -0
  242. package/src/messaging/providers/slack/send.test.ts +114 -2
  243. package/src/messaging/providers/slack/send.ts +30 -7
  244. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  245. package/src/messaging/providers/slack/withdraw.ts +161 -0
  246. package/src/notifications/AGENTS.md +2 -0
  247. package/src/notifications/access-request-copy.ts +72 -59
  248. package/src/notifications/adapters/slack.ts +55 -73
  249. package/src/notifications/approval-card-data.ts +333 -0
  250. package/src/notifications/broadcaster.ts +6 -2
  251. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  252. package/src/notifications/copy-composer.ts +3 -3
  253. package/src/notifications/decision-engine.ts +4 -2
  254. package/src/notifications/destination-resolver.ts +4 -6
  255. package/src/notifications/guardian-question-mode.ts +10 -0
  256. package/src/notifications/home-feed-side-effect.ts +3 -13
  257. package/src/notifications/notification-utils.ts +2 -1
  258. package/src/notifications/signal.ts +79 -43
  259. package/src/notifications/types.ts +98 -128
  260. package/src/permissions/checker.test.ts +51 -0
  261. package/src/permissions/checker.ts +185 -26
  262. package/src/permissions/ipc-risk-types.ts +24 -0
  263. package/src/permissions/question-prompter.test.ts +27 -0
  264. package/src/permissions/question-prompter.ts +4 -0
  265. package/src/platform/client.test.ts +119 -0
  266. package/src/platform/client.ts +66 -0
  267. package/src/platform/consent-cache.test.ts +267 -0
  268. package/src/platform/consent-cache.ts +174 -0
  269. package/src/plugin-api/index.ts +27 -0
  270. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  271. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  272. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  273. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  274. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  275. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  276. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  277. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  278. package/src/plugins/defaults/advisor/config.ts +21 -0
  279. package/src/plugins/defaults/advisor/consult.ts +93 -0
  280. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  281. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  282. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  283. package/src/plugins/defaults/advisor/package.json +14 -0
  284. package/src/plugins/defaults/advisor/steering.ts +67 -0
  285. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  286. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  287. package/src/plugins/defaults/index.ts +35 -0
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  289. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  290. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  291. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  292. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  293. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +75 -7
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  297. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  298. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  299. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +37 -4
  300. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  301. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  302. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  303. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +2 -12
  304. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  305. package/src/prompts/persona-resolver.ts +12 -2
  306. package/src/prompts/templates/system-sections.ts +7 -2
  307. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  308. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  309. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  310. package/src/providers/atlascloud/client.ts +85 -0
  311. package/src/providers/fetch-provider-catalog.ts +85 -0
  312. package/src/providers/inference/adapter-factory.ts +3 -0
  313. package/src/providers/model-catalog.ts +58 -0
  314. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  315. package/src/providers/openai/chat-completions-provider.ts +7 -0
  316. package/src/providers/openai/responses-provider.ts +10 -0
  317. package/src/providers/provider-send-message.ts +11 -3
  318. package/src/providers/retry.ts +53 -12
  319. package/src/providers/search-provider-catalog.ts +10 -0
  320. package/src/providers/weak-open-model.ts +22 -0
  321. package/src/runtime/__tests__/agent-wake.test.ts +181 -0
  322. package/src/runtime/__tests__/client-health.test.ts +44 -0
  323. package/src/runtime/access-request-helper.ts +21 -53
  324. package/src/runtime/actor-trust-resolver.ts +49 -21
  325. package/src/runtime/agent-wake.ts +52 -0
  326. package/src/runtime/assistant-event-hub.ts +18 -4
  327. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  328. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  329. package/src/runtime/capabilities.test.ts +120 -0
  330. package/src/runtime/capabilities.ts +197 -0
  331. package/src/runtime/channel-approval-types.ts +5 -1
  332. package/src/runtime/channel-retry-sweep.ts +1 -0
  333. package/src/runtime/channel-verification-service.ts +1 -2
  334. package/src/runtime/client-health.ts +26 -0
  335. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  336. package/src/runtime/effective-capabilities.test.ts +128 -0
  337. package/src/runtime/effective-capabilities.ts +84 -0
  338. package/src/runtime/guardian-reply-router.ts +106 -21
  339. package/src/runtime/invite-redemption-service.ts +6 -22
  340. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
  341. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  342. package/src/runtime/pending-interactions.ts +15 -0
  343. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  344. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  345. package/src/runtime/routes/__tests__/plugins-routes.test.ts +35 -13
  346. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  347. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  348. package/src/runtime/routes/client-routes.ts +10 -0
  349. package/src/runtime/routes/contact-routes.ts +31 -8
  350. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  351. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  352. package/src/runtime/routes/conversation-routes.ts +37 -12
  353. package/src/runtime/routes/events-routes.ts +1 -3
  354. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  355. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  356. package/src/runtime/routes/home-feed-routes.ts +8 -3
  357. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  358. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +88 -6
  359. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  360. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  361. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  362. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  363. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  364. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  365. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  366. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  367. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  368. package/src/runtime/routes/index.ts +2 -0
  369. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  370. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  371. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  372. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  373. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  374. package/src/runtime/routes/notification-routes.ts +122 -133
  375. package/src/runtime/routes/platform-routes.ts +2 -2
  376. package/src/runtime/routes/plugins-routes.ts +40 -7
  377. package/src/runtime/routes/secret-routes.ts +10 -0
  378. package/src/runtime/routes/surface-action-routes.ts +2 -1
  379. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  380. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  381. package/src/runtime/routes/workflow-routes.test.ts +225 -1
  382. package/src/runtime/routes/workflow-routes.ts +131 -1
  383. package/src/runtime/tool-grant-request-helper.ts +18 -16
  384. package/src/runtime/trust-context-resolver.ts +8 -5
  385. package/src/schedule/schedule-store.ts +1 -1
  386. package/src/schedule/scheduler-types.ts +5 -1
  387. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  388. package/src/security/secret-patterns.ts +3 -0
  389. package/src/subagent/manager.ts +11 -4
  390. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  391. package/src/telemetry/trace-collection-policy.ts +30 -0
  392. package/src/telemetry/types.ts +89 -0
  393. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  394. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  395. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  396. package/src/tools/browser/browser-execution.ts +29 -18
  397. package/src/tools/document/document-tool.ts +2 -3
  398. package/src/tools/executor.ts +5 -3
  399. package/src/tools/host-terminal/host-shell.ts +5 -4
  400. package/src/tools/memory/register.ts +2 -2
  401. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  402. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  403. package/src/tools/network/web-fetch.ts +372 -1
  404. package/src/tools/network/web-search.ts +213 -10
  405. package/src/tools/permission-checker.ts +3 -2
  406. package/src/tools/registry.ts +20 -0
  407. package/src/tools/schedule/create.ts +4 -3
  408. package/src/tools/schedule/update.ts +2 -1
  409. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  410. package/src/tools/skills/execute.ts +1 -2
  411. package/src/tools/subagent/spawn.ts +37 -13
  412. package/src/tools/terminal/shell.ts +10 -4
  413. package/src/tools/tool-approval-handler.ts +17 -10
  414. package/src/tools/types.ts +9 -0
  415. package/src/tools/ui-surface/definitions.ts +25 -2
  416. package/src/tools/verification-control-plane-policy.ts +3 -1
  417. package/src/tools/workflows/run-workflow.ts +1 -0
  418. package/src/util/disk-usage.ts +78 -23
  419. package/src/util/platform.ts +8 -1
  420. package/src/watcher/telemetry.ts +2 -2
  421. package/src/workflows/engine.test.ts +175 -1
  422. package/src/workflows/engine.ts +82 -0
  423. package/src/workflows/journal-store.test.ts +70 -0
  424. package/src/workflows/journal-store.ts +18 -3
  425. package/src/workflows/run-manager.test.ts +171 -3
  426. package/src/workflows/run-manager.ts +64 -0
  427. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  428. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  429. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  430. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  431. package/src/workspace/migrations/registry.ts +8 -0
  432. package/src/notifications/tool-approval-copy.ts +0 -142
  433. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
@@ -18,7 +18,6 @@ function formatContactSummary(c: ContactWithChannels): string {
18
18
  .map((ch) => {
19
19
  let s = `${ch.type}:${ch.address}${ch.isPrimary ? "*" : ""}`;
20
20
  const extras: string[] = [];
21
- if (ch.externalUserId) extras.push(`userId: ${ch.externalUserId}`);
22
21
  if (ch.externalChatId) extras.push(`chatId: ${ch.externalChatId}`);
23
22
  if (extras.length > 0) s += ` (${extras.join(", ")})`;
24
23
  return s;
@@ -28,6 +28,8 @@ When the user mentions "email" - sending, reading, checking, decluttering, draft
28
28
 
29
29
  Do not offer the assistant's own email as an option unless the user specifically asks. If Gmail and Outlook are not connected, guide them through setup.
30
30
 
31
+ Reading, searching, or summarizing the user's inbox is a **messaging task** — use the messaging tools (or the Gmail connection flow below if nothing is connected). Never run `assistant channels` commands for a mailbox request: channels are the assistant's own inbound delivery routes, not the user's mailbox, and inspecting them sends you down the wrong path.
32
+
31
33
  When a platform is connected (auth test succeeds), always use the messaging API tools for that platform. Never fall back to browser automation, shell commands (bash, curl), or any other approach for operations that messaging tools can handle. The messaging tools handle authentication internally - never try to access tokens or call APIs directly. Browser automation is only appropriate for initial credential setup (OAuth consent screens), not for day-to-day messaging operations.
32
34
 
33
35
  **Exception: Slack.** Slack messaging should use the Slack Web API directly via CLI, not messaging tools. See the **slack** skill for details.
@@ -50,13 +52,13 @@ When the user asks to "connect my email", "set up email", "manage my email", or
50
52
 
51
53
  ### Gmail
52
54
 
53
- 1. **Try connecting directly first.** Run `assistant oauth status google`. This will show whether or not the user had previously connected their google account. If so, they are ready to go.
54
- 2. **If no connections are found:** Call `skill_load` with `skill: "vellum-oauth-integrations"`. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.
55
+ 1. **Check the connection.** Run `assistant oauth status google`. If a connection exists, the user is ready to go proceed with their request.
56
+ 2. **If no connections are found, render the connect button in one step:** call `ui_show` with `surface_type: "oauth_connect"` and `data.providerKey: "google"`. That surface is always available — do **not** run `assistant channels`, `oauth providers get`, or load `vellum-oauth-integrations` just to display the button, and do **not** fall back to `assistant oauth connect`. Only load `vellum-oauth-integrations` when the managed-vs-your-own-credentials decision genuinely needs handling (e.g. a BYOK setup where the managed connect surface isn't available).
55
57
 
56
58
  ### Outlook
57
59
 
58
- 1. **Try connecting directly first.** Run `assistant oauth status outlook`. This will show whether the user has previously connected their Outlook account.
59
- 2. **If no connections are found:** Call `skill_load` with `skill: "vellum-oauth-integrations"`. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.
60
+ 1. **Check the connection.** Run `assistant oauth status outlook`. If a connection exists, the user is ready to go — proceed with their request.
61
+ 2. **If no connections are found, render the connect button in one step:** call `ui_show` with `surface_type: "oauth_connect"` and `data.providerKey: "outlook"`. The same rules as Gmail apply — don't probe further or load a setup skill just to show the button; only load `vellum-oauth-integrations` when a managed-vs-your-own-credentials decision genuinely needs handling.
60
62
 
61
63
  ### Slack
62
64
 
@@ -1,3 +1,4 @@
1
+ import { isArchiveBySenderAuthorized } from "../../../../runtime/effective-capabilities.js";
1
2
  import type {
2
3
  ToolContext,
3
4
  ToolExecutionResult,
@@ -8,14 +9,14 @@ export async function run(
8
9
  input: Record<string, unknown>,
9
10
  context: ToolContext,
10
11
  ): Promise<ToolExecutionResult> {
11
- const userApproved =
12
- input.user_approved === true && context.trustClass === "guardian";
13
- if (
14
- !context.triggeredBySurfaceAction &&
15
- !context.batchAuthorizedByTask &&
16
- !context.approvedViaPrompt &&
17
- !userApproved
18
- ) {
12
+ const authorized = isArchiveBySenderAuthorized({
13
+ trustClass: context.trustClass,
14
+ triggeredBySurfaceAction: context.triggeredBySurfaceAction,
15
+ batchAuthorizedByTask: context.batchAuthorizedByTask,
16
+ approvedViaPrompt: context.approvedViaPrompt,
17
+ userApproved: input.user_approved === true,
18
+ });
19
+ if (!authorized) {
19
20
  return err(
20
21
  "This tool requires either a surface action or a scheduled task run with this tool in required_tools. Present results in a selection table with action buttons and wait for the user to click before proceeding.",
21
22
  );
@@ -1,18 +1,22 @@
1
1
  ---
2
2
  name: workflows
3
- description: Author and run autonomous multi-agent workflows that fan work across parallel leaf agents
3
+ description: Delegate a big or high-stakes job to a fleet of parallel subagents, orchestrated deterministically; runs unattended and reports back
4
4
  compatibility: "Designed for Vellum personal assistants"
5
5
  metadata:
6
6
  emoji: "⚙️"
7
7
  vellum:
8
8
  display-name: "Workflows"
9
9
  category: "system"
10
+ always-candidate: true
10
11
  activation-hints:
11
- - "A task decomposes into many similar sub-tasks that can run concurrently (score every item, extract a field from each of many documents, draft-then-verify a batch)"
12
- - "You want fan-out orchestrated deterministically and the result reported back when the whole run finishes"
12
+ - "Batch apply one operation to each of MANY items (score / rate / rank / classify / extract / summarize each of a large set)"
13
+ - "Comprehensive coverage exhaustively sweep, audit, or find EVERY instance across a large surface"
14
+ - "Research & synthesize — gather across many sources or pages and combine into one answer"
15
+ - "Confidence — generate several independent attempts and judge them, or adversarially verify findings before trusting the result"
16
+ - "Scale — work too large to finish well in one inline pass"
13
17
  avoid-when:
14
- - "The task is a single tool call or a quick lookup do it inline"
15
- - "The work needs interactive, conversational back-and-forth rather than unattended fan-out"
18
+ - "A single inline answer, a quick lookup, or a small one-off"
19
+ - "Interactive, conversational back-and-forth rather than unattended fan-out"
16
20
  ---
17
21
 
18
22
  A workflow is a short JS/TS script you author that runs in a sandbox and fans work
@@ -21,8 +25,11 @@ one with `run_workflow` (inline `script` OR saved `name`, exactly one). It retur
21
25
  `runId` immediately; the run is asynchronous and you are notified in this
22
26
  conversation when it completes — **do NOT poll**.
23
27
 
24
- Reach for one when a task decomposes into many similar small sub-tasks that can run
25
- concurrently. For a single task or a quick lookup, do it inline.
28
+ Reach for one when a job is too big, too parallel, or too important for one inline
29
+ pass. That is more than batch/map-reduce over many items it also covers exhaustively
30
+ sweeping or auditing a large surface, researching across many sources and synthesizing,
31
+ and generating several independent attempts to judge or adversarially verify before
32
+ trusting the result. For a single task or a quick lookup, do it inline.
26
33
 
27
34
  ## The script model
28
35
 
@@ -69,6 +69,9 @@ export const CALL_SITE_DEFAULTS: Record<LLMCallSite, CallSiteDefaultConfig> = {
69
69
  meetConsentMonitor: { profile: "cost-optimized" },
70
70
  meetChatOpportunity: { profile: "cost-optimized" },
71
71
  inference: { profile: "cost-optimized" },
72
+ // The advisor consults the strongest managed profile by default; a workspace
73
+ // overrides this via `llm.advisorProfile` (which floats above this).
74
+ advisor: { profile: "quality-optimized" },
72
75
 
73
76
  heartbeatAgent: {
74
77
  profile: "cost-optimized",
@@ -24,7 +24,10 @@
24
24
  "label": "Pre-chat Onboarding Experiment 2026-06-06",
25
25
  "description": "Pre-chat onboarding experiment with control and variant-a arms. Control shows the full funnel; variant-a shows the condensed pared-down flow.",
26
26
  "defaultEnabled": "control",
27
- "values": ["control", "variant-a"]
27
+ "values": [
28
+ "control",
29
+ "variant-a"
30
+ ]
28
31
  },
29
32
  {
30
33
  "id": "experiment-activation-flow-2026-06-03",
@@ -33,7 +36,11 @@
33
36
  "label": "Activation Flow Experiment 2026-06-03",
34
37
  "description": "Multivariate activation-flow experiment. control = standard flow; variant-a = activation rail; personal-page = new sign-up-page variant (front-end only). Targeted via LaunchDarkly.",
35
38
  "defaultEnabled": "control",
36
- "values": ["control", "variant-a", "personal-page"]
39
+ "values": [
40
+ "control",
41
+ "variant-a",
42
+ "personal-page"
43
+ ]
37
44
  },
38
45
  {
39
46
  "id": "local-docker-enabled",
@@ -51,6 +58,14 @@
51
58
  "description": "Enable the A2A (Agent-to-Agent) channel for inter-assistant communication via the open A2A protocol",
52
59
  "defaultEnabled": false
53
60
  },
61
+ {
62
+ "id": "trace-collection",
63
+ "scope": "assistant",
64
+ "key": "trace-collection",
65
+ "label": "Trace Collection",
66
+ "description": "Gate per-turn conversation trace (user/assistant/tool-call/tool-response) collection. The daemon attaches a trace to its turn telemetry only when this flag AND the owner's share_diagnostics consent are both on. Defaults off (fail-closed) — the live value is delivered from LaunchDarkly.",
67
+ "defaultEnabled": false
68
+ },
54
69
  {
55
70
  "id": "workspace-tools-watcher",
56
71
  "scope": "assistant",
@@ -171,14 +186,6 @@
171
186
  "description": "Enable Anthropic fast mode for Opus models (4.6, 4.7, 4.8), delivering up to 2.5x higher output tokens per second at premium pricing",
172
187
  "defaultEnabled": false
173
188
  },
174
- {
175
- "id": "conversation-groups-ui",
176
- "scope": "assistant",
177
- "key": "conversation-groups-ui",
178
- "label": "Conversation Groups",
179
- "description": "Enable custom conversation group creation, move-to-group, and group management in the sidebar",
180
- "defaultEnabled": false
181
- },
182
189
  {
183
190
  "id": "teleport",
184
191
  "scope": "client",
@@ -387,14 +394,6 @@
387
394
  "description": "When on, runs the new memory-v3 topic-tree retrieval alongside v2 in shadow mode: logs selections to memory_v3_selections, does not modify injected context. Off by default.",
388
395
  "defaultEnabled": false
389
396
  },
390
- {
391
- "id": "memory-v3-live",
392
- "scope": "assistant",
393
- "key": "memory-v3-live",
394
- "label": "Memory v3 Live",
395
- "description": "When on, memory-v3 topic-tree retrieval becomes the live injected memory source (suppressing v2 injection). Off by default; only enable after shadow telemetry validates the design.",
396
- "defaultEnabled": false
397
- },
398
397
  {
399
398
  "id": "self-intro-greeting",
400
399
  "scope": "both",
@@ -402,6 +401,38 @@
402
401
  "label": "Self-intro first message",
403
402
  "description": "On the first conversation, send a natural self-introduction (e.g. \"Hi Vela, I'm alex. Nice to meet you.\") on the user's behalf and route it through real LLM inference, instead of serving the canned first greeting. Names come from the onboarding context; falls back to the canned greeting when no name is known. Exposed to clients so pre-hatch onboarding can compute the source-of-truth initial message, and to the assistant so older clients can still be gated server-side. See assistant/src/daemon/first-greeting.ts (buildSelfIntroMessage).",
404
403
  "defaultEnabled": false
404
+ },
405
+ {
406
+ "id": "research-onboarding",
407
+ "scope": "client",
408
+ "key": "research-onboarding",
409
+ "label": "Research onboarding (spike)",
410
+ "description": "Spike: replace pre-chat onboarding with a web-research \"here's what I know about you\" flow, including a Google Calendar \"Let's chat tomorrow\" step shown over the streaming research. Gates the /assistant/onboarding/research route and the research mock harness. Off by default; enable locally via the feature-flags panel.",
411
+ "defaultEnabled": false
412
+ },
413
+ {
414
+ "id": "channel-trust-floors",
415
+ "scope": "assistant",
416
+ "key": "channel-trust-floors",
417
+ "label": "Channel Trust Floors",
418
+ "description": "Expose the Channel Trust Floors settings card (per-channel inbound admission policy) on the Privacy settings page. When off, the card is hidden and channels fall back to their default admission floors. Off by default while the feature is in development.",
419
+ "defaultEnabled": false
420
+ },
421
+ {
422
+ "id": "mcp-settings",
423
+ "scope": "assistant",
424
+ "key": "mcp-settings",
425
+ "label": "MCP Settings",
426
+ "description": "Show the MCP page in Settings for managing Model Context Protocol server connections: view status, enable/disable, configure, and inspect registered tools per server.",
427
+ "defaultEnabled": false
428
+ },
429
+ {
430
+ "id": "os-beta",
431
+ "scope": "assistant",
432
+ "key": "os-beta",
433
+ "label": "OS Beta",
434
+ "description": "Enable the OS Beta model profile (GLM 5.2 / Fireworks) in the assistant's model profile selection.",
435
+ "defaultEnabled": false
405
436
  }
406
437
  ]
407
438
  }
@@ -366,6 +366,9 @@ function profileConfigFragment(profile: ProfileEntry): Mergeable {
366
366
  // lower-precedence (e.g. active) profile into one that merely inherited it.
367
367
  // `RetryProvider` resolves it from the applied profile, not the merge.
368
368
  logitBias: _logitBias,
369
+ // Per-profile advisor toggle is profile identity, not inheritable model
370
+ // config — strip it so it can't leak into the merged `LLMConfigBase`.
371
+ advisorEnabled: _advisorEnabled,
369
372
  ...config
370
373
  } = profile;
371
374
  return config as Mergeable;
@@ -0,0 +1,11 @@
1
+ import type { AssistantConfig } from "./schema.js";
2
+
3
+ /**
4
+ * Whether memory-v3 is the live injected memory source for this assistant,
5
+ * suppressing v2 injection. Gated by workspace config (`memory.v3.live`): new
6
+ * assistants are switched on at creation via a workspace migration, while
7
+ * existing assistants stay on v2 until the value is set explicitly.
8
+ */
9
+ export function isMemoryV3Live(config: AssistantConfig): boolean {
10
+ return config.memory?.v3?.live === true;
11
+ }
@@ -136,16 +136,18 @@ export const AssistantConfigSchema = z
136
136
  .describe(
137
137
  "Per-plugin configuration keyed by plugin name. Validated downstream by each plugin's manifest.config validator at bootstrap.",
138
138
  ),
139
- collectUsageData: z
139
+ legacyTelemetryOptOut: z
140
140
  .boolean()
141
- .default(true)
141
+ .optional()
142
142
  .describe(
143
- "Whether to collect anonymous usage data to help improve the assistant",
143
+ "Fail-closed telemetry marker: set for a workspace that had an explicit local usage-data opt-out before telemetry moved to platform share_analytics consent. While set, usage telemetry stays disabled regardless of platform consent.",
144
144
  ),
145
- sendDiagnostics: z
145
+ legacyDiagnosticsOptOut: z
146
146
  .boolean()
147
- .default(true)
148
- .describe("Whether to send diagnostic/crash reports"),
147
+ .optional()
148
+ .describe(
149
+ "Fail-closed diagnostics marker: set for a workspace that had an explicit local sendDiagnostics opt-out before crash reporting moved to platform share_diagnostics consent. While set, Sentry stays disabled regardless of platform consent.",
150
+ ),
149
151
  maxStepsPerSession: z
150
152
  .number({ error: "maxStepsPerSession must be a number" })
151
153
  .int("maxStepsPerSession must be an integer")
@@ -6,6 +6,7 @@ describe("MemoryV3ConfigSchema", () => {
6
6
  test("parses an empty object to documented defaults", () => {
7
7
  const parsed = MemoryV3ConfigSchema.parse({});
8
8
  expect(parsed).toEqual({
9
+ live: false,
9
10
  prune: { maxResidentBytes: 393216, targetResidentBytes: 262144 },
10
11
  hotSet: { k: 40, halfLifeDays: 14 },
11
12
  freshSet: { k: 100 },
@@ -300,6 +300,13 @@ const CATALOG_RECORD: CatalogRecord = {
300
300
  description: "General-purpose LLM inference call site for skill use.",
301
301
  domain: "skills",
302
302
  },
303
+ advisor: {
304
+ id: "advisor",
305
+ displayName: "Advisor",
306
+ description:
307
+ "Stronger reviewer model consulted mid-task to shape or pressure-test the plan.",
308
+ domain: "skills",
309
+ },
303
310
  homeGreeting: {
304
311
  id: "homeGreeting",
305
312
  displayName: "Home Greeting",
@@ -136,5 +136,16 @@ export const SlackConfigSchema = z
136
136
  .string({ error: "slack.botUsername must be a string" })
137
137
  .default("")
138
138
  .describe("Slack bot display name"),
139
+ threadMode: z
140
+ .enum(["mention_only", "mention_then_thread"], {
141
+ error:
142
+ "slack.threadMode must be 'mention_only' or 'mention_then_thread'",
143
+ })
144
+ .default("mention_then_thread")
145
+ .describe(
146
+ "Controls whether the bot follows threads after an initial @mention. " +
147
+ "'mention_only' requires every message to @-mention the bot. " +
148
+ "'mention_then_thread' auto-follows the thread after the first mention.",
149
+ ),
139
150
  })
140
151
  .describe("Slack channel configuration");
@@ -23,6 +23,7 @@ export const LLMProvider = z
23
23
  "openrouter",
24
24
  "openai-compatible",
25
25
  "minimax",
26
+ "atlascloud",
26
27
  ])
27
28
  .meta({ id: "LLMProvider" });
28
29
  type LLMProvider = z.infer<typeof LLMProvider>;
@@ -77,6 +78,7 @@ export const LLMCallSiteEnum = z.enum([
77
78
  "meetConsentMonitor",
78
79
  "meetChatOpportunity",
79
80
  "inference",
81
+ "advisor",
80
82
  "trustRuleSuggestion",
81
83
  "homeGreeting",
82
84
  "homeSuggestedPrompts",
@@ -126,6 +128,11 @@ const VerbosityEnum = z.enum(["low", "medium", "high"]);
126
128
  const ModelSchema = z.string().min(1);
127
129
  const MaxTokensSchema = z.number().int().positive();
128
130
  const TemperatureSchema = z.number().min(0).max(2).nullable();
131
+ // `top_p` (nucleus sampling). Range 0–1; `null` = "no opinion — let the
132
+ // provider pick its own default" (matches TemperatureSchema's null
133
+ // semantics). `RetryProvider` renames `topP`→`top_p` and only forwards a
134
+ // non-null value, so providers never receive `top_p: null`.
135
+ const TopPSchema = z.number().min(0).max(1).nullable();
129
136
  // Named, code-resolved logit-bias preset a profile may opt into. The value is a
130
137
  // preset *name*, not an inline token→bias map, so the workspace config stays
131
138
  // small. This is profile-identity metadata, not inheritable config: the resolver
@@ -326,6 +333,7 @@ export const LLMConfigBase = z.object({
326
333
  speed: SpeedEnum.default("standard"),
327
334
  verbosity: VerbosityEnum.default("medium"),
328
335
  temperature: TemperatureSchema.default(null),
336
+ topP: TopPSchema.default(null),
329
337
  thinking: ThinkingSchema.default(ThinkingSchema.parse({})),
330
338
  contextWindow: ContextWindowSchema.default(ContextWindowSchema.parse({})),
331
339
  openrouter: OpenRouterSchema.default(OpenRouterSchema.parse({})),
@@ -361,6 +369,7 @@ export const LLMConfigFragment = z
361
369
  speed: SpeedEnum.optional(),
362
370
  verbosity: VerbosityEnum.optional(),
363
371
  temperature: TemperatureSchema.optional(),
372
+ topP: TopPSchema.optional(),
364
373
  thinking: ThinkingFragmentSchema.optional(),
365
374
  contextWindow: ContextWindowDeepPartialSchema.optional(),
366
375
  openrouter: OpenRouterDeepPartialSchema.optional(),
@@ -431,6 +440,13 @@ export const ProfileEntry = LLMConfigFragment.extend({
431
440
  * #30362 even though the schema didn't accept it until now.
432
441
  */
433
442
  status: ProfileStatusSchema.nullable().optional(),
443
+ /**
444
+ * Whether the advisor is active while this profile is the chat profile.
445
+ * Absent/null means enabled (default on); only an explicit `false` disables
446
+ * it. `.nullable()` matches `status`/`label` so the PUT route's "send null
447
+ * to clear" sentinel resets it back to the default-on state.
448
+ */
449
+ advisorEnabled: z.boolean().nullable().optional(),
434
450
  /**
435
451
  * When present, this profile is a "mix": it carries no model config and
436
452
  * instead references a weighted list of standard profiles. The resolver
@@ -474,6 +490,11 @@ export const LLMSchema = z
474
490
  // schema level, so `LLMSchema.parse({})` yields an empty map.
475
491
  callSites: z.partialRecord(LLMCallSiteEnum, LLMCallSiteConfig).default({}),
476
492
  activeProfile: z.string().min(1).optional(),
493
+ // The profile the advisor consults (chosen under Models & Services). It is
494
+ // excluded from the chat-profile pickers so it can't be selected as the
495
+ // assistant's chat model. Absent falls back to the `advisor` call-site
496
+ // default (`quality-optimized`).
497
+ advisorProfile: z.string().min(1).optional(),
477
498
  // TTL bounds for inference profile sessions. `defaultTtlSeconds` is read by
478
499
  // the CLI to apply when `--ttl` is omitted; the daemon handler itself only
479
500
  // reads `maxTtlSeconds` (to clamp caller-supplied values).
@@ -507,6 +528,16 @@ export const LLMSchema = z
507
528
  message: `Profile "${config.activeProfile}" referenced by llm.activeProfile is not defined in llm.profiles`,
508
529
  });
509
530
  }
531
+ if (
532
+ config.advisorProfile != null &&
533
+ !profileNames.has(config.advisorProfile)
534
+ ) {
535
+ ctx.addIssue({
536
+ code: "custom",
537
+ path: ["advisorProfile"],
538
+ message: `Profile "${config.advisorProfile}" referenced by llm.advisorProfile is not defined in llm.profiles`,
539
+ });
540
+ }
510
541
 
511
542
  // --- Mix profile validation --------------------------------------------
512
543
  // Config keys a mix profile must NOT also set (a mix only references other
@@ -133,13 +133,9 @@ export const MemoryCleanupConfigSchema = z
133
133
  .nonnegative(
134
134
  "memory.cleanup.llmRequestLogRetentionMs must be non-negative",
135
135
  )
136
- // Upper bound must match gateway MAX_LLM_REQUEST_LOG_RETENTION_MS in
137
- // gateway/src/http/routes/privacy-config.ts. If a manually edited
138
- // config.json sets a value larger than this, the gateway GET would
139
- // return it and the macOS picker would snap it to its largest known
140
- // option, and the next PATCH would silently truncate the value —
141
- // causing quiet data loss. Enforcing the same cap here prevents the
142
- // daemon from accepting out-of-range values in the first place.
136
+ // Cap retention at 365 days. Enforced daemon-side only: the cleanup jobs
137
+ // honor this bound, so a manually edited config.json with a larger value
138
+ // is rejected here rather than silently retained.
143
139
  .max(
144
140
  365 * 24 * 60 * 60 * 1000,
145
141
  "memory.cleanup.llmRequestLogRetentionMs must be <= 365 days in ms",
@@ -220,6 +220,12 @@ export const MemoryV3PruneSchema = z
220
220
  // so legacy configs keep parsing. Do not make this object `.strict()`.
221
221
  export const MemoryV3ConfigSchema = z
222
222
  .object({
223
+ live: z
224
+ .boolean({ error: "memory.v3.live must be a boolean" })
225
+ .default(false)
226
+ .describe(
227
+ "Whether memory-v3 is the live injected memory source, suppressing v2 injection. Off by default; brand-new assistants are switched on at creation via a workspace migration, while existing assistants stay on v2 until explicitly enabled.",
228
+ ),
223
229
  prune: MemoryV3PruneSchema.default(MemoryV3PruneSchema.parse({})),
224
230
  hotSet: MemoryV3HotSetSchema.default(MemoryV3HotSetSchema.parse({})),
225
231
  freshSet: MemoryV3FreshSetSchema.default(MemoryV3FreshSetSchema.parse({})),
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  import { DEFAULT_IMAGE_MODEL } from "../../media/image-models.js";
4
+ import { FETCH_PROVIDER_IDS } from "../../providers/fetch-provider-catalog.js";
4
5
  import { SEARCH_PROVIDER_IDS } from "../../providers/search-provider-catalog.js";
5
6
  import { SttServiceSchema } from "./stt.js";
6
7
  import { TtsServiceSchema } from "./tts.js";
@@ -28,6 +29,13 @@ const VALID_IMAGE_GEN_PROVIDERS = ["gemini", "openai"] as const;
28
29
  */
29
30
  const VALID_WEB_SEARCH_PROVIDERS = SEARCH_PROVIDER_IDS;
30
31
 
32
+ /**
33
+ * Derived from `FETCH_PROVIDER_CATALOG`. Adding a new web-fetch provider
34
+ * to the catalog automatically extends the config-schema enum — no edit
35
+ * here required.
36
+ */
37
+ const VALID_WEB_FETCH_PROVIDERS = FETCH_PROVIDER_IDS;
38
+
31
39
  const BaseServiceSchema = z.object({
32
40
  mode: ServiceModeSchema.default("your-own"),
33
41
  });
@@ -58,6 +66,15 @@ const WebSearchServiceSchema = BaseServiceSchema.extend({
58
66
  .default("inference-provider-native"),
59
67
  });
60
68
 
69
+ const WebFetchServiceSchema = BaseServiceSchema.extend({
70
+ // Provider that backs the `web_fetch` tool. `default` is the daemon's
71
+ // built-in HTTP fetch + extract path (no key). BYOK providers (e.g.
72
+ // `firecrawl`) scrape via their hosted API and reuse the same stored key as
73
+ // their web-search counterpart. The `mode` field is inherited from
74
+ // `BaseServiceSchema` for symmetry; web-fetch has no managed proxy today.
75
+ provider: z.enum(VALID_WEB_FETCH_PROVIDERS).default("default"),
76
+ });
77
+
61
78
  const GoogleOAuthServiceSchema = BaseServiceSchema.extend({
62
79
  mode: ServiceModeSchema.default("managed"),
63
80
  });
@@ -142,6 +159,7 @@ export const ServicesSchema = z.object({
142
159
  "web-search": WebSearchServiceSchema.default(
143
160
  WebSearchServiceSchema.parse({}),
144
161
  ),
162
+ "web-fetch": WebFetchServiceSchema.default(WebFetchServiceSchema.parse({})),
145
163
  stt: SttServiceSchema.default({
146
164
  mode: "your-own" as const,
147
165
  provider: "deepgram" as const,