@vellumai/assistant 0.11.3-staging.4 → 0.11.4-staging.1

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 (324) hide show
  1. package/ARCHITECTURE.md +11 -6
  2. package/docs/architecture/memory.md +11 -0
  3. package/docs/architecture/turn-actor.md +70 -0
  4. package/docs/flux-turn-detection-spike.md +243 -0
  5. package/docs/stt-provider-onboarding.md +3 -1
  6. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
  7. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
  8. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +34 -0
  9. package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
  10. package/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
  11. package/openapi.yaml +140 -38
  12. package/package.json +1 -1
  13. package/scripts/voice-ttft-spike.ts +3 -3
  14. package/src/__tests__/app-compiler.test.ts +38 -3
  15. package/src/__tests__/attachments-store.test.ts +21 -12
  16. package/src/__tests__/byok-default-profile-ensure.test.ts +2 -0
  17. package/src/__tests__/call-setup-flow-name-capture.test.ts +0 -1
  18. package/src/__tests__/call-site-routing-provider.test.ts +1 -1
  19. package/src/__tests__/channel-availability-routes.test.ts +14 -1
  20. package/src/__tests__/channel-capabilities-dedupe.test.ts +214 -0
  21. package/src/__tests__/channel-delivery-store.test.ts +14 -14
  22. package/src/__tests__/config-loader-backfill.test.ts +3 -3
  23. package/src/__tests__/config-schema.test.ts +25 -10
  24. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +8 -11
  25. package/src/__tests__/conversation-agent-loop-overflow.test.ts +8 -11
  26. package/src/__tests__/conversation-agent-loop.test.ts +28 -20
  27. package/src/__tests__/conversation-attention-store.test.ts +63 -0
  28. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -4
  29. package/src/__tests__/conversation-fork-crud.test.ts +69 -0
  30. package/src/__tests__/conversation-fork-referential.test.ts +67 -0
  31. package/src/__tests__/conversation-fork-retrospective.test.ts +24 -0
  32. package/src/__tests__/conversation-notifiers-provenance.test.ts +59 -0
  33. package/src/__tests__/conversation-queue.test.ts +55 -4
  34. package/src/__tests__/conversation-runtime-assembly.test.ts +134 -102
  35. package/src/__tests__/conversation-runtime-workspace.test.ts +14 -10
  36. package/src/__tests__/credential-prompt-route.test.ts +7 -10
  37. package/src/__tests__/custom-profile-ensure.test.ts +5 -1
  38. package/src/__tests__/discord-access-request-privacy.test.ts +5 -1
  39. package/src/__tests__/discord-requester-notice-privacy.test.ts +3 -3
  40. package/src/__tests__/document-append-idempotency.test.ts +233 -0
  41. package/src/__tests__/edit-propagation.test.ts +0 -7
  42. package/src/__tests__/helpers/mock-actor-context.ts +49 -0
  43. package/src/__tests__/helpers/mock-conversation.ts +13 -1
  44. package/src/__tests__/injector-chain.test.ts +63 -41
  45. package/src/__tests__/injector-disk-pressure.test.ts +11 -23
  46. package/src/__tests__/llm-context-resolution.test.ts +73 -1
  47. package/src/__tests__/llm-schema.test.ts +5 -2
  48. package/src/__tests__/mcp-list-plugin-servers.test.ts +250 -0
  49. package/src/__tests__/memory-retrieval-hook.test.ts +6 -5
  50. package/src/__tests__/messages-read-boundary-guard.test.ts +134 -0
  51. package/src/__tests__/mtime-cache.test.ts +1 -1
  52. package/src/__tests__/non-member-access-request.test.ts +0 -20
  53. package/src/__tests__/outbound-slack-persistence.test.ts +40 -1
  54. package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -0
  55. package/src/__tests__/plugin-secret-pattern-contribution.test.ts +1 -1
  56. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +14 -7
  57. package/src/__tests__/provider-commit-message-generator.test.ts +20 -0
  58. package/src/__tests__/run-conversation-turn-persistence.test.ts +434 -105
  59. package/src/__tests__/scoped-approval-grants.test.ts +11 -6
  60. package/src/__tests__/secret-ingress-channel.test.ts +0 -1
  61. package/src/__tests__/skills.test.ts +32 -0
  62. package/src/__tests__/slack-edit-ordering-characterization.test.ts +0 -1
  63. package/src/__tests__/subagent-call-site-routing.test.ts +31 -19
  64. package/src/__tests__/subagent-spawn-and-await.test.ts +14 -10
  65. package/src/__tests__/turn-events-store.test.ts +43 -0
  66. package/src/__tests__/user-plugin-loader.test.ts +1 -1
  67. package/src/__tests__/visible-app-context.test.ts +16 -9
  68. package/src/__tests__/worker-entrypoint-guards.test.ts +54 -0
  69. package/src/__tests__/worker-plugin-surface.test.ts +77 -0
  70. package/src/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +158 -0
  71. package/src/__tests__/workspace-migration-143-repair-deprecated-codex-model-id.test.ts +133 -0
  72. package/src/__tests__/workspace-migration-144-convert-stranded-subscription-openai-profiles.test.ts +316 -0
  73. package/src/__tests__/workspace-migration-145-collapse-profile-bindings-to-entries.test.ts +325 -0
  74. package/src/acp/__tests__/acp-claude-oauth.test.ts +10 -2
  75. package/src/acp/__tests__/auth-required.test.ts +161 -0
  76. package/src/acp/acp-claude-oauth.ts +19 -2
  77. package/src/acp/agent-process.test.ts +100 -0
  78. package/src/acp/agent-process.ts +29 -26
  79. package/src/acp/auth-required.ts +102 -0
  80. package/src/acp/session-manager.test.ts +119 -0
  81. package/src/acp/session-manager.ts +68 -2
  82. package/src/api/events/acp-auth-required.ts +55 -0
  83. package/src/api/index.ts +7 -0
  84. package/src/apps/app-store.ts +3 -0
  85. package/src/bundler/package-resolver.ts +2 -30
  86. package/src/calls/__tests__/voice-session-bridge.test.ts +173 -1
  87. package/src/calls/__tests__/voice-triage-escalate.test.ts +94 -0
  88. package/src/calls/call-controller.ts +9 -2
  89. package/src/calls/call-setup-flow.ts +0 -1
  90. package/src/calls/media-stream-stt-session.ts +15 -0
  91. package/src/calls/voice-session-bridge.ts +71 -16
  92. package/src/calls/voice-triage-escalate.ts +104 -2
  93. package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
  94. package/src/channels/config.ts +13 -0
  95. package/src/channels/plugin-channel-declarations.ts +108 -0
  96. package/src/channels/types.ts +30 -0
  97. package/src/cli/AGENTS.md +5 -2
  98. package/src/cli/commands/credentials.help.ts +2 -2
  99. package/src/cli/commands/inference-providers.ts +1 -1
  100. package/src/cli/commands/mcp.help.ts +13 -4
  101. package/src/cli/commands/mcp.ts +9 -0
  102. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +128 -5
  103. package/src/cli/commands/memory/index.help.ts +43 -1
  104. package/src/cli/commands/memory/memory-v3.ts +64 -0
  105. package/src/cli/commands/stt.help.ts +27 -2
  106. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +39 -0
  107. package/src/cli/lib/bundled-marketplace.json +13 -0
  108. package/src/cli/lib/upgrade-plugin.ts +42 -0
  109. package/src/config/__tests__/default-profile-catalog.test.ts +34 -2
  110. package/src/config/__tests__/default-provider.test.ts +6 -1
  111. package/src/config/__tests__/profile-materialization.test.ts +75 -19
  112. package/src/config/bundled-skills/acp/SKILL.md +6 -7
  113. package/src/config/bundled-skills/document-editor/SKILL.md +2 -2
  114. package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
  115. package/src/config/bundled-skills/media-processing/services/preprocess.ts +14 -4
  116. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  117. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +22 -1
  118. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
  119. package/src/config/call-site-defaults.ts +4 -5
  120. package/src/config/default-profile-catalog.ts +82 -11
  121. package/src/config/default-profile-names.ts +4 -1
  122. package/src/config/default-provider-resolution.ts +4 -0
  123. package/src/config/llm-context-resolution.ts +11 -3
  124. package/src/config/llm-resolver.ts +28 -1
  125. package/src/config/profile-materialization.ts +70 -22
  126. package/src/config/schemas/__tests__/live-voice.test.ts +107 -4
  127. package/src/config/schemas/call-site-catalog.ts +4 -4
  128. package/src/config/schemas/live-voice.ts +57 -23
  129. package/src/config/schemas/llm.ts +59 -32
  130. package/src/config/schemas/mcp.ts +23 -0
  131. package/src/config/schemas/plugin-updates.ts +6 -2
  132. package/src/config/schemas/stt.ts +1 -0
  133. package/src/context/outbound-sanitize.ts +96 -1
  134. package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +82 -0
  135. package/src/daemon/conversation-agent-loop-handlers.ts +15 -10
  136. package/src/daemon/conversation-agent-loop.ts +17 -6
  137. package/src/daemon/conversation-messaging.ts +5 -1
  138. package/src/daemon/conversation-notifiers.ts +9 -1
  139. package/src/daemon/conversation-process.ts +9 -6
  140. package/src/daemon/conversation-runtime-assembly.ts +3 -4
  141. package/src/daemon/conversation-tool-setup.ts +1 -2
  142. package/src/daemon/conversation.ts +48 -0
  143. package/src/daemon/mcp-reload-service.ts +36 -6
  144. package/src/daemon/process-message.ts +13 -3
  145. package/src/daemon/providers-setup.ts +6 -3
  146. package/src/daemon/trust-context-types.ts +29 -0
  147. package/src/daemon/wake-conversation-ops.ts +3 -2
  148. package/src/documents/document-store.ts +138 -5
  149. package/src/hooks/hook-loader.ts +3 -3
  150. package/src/hooks/registry.ts +50 -6
  151. package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
  152. package/src/inbound/oauth-callback-url.ts +61 -0
  153. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +1 -104
  154. package/src/live-voice/__tests__/live-voice-events.test.ts +7 -8
  155. package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +932 -0
  156. package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
  157. package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
  158. package/src/live-voice/__tests__/live-voice-progress.test.ts +60 -194
  159. package/src/live-voice/__tests__/live-voice-stt.test.ts +14 -0
  160. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +29 -0
  161. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
  162. package/src/live-voice/__tests__/live-voice-vad.test.ts +0 -16
  163. package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
  164. package/src/live-voice/live-voice-archive.ts +2 -0
  165. package/src/live-voice/live-voice-metrics.ts +57 -32
  166. package/src/live-voice/live-voice-photo.ts +1 -2
  167. package/src/live-voice/live-voice-session.ts +535 -314
  168. package/src/live-voice/progress-narration.ts +277 -0
  169. package/src/live-voice/protocol.ts +21 -1
  170. package/src/mcp/__tests__/effective-config.test.ts +238 -0
  171. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
  172. package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +200 -0
  173. package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
  174. package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +95 -0
  175. package/src/mcp/client.ts +16 -11
  176. package/src/mcp/effective-config.ts +113 -0
  177. package/src/mcp/manager.ts +11 -6
  178. package/src/mcp/mcp-auth-orchestrator.ts +13 -22
  179. package/src/mcp/mcp-oauth-provider.ts +205 -240
  180. package/src/monitoring/__tests__/plugin-auto-update.test.ts +166 -3
  181. package/src/monitoring/plugin-auto-update.ts +128 -24
  182. package/src/notifications/signal.ts +1 -0
  183. package/src/permissions/confirmation-guardian-request.test.ts +15 -11
  184. package/src/permissions/confirmation-guardian-request.ts +2 -2
  185. package/src/permissions/question-guardian-request.test.ts +14 -6
  186. package/src/permissions/question-guardian-request.ts +1 -2
  187. package/src/persistence/attachments-store.ts +8 -1
  188. package/src/persistence/bookmark-crud.ts +3 -7
  189. package/src/persistence/conversation-attention-store.ts +16 -45
  190. package/src/persistence/conversation-crud.ts +33 -4
  191. package/src/persistence/conversation-lineage.ts +9 -0
  192. package/src/persistence/conversation-queries.ts +108 -41
  193. package/src/persistence/delivery-crud.ts +38 -29
  194. package/src/persistence/external-conversation-store.ts +32 -4
  195. package/src/persistence/llm-request-log-store.ts +4 -10
  196. package/src/persistence/llm-usage-store.ts +8 -3
  197. package/src/persistence/message-reads.test.ts +197 -0
  198. package/src/persistence/message-reads.ts +211 -0
  199. package/src/persistence/migrations/366-chatgpt-subscription-row-identity.test.ts +120 -0
  200. package/src/persistence/migrations/366-chatgpt-subscription-row-identity.ts +62 -0
  201. package/src/persistence/real-user-turn-filter.ts +27 -3
  202. package/src/persistence/steps.ts +9 -0
  203. package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
  204. package/src/plugin-api/conversation-turn.ts +168 -5
  205. package/src/plugin-api/index.ts +21 -5
  206. package/src/plugins/__tests__/mcp-servers.test.ts +371 -0
  207. package/src/plugins/defaults/memory/AGENTS.md +4 -0
  208. package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +204 -0
  209. package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +72 -0
  210. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +4 -1
  211. package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +4 -1
  212. package/src/plugins/defaults/memory/buffer-format.ts +165 -0
  213. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +6 -0
  214. package/src/plugins/defaults/memory/graph/image-ref-utils.ts +3 -0
  215. package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -30
  216. package/src/plugins/defaults/memory/graph-topology/pending-buffer.test.ts +34 -0
  217. package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +8 -12
  218. package/src/plugins/defaults/memory/hooks/post-compact.ts +1 -4
  219. package/src/plugins/defaults/memory/indexer.ts +3 -1
  220. package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +19 -7
  221. package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +281 -0
  222. package/src/plugins/defaults/memory/src/memory-v3-routes.ts +207 -0
  223. package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +33 -0
  224. package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +199 -2
  225. package/src/plugins/defaults/memory/substrate/consolidation-job.ts +25 -18
  226. package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
  227. package/src/plugins/defaults/memory/substrate/static-context.ts +160 -4
  228. package/src/plugins/defaults/memory/substrate/sweep-job.ts +2 -4
  229. package/src/plugins/defaults/memory/v1/graph/extraction.ts +3 -1
  230. package/src/plugins/defaults/memory/v3/prune.ts +2 -0
  231. package/src/plugins/defaults/memory/v3/selection-log-store.ts +2 -0
  232. package/src/plugins/defaults/memory/worker.ts +6 -3
  233. package/src/plugins/external-plugin-loader.ts +47 -0
  234. package/src/plugins/mcp-servers.ts +361 -0
  235. package/src/plugins/mtime-cache.ts +23 -49
  236. package/src/plugins/worker-plugin-surface.ts +33 -0
  237. package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
  238. package/src/providers/__tests__/dispatch-connection-routing.test.ts +214 -2
  239. package/src/providers/__tests__/preflight-resolved-config.test.ts +57 -0
  240. package/src/providers/__tests__/retry-callsite.test.ts +5 -2
  241. package/src/providers/call-site-routing.ts +30 -3
  242. package/src/providers/connection-resolution.ts +194 -11
  243. package/src/providers/inference/auth.ts +6 -0
  244. package/src/providers/inference/connection-availability.ts +24 -2
  245. package/src/providers/inference/connections.ts +2 -0
  246. package/src/providers/model-intents.ts +26 -6
  247. package/src/providers/openai/codex-models.ts +2 -1
  248. package/src/providers/provider-send-message.ts +32 -3
  249. package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +433 -0
  250. package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +620 -0
  251. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
  252. package/src/providers/speech-to-text/__tests__/resolve.test.ts +285 -6
  253. package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
  254. package/src/providers/speech-to-text/deepgram-flux-realtime.ts +719 -0
  255. package/src/providers/speech-to-text/provider-catalog.ts +99 -8
  256. package/src/providers/speech-to-text/resolve.ts +25 -2
  257. package/src/routes/worker.ts +17 -5
  258. package/src/runtime/access-request-helper.ts +9 -12
  259. package/src/runtime/agent-wake.ts +3 -3
  260. package/src/runtime/pre-first-message-gate.ts +4 -0
  261. package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +12 -4
  262. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +219 -1
  263. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +52 -0
  264. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +61 -0
  265. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +44 -0
  266. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +102 -1
  267. package/src/runtime/routes/__tests__/plugins-routes.test.ts +44 -0
  268. package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
  269. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +62 -1
  270. package/src/runtime/routes/channel-availability-routes.ts +32 -14
  271. package/src/runtime/routes/channel-route-shared.ts +0 -6
  272. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +6 -6
  273. package/src/runtime/routes/conversation-list-routes.ts +112 -1
  274. package/src/runtime/routes/conversation-query-routes.ts +40 -27
  275. package/src/runtime/routes/credential-prompt-routes.ts +4 -7
  276. package/src/runtime/routes/default-provider-routes.ts +15 -0
  277. package/src/runtime/routes/inbound-message-handler.ts +17 -41
  278. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -1
  279. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -9
  280. package/src/runtime/routes/inbound-stages/admission-policy.ts +1 -17
  281. package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -1
  282. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -3
  283. package/src/runtime/routes/inbound-stages/edit-intercept.ts +1 -3
  284. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -1
  285. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -4
  286. package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +0 -1
  287. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +11 -20
  288. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +2 -3
  289. package/src/runtime/routes/inference-profiles-routes.ts +20 -11
  290. package/src/runtime/routes/inference-provider-connection-routes.ts +77 -15
  291. package/src/runtime/routes/log-export-routes.ts +3 -0
  292. package/src/runtime/routes/mcp-auth-routes.ts +148 -57
  293. package/src/runtime/routes/plugins-routes.ts +21 -3
  294. package/src/runtime/routes/stt-routes.ts +31 -25
  295. package/src/runtime/routes/surface-conversation-resolver.ts +3 -0
  296. package/src/runtime/routes/user-route-dispatcher.ts +39 -14
  297. package/src/runtime/routes/user-route-import.ts +108 -0
  298. package/src/schedule/worker.ts +6 -0
  299. package/src/security/oauth2.ts +6 -22
  300. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +22 -0
  301. package/src/stt/__tests__/types.test.ts +94 -0
  302. package/src/stt/daemon-batch-transcriber.ts +10 -0
  303. package/src/stt/stt-stream-session.ts +8 -4
  304. package/src/stt/types.ts +103 -0
  305. package/src/subagent/manager.ts +1 -3
  306. package/src/subagent/types.ts +7 -6
  307. package/src/tools/acp/spawn.test.ts +97 -0
  308. package/src/tools/acp/spawn.ts +32 -0
  309. package/src/tools/document/document-tool.ts +12 -3
  310. package/src/tools/registry.ts +2 -1
  311. package/src/tools/workflows/run-workflow.ts +1 -2
  312. package/src/tts/__tests__/reasoning-tag-filter.test.ts +63 -0
  313. package/src/tts/reasoning-tag-filter.ts +110 -0
  314. package/src/workspace/byok-default-profile-ensure.ts +61 -18
  315. package/src/workspace/custom-profile-ensure.ts +4 -24
  316. package/src/workspace/migrations/142-consolidate-voice-front-door.ts +70 -0
  317. package/src/workspace/migrations/143-repair-deprecated-codex-model-id.ts +134 -0
  318. package/src/workspace/migrations/144-convert-stranded-subscription-openai-profiles.ts +265 -0
  319. package/src/workspace/migrations/145-collapse-profile-bindings-to-entries.ts +328 -0
  320. package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +0 -10
  321. package/src/workspace/migrations/registry.ts +8 -0
  322. package/src/workspace/provider-commit-message-generator.ts +7 -5
  323. package/src/live-voice/__tests__/front-decision.test.ts +0 -645
  324. package/src/live-voice/front-decision.ts +0 -476
package/openapi.yaml CHANGED
@@ -3,7 +3,7 @@
3
3
  openapi: 3.1.0
4
4
  info:
5
5
  title: Vellum Assistant API
6
- version: 0.11.3
6
+ version: 0.11.4
7
7
  description: Auto-generated OpenAPI specification for the Vellum Assistant runtime HTTP server.
8
8
  servers:
9
9
  - url: http://127.0.0.1:7821
@@ -4017,8 +4017,8 @@ paths:
4017
4017
  summary: Get available channels
4018
4018
  description:
4019
4019
  Return the channels this assistant can surface to clients, with display metadata (label, icon, verification
4020
- capability, setup copy). Today this is a fixed base list plus `email` when an inbox is registered; will become
4021
- plugin/skill-driven in future.
4020
+ capability, setup copy). A fixed base list plus `email` when an inbox is registered, plus the channels installed
4021
+ plugins bring by declaring ingress routes. Each carries a `source` saying which of those it is.
4022
4022
  tags:
4023
4023
  - channels
4024
4024
  responses:
@@ -4036,16 +4036,9 @@ paths:
4036
4036
  properties:
4037
4037
  id:
4038
4038
  type: string
4039
- enum:
4040
- - telegram
4041
- - phone
4042
- - vellum
4043
- - whatsapp
4044
- - slack
4045
- - email
4046
- - platform
4047
- - a2a
4048
- - discord
4039
+ source:
4040
+ type: string
4041
+ description: "`default` for a channel the assistant ships, `plugin:<name>` for one an installed plugin brings"
4049
4042
  label:
4050
4043
  type: string
4051
4044
  subtitle:
@@ -4067,13 +4060,16 @@ paths:
4067
4060
  additionalProperties: false
4068
4061
  required:
4069
4062
  - id
4063
+ - source
4070
4064
  - label
4071
4065
  - subtitle
4072
4066
  - icon
4073
4067
  - supportsVerification
4074
4068
  - setupMessages
4075
4069
  additionalProperties: false
4076
- description: Available channels in display order
4070
+ description:
4071
+ "Available channels in display order: the ones the assistant ships, then the ones installed plugins bring
4072
+ by declaring ingress routes. `source` distinguishes them."
4077
4073
  required:
4078
4074
  - channels
4079
4075
  additionalProperties: false
@@ -4358,6 +4354,7 @@ paths:
4358
4354
  - platform
4359
4355
  - a2a
4360
4356
  - discord
4357
+ - plugin
4361
4358
  ready:
4362
4359
  type: boolean
4363
4360
  setupStatus:
@@ -4448,6 +4445,7 @@ paths:
4448
4445
  - platform
4449
4446
  - a2a
4450
4447
  - discord
4448
+ - plugin
4451
4449
  includeRemote:
4452
4450
  description: Include remote checks (default true)
4453
4451
  type: boolean
@@ -4478,6 +4476,7 @@ paths:
4478
4476
  - platform
4479
4477
  - a2a
4480
4478
  - discord
4479
+ - plugin
4481
4480
  ready:
4482
4481
  type: boolean
4483
4482
  setupStatus:
@@ -4827,6 +4826,7 @@ paths:
4827
4826
  - gemini
4828
4827
  - fireworks
4829
4828
  - openrouter
4829
+ - chatgpt
4830
4830
  - vellum
4831
4831
  - together
4832
4832
  - vercel-ai-gateway
@@ -6582,6 +6582,7 @@ paths:
6582
6582
  - platform
6583
6583
  - a2a
6584
6584
  - discord
6585
+ - plugin
6585
6586
  description:
6586
6587
  Filter by origin channel. When provided, only conversations with this exact origin_channel value are
6587
6588
  returned. Omit to include all channels.
@@ -6593,8 +6594,8 @@ paths:
6593
6594
  description:
6594
6595
  Filter to a single group, so each sidebar section can load independently of the paginated list. Pass
6595
6596
  "system:all" for conversations in no group, "system:pinned" for the Pinned section, or a custom group id. A
6596
- group-scoped request is ordered by the user's arrangement (display order, then recency) and never has pinned
6597
- rows appended to it. Omit to span every group.
6597
+ group-scoped request is recency-ordered like every list read (COALESCE(last_message_at, updated_at)
6598
+ descending) and never has pinned rows appended to it. Omit to span every group.
6598
6599
  responses:
6599
6600
  "200":
6600
6601
  description: Successful response
@@ -6718,6 +6719,7 @@ paths:
6718
6719
  - platform
6719
6720
  - a2a
6720
6721
  - discord
6722
+ - plugin
6721
6723
  - type: "null"
6722
6724
  assistantAttention:
6723
6725
  type: object
@@ -7081,6 +7083,7 @@ paths:
7081
7083
  - platform
7082
7084
  - a2a
7083
7085
  - discord
7086
+ - plugin
7084
7087
  - type: "null"
7085
7088
  assistantAttention:
7086
7089
  type: object
@@ -8294,6 +8297,7 @@ paths:
8294
8297
  - platform
8295
8298
  - a2a
8296
8299
  - discord
8300
+ - plugin
8297
8301
  - type: "null"
8298
8302
  assistantAttention:
8299
8303
  type: object
@@ -9379,6 +9383,107 @@ paths:
9379
9383
  - query
9380
9384
  - results
9381
9385
  additionalProperties: false
9386
+ /v1/conversations/sections:
9387
+ get:
9388
+ operationId: conversations_sections_get
9389
+ summary: Sidebar section index
9390
+ description:
9391
+ "One row per renderable sidebar section (Pinned, each non-empty custom group, each origin channel with
9392
+ unassigned conversations, Chats) with total and unread counts and no conversation rows. Lets a client know which
9393
+ sections exist, and what their badges say, without fetching any conversation list. Totals follow the standard
9394
+ listing visibility; unread applies the same rules as GET /v1/conversations/unread-count scoped to the section.
9395
+ Chats is always present, even at zero: it is the leftover bucket and renders regardless."
9396
+ tags:
9397
+ - conversations
9398
+ responses:
9399
+ "200":
9400
+ description: Successful response
9401
+ content:
9402
+ application/json:
9403
+ schema:
9404
+ type: object
9405
+ properties:
9406
+ sections:
9407
+ type: array
9408
+ items:
9409
+ oneOf:
9410
+ - type: object
9411
+ properties:
9412
+ kind:
9413
+ type: string
9414
+ const: pinned
9415
+ total:
9416
+ type: number
9417
+ unread:
9418
+ type: number
9419
+ required:
9420
+ - kind
9421
+ - total
9422
+ - unread
9423
+ additionalProperties: false
9424
+ - type: object
9425
+ properties:
9426
+ kind:
9427
+ type: string
9428
+ const: group
9429
+ groupId:
9430
+ type: string
9431
+ name:
9432
+ type: string
9433
+ icon:
9434
+ anyOf:
9435
+ - type: string
9436
+ - type: "null"
9437
+ sortPosition:
9438
+ type: number
9439
+ total:
9440
+ type: number
9441
+ unread:
9442
+ type: number
9443
+ required:
9444
+ - kind
9445
+ - groupId
9446
+ - name
9447
+ - icon
9448
+ - sortPosition
9449
+ - total
9450
+ - unread
9451
+ additionalProperties: false
9452
+ - type: object
9453
+ properties:
9454
+ kind:
9455
+ type: string
9456
+ const: channel
9457
+ channelId:
9458
+ type: string
9459
+ total:
9460
+ type: number
9461
+ unread:
9462
+ type: number
9463
+ required:
9464
+ - kind
9465
+ - channelId
9466
+ - total
9467
+ - unread
9468
+ additionalProperties: false
9469
+ - type: object
9470
+ properties:
9471
+ kind:
9472
+ type: string
9473
+ const: chats
9474
+ total:
9475
+ type: number
9476
+ unread:
9477
+ type: number
9478
+ required:
9479
+ - kind
9480
+ - total
9481
+ - unread
9482
+ additionalProperties: false
9483
+ type: object
9484
+ required:
9485
+ - sections
9486
+ additionalProperties: false
9382
9487
  /v1/conversations/seen:
9383
9488
  post:
9384
9489
  operationId: conversations_seen_post
@@ -14832,7 +14937,7 @@ paths:
14832
14937
  type: string
14833
14938
  description:
14834
14939
  "Filter by provider. One of: anthropic, openai, gemini, ollama, fireworks, together, openrouter,
14835
- vercel-ai-gateway, litellm, openai-compatible, minimax, atlascloud, baseten, poolside, vellum"
14940
+ vercel-ai-gateway, litellm, openai-compatible, minimax, atlascloud, baseten, poolside, vellum, chatgpt"
14836
14941
  responses:
14837
14942
  "200":
14838
14943
  description: Successful response
@@ -21962,6 +22067,7 @@ paths:
21962
22067
  - platform
21963
22068
  - a2a
21964
22069
  - discord
22070
+ - plugin
21965
22071
  - scheduler
21966
22072
  - watcher
21967
22073
  sourceContextId:
@@ -24335,8 +24441,9 @@ paths:
24335
24441
  non-conflicting edits from both sides forward and resolving conflicting hunks toward the local edit (`ours`) or
24336
24442
  the target (`theirs`), or writing git conflict markers into the file and reporting them in
24337
24443
  `conflicts`/`binaryConflicts` for the assistant to resolve (`assistant`). A merge strategy whose install-time
24338
- baseline cannot be reconstructed returns 409. Mirrors the CLI''s `assistant plugins upgrade <name> [--strategy
24339
- <s>]`.'
24444
+ baseline cannot be reconstructed returns 409. Pass `marketplaceOnly` to refuse the untrusted direct path
24445
+ outright (409), which is what the unattended auto-update sweep does. Mirrors the CLI''s `assistant plugins
24446
+ upgrade <name> [--strategy <s>]`.'
24340
24447
  tags:
24341
24448
  - plugins
24342
24449
  parameters:
@@ -24366,6 +24473,13 @@ paths:
24366
24473
  - theirs
24367
24474
  - overwrite
24368
24475
  - assistant
24476
+ marketplaceOnly:
24477
+ description:
24478
+ Refuse the upgrade (409) when the marketplace does not claim this plugin, instead of advancing it to
24479
+ whatever its recorded GitHub ref now resolves to. Set by unattended callers such as the automatic
24480
+ update sweep, for which running code no curator reviewed is never an acceptable outcome. Defaults to
24481
+ false.
24482
+ type: boolean
24369
24483
  responses:
24370
24484
  "200":
24371
24485
  description: Successful response
@@ -24465,8 +24579,9 @@ paths:
24465
24579
  description: No copy of the plugin is installed, or its source resolves to nothing.
24466
24580
  "409":
24467
24581
  description:
24468
- The install has neither a marketplace entry nor a recorded GitHub source to advance to, or a merge strategy
24469
- was requested whose install-time baseline cannot be reconstructed.
24582
+ The install has neither a marketplace entry nor a recorded GitHub source to advance to, a `marketplaceOnly`
24583
+ upgrade was requested for an install the marketplace does not claim, or a merge strategy was requested whose
24584
+ install-time baseline cannot be reconstructed.
24470
24585
  "503":
24471
24586
  description: The plugin source (GitHub) was temporarily unavailable; the upgrade is retryable.
24472
24587
  /v1/plugins/{name}/versions:
@@ -33912,23 +34027,7 @@ components:
33912
34027
  additionalProperties: {}
33913
34028
  LLMProvider:
33914
34029
  type: string
33915
- enum:
33916
- - anthropic
33917
- - openai
33918
- - gemini
33919
- - ollama
33920
- - fireworks
33921
- - openrouter
33922
- - vercel-ai-gateway
33923
- - openai-compatible
33924
- - minimax
33925
- - atlascloud
33926
- - together
33927
- - litellm
33928
- - baseten
33929
- - poolside
33930
- - vellum
33931
- - chatgpt
34030
+ minLength: 1
33932
34031
  ProfilePatchEntry:
33933
34032
  type: object
33934
34033
  properties:
@@ -34309,6 +34408,7 @@ components:
34309
34408
  - baseten
34310
34409
  - poolside
34311
34410
  - vellum
34411
+ - chatgpt
34312
34412
  Auth:
34313
34413
  oneOf:
34314
34414
  - type: object
@@ -34526,6 +34626,7 @@ components:
34526
34626
  - gemini
34527
34627
  - fireworks
34528
34628
  - openrouter
34629
+ - chatgpt
34529
34630
  - vellum
34530
34631
  - together
34531
34632
  - vercel-ai-gateway
@@ -34903,6 +35004,7 @@ components:
34903
35004
  - gemini
34904
35005
  - fireworks
34905
35006
  - openrouter
35007
+ - chatgpt
34906
35008
  - vellum
34907
35009
  - together
34908
35010
  - vercel-ai-gateway
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/assistant",
3
- "version": "0.11.3-staging.4",
3
+ "version": "0.11.4-staging.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -8,7 +8,7 @@
8
8
  * script's `full` variants and the live session's `llmFirstDeltaMs`).
9
9
  *
10
10
  * Variants:
11
- * slim-haiku voiceFrontDecision call site (Haiku pin), slim prompt
11
+ * slim-front voiceFrontDoor call site, slim prompt
12
12
  * slim-flash cost-optimized profile, same slim prompt
13
13
  * full-notools cost-optimized, real buildSystemPrompt(), no tools
14
14
  * full-flash cost-optimized, real buildSystemPrompt() + full tool defs
@@ -170,8 +170,8 @@ async function main(): Promise<void> {
170
170
 
171
171
  const variants: VariantSpec[] = [
172
172
  {
173
- name: "slim-haiku",
174
- callSite: "voiceFrontDecision",
173
+ name: "slim-front",
174
+ callSite: "voiceFrontDoor",
175
175
  systemPrompt: () => SLIM_SYSTEM_PROMPT,
176
176
  },
177
177
  {
@@ -20,6 +20,7 @@ import {
20
20
  packageName,
21
21
  resolvePackage,
22
22
  } from "../bundler/package-resolver.js";
23
+ import { ensureBun } from "../util/bun-runtime.js";
23
24
 
24
25
  // ---------------------------------------------------------------------------
25
26
  // Shared temp directory
@@ -56,6 +57,29 @@ async function scaffold(
56
57
  return appDir;
57
58
  }
58
59
 
60
+ /**
61
+ * Download `pkg` into bun's global module cache via a throwaway install.
62
+ *
63
+ * `resolvePackage` bounds its own install at INSTALL_TIMEOUT_MS (10s), which a
64
+ * cold global cache can exceed for a large package on a slow network. Priming
65
+ * first is unbounded, so the install the test measures resolves from cache and
66
+ * stays well inside that bound.
67
+ */
68
+ async function primeBunCache(pkg: string): Promise<void> {
69
+ const primeDir = join(tempDir, `prime-${pkg.replaceAll(/[^a-z0-9]/gi, "-")}`);
70
+ await mkdir(primeDir, { recursive: true });
71
+ await writeFile(
72
+ join(primeDir, "package.json"),
73
+ JSON.stringify({ name: "prime-cache", private: true }),
74
+ );
75
+ const proc = Bun.spawn([await ensureBun(), "install", "--no-save", pkg], {
76
+ cwd: primeDir,
77
+ stdout: "ignore",
78
+ stderr: "ignore",
79
+ });
80
+ await proc.exited;
81
+ }
82
+
59
83
  const MINIMAL_HTML = `<!DOCTYPE html>
60
84
  <html>
61
85
  <head><title>Test</title></head>
@@ -466,10 +490,21 @@ describe("package-resolver", () => {
466
490
  expect(ALLOWED_PACKAGES).toContain("clsx");
467
491
  });
468
492
 
469
- // `lucide` (the vanilla package) unpacks to ~29 MB, far above the resolver's
470
- // size cap, so it is installed then deleted and never resolves. It also
471
- // exports icon data arrays, not Preact components. Apps use inline SVG.
493
+ // `lucide` (the vanilla package) exports icon data arrays, not Preact
494
+ // components, and unpacks to ~29 MB for no benefit. Apps use inline SVG.
472
495
  test("ALLOWED_PACKAGES excludes lucide", () => {
473
496
  expect(ALLOWED_PACKAGES).not.toContain("lucide");
474
497
  });
498
+
499
+ // `chart.js` is a large allowlisted package: it must install into the shared
500
+ // cache and resolve so apps importing it can compile.
501
+ test("resolvePackage installs a large allowlisted package", async () => {
502
+ await primeBunCache("chart.js");
503
+
504
+ const result = await resolvePackage("chart.js");
505
+ expect(result).not.toBeNull();
506
+ expect(existsSync(join(getCacheDir(), "node_modules", "chart.js"))).toBe(
507
+ true,
508
+ );
509
+ }, 60_000);
475
510
  });
@@ -722,12 +722,6 @@ describe("validateAttachmentUpload", () => {
722
722
  expect(exeResult.error).toContain(".exe");
723
723
  }
724
724
 
725
- const shResult = validateAttachmentUpload("script.sh", "text/plain");
726
- expect(shResult.ok).toBe(false);
727
- if (!shResult.ok) {
728
- expect(shResult.error).toContain(".sh");
729
- }
730
-
731
725
  const isoResult = validateAttachmentUpload(
732
726
  "disk.iso",
733
727
  "application/octet-stream",
@@ -738,6 +732,24 @@ describe("validateAttachmentUpload", () => {
738
732
  }
739
733
  });
740
734
 
735
+ test("accepts shell scripts as text attachments", () => {
736
+ expect(validateAttachmentUpload("script.sh", "text/plain").ok).toBe(true);
737
+ expect(validateAttachmentUpload("script.SH", "text/plain").ok).toBe(true);
738
+ expect(
739
+ validateAttachmentUpload("setup.sh", "application/x-sh").ok,
740
+ ).toBe(true);
741
+ expect(
742
+ validateAttachmentUpload("run.sh", "application/x-shellscript").ok,
743
+ ).toBe(true);
744
+ expect(validateAttachmentUpload("run.sh", "text/x-sh").ok).toBe(true);
745
+ expect(validateAttachmentUpload("run.sh", "text/x-shellscript").ok).toBe(
746
+ true,
747
+ );
748
+ expect(
749
+ validateAttachmentUpload("run.sh", "application/octet-stream").ok,
750
+ ).toBe(true);
751
+ });
752
+
741
753
  test("rejects dangerous extensions regardless of claimed MIME type", () => {
742
754
  // .exe disguised as image/png
743
755
  const result = validateAttachmentUpload("payload.exe", "image/png");
@@ -748,7 +760,9 @@ describe("validateAttachmentUpload", () => {
748
760
  expect(
749
761
  validateAttachmentUpload("PROGRAM.EXE", "application/octet-stream").ok,
750
762
  ).toBe(false);
751
- expect(validateAttachmentUpload("script.SH", "text/plain").ok).toBe(false);
763
+ expect(validateAttachmentUpload("INSTALL.DMG", "application/octet-stream").ok).toBe(
764
+ false,
765
+ );
752
766
  });
753
767
 
754
768
  test("rejects unsupported MIME types", () => {
@@ -815,11 +829,6 @@ describe("validateAttachmentUpload", () => {
815
829
  trustedSource: true,
816
830
  }).ok,
817
831
  ).toBe(true);
818
- expect(
819
- validateAttachmentUpload("build.sh", "text/plain", {
820
- trustedSource: true,
821
- }).ok,
822
- ).toBe(true);
823
832
  });
824
833
 
825
834
  test("trustedSource: false keeps strict validation", () => {
@@ -278,6 +278,8 @@ describe("ensureByokDefaultProfiles", () => {
278
278
  ["openrouter", "quality-optimized", "anthropic/claude-opus-4.8"],
279
279
  ["gemini", "cost-optimized", "gemini-3.1-flash-lite-preview"],
280
280
  ["openai", "cost-optimized", "gpt-5.4-nano"],
281
+ ["openai", "balanced", "gpt-5.4-mini"],
282
+ ["openai", "quality-optimized", "gpt-5.4"],
281
283
  ["fireworks", "balanced", "accounts/fireworks/models/kimi-k2p5"],
282
284
  ["fireworks", "balanced", "accounts/fireworks/models/kimi-k2p6"],
283
285
  [
@@ -360,7 +360,6 @@ describe("CallSetupFlow name capture", () => {
360
360
  ).toEqual({ from: PHONE_NUMBER, callerName: CALLER_NAME });
361
361
  expect(f.notifyCalls).toEqual([
362
362
  {
363
- canonicalAssistantId: "self",
364
363
  sourceChannel: "phone",
365
364
  conversationExternalId: PHONE_NUMBER,
366
365
  actorExternalId: PHONE_NUMBER,
@@ -67,7 +67,7 @@ function makeConnectionHook(
67
67
  byConnection: Record<string, Provider>,
68
68
  ): (
69
69
  connectionName: string,
70
- expectedProvider: string,
70
+ expectedProvider: string | undefined,
71
71
  ) => Promise<Provider | null> {
72
72
  return async (connectionName, _expectedProvider) =>
73
73
  byConnection[connectionName] ?? null;
@@ -57,6 +57,8 @@ const handler = ROUTES[0]!.handler;
57
57
 
58
58
  interface ChannelEntry {
59
59
  id: string;
60
+ /** `default` here, `plugin:<name>` for a channel a plugin brings. */
61
+ source: string;
60
62
  label: string;
61
63
  subtitle: string;
62
64
  icon: string;
@@ -173,10 +175,21 @@ describe("channels/available", () => {
173
175
  for (const channel of result.channels) {
174
176
  const expected = (CHANNEL_METADATA as any)[channel.id];
175
177
  expect(expected).toBeDefined();
176
- expect(channel).toEqual(expected);
178
+ // Plus `source`, which the metadata does not carry: it says who
179
+ // contributes the row, and every row here comes from the assistant.
180
+ expect(channel).toEqual({ ...expected, source: "default" });
177
181
  }
178
182
  });
179
183
 
184
+ test("marks every channel the assistant ships as its own", async () => {
185
+ // The base list is what a client compares a plugin-contributed row
186
+ // against, so the marker has to be present rather than implied by an
187
+ // absent field.
188
+ const result = (await handler({})) as HandlerResult;
189
+
190
+ expect(result.channels.every((c) => c.source === "default")).toBe(true);
191
+ });
192
+
180
193
  test("email metadata: not verification-capable, mail icon", async () => {
181
194
  mockEmailAddressesResponse = {
182
195
  ok: true,