@vellumai/assistant 0.9.0 → 0.10.0-dev.202606192226.8ed8a6a

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 (624) hide show
  1. package/ARCHITECTURE.md +19 -35
  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 +1128 -119
  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__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
  28. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
  29. package/src/__tests__/app-compiler.test.ts +15 -1
  30. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  31. package/src/__tests__/approval-cascade.test.ts +6 -0
  32. package/src/__tests__/approval-routes-http.test.ts +128 -0
  33. package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
  34. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  35. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  36. package/src/__tests__/avatar-identity-sync.test.ts +2 -27
  37. package/src/__tests__/btw-routes.test.ts +6 -8
  38. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  39. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  40. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  41. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  42. package/src/__tests__/checker.test.ts +0 -3
  43. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  44. package/src/__tests__/compaction-events.test.ts +6 -0
  45. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  46. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  47. package/src/__tests__/config-loader-backfill.test.ts +268 -27
  48. package/src/__tests__/config-schema.test.ts +35 -0
  49. package/src/__tests__/config-watcher.test.ts +0 -18
  50. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  51. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  52. package/src/__tests__/contacts-tools.test.ts +29 -0
  53. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  54. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
  55. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  56. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  57. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  58. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
  59. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  60. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  61. package/src/__tests__/conversation-process-callsite.test.ts +6 -0
  62. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  63. package/src/__tests__/conversation-queue.test.ts +6 -0
  64. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  65. package/src/__tests__/conversation-slash-queue.test.ts +6 -0
  66. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  67. package/src/__tests__/conversation-speed-override.test.ts +6 -0
  68. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  69. package/src/__tests__/conversation-title-service.test.ts +62 -0
  70. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
  71. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  72. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  73. package/src/__tests__/credential-broker.test.ts +449 -1
  74. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  75. package/src/__tests__/credential-execution-tools.test.ts +0 -1
  76. package/src/__tests__/credential-prompt-route.test.ts +4 -4
  77. package/src/__tests__/credential-routes.test.ts +360 -0
  78. package/src/__tests__/credential-security-invariants.test.ts +4 -13
  79. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  80. package/src/__tests__/disk-pressure-tools.test.ts +41 -1
  81. package/src/__tests__/disk-usage.test.ts +65 -0
  82. package/src/__tests__/document-tool-security.test.ts +9 -6
  83. package/src/__tests__/document-update-default-surface.test.ts +202 -0
  84. package/src/__tests__/dynamic-page-surface.test.ts +152 -1
  85. package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
  86. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  87. package/src/__tests__/gateway-only-guard.test.ts +3 -7
  88. package/src/__tests__/gemini-count-tokens.test.ts +70 -0
  89. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  90. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  91. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  92. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  93. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  94. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  95. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  96. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  97. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  98. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  99. package/src/__tests__/identity-routes.test.ts +0 -189
  100. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  101. package/src/__tests__/injector-disk-pressure.test.ts +10 -5
  102. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  103. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  104. package/src/__tests__/invite-redemption-service.test.ts +4 -7
  105. package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
  106. package/src/__tests__/llm-catalog-parity.test.ts +30 -23
  107. package/src/__tests__/llm-resolver.test.ts +70 -24
  108. package/src/__tests__/llm-schema.test.ts +1 -0
  109. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  110. package/src/__tests__/mcp-health-check.test.ts +6 -7
  111. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  112. package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
  113. package/src/__tests__/onboarding-persona-write.test.ts +1 -1
  114. package/src/__tests__/path-policy.test.ts +34 -0
  115. package/src/__tests__/persona-resolver.test.ts +49 -14
  116. package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
  117. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  118. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  119. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  120. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  121. package/src/__tests__/reaction-persistence.test.ts +150 -29
  122. package/src/__tests__/registry.test.ts +2 -7
  123. package/src/__tests__/relay-server.test.ts +285 -0
  124. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  125. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
  126. package/src/__tests__/schedule-routes.test.ts +0 -30
  127. package/src/__tests__/schedule-tools.test.ts +2 -18
  128. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  129. package/src/__tests__/secret-response-routing.test.ts +35 -0
  130. package/src/__tests__/secret-routes-platform-proxy.test.ts +16 -2
  131. package/src/__tests__/skill-execute-input.test.ts +177 -1
  132. package/src/__tests__/skill-load-tool.test.ts +72 -0
  133. package/src/__tests__/skill-runtime-path.test.ts +2 -3
  134. package/src/__tests__/skills.test.ts +51 -0
  135. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  136. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  137. package/src/__tests__/subagent-tools.test.ts +266 -0
  138. package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
  139. package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
  140. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  141. package/src/__tests__/title-generate-hook.test.ts +100 -3
  142. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
  143. package/src/__tests__/token-manager.test.ts +519 -0
  144. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  145. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  146. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  147. package/src/__tests__/tool-executor.test.ts +0 -79
  148. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  149. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  150. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  151. package/src/__tests__/trusted-contact-verification.test.ts +8 -10
  152. package/src/__tests__/twilio-routes.test.ts +81 -1
  153. package/src/__tests__/voice-invite-redemption.test.ts +2 -3
  154. package/src/__tests__/weak-open-model.test.ts +30 -0
  155. package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
  156. package/src/__tests__/workspace-greetings.test.ts +152 -0
  157. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  158. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  159. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  160. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  161. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  162. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  163. package/src/agent/loop.ts +75 -29
  164. package/src/api/README.md +6 -6
  165. package/src/api/events/tool-result.ts +6 -0
  166. package/src/api/events/workflow-completed.ts +53 -0
  167. package/src/api/events/workflow-leaf-finished.ts +38 -0
  168. package/src/api/events/workflow-leaf-started.ts +35 -0
  169. package/src/api/events/workflow-progress.ts +32 -0
  170. package/src/api/events/workflow-started.ts +31 -0
  171. package/src/api/index.ts +40 -0
  172. package/src/api/responses/conversation-message.ts +28 -4
  173. package/src/api/responses/home.ts +26 -4
  174. package/src/api/responses/workflow-journal.ts +53 -0
  175. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  176. package/src/approvals/guardian-decision-primitive.ts +26 -3
  177. package/src/approvals/guardian-request-resolvers.ts +183 -80
  178. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  179. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  180. package/src/calls/call-pointer-messages.ts +10 -4
  181. package/src/calls/channel-admission-reader.ts +104 -0
  182. package/src/calls/guardian-dispatch.ts +17 -45
  183. package/src/calls/media-stream-server.ts +84 -2
  184. package/src/calls/relay-access-wait.ts +1 -1
  185. package/src/calls/relay-server.ts +66 -0
  186. package/src/calls/relay-setup-router.ts +82 -1
  187. package/src/calls/twilio-routes.ts +17 -8
  188. package/src/calls/voice-session-bridge.ts +2 -2
  189. package/src/cli/commands/clients.ts +3 -0
  190. package/src/cli/commands/db/status.ts +37 -3
  191. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  192. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  193. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  194. package/src/cli/commands/memory/index.ts +30 -0
  195. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  196. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  197. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  198. package/src/cli/commands/oauth/status.test.ts +36 -0
  199. package/src/cli/commands/oauth/status.ts +23 -3
  200. package/src/cli/commands/plugins.ts +400 -14
  201. package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
  202. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  203. package/src/cli/lib/__tests__/install-from-github.test.ts +31 -0
  204. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
  205. package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
  206. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  207. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
  208. package/src/cli/lib/diff-plugin.ts +346 -0
  209. package/src/cli/lib/inspect-plugin.ts +12 -1
  210. package/src/cli/lib/install-from-github.ts +128 -19
  211. package/src/cli/lib/merge-plugin-tree.ts +328 -0
  212. package/src/cli/lib/plugin-fingerprint.ts +14 -0
  213. package/src/cli/lib/plugin-marketplace.ts +11 -0
  214. package/src/cli/lib/plugin-pin-history.ts +257 -0
  215. package/src/cli/lib/plugin-surfaces.ts +104 -0
  216. package/src/cli/lib/upgrade-plugin.ts +298 -10
  217. package/src/cli/program.ts +2 -6
  218. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  219. package/src/config/assistant-feature-flags.ts +22 -7
  220. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  221. package/src/config/bundled-skills/document-editor/SKILL.md +3 -3
  222. package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
  223. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  224. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  225. package/src/config/bundled-skills/subagent/SKILL.md +4 -0
  226. package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
  227. package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
  228. package/src/config/bundled-skills/workflows/SKILL.md +14 -8
  229. package/src/config/bundled-tool-registry.ts +2 -7
  230. package/src/config/call-site-defaults.ts +15 -2
  231. package/src/config/feature-flag-registry.json +46 -31
  232. package/src/config/inference-profile-validation.ts +26 -0
  233. package/src/config/llm-resolver.ts +3 -0
  234. package/src/config/loader.ts +4 -0
  235. package/src/config/memory-v3-gate.ts +11 -0
  236. package/src/config/profile-order.ts +28 -0
  237. package/src/config/schema.ts +8 -6
  238. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  239. package/src/config/schemas/call-site-catalog.ts +7 -0
  240. package/src/config/schemas/channels.ts +11 -0
  241. package/src/config/schemas/elevenlabs.ts +0 -1
  242. package/src/config/schemas/llm.ts +31 -0
  243. package/src/config/schemas/memory-lifecycle.ts +3 -7
  244. package/src/config/schemas/memory-v3.ts +6 -0
  245. package/src/config/schemas/platform.ts +0 -8
  246. package/src/config/schemas/services.ts +18 -0
  247. package/src/config/seed-inference-profiles.ts +109 -44
  248. package/src/config/skills.ts +21 -0
  249. package/src/config/sync-gated-profiles.ts +220 -0
  250. package/src/contacts/contact-store.ts +89 -106
  251. package/src/contacts/contacts-write.ts +5 -22
  252. package/src/contacts/types.ts +0 -1
  253. package/src/context/compactor.ts +88 -54
  254. package/src/context/strip-injections.ts +58 -10
  255. package/src/context/token-estimator.ts +1 -1
  256. package/src/credential-execution/process-manager.ts +55 -14
  257. package/src/credential-execution/prompted-credential.ts +2 -3
  258. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  259. package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
  260. package/src/daemon/config-watcher.ts +0 -4
  261. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  262. package/src/daemon/conversation-agent-loop.ts +114 -22
  263. package/src/daemon/conversation-history.ts +1 -1
  264. package/src/daemon/conversation-lifecycle.ts +3 -5
  265. package/src/daemon/conversation-process.ts +13 -5
  266. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  267. package/src/daemon/conversation-slash.ts +2 -23
  268. package/src/daemon/conversation-surfaces.ts +26 -0
  269. package/src/daemon/conversation-tool-setup.ts +53 -19
  270. package/src/daemon/conversation.ts +131 -20
  271. package/src/daemon/disk-pressure-policy.ts +5 -3
  272. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  273. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  274. package/src/daemon/handlers/config-a2a.ts +0 -2
  275. package/src/daemon/handlers/config-channels.ts +15 -16
  276. package/src/daemon/handlers/config-slack-channel.ts +22 -3
  277. package/src/daemon/handlers/conversations.ts +107 -0
  278. package/src/daemon/host-browser-proxy.ts +41 -0
  279. package/src/daemon/lifecycle.ts +55 -27
  280. package/src/daemon/memory-v2-startup.test.ts +131 -0
  281. package/src/daemon/memory-v2-startup.ts +100 -1
  282. package/src/daemon/message-provenance.ts +2 -0
  283. package/src/daemon/message-types/contacts.ts +0 -1
  284. package/src/daemon/message-types/conversations.ts +3 -3
  285. package/src/daemon/message-types/sync.ts +0 -1
  286. package/src/daemon/message-types/web-activity.ts +7 -1
  287. package/src/daemon/message-types/workflows.ts +83 -1
  288. package/src/daemon/orphan-reaper.test.ts +0 -19
  289. package/src/daemon/orphan-reaper.ts +2 -24
  290. package/src/daemon/server.ts +0 -10
  291. package/src/daemon/tool-setup-types.ts +4 -0
  292. package/src/daemon/trust-context.ts +1 -1
  293. package/src/daemon/wake-conversation-ops.ts +1 -0
  294. package/src/events/tool-audit-listener.ts +2 -2
  295. package/src/home/feed-source-enrichment.test.ts +151 -0
  296. package/src/home/feed-source-enrichment.ts +176 -0
  297. package/src/home/relationship-state.ts +2 -4
  298. package/src/instrument.ts +18 -6
  299. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  300. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  301. package/src/ipc/assistant-server.ts +37 -4
  302. package/src/ipc/gateway-flag-listener.ts +18 -2
  303. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  304. package/src/memory/__tests__/db-logs-attach.test.ts +122 -0
  305. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  306. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  307. package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
  308. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  309. package/src/memory/auth-fallback-events-store.ts +2 -2
  310. package/src/memory/auto-analysis-enqueue.ts +3 -5
  311. package/src/memory/bookmark-crud.ts +1 -2
  312. package/src/memory/canonical-guardian-store.ts +39 -1
  313. package/src/memory/conversation-crud.ts +9 -4
  314. package/src/memory/conversation-key-store.ts +17 -2
  315. package/src/memory/conversation-title-service.ts +64 -7
  316. package/src/memory/db-async-query.ts +20 -2
  317. package/src/memory/db-connection.ts +49 -5
  318. package/src/memory/db-init.ts +17 -17
  319. package/src/memory/embedding-backend.ts +38 -1
  320. package/src/memory/embedding-billing-breaker.ts +96 -0
  321. package/src/memory/jobs-store.ts +25 -13
  322. package/src/memory/jobs-worker.ts +54 -1
  323. package/src/memory/lifecycle-events-store.ts +2 -2
  324. package/src/memory/memory-retrospective-constants.ts +4 -4
  325. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  326. package/src/memory/memory-retrospective-job.ts +28 -227
  327. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  328. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  329. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  330. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
  331. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  332. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  333. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  334. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  335. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  336. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  337. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  338. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  339. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  340. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
  341. package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
  342. package/src/memory/migrations/index.ts +6 -0
  343. package/src/memory/migrations/run-migrations.ts +41 -0
  344. package/src/memory/migrations/validate-migration-state.ts +1 -1
  345. package/src/memory/onboarding-events-store.ts +3 -3
  346. package/src/memory/schema/contacts.ts +0 -5
  347. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  348. package/src/memory/skill-loaded-events-store.ts +2 -2
  349. package/src/memory/tool-executed-events-store.test.ts +7 -7
  350. package/src/memory/turn-trace-store.test.ts +736 -0
  351. package/src/memory/turn-trace-store.ts +364 -0
  352. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  353. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  354. package/src/memory/v2/consolidation-job.ts +2 -2
  355. package/src/memory/v2/skill-content.ts +25 -7
  356. package/src/memory/v2/skill-store.ts +7 -1
  357. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  358. package/src/memory/v3-eval/eval-packets.ts +546 -0
  359. package/src/messaging/providers/slack/adapter.ts +1 -1
  360. package/src/messaging/providers/slack/api.ts +31 -0
  361. package/src/messaging/providers/slack/send.test.ts +114 -2
  362. package/src/messaging/providers/slack/send.ts +30 -7
  363. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  364. package/src/messaging/providers/slack/withdraw.ts +161 -0
  365. package/src/notifications/AGENTS.md +2 -0
  366. package/src/notifications/access-request-copy.ts +72 -59
  367. package/src/notifications/adapters/shared.ts +29 -0
  368. package/src/notifications/adapters/slack.ts +58 -103
  369. package/src/notifications/adapters/telegram.ts +2 -20
  370. package/src/notifications/approval-card-data.ts +333 -0
  371. package/src/notifications/broadcaster.ts +16 -3
  372. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  373. package/src/notifications/copy-composer.ts +3 -3
  374. package/src/notifications/decision-engine.ts +4 -2
  375. package/src/notifications/destination-resolver.ts +4 -6
  376. package/src/notifications/guardian-question-mode.ts +10 -0
  377. package/src/notifications/home-feed-side-effect.ts +7 -16
  378. package/src/notifications/notification-utils.ts +19 -20
  379. package/src/notifications/signal.ts +79 -43
  380. package/src/notifications/types.ts +98 -121
  381. package/src/oauth/AGENTS.md +5 -24
  382. package/src/permissions/checker.test.ts +51 -0
  383. package/src/permissions/checker.ts +185 -26
  384. package/src/permissions/ipc-risk-types.ts +24 -0
  385. package/src/permissions/question-prompter.test.ts +27 -0
  386. package/src/permissions/question-prompter.ts +4 -0
  387. package/src/permissions/secret-prompter.ts +15 -1
  388. package/src/platform/client.test.ts +119 -0
  389. package/src/platform/client.ts +66 -0
  390. package/src/platform/consent-cache.test.ts +267 -0
  391. package/src/platform/consent-cache.ts +174 -0
  392. package/src/plugin-api/constants.ts +1 -1
  393. package/src/plugin-api/index.ts +33 -1
  394. package/src/plugin-api/model-profiles.ts +33 -0
  395. package/src/plugin-api/types.ts +50 -2
  396. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  397. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  398. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  399. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  400. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  401. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  402. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  403. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  404. package/src/plugins/defaults/advisor/config.ts +21 -0
  405. package/src/plugins/defaults/advisor/consult.ts +93 -0
  406. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  407. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  408. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  409. package/src/plugins/defaults/advisor/package.json +14 -0
  410. package/src/plugins/defaults/advisor/steering.ts +67 -0
  411. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  412. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  413. package/src/plugins/defaults/compaction/window-manager.ts +18 -0
  414. package/src/plugins/defaults/index.ts +60 -0
  415. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  416. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  417. package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
  418. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  419. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  420. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  421. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  422. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
  423. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  424. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  425. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  426. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  427. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
  428. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  429. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  430. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  431. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
  432. package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
  433. package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
  434. package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
  435. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
  436. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  437. package/src/prompts/persona-resolver.ts +14 -4
  438. package/src/prompts/templates/system-sections.ts +7 -2
  439. package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
  440. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  441. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  442. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  443. package/src/providers/anthropic/client.ts +230 -175
  444. package/src/providers/atlascloud/client.ts +85 -0
  445. package/src/providers/call-site-routing.ts +10 -0
  446. package/src/providers/fetch-provider-catalog.ts +85 -0
  447. package/src/providers/gemini/client.ts +43 -0
  448. package/src/providers/inference/adapter-factory.ts +3 -0
  449. package/src/providers/model-catalog.ts +58 -0
  450. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  451. package/src/providers/openai/chat-completions-provider.ts +7 -0
  452. package/src/providers/openai/responses-provider.ts +10 -0
  453. package/src/providers/provider-send-message.ts +11 -3
  454. package/src/providers/ratelimit.ts +9 -0
  455. package/src/providers/retry.ts +62 -12
  456. package/src/providers/search-provider-catalog.ts +10 -0
  457. package/src/providers/types.ts +16 -0
  458. package/src/providers/usage-tracking.ts +7 -0
  459. package/src/providers/weak-open-model.ts +22 -0
  460. package/src/runtime/AGENTS.md +0 -1
  461. package/src/runtime/__tests__/agent-wake.test.ts +227 -0
  462. package/src/runtime/__tests__/client-health.test.ts +44 -0
  463. package/src/runtime/access-request-helper.ts +21 -53
  464. package/src/runtime/actor-trust-resolver.ts +59 -63
  465. package/src/runtime/agent-wake.ts +71 -0
  466. package/src/runtime/assistant-event-hub.ts +18 -4
  467. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  468. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  469. package/src/runtime/btw-sidechain.ts +3 -6
  470. package/src/runtime/capabilities.test.ts +120 -0
  471. package/src/runtime/capabilities.ts +197 -0
  472. package/src/runtime/channel-approval-types.ts +22 -45
  473. package/src/runtime/channel-invite-transports/telegram.ts +4 -4
  474. package/src/runtime/channel-retry-sweep.ts +1 -0
  475. package/src/runtime/channel-verification-service.ts +3 -3
  476. package/src/runtime/client-health.ts +26 -0
  477. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  478. package/src/runtime/effective-capabilities.test.ts +128 -0
  479. package/src/runtime/effective-capabilities.ts +84 -0
  480. package/src/runtime/guardian-reply-router.ts +106 -21
  481. package/src/runtime/invite-redemption-service.ts +9 -25
  482. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +126 -0
  483. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  484. package/src/runtime/pending-interactions.ts +35 -0
  485. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  486. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  487. package/src/runtime/routes/__tests__/plugins-routes.test.ts +383 -1
  488. package/src/runtime/routes/app-routes.ts +1 -1
  489. package/src/runtime/routes/approval-routes.ts +40 -9
  490. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
  491. package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
  492. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  493. package/src/runtime/routes/btw-routes.ts +1 -27
  494. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  495. package/src/runtime/routes/client-routes.ts +10 -0
  496. package/src/runtime/routes/contact-routes.ts +31 -8
  497. package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
  498. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  499. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  500. package/src/runtime/routes/conversation-routes.ts +39 -14
  501. package/src/runtime/routes/credential-routes.ts +40 -16
  502. package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
  503. package/src/runtime/routes/events-routes.ts +1 -3
  504. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  505. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  506. package/src/runtime/routes/home-feed-routes.ts +8 -3
  507. package/src/runtime/routes/identity-routes.ts +1 -296
  508. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  509. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
  510. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  511. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  512. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  513. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  514. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  515. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  516. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  517. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  518. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  519. package/src/runtime/routes/index.ts +2 -0
  520. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  521. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  522. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  523. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  524. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  525. package/src/runtime/routes/notification-routes.ts +122 -133
  526. package/src/runtime/routes/platform-routes.ts +2 -2
  527. package/src/runtime/routes/plugins-routes.ts +366 -11
  528. package/src/runtime/routes/schedule-routes.ts +0 -22
  529. package/src/runtime/routes/secret-routes.ts +15 -0
  530. package/src/runtime/routes/surface-action-routes.ts +2 -1
  531. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  532. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  533. package/src/runtime/routes/workflow-routes.test.ts +229 -44
  534. package/src/runtime/routes/workflow-routes.ts +131 -29
  535. package/src/runtime/routes/workspace-greetings.ts +55 -0
  536. package/src/runtime/sync/resource-sync-events.ts +1 -11
  537. package/src/runtime/tool-grant-request-helper.ts +18 -16
  538. package/src/runtime/trust-context-resolver.ts +8 -5
  539. package/src/schedule/inference-profile.ts +2 -14
  540. package/src/schedule/schedule-store.ts +1 -1
  541. package/src/schedule/scheduler-types.ts +5 -1
  542. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  543. package/src/security/secret-patterns.ts +3 -0
  544. package/src/subagent/manager.ts +17 -4
  545. package/src/subagent/types.ts +6 -0
  546. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  547. package/src/telemetry/trace-collection-policy.ts +30 -0
  548. package/src/telemetry/types.ts +89 -0
  549. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  550. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  551. package/src/tools/AGENTS.md +3 -3
  552. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  553. package/src/tools/browser/browser-execution.ts +30 -19
  554. package/src/tools/document/document-tool.ts +30 -6
  555. package/src/tools/executor.ts +5 -3
  556. package/src/tools/host-terminal/host-shell.ts +5 -4
  557. package/src/tools/memory/register.ts +2 -2
  558. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  559. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  560. package/src/tools/network/web-fetch.ts +372 -1
  561. package/src/tools/network/web-search-error.ts +1 -1
  562. package/src/tools/network/web-search.ts +213 -10
  563. package/src/tools/permission-checker.ts +4 -3
  564. package/src/tools/registry.ts +20 -0
  565. package/src/tools/schedule/create.ts +7 -12
  566. package/src/tools/schedule/update.ts +4 -11
  567. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  568. package/src/tools/side-effects.ts +2 -17
  569. package/src/tools/skills/execute.ts +99 -2
  570. package/src/tools/skills/load.ts +43 -2
  571. package/src/tools/subagent/spawn.ts +64 -15
  572. package/src/tools/terminal/shell.ts +10 -4
  573. package/src/tools/tool-approval-handler.ts +18 -13
  574. package/src/tools/tool-manifest.ts +0 -2
  575. package/src/tools/types.ts +10 -0
  576. package/src/tools/ui-surface/definitions.ts +64 -3
  577. package/src/tools/verification-control-plane-policy.ts +3 -1
  578. package/src/tools/workflows/run-workflow.test.ts +8 -18
  579. package/src/tools/workflows/run-workflow.ts +1 -0
  580. package/src/util/disk-usage.ts +78 -23
  581. package/src/util/logs-db-path.ts +22 -0
  582. package/src/util/platform.ts +10 -3
  583. package/src/watcher/telemetry.ts +2 -2
  584. package/src/workflows/capabilities.ts +2 -3
  585. package/src/workflows/engine.test.ts +175 -1
  586. package/src/workflows/engine.ts +82 -0
  587. package/src/workflows/journal-store.test.ts +70 -0
  588. package/src/workflows/journal-store.ts +18 -3
  589. package/src/workflows/run-manager.test.ts +171 -28
  590. package/src/workflows/run-manager.ts +66 -24
  591. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  592. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  593. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  594. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  595. package/src/workspace/migrations/registry.ts +8 -0
  596. package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
  597. package/src/__tests__/credential-security-e2e.test.ts +0 -362
  598. package/src/__tests__/credential-vault-unit.test.ts +0 -1528
  599. package/src/__tests__/credential-vault.test.ts +0 -1706
  600. package/src/__tests__/identity-intro-cache.test.ts +0 -315
  601. package/src/__tests__/secret-onetime-send.test.ts +0 -182
  602. package/src/cli/commands/__tests__/task.test.ts +0 -914
  603. package/src/cli/commands/task.ts +0 -771
  604. package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
  605. package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
  606. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
  607. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
  608. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
  609. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
  610. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
  611. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
  612. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
  613. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
  614. package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
  615. package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
  616. package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
  617. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
  618. package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
  619. package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
  620. package/src/memory/preloaded-apps.ts +0 -116
  621. package/src/notifications/tool-approval-copy.ts +0 -142
  622. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
  623. package/src/runtime/routes/identity-intro-cache.ts +0 -172
  624. package/src/tools/credentials/vault.ts +0 -712
@@ -689,6 +689,82 @@ describe("standalone approval endpoints — HTTP layer", () => {
689
689
  await stopServer();
690
690
  });
691
691
 
692
+ test("cancels a secret request when value is omitted", async () => {
693
+ let secretRequestId: string | undefined;
694
+ let secretValue: string | undefined;
695
+
696
+ const session = makeIdleSession({
697
+ onSecret: (reqId, val) => {
698
+ secretRequestId = reqId;
699
+ secretValue = val;
700
+ },
701
+ });
702
+
703
+ await startServer(() => session);
704
+
705
+ pendingInteractions.register("secret-cancel-1", {
706
+ conversationId: "conv-1",
707
+ kind: "secret",
708
+ });
709
+
710
+ const res = await fetch(url("secret"), {
711
+ method: "POST",
712
+ headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
713
+ body: JSON.stringify({ requestId: "secret-cancel-1" }),
714
+ });
715
+ const body = (await res.json()) as { accepted: boolean };
716
+
717
+ expect(res.status).toBe(200);
718
+ expect(body.accepted).toBe(true);
719
+ expect(secretRequestId).toBe("secret-cancel-1");
720
+ expect(secretValue).toBeUndefined();
721
+ expect(pendingInteractions.get("secret-cancel-1")).toBeUndefined();
722
+
723
+ await stopServer();
724
+ });
725
+
726
+ test('legacy delivery "none" cancels the request without 400', async () => {
727
+ let secretRequestId: string | undefined;
728
+ let secretValue: string | undefined;
729
+ let secretDelivery: string | undefined;
730
+
731
+ const session = makeIdleSession({
732
+ onSecret: (reqId, val, del) => {
733
+ secretRequestId = reqId;
734
+ secretValue = val;
735
+ secretDelivery = del;
736
+ },
737
+ });
738
+
739
+ await startServer(() => session);
740
+
741
+ pendingInteractions.register("secret-legacy-cancel-1", {
742
+ conversationId: "conv-1",
743
+ kind: "secret",
744
+ });
745
+
746
+ const res = await fetch(url("secret"), {
747
+ method: "POST",
748
+ headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
749
+ body: JSON.stringify({
750
+ requestId: "secret-legacy-cancel-1",
751
+ value: "ignored-by-cancel",
752
+ delivery: "none",
753
+ }),
754
+ });
755
+ const body = (await res.json()) as { accepted: boolean };
756
+
757
+ expect(res.status).toBe(200);
758
+ expect(body.accepted).toBe(true);
759
+ expect(secretRequestId).toBe("secret-legacy-cancel-1");
760
+ // delivery "none" normalizes to the cancellation path: value/delivery dropped.
761
+ expect(secretValue).toBeUndefined();
762
+ expect(secretDelivery).toBeUndefined();
763
+ expect(pendingInteractions.get("secret-legacy-cancel-1")).toBeUndefined();
764
+
765
+ await stopServer();
766
+ });
767
+
692
768
  test("rejects a non-secret requestId without consuming it", async () => {
693
769
  /**
694
770
  * /v1/secret only settles secret prompts. A confirmation (or any other
@@ -790,6 +866,58 @@ describe("standalone approval endpoints — HTTP layer", () => {
790
866
  });
791
867
  });
792
868
 
869
+ // ── GET /v1/pending-interactions ─────────────────────────────────────
870
+
871
+ describe("GET /v1/pending-interactions", () => {
872
+ test("returns full secret prompt metadata for a registered secret", async () => {
873
+ const session = makeIdleSession();
874
+ await startServer(() => session);
875
+
876
+ pendingInteractions.register("secret-meta-1", {
877
+ conversationId: "conv-meta",
878
+ kind: "secret",
879
+ secretDetails: {
880
+ service: "github",
881
+ field: "token",
882
+ label: "GitHub Token",
883
+ description: "Personal access token",
884
+ placeholder: "ghp_...",
885
+ purpose: "Push commits",
886
+ allowedTools: ["git_push"],
887
+ allowedDomains: ["github.com"],
888
+ allowOneTimeSend: true,
889
+ },
890
+ });
891
+
892
+ const res = await fetch(
893
+ url("pending-interactions?conversationId=conv-meta"),
894
+ {
895
+ method: "GET",
896
+ headers: { ...AUTH_HEADERS },
897
+ },
898
+ );
899
+ const body = (await res.json()) as {
900
+ pendingSecret: Record<string, unknown> | null;
901
+ };
902
+
903
+ expect(res.status).toBe(200);
904
+ expect(body.pendingSecret).toEqual({
905
+ requestId: "secret-meta-1",
906
+ service: "github",
907
+ field: "token",
908
+ label: "GitHub Token",
909
+ description: "Personal access token",
910
+ placeholder: "ghp_...",
911
+ purpose: "Push commits",
912
+ allowedTools: ["git_push"],
913
+ allowedDomains: ["github.com"],
914
+ allowOneTimeSend: true,
915
+ });
916
+
917
+ await stopServer();
918
+ });
919
+ });
920
+
793
921
  // ── getByConversation ────────────────────────────────────────────────
794
922
 
795
923
  describe("getByConversation", () => {
@@ -60,10 +60,7 @@ const CANONICAL_KEY_RE = /^[a-z0-9][a-z0-9-]*$/;
60
60
  * Keep this list minimal — only files that genuinely need to reference
61
61
  * the legacy format for backward compatibility.
62
62
  */
63
- const LEGACY_KEY_ALLOWLIST = new Set([
64
- // macOS client: fallback reads from legacy config section
65
- "clients/macos/vellum-assistant/Features/Settings/SettingsAccountTab.swift",
66
- ]);
63
+ const LEGACY_KEY_ALLOWLIST = new Set<string>([]);
67
64
 
68
65
  function isTestFile(filePath: string): boolean {
69
66
  return (
@@ -58,8 +58,6 @@ function loadRegistry(): Registry {
58
58
  const LEGACY_KEY_ALLOWLIST = new Set([
59
59
  // Type definitions documenting the legacy format
60
60
  "assistant/src/config/types.ts",
61
- // macOS client: fallback reads from legacy config section
62
- "clients/macos/vellum-assistant/Features/Settings/SettingsAccountTab.swift",
63
61
  ]);
64
62
 
65
63
  function isTestFile(filePath: string): boolean {
@@ -7,18 +7,10 @@ mock.module("../util/logger.js", () => ({
7
7
  }),
8
8
  }));
9
9
 
10
- let collectUsageData = true;
10
+ let shareAnalytics = true;
11
11
 
12
- mock.module("../config/loader.js", () => ({
13
- getConfig: () => ({
14
- ui: {},
15
- model: "test",
16
- provider: "test",
17
- memory: { enabled: false },
18
- rateLimit: { maxRequestsPerMinute: 0 },
19
- secretDetection: { enabled: false },
20
- collectUsageData,
21
- }),
12
+ mock.module("../platform/consent-cache.js", () => ({
13
+ getCachedShareAnalytics: () => shareAnalytics,
22
14
  }));
23
15
 
24
16
  import {
@@ -53,7 +45,7 @@ const SAMPLE: AuthFallbackCount[] = [
53
45
 
54
46
  describe("auth-fallback-events-store", () => {
55
47
  beforeEach(() => {
56
- collectUsageData = true;
48
+ shareAnalytics = true;
57
49
  resetTable();
58
50
  });
59
51
 
@@ -78,8 +70,8 @@ describe("auth-fallback-events-store", () => {
78
70
  });
79
71
  });
80
72
 
81
- test("honors the collectUsageData opt-out (records nothing)", () => {
82
- collectUsageData = false;
73
+ test("honors the share_analytics opt-out (records nothing)", () => {
74
+ shareAnalytics = false;
83
75
  const recorded = recordAuthFallbackCounts(1000, 2000, SAMPLE);
84
76
  expect(recorded).toBe(0);
85
77
  expect(queryUnreportedAuthFallbackEvents(0, undefined, 100).length).toBe(0);
@@ -4,10 +4,7 @@ import { SYNC_TAGS } from "../daemon/message-types/sync.js";
4
4
  import type { AssistantEvent } from "../runtime/assistant-event.js";
5
5
  import { assistantEventHub } from "../runtime/assistant-event-hub.js";
6
6
  import { ROUTES as AVATAR_ROUTES } from "../runtime/routes/avatar-routes.js";
7
- import {
8
- publishIdentityChanged,
9
- publishIdentityIntroChanged,
10
- } from "../runtime/sync/resource-sync-events.js";
7
+ import { publishIdentityChanged } from "../runtime/sync/resource-sync-events.js";
11
8
 
12
9
  async function waitFor(predicate: () => boolean): Promise<void> {
13
10
  const deadline = Date.now() + 500;
@@ -81,29 +78,7 @@ describe("avatar and identity sync events", () => {
81
78
  });
82
79
  expect(received[1].message).toEqual({
83
80
  type: "sync_changed",
84
- tags: [SYNC_TAGS.assistantIdentity, SYNC_TAGS.assistantIdentityIntro],
85
- });
86
- } finally {
87
- subscription.dispose();
88
- }
89
- });
90
-
91
- test("identity intro changes emit only the identity intro sync tag", async () => {
92
- const received: AssistantEvent[] = [];
93
- const subscription = assistantEventHub.subscribe({
94
- type: "process",
95
- callback: (event) => {
96
- received.push(event);
97
- },
98
- });
99
-
100
- try {
101
- publishIdentityIntroChanged();
102
- await waitFor(() => received.length === 1);
103
-
104
- expect(received[0].message).toEqual({
105
- type: "sync_changed",
106
- tags: [SYNC_TAGS.assistantIdentityIntro],
81
+ tags: [SYNC_TAGS.assistantIdentity],
107
82
  });
108
83
  } finally {
109
84
  subscription.dispose();
@@ -78,10 +78,8 @@ mock.module("../prompts/persona-resolver.js", () => ({
78
78
  resolveUserSlug: () => null,
79
79
  }));
80
80
 
81
- mock.module("../runtime/routes/identity-intro-cache.js", () => ({
82
- getCachedIntro: () => null,
83
- readWorkspaceIdentityIntro: () => null,
84
- setCachedIntro: () => {},
81
+ mock.module("../runtime/routes/workspace-greetings.js", () => ({
82
+ readWorkspaceGreetings: () => null,
85
83
  }));
86
84
 
87
85
  // Mock getOrCreateConversation from conversation-store so the handler
@@ -345,13 +343,13 @@ describe("POST /v1/btw", () => {
345
343
  expect(options!.config!.callSite).toBe("emptyStateGreeting");
346
344
  });
347
345
 
348
- test("identity intro requests pass callSite: 'identityIntro'", async () => {
346
+ test("generic requests pass the default callSite", async () => {
349
347
  const provider = makeMockProvider();
350
348
  const session = makeMockSession(provider);
351
349
  mockGetOrCreateConversation.mockImplementationOnce(async () => session);
352
350
 
353
351
  const { result } = await callHandler({
354
- conversationKey: "identity-intro",
352
+ conversationKey: "profile-intro",
355
353
  content: "Generate an intro",
356
354
  });
357
355
  await readStream(result as ReadableStream<Uint8Array>);
@@ -361,7 +359,7 @@ describe("POST /v1/btw", () => {
361
359
  expect(options!.config!.callSite).toBe("identityIntro");
362
360
  });
363
361
 
364
- test("identity intro requests do not synthesize a static name greeting", async () => {
362
+ test("generic requests do not synthesize a static name greeting", async () => {
365
363
  const identityPath = join(getWorkspaceDir(), "IDENTITY.md");
366
364
  writeFileSync(
367
365
  identityPath,
@@ -375,7 +373,7 @@ describe("POST /v1/btw", () => {
375
373
  mockGetOrCreateConversation.mockImplementationOnce(async () => session);
376
374
 
377
375
  const { result } = await callHandler({
378
- conversationKey: "identity-intro",
376
+ conversationKey: "profile-intro",
379
377
  content: "Generate an intro",
380
378
  });
381
379
  const text = await readStream(result as ReadableStream<Uint8Array>);
@@ -343,6 +343,34 @@ describe("addPointerMessage", () => {
343
343
  expect(processorCalled).toBe(true);
344
344
  });
345
345
 
346
+ test("unverified_contact provenance round-trips through the metadata schema and is treated as trusted audience", async () => {
347
+ // Persisted unverified_contact metadata must survive the schema parse so
348
+ // downstream consumers (e.g. memory write gate, pointer audience trust)
349
+ // see the durable trust snapshot rather than a silently-dropped undefined.
350
+ const convId = "conv-ptr-uvc-provenance";
351
+ ensureConversation(convId);
352
+ await addMessage(convId, "user", "hello", {
353
+ metadata: { provenanceTrustClass: "unverified_contact" },
354
+ });
355
+
356
+ // Confirm the durable snapshot round-trips through the schema parser.
357
+ const { getConversationRecentProvenanceTrustClass } = await import(
358
+ "../memory/conversation-crud.js"
359
+ );
360
+ expect(getConversationRecentProvenanceTrustClass(convId)).toBe(
361
+ "unverified_contact",
362
+ );
363
+
364
+ // And that pointer-audience trust treats it identically to trusted_contact.
365
+ let processorCalled = false;
366
+ setPointerMessageProcessor(async () => {
367
+ processorCalled = true;
368
+ });
369
+
370
+ await addPointerMessage(convId, "completed", "+15559876543");
371
+ expect(processorCalled).toBe(true);
372
+ });
373
+
346
374
  test("unknown provenance trust class does not grant trusted audience", () => {
347
375
  const convId = "conv-ptr-unknown-provenance";
348
376
  ensureConversation(convId);
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Cancel contract: a user cancel raises the conversation's AbortController and
3
+ * defers clearing the `processing` flag to the in-flight turn's `finally`.
4
+ *
5
+ * `cancelGeneration` no longer force-clears `processing` itself. Abort now
6
+ * propagates into the provider call and tool execution — and is backed by the
7
+ * agent loop's abort watchdog — so a cancelled turn always reaches its
8
+ * `finally` within a bounded time and tears down its own state there. The
9
+ * watchdog-driven path (turn reaches `finally`, processing clears) is covered
10
+ * by `conversation-agent-loop.test.ts`; this file pins the handler-side
11
+ * contract: cancel signals abort and leaves the flag to the turn.
12
+ */
13
+ import { afterEach, describe, expect, test } from "bun:test";
14
+
15
+ import type { Conversation } from "../daemon/conversation.js";
16
+ import {
17
+ deleteConversation,
18
+ setConversation,
19
+ } from "../daemon/conversation-registry.js";
20
+ import { cancelGeneration } from "../daemon/handlers/conversations.js";
21
+
22
+ interface CancelledConversation {
23
+ isProcessing: () => boolean;
24
+ setProcessingCalls: () => boolean[];
25
+ abortCount: () => number;
26
+ }
27
+
28
+ /**
29
+ * Register a conversation whose in-flight turn is processing. The fake records
30
+ * abort calls and any `setProcessing` writes so the test can assert that
31
+ * `cancelGeneration` signals abort without flipping the flag itself.
32
+ */
33
+ function registerProcessingTurn(id: string): CancelledConversation {
34
+ let processing = true;
35
+ let abortCount = 0;
36
+ const setProcessingCalls: boolean[] = [];
37
+ const fake = {
38
+ isProcessing: () => processing,
39
+ setProcessing: (value: boolean) => {
40
+ setProcessingCalls.push(value);
41
+ processing = value;
42
+ },
43
+ abort: () => {
44
+ abortCount += 1;
45
+ },
46
+ };
47
+ setConversation(id, fake as unknown as Conversation);
48
+ return {
49
+ isProcessing: () => processing,
50
+ setProcessingCalls: () => setProcessingCalls,
51
+ abortCount: () => abortCount,
52
+ };
53
+ }
54
+
55
+ describe("cancelGeneration", () => {
56
+ const conversationId = "cancel-clears-processing-test-conversation";
57
+
58
+ afterEach(() => {
59
+ deleteConversation(conversationId);
60
+ });
61
+
62
+ test("raises abort and defers clearing processing to the turn's finally", () => {
63
+ // GIVEN a registered conversation that is processing
64
+ const fake = registerProcessingTurn(conversationId);
65
+ expect(fake.isProcessing()).toBe(true);
66
+
67
+ // WHEN the user cancels generation
68
+ const cancelled = cancelGeneration(conversationId);
69
+
70
+ // THEN the cancel is acknowledged
71
+ expect(cancelled).toBe(true);
72
+ // AND the abort signal is raised on the conversation
73
+ expect(fake.abortCount()).toBe(1);
74
+ // AND cancelGeneration does NOT force-clear the flag itself — the in-flight
75
+ // turn's `finally` owns that teardown once abort drives it there.
76
+ expect(fake.setProcessingCalls()).not.toContain(false);
77
+ expect(fake.isProcessing()).toBe(true);
78
+ });
79
+
80
+ test("returns false for a conversation that is not registered", () => {
81
+ // GIVEN no conversation registered under the id
82
+
83
+ // WHEN the user cancels generation for the unknown id
84
+ const cancelled = cancelGeneration("cancel-clears-processing-unknown-id");
85
+
86
+ // THEN the cancel reports that nothing was found
87
+ expect(cancelled).toBe(false);
88
+ });
89
+ });
@@ -224,14 +224,12 @@ function ensureTestContact(): void {
224
224
  {
225
225
  type: "telegram",
226
226
  address: "telegram-user-default",
227
- externalUserId: "telegram-user-default",
228
227
  status: "active",
229
228
  policy: "allow",
230
229
  },
231
230
  {
232
231
  type: "slack",
233
232
  address: "slack-user-default",
234
- externalUserId: "slack-user-default",
235
233
  status: "active",
236
234
  policy: "allow",
237
235
  },
@@ -2054,7 +2052,6 @@ describe("requester cancel of guardian-gated pending request", () => {
2054
2052
  {
2055
2053
  type: "telegram",
2056
2054
  address: "requester-cancel-user",
2057
- externalUserId: "requester-cancel-user",
2058
2055
  status: "active",
2059
2056
  policy: "allow",
2060
2057
  },
@@ -2981,7 +2978,6 @@ describe("trusted-contact self-approval blocked before guardian approval row exi
2981
2978
  {
2982
2979
  type: "telegram",
2983
2980
  address: "tc-selfapproval-user",
2984
- externalUserId: "tc-selfapproval-user",
2985
2981
  status: "active",
2986
2982
  policy: "allow",
2987
2983
  },
@@ -97,7 +97,6 @@ function seedTrustedContact(policy: "allow" | "escalate" = "allow"): void {
97
97
  {
98
98
  type: "telegram",
99
99
  address: "telegram-user-1",
100
- externalUserId: "telegram-user-1",
101
100
  status: "active",
102
101
  policy,
103
102
  },
@@ -237,14 +236,13 @@ describe("channel inbound disk pressure gate", () => {
237
236
  expect(db.select().from(messages).all()).toHaveLength(0);
238
237
  });
239
238
 
240
- test("blocks non-guardian Slack reactions before persistence while locked", async () => {
239
+ test("blocks non-guardian Slack reactions silently (no reply) before persistence while locked", async () => {
241
240
  upsertContact({
242
241
  displayName: "Example Slack User",
243
242
  channels: [
244
243
  {
245
244
  type: "slack",
246
245
  address: "slack-user-1",
247
- externalUserId: "slack-user-1",
248
246
  status: "active",
249
247
  policy: "allow",
250
248
  },
@@ -276,18 +274,10 @@ describe("channel inbound disk pressure gate", () => {
276
274
  reason: "trusted-contact",
277
275
  });
278
276
  expect(processMessage).not.toHaveBeenCalled();
279
- expect(deliverChannelReplyMock.mock.calls).toEqual([
280
- [
281
- "https://gateway.test/deliver/slack",
282
- {
283
- chatId: "slack-channel-1",
284
- text: expectedRemoteBlockReply,
285
- assistantId: "self",
286
- ephemeral: true,
287
- user: "slack-user-1",
288
- },
289
- ],
290
- ]);
277
+ // Reactions are blocked silently during disk pressure: a passive signal
278
+ // has nothing to "try again", so no block reply is delivered (unlike the
279
+ // message path, which does reply).
280
+ expect(deliverChannelReplyMock).not.toHaveBeenCalled();
291
281
 
292
282
  const db = getDb();
293
283
  const event = db
@@ -790,9 +790,6 @@ describe("Permission Checker", () => {
790
790
  const workingDir = join(homedir(), "projects", "myapp");
791
791
  expect(generateScopeOptions(workingDir, "web_fetch")).toHaveLength(0);
792
792
  expect(generateScopeOptions(workingDir, "skill_load")).toHaveLength(0);
793
- expect(generateScopeOptions(workingDir, "credential_store")).toHaveLength(
794
- 0,
795
- );
796
793
  expect(
797
794
  generateScopeOptions(workingDir, "computer_use_click"),
798
795
  ).toHaveLength(0);
@@ -52,7 +52,7 @@ mock.module("../memory/v2/skill-store.js", () => ({
52
52
  // ---------------------------------------------------------------------------
53
53
 
54
54
  const { registerMemoryV2Command } =
55
- await import("../cli/commands/memory-v2.js");
55
+ await import("../cli/commands/memory/memory-v2.js");
56
56
  const { ROUTES: memoryV2Routes, MEMORY_V2_DISABLED_CODE } =
57
57
  await import("../runtime/routes/memory-v2-routes.js");
58
58
  const { RouteError } = await import("../runtime/routes/errors.js");
@@ -68,9 +68,8 @@ function buildProgram(): Command {
68
68
  writeErr: () => {},
69
69
  writeOut: () => {},
70
70
  });
71
- // The registrar creates the `memory` parent itself, so callers don't
72
- // need to stub one.
73
- registerMemoryV2Command(program);
71
+ const memory = program.command("memory");
72
+ registerMemoryV2Command(memory);
74
73
  return program;
75
74
  }
76
75
 
@@ -196,6 +196,12 @@ const updateConfigCalls: Array<{ maxInputTokens?: number }> = [];
196
196
 
197
197
  mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
198
198
  ContextWindowManager: class {
199
+ estimateInputTokens() {
200
+ return 0;
201
+ }
202
+ get tokenCountInputs() {
203
+ return { systemPrompt: "", tools: undefined };
204
+ }
199
205
  nonPersistedPrefixCount = 0;
200
206
  constructor() {}
201
207
  updateConfig(cfg: { maxInputTokens?: number }) {
@@ -41,7 +41,11 @@ function resetTables(): void {
41
41
 
42
42
  async function addImageMessage(
43
43
  conversationId: string,
44
- provenanceTrustClass: "guardian" | "trusted_contact" | "unknown",
44
+ provenanceTrustClass:
45
+ | "guardian"
46
+ | "trusted_contact"
47
+ | "unverified_contact"
48
+ | "unknown",
45
49
  filename: string,
46
50
  ): Promise<void> {
47
51
  const inserted = await addMessage(
@@ -109,4 +113,20 @@ describe("collectImageManifest trust filtering", () => {
109
113
  expect(filenames).toContain("contact.png");
110
114
  expect(filenames).not.toContain("guardian-secret.png");
111
115
  });
116
+
117
+ test("unverified_contact actor manifest excludes guardian images but keeps unverified-provenance images", async () => {
118
+ // GIVEN a conversation with a guardian image and an unverified-contact image
119
+ const conv = createConversation();
120
+ await addImageMessage(conv.id, "guardian", "guardian-secret.png");
121
+ await addImageMessage(conv.id, "unverified_contact", "unverified.png");
122
+
123
+ // WHEN the manifest is built for an unverified_contact actor
124
+ const manifest = collectImageManifest(conv.id, "unverified_contact");
125
+
126
+ // THEN the unverified-provenance image is listed and the guardian image
127
+ // is excluded — unverified_contact is treated as untrusted downstream.
128
+ const filenames = manifest.map((e) => e.filename);
129
+ expect(filenames).toContain("unverified.png");
130
+ expect(filenames).not.toContain("guardian-secret.png");
131
+ });
112
132
  });