@vellumai/assistant 0.9.0 → 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 (572) hide show
  1. package/ARCHITECTURE.md +18 -34
  2. package/bun.lock +7 -8
  3. package/docs/activation-funnel-telemetry.md +28 -22
  4. package/docs/architecture/security.md +29 -28
  5. package/docs/stt-provider-onboarding.md +3 -5
  6. package/docs/workflows-testing.md +13 -44
  7. package/docs/workflows.md +3 -5
  8. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
  9. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
  10. package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
  11. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
  12. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  13. package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
  14. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
  15. package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
  16. package/openapi.yaml +976 -63
  17. package/package.json +2 -1
  18. package/scripts/sync-llm-catalog.ts +6 -15
  19. package/scripts/sync-web-search-catalog.ts +3 -11
  20. package/src/__tests__/access-request-card-view.test.ts +98 -0
  21. package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
  22. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
  23. package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
  24. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
  25. package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
  26. package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
  27. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
  28. package/src/__tests__/app-compiler.test.ts +15 -1
  29. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  30. package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
  31. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  32. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  33. package/src/__tests__/avatar-identity-sync.test.ts +2 -27
  34. package/src/__tests__/btw-routes.test.ts +6 -8
  35. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  36. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  37. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  38. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  39. package/src/__tests__/checker.test.ts +0 -3
  40. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  41. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  42. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  43. package/src/__tests__/config-loader-backfill.test.ts +268 -27
  44. package/src/__tests__/config-schema.test.ts +35 -0
  45. package/src/__tests__/config-watcher.test.ts +0 -18
  46. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  47. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  48. package/src/__tests__/contacts-tools.test.ts +29 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  51. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  52. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  53. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  54. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  55. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  56. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  57. package/src/__tests__/conversation-title-service.test.ts +62 -0
  58. package/src/__tests__/credential-broker.test.ts +449 -1
  59. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  60. package/src/__tests__/credential-execution-tools.test.ts +0 -1
  61. package/src/__tests__/credential-prompt-route.test.ts +4 -4
  62. package/src/__tests__/credential-routes.test.ts +360 -0
  63. package/src/__tests__/credential-security-invariants.test.ts +4 -13
  64. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  65. package/src/__tests__/disk-usage.test.ts +65 -0
  66. package/src/__tests__/dynamic-page-surface.test.ts +152 -1
  67. package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
  68. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  69. package/src/__tests__/gateway-only-guard.test.ts +3 -7
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  71. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  72. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  73. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  74. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  75. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  76. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  77. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  78. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  79. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  80. package/src/__tests__/identity-routes.test.ts +0 -189
  81. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  82. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  83. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  84. package/src/__tests__/invite-redemption-service.test.ts +4 -7
  85. package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
  86. package/src/__tests__/llm-catalog-parity.test.ts +30 -23
  87. package/src/__tests__/llm-resolver.test.ts +70 -24
  88. package/src/__tests__/llm-schema.test.ts +1 -0
  89. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  90. package/src/__tests__/mcp-health-check.test.ts +6 -7
  91. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  92. package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
  93. package/src/__tests__/onboarding-persona-write.test.ts +1 -1
  94. package/src/__tests__/path-policy.test.ts +34 -0
  95. package/src/__tests__/persona-resolver.test.ts +49 -14
  96. package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
  97. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  98. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  99. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  100. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  101. package/src/__tests__/reaction-persistence.test.ts +150 -29
  102. package/src/__tests__/registry.test.ts +2 -7
  103. package/src/__tests__/relay-server.test.ts +285 -0
  104. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  105. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
  106. package/src/__tests__/schedule-routes.test.ts +0 -30
  107. package/src/__tests__/schedule-tools.test.ts +2 -18
  108. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  109. package/src/__tests__/skill-execute-input.test.ts +51 -1
  110. package/src/__tests__/skill-runtime-path.test.ts +2 -3
  111. package/src/__tests__/skills.test.ts +51 -0
  112. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  113. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  114. package/src/__tests__/subagent-tools.test.ts +266 -0
  115. package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
  116. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  117. package/src/__tests__/title-generate-hook.test.ts +100 -3
  118. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
  119. package/src/__tests__/token-manager.test.ts +519 -0
  120. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  121. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  122. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  123. package/src/__tests__/tool-executor.test.ts +0 -79
  124. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  125. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  126. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  127. package/src/__tests__/trusted-contact-verification.test.ts +8 -10
  128. package/src/__tests__/twilio-routes.test.ts +81 -1
  129. package/src/__tests__/voice-invite-redemption.test.ts +2 -3
  130. package/src/__tests__/weak-open-model.test.ts +30 -0
  131. package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
  132. package/src/__tests__/workspace-greetings.test.ts +152 -0
  133. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  134. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  136. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  137. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  138. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  139. package/src/agent/loop.ts +49 -29
  140. package/src/api/README.md +6 -6
  141. package/src/api/events/tool-result.ts +6 -0
  142. package/src/api/events/workflow-completed.ts +53 -0
  143. package/src/api/events/workflow-leaf-finished.ts +38 -0
  144. package/src/api/events/workflow-leaf-started.ts +35 -0
  145. package/src/api/events/workflow-progress.ts +32 -0
  146. package/src/api/events/workflow-started.ts +31 -0
  147. package/src/api/index.ts +40 -0
  148. package/src/api/responses/conversation-message.ts +28 -4
  149. package/src/api/responses/home.ts +26 -4
  150. package/src/api/responses/workflow-journal.ts +53 -0
  151. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  152. package/src/approvals/guardian-decision-primitive.ts +26 -3
  153. package/src/approvals/guardian-request-resolvers.ts +183 -80
  154. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  155. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  156. package/src/calls/call-pointer-messages.ts +10 -4
  157. package/src/calls/channel-admission-reader.ts +104 -0
  158. package/src/calls/guardian-dispatch.ts +17 -45
  159. package/src/calls/media-stream-server.ts +84 -2
  160. package/src/calls/relay-access-wait.ts +1 -1
  161. package/src/calls/relay-server.ts +66 -0
  162. package/src/calls/relay-setup-router.ts +82 -1
  163. package/src/calls/twilio-routes.ts +17 -8
  164. package/src/calls/voice-session-bridge.ts +2 -2
  165. package/src/cli/commands/clients.ts +3 -0
  166. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  167. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  168. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  169. package/src/cli/commands/memory/index.ts +30 -0
  170. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  171. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  172. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  173. package/src/cli/commands/oauth/status.test.ts +36 -0
  174. package/src/cli/commands/oauth/status.ts +23 -3
  175. package/src/cli/commands/plugins.ts +197 -4
  176. package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
  177. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  178. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
  179. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  180. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
  181. package/src/cli/lib/diff-plugin.ts +346 -0
  182. package/src/cli/lib/inspect-plugin.ts +12 -1
  183. package/src/cli/lib/install-from-github.ts +105 -17
  184. package/src/cli/lib/merge-plugin-tree.ts +328 -0
  185. package/src/cli/lib/plugin-fingerprint.ts +14 -0
  186. package/src/cli/lib/plugin-surfaces.ts +104 -0
  187. package/src/cli/lib/upgrade-plugin.ts +298 -10
  188. package/src/cli/program.ts +2 -6
  189. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  190. package/src/config/assistant-feature-flags.ts +22 -7
  191. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  192. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  193. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  194. package/src/config/bundled-skills/subagent/SKILL.md +4 -0
  195. package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
  196. package/src/config/bundled-skills/workflows/SKILL.md +14 -8
  197. package/src/config/bundled-tool-registry.ts +2 -7
  198. package/src/config/call-site-defaults.ts +15 -2
  199. package/src/config/feature-flag-registry.json +46 -31
  200. package/src/config/inference-profile-validation.ts +26 -0
  201. package/src/config/llm-resolver.ts +3 -0
  202. package/src/config/loader.ts +4 -0
  203. package/src/config/memory-v3-gate.ts +11 -0
  204. package/src/config/profile-order.ts +28 -0
  205. package/src/config/schema.ts +8 -6
  206. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  207. package/src/config/schemas/call-site-catalog.ts +7 -0
  208. package/src/config/schemas/channels.ts +11 -0
  209. package/src/config/schemas/elevenlabs.ts +0 -1
  210. package/src/config/schemas/llm.ts +31 -0
  211. package/src/config/schemas/memory-lifecycle.ts +3 -7
  212. package/src/config/schemas/memory-v3.ts +6 -0
  213. package/src/config/schemas/platform.ts +0 -8
  214. package/src/config/schemas/services.ts +18 -0
  215. package/src/config/seed-inference-profiles.ts +109 -44
  216. package/src/config/skills.ts +21 -0
  217. package/src/config/sync-gated-profiles.ts +220 -0
  218. package/src/contacts/contact-store.ts +89 -106
  219. package/src/contacts/contacts-write.ts +5 -22
  220. package/src/contacts/types.ts +0 -1
  221. package/src/context/compactor.ts +88 -54
  222. package/src/context/strip-injections.ts +58 -10
  223. package/src/context/token-estimator.ts +1 -1
  224. package/src/credential-execution/process-manager.ts +55 -14
  225. package/src/credential-execution/prompted-credential.ts +2 -3
  226. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  227. package/src/daemon/config-watcher.ts +0 -4
  228. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  229. package/src/daemon/conversation-agent-loop.ts +114 -22
  230. package/src/daemon/conversation-history.ts +1 -1
  231. package/src/daemon/conversation-lifecycle.ts +3 -5
  232. package/src/daemon/conversation-process.ts +13 -5
  233. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  234. package/src/daemon/conversation-slash.ts +2 -23
  235. package/src/daemon/conversation-surfaces.ts +26 -0
  236. package/src/daemon/conversation-tool-setup.ts +27 -14
  237. package/src/daemon/conversation.ts +66 -14
  238. package/src/daemon/disk-pressure-policy.ts +5 -3
  239. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  240. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  241. package/src/daemon/handlers/config-a2a.ts +0 -2
  242. package/src/daemon/handlers/config-channels.ts +15 -16
  243. package/src/daemon/handlers/config-slack-channel.ts +22 -3
  244. package/src/daemon/handlers/conversations.ts +107 -0
  245. package/src/daemon/host-browser-proxy.ts +41 -0
  246. package/src/daemon/lifecycle.ts +55 -27
  247. package/src/daemon/message-provenance.ts +2 -0
  248. package/src/daemon/message-types/contacts.ts +0 -1
  249. package/src/daemon/message-types/conversations.ts +3 -3
  250. package/src/daemon/message-types/sync.ts +0 -1
  251. package/src/daemon/message-types/web-activity.ts +7 -1
  252. package/src/daemon/message-types/workflows.ts +83 -1
  253. package/src/daemon/orphan-reaper.test.ts +0 -19
  254. package/src/daemon/orphan-reaper.ts +2 -24
  255. package/src/daemon/server.ts +0 -10
  256. package/src/daemon/tool-setup-types.ts +4 -0
  257. package/src/daemon/trust-context.ts +1 -1
  258. package/src/events/tool-audit-listener.ts +2 -2
  259. package/src/home/feed-source-enrichment.test.ts +151 -0
  260. package/src/home/feed-source-enrichment.ts +176 -0
  261. package/src/home/relationship-state.ts +2 -4
  262. package/src/instrument.ts +18 -6
  263. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  264. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  265. package/src/ipc/assistant-server.ts +37 -4
  266. package/src/ipc/gateway-flag-listener.ts +18 -2
  267. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  268. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  269. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  270. package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
  271. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  272. package/src/memory/auth-fallback-events-store.ts +2 -2
  273. package/src/memory/auto-analysis-enqueue.ts +3 -5
  274. package/src/memory/bookmark-crud.ts +1 -2
  275. package/src/memory/canonical-guardian-store.ts +39 -1
  276. package/src/memory/conversation-crud.ts +9 -4
  277. package/src/memory/conversation-key-store.ts +17 -2
  278. package/src/memory/conversation-title-service.ts +64 -7
  279. package/src/memory/db-init.ts +17 -17
  280. package/src/memory/embedding-backend.ts +38 -1
  281. package/src/memory/embedding-billing-breaker.ts +96 -0
  282. package/src/memory/jobs-store.ts +25 -13
  283. package/src/memory/jobs-worker.ts +54 -1
  284. package/src/memory/lifecycle-events-store.ts +2 -2
  285. package/src/memory/memory-retrospective-constants.ts +4 -4
  286. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  287. package/src/memory/memory-retrospective-job.ts +28 -227
  288. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  289. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  290. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  291. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
  292. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  293. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  294. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  295. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  296. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  297. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  298. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  299. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  300. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  301. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
  302. package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
  303. package/src/memory/migrations/index.ts +6 -0
  304. package/src/memory/migrations/run-migrations.ts +41 -0
  305. package/src/memory/migrations/validate-migration-state.ts +1 -1
  306. package/src/memory/onboarding-events-store.ts +3 -3
  307. package/src/memory/schema/contacts.ts +0 -5
  308. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  309. package/src/memory/skill-loaded-events-store.ts +2 -2
  310. package/src/memory/tool-executed-events-store.test.ts +7 -7
  311. package/src/memory/turn-trace-store.test.ts +736 -0
  312. package/src/memory/turn-trace-store.ts +364 -0
  313. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  314. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  315. package/src/memory/v2/consolidation-job.ts +2 -2
  316. package/src/memory/v2/skill-content.ts +25 -7
  317. package/src/memory/v2/skill-store.ts +7 -1
  318. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  319. package/src/memory/v3-eval/eval-packets.ts +546 -0
  320. package/src/messaging/providers/slack/adapter.ts +1 -1
  321. package/src/messaging/providers/slack/api.ts +31 -0
  322. package/src/messaging/providers/slack/send.test.ts +114 -2
  323. package/src/messaging/providers/slack/send.ts +30 -7
  324. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  325. package/src/messaging/providers/slack/withdraw.ts +161 -0
  326. package/src/notifications/AGENTS.md +2 -0
  327. package/src/notifications/access-request-copy.ts +72 -59
  328. package/src/notifications/adapters/shared.ts +29 -0
  329. package/src/notifications/adapters/slack.ts +58 -103
  330. package/src/notifications/adapters/telegram.ts +2 -20
  331. package/src/notifications/approval-card-data.ts +333 -0
  332. package/src/notifications/broadcaster.ts +16 -3
  333. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  334. package/src/notifications/copy-composer.ts +3 -3
  335. package/src/notifications/decision-engine.ts +4 -2
  336. package/src/notifications/destination-resolver.ts +4 -6
  337. package/src/notifications/guardian-question-mode.ts +10 -0
  338. package/src/notifications/home-feed-side-effect.ts +7 -16
  339. package/src/notifications/notification-utils.ts +19 -20
  340. package/src/notifications/signal.ts +79 -43
  341. package/src/notifications/types.ts +98 -121
  342. package/src/oauth/AGENTS.md +5 -24
  343. package/src/permissions/checker.test.ts +51 -0
  344. package/src/permissions/checker.ts +185 -26
  345. package/src/permissions/ipc-risk-types.ts +24 -0
  346. package/src/permissions/question-prompter.test.ts +27 -0
  347. package/src/permissions/question-prompter.ts +4 -0
  348. package/src/platform/client.test.ts +119 -0
  349. package/src/platform/client.ts +66 -0
  350. package/src/platform/consent-cache.test.ts +267 -0
  351. package/src/platform/consent-cache.ts +174 -0
  352. package/src/plugin-api/constants.ts +1 -1
  353. package/src/plugin-api/index.ts +33 -1
  354. package/src/plugin-api/model-profiles.ts +33 -0
  355. package/src/plugin-api/types.ts +50 -2
  356. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  357. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  358. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  359. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  360. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  361. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  362. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  363. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  364. package/src/plugins/defaults/advisor/config.ts +21 -0
  365. package/src/plugins/defaults/advisor/consult.ts +93 -0
  366. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  367. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  368. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  369. package/src/plugins/defaults/advisor/package.json +14 -0
  370. package/src/plugins/defaults/advisor/steering.ts +67 -0
  371. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  372. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  373. package/src/plugins/defaults/index.ts +60 -0
  374. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  375. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  376. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  377. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  378. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  379. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  380. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
  381. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  382. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  383. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  384. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  385. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
  386. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  387. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  388. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  389. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
  390. package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
  391. package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
  392. package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
  393. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
  394. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  395. package/src/prompts/persona-resolver.ts +14 -4
  396. package/src/prompts/templates/system-sections.ts +7 -2
  397. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  398. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  399. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  400. package/src/providers/atlascloud/client.ts +85 -0
  401. package/src/providers/fetch-provider-catalog.ts +85 -0
  402. package/src/providers/inference/adapter-factory.ts +3 -0
  403. package/src/providers/model-catalog.ts +58 -0
  404. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  405. package/src/providers/openai/chat-completions-provider.ts +7 -0
  406. package/src/providers/openai/responses-provider.ts +10 -0
  407. package/src/providers/provider-send-message.ts +11 -3
  408. package/src/providers/retry.ts +53 -12
  409. package/src/providers/search-provider-catalog.ts +10 -0
  410. package/src/providers/weak-open-model.ts +22 -0
  411. package/src/runtime/AGENTS.md +0 -1
  412. package/src/runtime/__tests__/agent-wake.test.ts +181 -0
  413. package/src/runtime/__tests__/client-health.test.ts +44 -0
  414. package/src/runtime/access-request-helper.ts +21 -53
  415. package/src/runtime/actor-trust-resolver.ts +59 -63
  416. package/src/runtime/agent-wake.ts +52 -0
  417. package/src/runtime/assistant-event-hub.ts +18 -4
  418. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  419. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  420. package/src/runtime/btw-sidechain.ts +3 -6
  421. package/src/runtime/capabilities.test.ts +120 -0
  422. package/src/runtime/capabilities.ts +197 -0
  423. package/src/runtime/channel-approval-types.ts +22 -45
  424. package/src/runtime/channel-invite-transports/telegram.ts +4 -4
  425. package/src/runtime/channel-retry-sweep.ts +1 -0
  426. package/src/runtime/channel-verification-service.ts +3 -3
  427. package/src/runtime/client-health.ts +26 -0
  428. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  429. package/src/runtime/effective-capabilities.test.ts +128 -0
  430. package/src/runtime/effective-capabilities.ts +84 -0
  431. package/src/runtime/guardian-reply-router.ts +106 -21
  432. package/src/runtime/invite-redemption-service.ts +9 -25
  433. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
  434. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  435. package/src/runtime/pending-interactions.ts +15 -0
  436. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  437. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  438. package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
  439. package/src/runtime/routes/app-routes.ts +1 -1
  440. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
  441. package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
  442. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  443. package/src/runtime/routes/btw-routes.ts +1 -27
  444. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  445. package/src/runtime/routes/client-routes.ts +10 -0
  446. package/src/runtime/routes/contact-routes.ts +31 -8
  447. package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
  448. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  449. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  450. package/src/runtime/routes/conversation-routes.ts +39 -14
  451. package/src/runtime/routes/credential-routes.ts +40 -16
  452. package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
  453. package/src/runtime/routes/events-routes.ts +1 -3
  454. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  455. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  456. package/src/runtime/routes/home-feed-routes.ts +8 -3
  457. package/src/runtime/routes/identity-routes.ts +1 -296
  458. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  459. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
  460. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  461. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  462. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  463. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  464. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  465. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  466. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  467. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  468. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  469. package/src/runtime/routes/index.ts +2 -0
  470. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  471. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  472. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  473. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  474. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  475. package/src/runtime/routes/notification-routes.ts +122 -133
  476. package/src/runtime/routes/platform-routes.ts +2 -2
  477. package/src/runtime/routes/plugins-routes.ts +202 -3
  478. package/src/runtime/routes/schedule-routes.ts +0 -22
  479. package/src/runtime/routes/secret-routes.ts +10 -0
  480. package/src/runtime/routes/surface-action-routes.ts +2 -1
  481. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  482. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  483. package/src/runtime/routes/workflow-routes.test.ts +229 -44
  484. package/src/runtime/routes/workflow-routes.ts +131 -29
  485. package/src/runtime/routes/workspace-greetings.ts +55 -0
  486. package/src/runtime/sync/resource-sync-events.ts +1 -11
  487. package/src/runtime/tool-grant-request-helper.ts +18 -16
  488. package/src/runtime/trust-context-resolver.ts +8 -5
  489. package/src/schedule/inference-profile.ts +2 -14
  490. package/src/schedule/schedule-store.ts +1 -1
  491. package/src/schedule/scheduler-types.ts +5 -1
  492. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  493. package/src/security/secret-patterns.ts +3 -0
  494. package/src/subagent/manager.ts +17 -4
  495. package/src/subagent/types.ts +6 -0
  496. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  497. package/src/telemetry/trace-collection-policy.ts +30 -0
  498. package/src/telemetry/types.ts +89 -0
  499. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  500. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  501. package/src/tools/AGENTS.md +3 -3
  502. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  503. package/src/tools/browser/browser-execution.ts +30 -19
  504. package/src/tools/document/document-tool.ts +2 -3
  505. package/src/tools/executor.ts +5 -3
  506. package/src/tools/host-terminal/host-shell.ts +5 -4
  507. package/src/tools/memory/register.ts +2 -2
  508. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  509. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  510. package/src/tools/network/web-fetch.ts +372 -1
  511. package/src/tools/network/web-search-error.ts +1 -1
  512. package/src/tools/network/web-search.ts +213 -10
  513. package/src/tools/permission-checker.ts +4 -3
  514. package/src/tools/registry.ts +20 -0
  515. package/src/tools/schedule/create.ts +7 -12
  516. package/src/tools/schedule/update.ts +4 -11
  517. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  518. package/src/tools/side-effects.ts +2 -17
  519. package/src/tools/skills/execute.ts +33 -0
  520. package/src/tools/subagent/spawn.ts +61 -12
  521. package/src/tools/terminal/shell.ts +10 -4
  522. package/src/tools/tool-approval-handler.ts +18 -13
  523. package/src/tools/tool-manifest.ts +0 -2
  524. package/src/tools/types.ts +9 -0
  525. package/src/tools/ui-surface/definitions.ts +64 -3
  526. package/src/tools/verification-control-plane-policy.ts +3 -1
  527. package/src/tools/workflows/run-workflow.test.ts +8 -18
  528. package/src/tools/workflows/run-workflow.ts +1 -0
  529. package/src/util/disk-usage.ts +78 -23
  530. package/src/util/platform.ts +10 -3
  531. package/src/watcher/telemetry.ts +2 -2
  532. package/src/workflows/capabilities.ts +2 -3
  533. package/src/workflows/engine.test.ts +175 -1
  534. package/src/workflows/engine.ts +82 -0
  535. package/src/workflows/journal-store.test.ts +70 -0
  536. package/src/workflows/journal-store.ts +18 -3
  537. package/src/workflows/run-manager.test.ts +171 -28
  538. package/src/workflows/run-manager.ts +66 -24
  539. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  540. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  541. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  542. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  543. package/src/workspace/migrations/registry.ts +8 -0
  544. package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
  545. package/src/__tests__/credential-security-e2e.test.ts +0 -362
  546. package/src/__tests__/credential-vault-unit.test.ts +0 -1528
  547. package/src/__tests__/credential-vault.test.ts +0 -1706
  548. package/src/__tests__/identity-intro-cache.test.ts +0 -315
  549. package/src/__tests__/secret-onetime-send.test.ts +0 -182
  550. package/src/cli/commands/__tests__/task.test.ts +0 -914
  551. package/src/cli/commands/task.ts +0 -771
  552. package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
  553. package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
  554. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
  555. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
  556. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
  557. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
  558. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
  559. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
  560. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
  561. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
  562. package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
  563. package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
  564. package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
  565. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
  566. package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
  567. package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
  568. package/src/memory/preloaded-apps.ts +0 -116
  569. package/src/notifications/tool-approval-copy.ts +0 -142
  570. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
  571. package/src/runtime/routes/identity-intro-cache.ts +0 -172
  572. package/src/tools/credentials/vault.ts +0 -712
@@ -29,17 +29,7 @@ export function publishIdentityChanged(
29
29
  emoji: fields.emoji,
30
30
  home: fields.home,
31
31
  });
32
- void publishSyncInvalidation(
33
- [SYNC_TAGS.assistantIdentity, SYNC_TAGS.assistantIdentityIntro],
34
- originClientId,
35
- );
36
- }
37
-
38
- export function publishIdentityIntroChanged(originClientId?: string): void {
39
- void publishSyncInvalidation(
40
- [SYNC_TAGS.assistantIdentityIntro],
41
- originClientId,
42
- );
32
+ void publishSyncInvalidation([SYNC_TAGS.assistantIdentity], originClientId);
43
33
  }
44
34
 
45
35
  export function publishConfigChanged(originClientId?: string): void {
@@ -13,12 +13,14 @@
13
13
 
14
14
  import type { ChannelId } from "../channels/types.js";
15
15
  import {
16
- createCanonicalGuardianDelivery,
17
16
  createCanonicalGuardianRequest,
18
17
  listCanonicalGuardianRequests,
19
18
  } from "../memory/canonical-guardian-store.js";
19
+ import {
20
+ recordApprovalCardDelivery,
21
+ recordGuardianRequestDeliveries,
22
+ } from "../notifications/canonical-delivery-recorder.js";
20
23
  import { emitNotificationSignal } from "../notifications/emit-signal.js";
21
- import type { NotificationSourceChannel } from "../notifications/signal.js";
22
24
  import { getLogger } from "../util/logger.js";
23
25
  import { getGuardianBinding } from "./channel-verification-service.js";
24
26
  import { GUARDIAN_APPROVAL_TTL_MS } from "./routes/channel-route-shared.js";
@@ -140,12 +142,16 @@ export function createOrReuseToolGrantRequest(
140
142
  canonicalRequest.requestCode ??
141
143
  canonicalRequest.id.slice(0, 6).toUpperCase();
142
144
 
145
+ // The vellum delivery row is created up front in onConversationCreated so the
146
+ // in-app client sees it immediately; the post-resolve recorder reuses it.
147
+ let vellumDeliveryId: string | undefined;
148
+
143
149
  // Emit notification so guardian is alerted. Uses 'guardian.question' as
144
150
  // sourceEventName so that existing request-code guidance in the notification
145
151
  // pipeline is preserved.
146
152
  const signalPromise = emitNotificationSignal({
147
153
  sourceEventName: "guardian.question",
148
- sourceChannel: sourceChannel as NotificationSourceChannel,
154
+ sourceChannel,
149
155
  sourceContextId: conversationId,
150
156
  requiresConversation: true,
151
157
  attentionHints: {
@@ -167,25 +173,21 @@ export function createOrReuseToolGrantRequest(
167
173
  },
168
174
  dedupeKey: `tool-grant-request:${canonicalRequest.id}`,
169
175
  onConversationCreated: (info) => {
170
- createCanonicalGuardianDelivery({
176
+ vellumDeliveryId = recordApprovalCardDelivery({
171
177
  requestId: canonicalRequest.id,
172
- destinationChannel: "vellum",
173
- destinationConversationId: info.conversationId,
174
- });
178
+ channel: "vellum",
179
+ conversationId: info.conversationId,
180
+ })?.id;
175
181
  },
176
182
  });
177
183
 
178
184
  // Record deliveries from the notification pipeline results (fire-and-forget).
179
185
  void signalPromise.then((signalResult) => {
180
- for (const result of signalResult.deliveryResults) {
181
- if (result.channel === "vellum") continue; // handled in onConversationCreated
182
- createCanonicalGuardianDelivery({
183
- requestId: canonicalRequest.id,
184
- destinationChannel: result.channel,
185
- destinationChatId:
186
- result.destination.length > 0 ? result.destination : undefined,
187
- });
188
- }
186
+ recordGuardianRequestDeliveries({
187
+ requestId: canonicalRequest.id,
188
+ deliveryResults: signalResult.deliveryResults,
189
+ vellumDeliveryId,
190
+ });
189
191
  });
190
192
 
191
193
  log.info(
@@ -16,6 +16,7 @@ import {
16
16
  type ResolveActorTrustInput,
17
17
  toTrustContext,
18
18
  } from "./actor-trust-resolver.js";
19
+ import { resolveCapabilities } from "./capabilities.js";
19
20
 
20
21
  /**
21
22
  * Resolve route-level trust context from canonical identity state.
@@ -64,14 +65,15 @@ export interface RoutingState {
64
65
  * Compute the routing state for a channel actor turn.
65
66
  *
66
67
  * Guardian actors are always interactive (they self-approve).
67
- * Trusted contacts are only interactive when a guardian binding exists
68
- * to receive approval notifications. Unknown actors are never interactive.
68
+ * Trusted and unverified contacts are only interactive when a guardian
69
+ * binding exists to receive approval notifications. Unknown actors are
70
+ * never interactive.
69
71
  */
70
72
  export function resolveRoutingState(
71
73
  ctx: Pick<TrustContext, "trustClass" | "guardianExternalUserId">,
72
74
  ): RoutingState {
75
+ const caps = resolveCapabilities(ctx.trustClass);
73
76
  const isGuardian = ctx.trustClass === "guardian";
74
- const isTrustedContact = ctx.trustClass === "trusted_contact";
75
77
 
76
78
  // Guardians self-approve — they are always interactive and route-resolvable.
77
79
  if (isGuardian) {
@@ -82,12 +84,13 @@ export function resolveRoutingState(
82
84
  };
83
85
  }
84
86
 
85
- // Trusted contacts can be interactive only if a guardian destination
87
+ // Identity-known non-guardian contacts (trusted_contact /
88
+ // unverified_contact) can be interactive only if a guardian destination
86
89
  // exists. The guardian binding populates guardianExternalUserId during
87
90
  // trust resolution; its presence means there is a verified guardian
88
91
  // to route approval notifications to.
89
92
  const guardianRouteResolvable = !!ctx.guardianExternalUserId;
90
- if (isTrustedContact) {
93
+ if (caps.mayBeInteractive) {
91
94
  return {
92
95
  canBeInteractive: true,
93
96
  guardianRouteResolvable,
@@ -1,4 +1,4 @@
1
- import { getConfigReadOnly } from "../config/loader.js";
1
+ import { validateInferenceProfileKey } from "../config/inference-profile-validation.js";
2
2
 
3
3
  /**
4
4
  * Validate a schedule's inference-profile key against the configured
@@ -12,17 +12,5 @@ import { getConfigReadOnly } from "../config/loader.js";
12
12
  export function validateScheduleInferenceProfile(
13
13
  profile: string,
14
14
  ): string | null {
15
- if (!profile.trim()) {
16
- return "inferenceProfile must be a non-empty string";
17
- }
18
- const profiles = getConfigReadOnly().llm?.profiles ?? {};
19
- if (!Object.prototype.hasOwnProperty.call(profiles, profile)) {
20
- const available = Object.keys(profiles).sort();
21
- const hint =
22
- available.length > 0
23
- ? ` Available profiles: ${available.join(", ")}.`
24
- : " No profiles defined in llm.profiles.";
25
- return `Inference profile "${profile}" is not defined in llm.profiles.${hint}`;
26
- }
27
- return null;
15
+ return validateInferenceProfileKey(profile);
28
16
  }
@@ -158,7 +158,7 @@ export function createSchedule(params: {
158
158
  const routingIntent = params.routingIntent ?? "all_channels";
159
159
  const routingHints = params.routingHints ?? {};
160
160
  const quiet = params.quiet ?? false;
161
- const reuseConversation = params.reuseConversation ?? !isOneShot;
161
+ const reuseConversation = params.reuseConversation ?? false;
162
162
  const maxRetries = params.maxRetries ?? 3;
163
163
  const retryBackoffMs = params.retryBackoffMs ?? 60000;
164
164
  const timeoutMs = params.timeoutMs ?? null;
@@ -7,7 +7,11 @@
7
7
  import type { LLMCallSite } from "../config/schemas/llm.js";
8
8
 
9
9
  export interface ScheduleMessageOptions {
10
- trustClass?: "guardian" | "trusted_contact" | "unknown";
10
+ trustClass?:
11
+ | "guardian"
12
+ | "trusted_contact"
13
+ | "unverified_contact"
14
+ | "unknown";
11
15
  taskRunId?: string;
12
16
  /**
13
17
  * Optional LLM call-site identifier propagated to the per-call provider
@@ -53,6 +53,7 @@ describe("getProviderKeyAsync env-var fallback (regression #27126)", () => {
53
53
  "BRAVE_API_KEY",
54
54
  "PERPLEXITY_API_KEY",
55
55
  "TAVILY_API_KEY",
56
+ "FIRECRAWL_API_KEY",
56
57
  "ANTHROPIC_API_KEY",
57
58
  "OPENAI_API_KEY",
58
59
  ];
@@ -103,6 +104,11 @@ describe("getProviderKeyAsync env-var fallback (regression #27126)", () => {
103
104
  expect(await getProviderKeyAsync("tavily")).toBe("tavily-env-test");
104
105
  });
105
106
 
107
+ test("returns FIRECRAWL_API_KEY from process.env when secure store is empty", async () => {
108
+ process.env.FIRECRAWL_API_KEY = "fc-env-test";
109
+ expect(await getProviderKeyAsync("firecrawl")).toBe("fc-env-test");
110
+ });
111
+
106
112
  test("returns ANTHROPIC_API_KEY from process.env when secure store is empty (LLM regression)", async () => {
107
113
  process.env.ANTHROPIC_API_KEY = "anthropic-env-test";
108
114
  expect(await getProviderKeyAsync("anthropic")).toBe("anthropic-env-test");
@@ -133,4 +133,7 @@ export const PREFIX_PATTERNS: SecretPrefixPattern[] = [
133
133
 
134
134
  // -- Tavily --
135
135
  { label: "Tavily API Key", regex: /tvly-[A-Za-z0-9]{20,}/ },
136
+
137
+ // -- Firecrawl --
138
+ { label: "Firecrawl API Key", regex: /fc-[A-Za-z0-9]{20,}/ },
136
139
  ];
@@ -237,10 +237,17 @@ export class SubagentManager {
237
237
  config.systemPromptOverride ??
238
238
  buildSubagentSystemPrompt({ ...config, id: subagentId }, role);
239
239
  }
240
- const maxTokens = resolveCallSiteConfig(
241
- "subagentSpawn",
242
- appConfig.llm,
243
- ).maxTokens;
240
+ // Resolve under the same profile the run will use (forwarded via
241
+ // `SubagentConfig`) so the constructed conversation's default token cap
242
+ // matches the inherited profile rather than the static `subagentSpawn`
243
+ // default. Per-call routing re-resolves the model anyway; this keeps the
244
+ // initial value consistent.
245
+ const maxTokens = resolveCallSiteConfig("subagentSpawn", appConfig.llm, {
246
+ ...(config.overrideProfile
247
+ ? { overrideProfile: config.overrideProfile }
248
+ : {}),
249
+ ...(config.forceOverrideProfile ? { forceOverrideProfile: true } : {}),
250
+ }).maxTokens;
244
251
  const workingDir = getSandboxWorkingDir();
245
252
 
246
253
  // ── Initialise state ────────────────────────────────────────────
@@ -453,6 +460,9 @@ export class SubagentManager {
453
460
  ...(managed.state.config.overrideProfile
454
461
  ? { overrideProfile: managed.state.config.overrideProfile }
455
462
  : {}),
463
+ ...(managed.state.config.forceOverrideProfile
464
+ ? { forceOverrideProfile: true }
465
+ : {}),
456
466
  });
457
467
 
458
468
  // Agent loop completed successfully.
@@ -641,6 +651,9 @@ export class SubagentManager {
641
651
  ...(managed.state.config.overrideProfile
642
652
  ? { overrideProfile: managed.state.config.overrideProfile }
643
653
  : {}),
654
+ ...(managed.state.config.forceOverrideProfile
655
+ ? { forceOverrideProfile: true }
656
+ : {}),
644
657
  })
645
658
  .catch((err) => {
646
659
  log.error({ subagentId, err }, "Subagent message processing failed");
@@ -69,6 +69,12 @@ export interface SubagentConfig {
69
69
  * profile, every spawned subagent inherits it automatically.
70
70
  */
71
71
  overrideProfile?: string;
72
+ /**
73
+ * When true, the subagent's `overrideProfile` is an explicit spawn-time
74
+ * request and must float above call-site layers. Inherited parent profiles
75
+ * leave this unset so existing call-site precedence stays intact.
76
+ */
77
+ forceOverrideProfile?: boolean;
72
78
  /**
73
79
  * Tool-use id of the `skill_execute` call that spawned this subagent.
74
80
  * Forwarded into the `subagent_spawned` event so the client can anchor the
@@ -0,0 +1,28 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ isDiagnosticsConsentVersionEligible,
5
+ TRACE_COLLECTION_MIN_DIAGNOSTICS_CONSENT_VERSION,
6
+ } from "./trace-collection-policy.js";
7
+
8
+ describe("isDiagnosticsConsentVersionEligible", () => {
9
+ test("the threshold version itself is eligible (>=, inclusive boundary)", () => {
10
+ expect(
11
+ isDiagnosticsConsentVersionEligible(
12
+ TRACE_COLLECTION_MIN_DIAGNOSTICS_CONSENT_VERSION,
13
+ ),
14
+ ).toBe(true);
15
+ });
16
+
17
+ test("a later version is eligible", () => {
18
+ expect(isDiagnosticsConsentVersionEligible("2999-01-01")).toBe(true);
19
+ });
20
+
21
+ test("an earlier version fails closed", () => {
22
+ expect(isDiagnosticsConsentVersionEligible("2000-01-01")).toBe(false);
23
+ });
24
+
25
+ test("the empty version (never accepted / unversioned default) fails closed", () => {
26
+ expect(isDiagnosticsConsentVersionEligible("")).toBe(false);
27
+ });
28
+ });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Per-turn trace-collection disclosure gate (daemon side).
3
+ *
4
+ * A "trace" is the full transcript of one assistant turn. Traces are only
5
+ * collected from owners who accepted the diagnostics-sharing consent copy that
6
+ * *discloses* trace collection — identified by its accepted version.
7
+ *
8
+ * This mirrors the platform's authoritative ingest gate in
9
+ * `vellum-assistant-platform`:
10
+ * - `django/app/core/trace_collection.py` (`is_trace_collection_enabled`)
11
+ * - `config.settings.TRACE_COLLECTION_MIN_DIAGNOSTICS_CONSENT_VERSION`
12
+ *
13
+ * The daemon applies the same `share_diagnostics_accepted_version >= threshold`
14
+ * check the platform does, so traces for ineligible owners never leave the
15
+ * device. (The platform would drop them anyway, but checking here keeps the PII
16
+ * local — data minimization.)
17
+ *
18
+ * Keep this constant in lockstep with the platform setting. Versions are
19
+ * "YYYY-MM-DD" strings, so the lexicographic compare is chronological; ""
20
+ * (never accepted) and older versions fail closed.
21
+ */
22
+ export const TRACE_COLLECTION_MIN_DIAGNOSTICS_CONSENT_VERSION = "2026-06-18";
23
+
24
+ /**
25
+ * True iff `version` (the owner's `share_diagnostics_accepted_version`) is at or
26
+ * past the disclosing version. Fails closed for "" / older versions.
27
+ */
28
+ export function isDiagnosticsConsentVersionEligible(version: string): boolean {
29
+ return version >= TRACE_COLLECTION_MIN_DIAGNOSTICS_CONSENT_VERSION;
30
+ }
@@ -147,6 +147,82 @@ export interface TurnTelemetryClientInfo {
147
147
  interface_version?: string;
148
148
  }
149
149
 
150
+ /**
151
+ * One message in a turn trace. `role` is the stored `messages.role`
152
+ * (`"user"` / `"assistant"` / `"system"`); tool-result rows persisted with
153
+ * role `"user"` keep that role here so the transcript is faithful to what was
154
+ * sent to the model. `content` is the parsed `messages.content` — either the
155
+ * modern `ContentBlock[]` (text / tool_use / tool_result / thinking / image /
156
+ * file blocks) or a legacy plain string. Stored verbatim by the platform as an
157
+ * opaque JSON column, so the shape is self-describing rather than normalized.
158
+ */
159
+ export interface TurnTraceMessage {
160
+ /** `messages.id` — stable per-row id. */
161
+ id: string;
162
+ /** Stored role of the message row. */
163
+ role: string;
164
+ /** Epoch-ms `messages.created_at`. */
165
+ created_at: number;
166
+ /**
167
+ * Parsed `messages.content`. `unknown` because it is forwarded verbatim:
168
+ * modern rows are `ContentBlock[]`, legacy rows are a plain string.
169
+ */
170
+ content: unknown;
171
+ }
172
+
173
+ /**
174
+ * One tool invocation in a turn trace, projected from the `tool_invocations`
175
+ * audit table for the turn window. Carries the full tool call + result so the
176
+ * platform sees the same transcript the assistant did. Both `input` and
177
+ * `result` are captured verbatim (full-fidelity) — no field-level redaction is
178
+ * applied. The protections for this PII are the owner consent gate, the
179
+ * PII-segregated `pii_turn_raw` table, and its 30-day TTL.
180
+ */
181
+ export interface TurnTraceToolCall {
182
+ /** `tool_invocations.id`. */
183
+ id: string;
184
+ tool_name: string;
185
+ /** Verbatim tool input — parsed JSON when it parses, else the raw string. */
186
+ input: unknown;
187
+ /** Stored tool result string (verbatim). */
188
+ result: string;
189
+ /** Audit decision (`"allow"` / `"error"` / …). */
190
+ decision: string;
191
+ duration_ms: number;
192
+ created_at: number;
193
+ }
194
+
195
+ /**
196
+ * Full transcript of a single turn — the user message, assistant response
197
+ * message(s), and the tool calls + results that occurred between this user
198
+ * turn and the next real user turn. Attached to the turn telemetry event's
199
+ * `trace` field ONLY when trace collection is enabled — the `trace-collection`
200
+ * feature flag AND the owner's `share_diagnostics` consent must both be true.
201
+ * The platform stores this verbatim as an opaque JSON column, so the daemon
202
+ * owns the shape.
203
+ *
204
+ * Each turn's trace is its natural window. A turn whose window holds no
205
+ * assistant response (a coalesced-batch head, or a turn that failed/cancelled
206
+ * before responding) traces user-only — faithful, since its window genuinely
207
+ * has no response. A coalesced batch's shared response lives on the batch's
208
+ * final turn's window, where the daemon already attributes it.
209
+ */
210
+ export interface TurnTrace {
211
+ /** Shape version so the platform/dbt can evolve parsing without ambiguity. */
212
+ schema_version: 1;
213
+ /**
214
+ * Ordered message rows for the turn (the user message first, then assistant
215
+ * responses and any tool-result rows), oldest-first by `(created_at, id)`.
216
+ */
217
+ messages: TurnTraceMessage[];
218
+ /**
219
+ * Tool invocations that occurred during the turn window, oldest-first. May
220
+ * be empty for turns with no tool use. Projected from `tool_invocations`,
221
+ * which complements the inline tool_use/tool_result blocks in `messages`.
222
+ */
223
+ tool_calls: TurnTraceToolCall[];
224
+ }
225
+
150
226
  /** Turn event — one per user message. */
151
227
  export interface TurnTelemetryEvent extends TelemetryEventBase {
152
228
  type: "turn";
@@ -200,6 +276,19 @@ export interface TurnTelemetryEvent extends TelemetryEventBase {
200
276
  * middleware hasn't been wired to yet).
201
277
  */
202
278
  client: TurnTelemetryClientInfo | null;
279
+ /**
280
+ * Full per-turn transcript (user message + assistant responses + tool
281
+ * calls/results). Present ONLY when trace collection is enabled — the daemon
282
+ * composes the gate itself from the `trace-collection` feature flag (delivered
283
+ * via the assistant-tagged flag sync, evaluated server-side for this
284
+ * assistant's owner) AND the owner's cached `share_diagnostics` consent, both
285
+ * of which must be true. Fail-closed: when either is off (or unknown) no trace
286
+ * is attached. The platform dual-writes consented traces into a separate PII
287
+ * table and keeps the trace-free turn row; downstream consumers that don't
288
+ * read traces ignore this field. Null / absent when the gate is off or the
289
+ * serialized trace exceeded the size cap.
290
+ */
291
+ trace?: TurnTrace | null;
203
292
  }
204
293
 
205
294
  /** Lifecycle event — app_open, hatch, etc. */