@vellumai/assistant 0.11.3 → 0.11.4-staging.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) 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 +139 -37
  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 +17 -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 +177 -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__/ui-shape-teaching.test.ts +33 -0
  67. package/src/__tests__/ui-voice-picker-surface.test.ts +128 -0
  68. package/src/__tests__/user-plugin-loader.test.ts +1 -1
  69. package/src/__tests__/visible-app-context.test.ts +16 -9
  70. package/src/__tests__/voice-config-update.test.ts +40 -0
  71. package/src/__tests__/worker-entrypoint-guards.test.ts +54 -0
  72. package/src/__tests__/worker-plugin-surface.test.ts +77 -0
  73. package/src/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +158 -0
  74. package/src/__tests__/workspace-migration-143-repair-deprecated-codex-model-id.test.ts +133 -0
  75. package/src/__tests__/workspace-migration-144-convert-stranded-subscription-openai-profiles.test.ts +316 -0
  76. package/src/__tests__/workspace-migration-145-collapse-profile-bindings-to-entries.test.ts +325 -0
  77. package/src/__tests__/workspace-migration-146-repair-retired-fireworks-deepseek-flash-model-id.test.ts +235 -0
  78. package/src/acp/__tests__/acp-claude-oauth.test.ts +10 -2
  79. package/src/acp/__tests__/auth-required.test.ts +161 -0
  80. package/src/acp/acp-claude-oauth.ts +19 -2
  81. package/src/acp/agent-process.test.ts +100 -0
  82. package/src/acp/agent-process.ts +29 -26
  83. package/src/acp/auth-required.ts +102 -0
  84. package/src/acp/session-manager.test.ts +119 -0
  85. package/src/acp/session-manager.ts +68 -2
  86. package/src/api/events/acp-auth-required.ts +55 -0
  87. package/src/api/index.ts +7 -0
  88. package/src/api/surfaces.ts +7 -3
  89. package/src/apps/app-store.ts +3 -0
  90. package/src/bundler/package-resolver.ts +2 -30
  91. package/src/calls/__tests__/voice-session-bridge.test.ts +173 -1
  92. package/src/calls/__tests__/voice-triage-escalate.test.ts +94 -0
  93. package/src/calls/call-controller.ts +19 -3
  94. package/src/calls/call-setup-flow.ts +0 -1
  95. package/src/calls/media-stream-stt-session.ts +15 -0
  96. package/src/calls/voice-session-bridge.ts +71 -16
  97. package/src/calls/voice-triage-escalate.ts +104 -2
  98. package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
  99. package/src/channels/config.ts +13 -0
  100. package/src/channels/plugin-channel-declarations.ts +108 -0
  101. package/src/channels/types.ts +30 -0
  102. package/src/cli/AGENTS.md +5 -2
  103. package/src/cli/commands/credentials.help.ts +2 -2
  104. package/src/cli/commands/inference-providers.ts +1 -1
  105. package/src/cli/commands/mcp.help.ts +13 -4
  106. package/src/cli/commands/mcp.ts +9 -0
  107. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +128 -5
  108. package/src/cli/commands/memory/index.help.ts +43 -1
  109. package/src/cli/commands/memory/memory-v3.ts +64 -0
  110. package/src/cli/commands/stt.help.ts +27 -2
  111. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +39 -0
  112. package/src/cli/lib/bundled-marketplace.json +13 -0
  113. package/src/cli/lib/upgrade-plugin.ts +42 -0
  114. package/src/config/__tests__/default-profile-catalog.test.ts +34 -2
  115. package/src/config/__tests__/default-provider.test.ts +6 -1
  116. package/src/config/__tests__/profile-materialization.test.ts +75 -19
  117. package/src/config/bundled-skills/acp/SKILL.md +6 -7
  118. package/src/config/bundled-skills/document-editor/SKILL.md +2 -2
  119. package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
  120. package/src/config/bundled-skills/media-processing/services/preprocess.ts +14 -4
  121. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  122. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.test.ts +65 -0
  123. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +7 -1
  124. package/src/config/bundled-skills/settings/tools/shared.ts +16 -0
  125. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -1
  126. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +22 -1
  127. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
  128. package/src/config/call-site-defaults.ts +4 -5
  129. package/src/config/default-profile-catalog.ts +83 -12
  130. package/src/config/default-profile-names.ts +4 -1
  131. package/src/config/default-provider-resolution.ts +4 -0
  132. package/src/config/llm-context-resolution.ts +11 -3
  133. package/src/config/llm-resolver.ts +28 -1
  134. package/src/config/profile-materialization.ts +70 -22
  135. package/src/config/schemas/__tests__/live-voice.test.ts +107 -4
  136. package/src/config/schemas/call-site-catalog.ts +4 -4
  137. package/src/config/schemas/live-voice.ts +57 -23
  138. package/src/config/schemas/llm.ts +59 -32
  139. package/src/config/schemas/mcp.ts +23 -0
  140. package/src/config/schemas/plugin-updates.ts +6 -2
  141. package/src/config/schemas/stt.ts +1 -0
  142. package/src/context/outbound-sanitize.ts +96 -1
  143. package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +82 -0
  144. package/src/daemon/conversation-agent-loop-handlers.ts +15 -10
  145. package/src/daemon/conversation-agent-loop.ts +17 -6
  146. package/src/daemon/conversation-messaging.ts +5 -1
  147. package/src/daemon/conversation-notifiers.ts +9 -1
  148. package/src/daemon/conversation-process.ts +36 -6
  149. package/src/daemon/conversation-runtime-assembly.ts +3 -4
  150. package/src/daemon/conversation-surfaces.ts +27 -5
  151. package/src/daemon/conversation-tool-setup.ts +1 -2
  152. package/src/daemon/conversation.ts +48 -0
  153. package/src/daemon/interactive-turn-sender.ts +59 -0
  154. package/src/daemon/mcp-reload-service.ts +36 -6
  155. package/src/daemon/process-message.ts +24 -24
  156. package/src/daemon/providers-setup.ts +6 -3
  157. package/src/daemon/trust-context-types.ts +29 -0
  158. package/src/daemon/wake-conversation-ops.ts +3 -2
  159. package/src/documents/document-store.ts +138 -5
  160. package/src/hooks/hook-loader.ts +3 -3
  161. package/src/hooks/registry.ts +50 -6
  162. package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
  163. package/src/inbound/oauth-callback-url.ts +61 -0
  164. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +1 -104
  165. package/src/live-voice/__tests__/live-voice-events.test.ts +7 -8
  166. package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +932 -0
  167. package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
  168. package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
  169. package/src/live-voice/__tests__/live-voice-progress.test.ts +60 -194
  170. package/src/live-voice/__tests__/live-voice-stt.test.ts +14 -0
  171. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +29 -0
  172. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
  173. package/src/live-voice/__tests__/live-voice-vad.test.ts +0 -16
  174. package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
  175. package/src/live-voice/live-voice-archive.ts +2 -0
  176. package/src/live-voice/live-voice-metrics.ts +57 -32
  177. package/src/live-voice/live-voice-photo.ts +1 -2
  178. package/src/live-voice/live-voice-session.ts +535 -314
  179. package/src/live-voice/progress-narration.ts +277 -0
  180. package/src/live-voice/protocol.ts +21 -1
  181. package/src/mcp/__tests__/effective-config.test.ts +238 -0
  182. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
  183. package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +200 -0
  184. package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
  185. package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +95 -0
  186. package/src/mcp/client.ts +16 -11
  187. package/src/mcp/effective-config.ts +113 -0
  188. package/src/mcp/manager.ts +11 -6
  189. package/src/mcp/mcp-auth-orchestrator.ts +13 -22
  190. package/src/mcp/mcp-oauth-provider.ts +205 -240
  191. package/src/monitoring/__tests__/plugin-auto-update.test.ts +166 -3
  192. package/src/monitoring/plugin-auto-update.ts +128 -24
  193. package/src/notifications/signal.ts +1 -0
  194. package/src/permissions/confirmation-guardian-request.test.ts +15 -11
  195. package/src/permissions/confirmation-guardian-request.ts +2 -2
  196. package/src/permissions/question-guardian-request.test.ts +14 -6
  197. package/src/permissions/question-guardian-request.ts +1 -2
  198. package/src/persistence/attachments-store.ts +8 -1
  199. package/src/persistence/bookmark-crud.ts +3 -7
  200. package/src/persistence/conversation-attention-store.ts +16 -45
  201. package/src/persistence/conversation-crud.ts +33 -4
  202. package/src/persistence/conversation-lineage.ts +9 -0
  203. package/src/persistence/conversation-queries.ts +108 -41
  204. package/src/persistence/delivery-crud.ts +38 -29
  205. package/src/persistence/external-conversation-store.ts +32 -4
  206. package/src/persistence/llm-request-log-store.ts +4 -10
  207. package/src/persistence/llm-usage-store.ts +8 -3
  208. package/src/persistence/message-reads.test.ts +197 -0
  209. package/src/persistence/message-reads.ts +211 -0
  210. package/src/persistence/migrations/366-chatgpt-subscription-row-identity.test.ts +120 -0
  211. package/src/persistence/migrations/366-chatgpt-subscription-row-identity.ts +62 -0
  212. package/src/persistence/real-user-turn-filter.ts +27 -3
  213. package/src/persistence/steps.ts +9 -0
  214. package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
  215. package/src/plugin-api/conversation-turn.ts +168 -5
  216. package/src/plugin-api/index.ts +21 -5
  217. package/src/plugin-api/vision-support.test.ts +1 -1
  218. package/src/plugins/__tests__/mcp-servers.test.ts +371 -0
  219. package/src/plugins/defaults/memory/AGENTS.md +4 -0
  220. package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +204 -0
  221. package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +72 -0
  222. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +4 -1
  223. package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +4 -1
  224. package/src/plugins/defaults/memory/buffer-format.ts +165 -0
  225. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +6 -0
  226. package/src/plugins/defaults/memory/graph/image-ref-utils.ts +3 -0
  227. package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -30
  228. package/src/plugins/defaults/memory/graph-topology/pending-buffer.test.ts +34 -0
  229. package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +8 -12
  230. package/src/plugins/defaults/memory/hooks/post-compact.ts +1 -4
  231. package/src/plugins/defaults/memory/indexer.ts +3 -1
  232. package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +19 -7
  233. package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +281 -0
  234. package/src/plugins/defaults/memory/src/memory-v3-routes.ts +207 -0
  235. package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +33 -0
  236. package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +199 -2
  237. package/src/plugins/defaults/memory/substrate/consolidation-job.ts +25 -18
  238. package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
  239. package/src/plugins/defaults/memory/substrate/static-context.ts +160 -4
  240. package/src/plugins/defaults/memory/substrate/sweep-job.ts +2 -4
  241. package/src/plugins/defaults/memory/v1/graph/extraction.ts +3 -1
  242. package/src/plugins/defaults/memory/v3/prune.ts +2 -0
  243. package/src/plugins/defaults/memory/v3/selection-log-store.ts +2 -0
  244. package/src/plugins/defaults/memory/worker.ts +6 -3
  245. package/src/plugins/external-plugin-loader.ts +47 -0
  246. package/src/plugins/mcp-servers.ts +361 -0
  247. package/src/plugins/mtime-cache.ts +23 -49
  248. package/src/plugins/worker-plugin-surface.ts +33 -0
  249. package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
  250. package/src/providers/__tests__/dispatch-connection-routing.test.ts +214 -2
  251. package/src/providers/__tests__/preflight-resolved-config.test.ts +57 -0
  252. package/src/providers/__tests__/retry-callsite.test.ts +5 -2
  253. package/src/providers/call-site-routing.ts +30 -3
  254. package/src/providers/connection-resolution.ts +194 -11
  255. package/src/providers/inference/auth.ts +6 -0
  256. package/src/providers/inference/connection-availability.ts +24 -2
  257. package/src/providers/inference/connections.ts +2 -0
  258. package/src/providers/model-catalog.ts +3 -3
  259. package/src/providers/model-intents.ts +28 -8
  260. package/src/providers/openai/chat-completions-provider.ts +5 -6
  261. package/src/providers/openai/codex-models.ts +2 -1
  262. package/src/providers/provider-send-message.ts +32 -3
  263. package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +433 -0
  264. package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +620 -0
  265. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
  266. package/src/providers/speech-to-text/__tests__/resolve.test.ts +285 -6
  267. package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
  268. package/src/providers/speech-to-text/deepgram-flux-realtime.ts +719 -0
  269. package/src/providers/speech-to-text/provider-catalog.ts +99 -8
  270. package/src/providers/speech-to-text/resolve.ts +25 -2
  271. package/src/routes/worker.ts +17 -5
  272. package/src/runtime/access-request-helper.ts +9 -12
  273. package/src/runtime/agent-wake.ts +3 -3
  274. package/src/runtime/pre-first-message-gate.ts +4 -0
  275. package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +12 -4
  276. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +219 -1
  277. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +52 -0
  278. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +61 -0
  279. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +44 -0
  280. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +102 -1
  281. package/src/runtime/routes/__tests__/plugins-routes.test.ts +44 -0
  282. package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
  283. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +62 -1
  284. package/src/runtime/routes/channel-availability-routes.ts +32 -14
  285. package/src/runtime/routes/channel-route-shared.ts +0 -6
  286. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +6 -6
  287. package/src/runtime/routes/conversation-list-routes.ts +112 -1
  288. package/src/runtime/routes/conversation-query-routes.ts +40 -27
  289. package/src/runtime/routes/credential-prompt-routes.ts +4 -7
  290. package/src/runtime/routes/default-provider-routes.ts +15 -0
  291. package/src/runtime/routes/inbound-message-handler.ts +17 -41
  292. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -1
  293. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -9
  294. package/src/runtime/routes/inbound-stages/admission-policy.ts +1 -17
  295. package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -1
  296. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -3
  297. package/src/runtime/routes/inbound-stages/edit-intercept.ts +1 -3
  298. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -1
  299. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -4
  300. package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +0 -1
  301. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +11 -20
  302. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +2 -3
  303. package/src/runtime/routes/inference-profiles-routes.ts +20 -11
  304. package/src/runtime/routes/inference-provider-connection-routes.ts +77 -15
  305. package/src/runtime/routes/log-export-routes.ts +3 -0
  306. package/src/runtime/routes/mcp-auth-routes.ts +148 -57
  307. package/src/runtime/routes/plugins-routes.ts +21 -3
  308. package/src/runtime/routes/stt-routes.ts +31 -25
  309. package/src/runtime/routes/surface-conversation-resolver.ts +3 -0
  310. package/src/runtime/routes/user-route-dispatcher.ts +39 -14
  311. package/src/runtime/routes/user-route-import.ts +108 -0
  312. package/src/schedule/worker.ts +6 -0
  313. package/src/security/oauth2.ts +6 -22
  314. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +22 -0
  315. package/src/stt/__tests__/types.test.ts +94 -0
  316. package/src/stt/daemon-batch-transcriber.ts +10 -0
  317. package/src/stt/stt-stream-session.ts +8 -4
  318. package/src/stt/types.ts +103 -0
  319. package/src/subagent/manager.ts +1 -3
  320. package/src/subagent/types.ts +7 -6
  321. package/src/tools/acp/spawn.test.ts +97 -0
  322. package/src/tools/acp/spawn.ts +32 -0
  323. package/src/tools/document/document-tool.ts +12 -3
  324. package/src/tools/registry.ts +2 -1
  325. package/src/tools/ui-surface/surface-shape-docs.ts +11 -0
  326. package/src/tools/workflows/run-workflow.ts +1 -2
  327. package/src/tts/__tests__/reasoning-tag-filter.test.ts +78 -0
  328. package/src/tts/reasoning-tag-filter.ts +89 -0
  329. package/src/util/think-tag-stream.ts +95 -0
  330. package/src/workspace/byok-default-profile-ensure.ts +76 -24
  331. package/src/workspace/custom-profile-ensure.ts +4 -24
  332. package/src/workspace/migrations/142-consolidate-voice-front-door.ts +70 -0
  333. package/src/workspace/migrations/143-repair-deprecated-codex-model-id.ts +134 -0
  334. package/src/workspace/migrations/144-convert-stranded-subscription-openai-profiles.ts +265 -0
  335. package/src/workspace/migrations/145-collapse-profile-bindings-to-entries.ts +328 -0
  336. package/src/workspace/migrations/146-repair-retired-fireworks-deepseek-flash-model-id.ts +195 -0
  337. package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +0 -10
  338. package/src/workspace/migrations/registry.ts +10 -0
  339. package/src/workspace/provider-commit-message-generator.ts +7 -5
  340. package/src/live-voice/__tests__/front-decision.test.ts +0 -645
  341. package/src/live-voice/front-decision.ts +0 -476
@@ -126,6 +126,12 @@ export const VALID_CONNECTION_PROVIDERS: readonly string[] = [
126
126
  // persisted `vellum` rows — the routing threaded in via `providerOverride`
127
127
  // never runs on a row that fails to load.
128
128
  VELLUM_MANAGED_PROVIDER,
129
+ // The ChatGPT-subscription row stores the "chatgpt" routing identity in its
130
+ // `provider` column for the same reason: the row IS the subscription route
131
+ // (auth modality = provider identity), and dispatch derives the openai
132
+ // upstream per-request. Allowlisted explicitly or the DB loaders would drop
133
+ // the persisted row.
134
+ "chatgpt",
129
135
  ];
130
136
 
131
137
  export type ConnectionProvider = string;
@@ -23,6 +23,10 @@ import {
23
23
  describeSubscriptionModelIncompatibility,
24
24
  isConnectionCompatibleWithModel,
25
25
  } from "../connection-model-compat.js";
26
+ import {
27
+ connectionProviderKind,
28
+ resolveEntryConnectionName,
29
+ } from "../connection-resolution.js";
26
30
  import { PROVIDER_CATALOG } from "../model-catalog.js";
27
31
  import { resolveManagedProxyContext } from "../platform-proxy/context.js";
28
32
  import {
@@ -161,7 +165,12 @@ export async function computeConnectionAvailability(
161
165
  if (resolvedConnectionName === VELLUM_MANAGED_CONNECTION_NAME) {
162
166
  return vellumConnectionAvailability();
163
167
  }
164
- if (connection.provider !== provider) {
168
+ // The ChatGPT-subscription row stores the "chatgpt" identity while its
169
+ // upstream is openai; the credential switch below is the right check for
170
+ // it (the subscription token is its credential).
171
+ const isChatgptRow =
172
+ connection.provider === "chatgpt" && provider === "openai";
173
+ if (!isChatgptRow && connection.provider !== provider) {
165
174
  return {
166
175
  status: "provider_mismatch",
167
176
  message: `Connection "${resolvedConnectionName}" is for provider "${connection.provider}", but the requested provider is "${provider}". Pick a connection for "${provider}" ${SETTINGS_HINT}.`,
@@ -326,9 +335,22 @@ export async function computeProfileAvailability(
326
335
  }
327
336
  }
328
337
 
338
+ // Precedence matches dispatch: an explicit provider_connection wins over
339
+ // an entry-name provider, and the vendor judged is the entry's
340
+ // dispatchable kind either way (the same translation dispatch uses).
341
+ const entryName = resolveEntryConnectionName(provider);
342
+ const entryKind =
343
+ entryName !== null
344
+ ? (connectionProviderKind(entryName, model) ?? provider)
345
+ : provider;
346
+
329
347
  const pinned = entry.provider_connection;
330
348
  if (typeof pinned === "string") {
331
- return computeConnectionAvailability(provider, pinned);
349
+ return computeConnectionAvailability(entryKind, pinned);
350
+ }
351
+
352
+ if (entryName !== null) {
353
+ return computeConnectionAvailability(entryKind, entryName);
332
354
  }
333
355
 
334
356
  // Mirror the dispatch-time auto-resolve (`resolveConfiguredProvider`): with
@@ -348,10 +348,12 @@ export function updateConnection(
348
348
  connection: {
349
349
  ...existing,
350
350
  auth,
351
+ provider: nextProvider,
351
352
  label: input.label !== undefined ? input.label : existing.label,
352
353
  baseUrl: nextBaseUrl,
353
354
  models: nextModels,
354
355
  updatedAt: now,
356
+ isManaged: isManagedRow({ name, provider: nextProvider, auth }),
355
357
  },
356
358
  };
357
359
  }
@@ -939,7 +939,7 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
939
939
  pricing: { inputPer1mTokens: 1.74, outputPer1mTokens: 3.48 },
940
940
  },
941
941
  {
942
- id: "accounts/fireworks/models/deepseek-v4-flash",
942
+ id: "accounts/fireworks/models/deepseek-v4-flash-0731",
943
943
  displayName: "DeepSeek V4 Flash",
944
944
  contextWindowTokens: 1040000,
945
945
  maxOutputTokens: 131072,
@@ -951,11 +951,11 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
951
951
  pricing: {
952
952
  inputPer1mTokens: 0.14,
953
953
  outputPer1mTokens: 0.28,
954
- cacheReadPer1mTokens: 0.03,
954
+ cacheReadPer1mTokens: 0.028,
955
955
  },
956
956
  },
957
957
  ],
958
- defaultModel: "accounts/fireworks/models/deepseek-v4-flash",
958
+ defaultModel: "accounts/fireworks/models/deepseek-v4-flash-0731",
959
959
  apiKeyUrl: "https://fireworks.ai/account/api-keys",
960
960
  apiKeyPlaceholder: "fw_...",
961
961
  },
@@ -1,4 +1,5 @@
1
1
  import { isModelInCatalog, PROVIDER_CATALOG } from "./model-catalog.js";
2
+ import { isCodexSubscriptionModel } from "./openai/codex-models.js";
2
3
  import type { ModelIntent } from "./types.js";
3
4
 
4
5
  /**
@@ -10,8 +11,10 @@ const PROVIDER_DEFAULT_MODELS: Record<string, string> = Object.fromEntries(
10
11
  );
11
12
 
12
13
  // `cost-optimized` is the cheapest model a provider serves, `latency-optimized`
13
- // the fastest to first token. On anthropic, ollama and fireworks the same model
14
- // is both, so those columns repeat by construction rather than by oversight.
14
+ // the fastest to first token. On anthropic, ollama, fireworks and openai the
15
+ // same model is both, so those columns repeat by construction rather than by
16
+ // oversight (openai's balanced repeats it too: the default-profile templates
17
+ // split those tiers by reasoning effort, not model).
15
18
  const PROVIDER_MODEL_INTENTS: Record<string, Record<ModelIntent, string>> = {
16
19
  anthropic: {
17
20
  balanced: "claude-sonnet-4-6",
@@ -21,11 +24,11 @@ const PROVIDER_MODEL_INTENTS: Record<string, Record<ModelIntent, string>> = {
21
24
  "vision-optimized": "claude-opus-4-6",
22
25
  },
23
26
  openai: {
24
- balanced: "gpt-5.4-mini",
25
- "cost-optimized": "gpt-5.4-nano",
27
+ balanced: "gpt-5.6-luna",
28
+ "cost-optimized": "gpt-5.6-luna",
26
29
  "latency-optimized": "gpt-5.6-luna",
27
- "quality-optimized": "gpt-5.4",
28
- "vision-optimized": "gpt-5.4",
30
+ "quality-optimized": "gpt-5.6-sol",
31
+ "vision-optimized": "gpt-5.6-terra",
29
32
  },
30
33
  gemini: {
31
34
  balanced: "gemini-3-flash-preview",
@@ -43,8 +46,8 @@ const PROVIDER_MODEL_INTENTS: Record<string, Record<ModelIntent, string>> = {
43
46
  },
44
47
  fireworks: {
45
48
  balanced: "accounts/fireworks/models/minimax-m3",
46
- "cost-optimized": "accounts/fireworks/models/deepseek-v4-flash",
47
- "latency-optimized": "accounts/fireworks/models/deepseek-v4-flash",
49
+ "cost-optimized": "accounts/fireworks/models/deepseek-v4-flash-0731",
50
+ "latency-optimized": "accounts/fireworks/models/deepseek-v4-flash-0731",
48
51
  "quality-optimized": "accounts/fireworks/models/kimi-k2p6",
49
52
  "vision-optimized": "accounts/fireworks/models/kimi-k2p6",
50
53
  },
@@ -89,6 +92,23 @@ for (const [provider, intents] of Object.entries(PROVIDER_MODEL_INTENTS)) {
89
92
  }
90
93
  }
91
94
 
95
+ // The openai column must additionally stay inside the ChatGPT Codex
96
+ // subscription set: the subscription default provider is stored as
97
+ // `llm.defaultProvider = { provider: "openai", connectionName:
98
+ // "chatgpt-subscription" }`, so the materialized default profiles resolve
99
+ // through this column while pinning the subscription connection, which
100
+ // bypasses the auto-resolution compat gate and hard-routes to the Codex
101
+ // endpoint, where a non-Codex model 400s on every request.
102
+ for (const [intent, modelId] of Object.entries(PROVIDER_MODEL_INTENTS.openai)) {
103
+ if (!isCodexSubscriptionModel(modelId)) {
104
+ throw new Error(
105
+ `PROVIDER_MODEL_INTENTS[openai][${intent}] references model "${modelId}" ` +
106
+ `which the ChatGPT subscription cannot serve. Pick a model from ` +
107
+ `CODEX_SUBSCRIPTION_MODEL_IDS in openai/codex-models.ts.`,
108
+ );
109
+ }
110
+ }
111
+
92
112
  export function isModelIntent(value: unknown): value is ModelIntent {
93
113
  return typeof value === "string" && MODEL_INTENTS.has(value as ModelIntent);
94
114
  }
@@ -5,6 +5,7 @@ import { isAbortReason } from "../../util/abort-reasons.js";
5
5
  import { ProviderError, type ProviderErrorReason } from "../../util/errors.js";
6
6
  import { getLogger } from "../../util/logger.js";
7
7
  import { extractRetryAfterMs } from "../../util/retry.js";
8
+ import { partialTagSuffix as sharedPartialTagSuffix } from "../../util/think-tag-stream.js";
8
9
  import { escapeXmlAttr } from "../../util/xml.js";
9
10
  import {
10
11
  base64Source,
@@ -293,13 +294,11 @@ const OPENAI_SUPPORTED_IMAGE_TYPES = new Set([
293
294
  "image/webp",
294
295
  ]);
295
296
 
297
+ // Think-tag scanning primitives are shared with the TTS reasoning filter
298
+ // (util/think-tag-stream.ts) so the two stream parsers cannot drift. This
299
+ // provider keeps its exact historical behavior: case-sensitive, <think> only.
296
300
  function partialTagSuffix(text: string, tag: string): number {
297
- for (let len = Math.min(text.length, tag.length - 1); len > 0; len--) {
298
- if (text.endsWith(tag.substring(0, len))) {
299
- return len;
300
- }
301
- }
302
- return 0;
301
+ return sharedPartialTagSuffix(text, [tag], false);
303
302
  }
304
303
 
305
304
  /**
@@ -13,9 +13,10 @@ export const CODEX_SUBSCRIPTION_MODEL_IDS: ReadonlySet<string> = new Set([
13
13
  "gpt-5.6-terra",
14
14
  "gpt-5.6-luna",
15
15
  "gpt-5.5",
16
+ // OpenAI retires these two from ChatGPT sign-in on 2026-08-31; API-key
17
+ // auth is unaffected.
16
18
  "gpt-5.4",
17
19
  "gpt-5.4-mini",
18
- "gpt-5.3-codex",
19
20
  ]);
20
21
 
21
22
  /** True when `model` is allowlisted for Codex subscription routing. */
@@ -17,6 +17,10 @@ import {
17
17
  isConnectionCompatibleWithModel,
18
18
  } from "./connection-model-compat.js";
19
19
  import {
20
+ connectionProviderKind,
21
+ dispatchProviderResolvable,
22
+ expectedVendorProvider,
23
+ resolveEntryConnectionName,
20
24
  resolveRoutingIdentity,
21
25
  tryResolveProviderForConnectionName,
22
26
  } from "./connection-resolution.js";
@@ -37,6 +41,13 @@ const log = getLogger("provider-send-message");
37
41
  export interface ConfiguredProviderResult {
38
42
  provider: Provider;
39
43
  configuredProviderName: string;
44
+ /**
45
+ * True when the profile's provider was an entry label and dispatch routed
46
+ * through that row. The row's own credential already signed resolution, so
47
+ * vendor-keyed preflights (which check the generic per-vendor key slot)
48
+ * do not apply to this result.
49
+ */
50
+ entryRouted: boolean;
40
51
  }
41
52
 
42
53
  export type ConfiguredProviderOptions = Pick<
@@ -140,7 +151,10 @@ export async function resolveConfiguredProvider(
140
151
  }
141
152
  }
142
153
 
143
- const resolved = resolveCallSiteConfig(callSite, config.llm, opts);
154
+ const resolved = resolveCallSiteConfig(callSite, config.llm, {
155
+ ...opts,
156
+ isResolvableProvider: dispatchProviderResolvable,
157
+ });
144
158
  const inferenceProvider = resolved.provider;
145
159
  let connectionName = resolved.provider_connection;
146
160
 
@@ -158,6 +172,14 @@ export async function resolveConfiguredProvider(
158
172
  resolved.model,
159
173
  )?.connectionName;
160
174
  }
175
+ // An entry-name provider IS the connection name: the label points at a
176
+ // row, and the row's own provider drives dispatch.
177
+ const entryRoute = connectionName
178
+ ? null
179
+ : resolveEntryConnectionName(inferenceProvider);
180
+ if (entryRoute) {
181
+ connectionName = entryRoute;
182
+ }
161
183
  if (!connectionName) {
162
184
  if (inferenceProvider) {
163
185
  try {
@@ -202,7 +224,7 @@ export async function resolveConfiguredProvider(
202
224
  const connectionProvider = await tryResolveProviderForConnectionName(
203
225
  connectionName,
204
226
  config,
205
- inferenceProvider,
227
+ expectedVendorProvider(inferenceProvider, resolved.model),
206
228
  resolved.model,
207
229
  );
208
230
  if (!connectionProvider) {
@@ -234,7 +256,14 @@ export async function resolveConfiguredProvider(
234
256
  opts.overrideProfile,
235
257
  opts.forceOverrideProfile,
236
258
  ),
237
- configuredProviderName: inferenceProvider,
259
+ // The dispatched vendor kind, not the config label: an entry-name
260
+ // provider reports its row's kind so provider-keyed consumers
261
+ // (telemetry, pricing) never see a label that matches no catalog id.
262
+ configuredProviderName:
263
+ (entryRoute
264
+ ? connectionProviderKind(entryRoute, resolved.model)
265
+ : undefined) ?? inferenceProvider,
266
+ entryRouted: entryRoute !== null,
238
267
  };
239
268
  }
240
269