@vellumai/assistant 0.8.3 → 0.8.5

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 (665) hide show
  1. package/ARCHITECTURE.md +2 -2
  2. package/docker-entrypoint.sh +0 -1
  3. package/docs/browser-use-architecture-phase2.md +1 -1
  4. package/knip.json +2 -1
  5. package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
  6. package/openapi.yaml +1492 -100
  7. package/package.json +1 -1
  8. package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
  9. package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
  10. package/src/__tests__/agent-loop.test.ts +88 -3
  11. package/src/__tests__/anthropic-provider.test.ts +302 -33
  12. package/src/__tests__/approval-cascade.test.ts +1 -1
  13. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  14. package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
  15. package/src/__tests__/audit-log-rotation.test.ts +70 -16
  16. package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
  17. package/src/__tests__/btw-routes.test.ts +2 -3
  18. package/src/__tests__/call-controller.test.ts +0 -1
  19. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  20. package/src/__tests__/channel-delivery-store.test.ts +193 -0
  21. package/src/__tests__/channel-guardian.test.ts +3 -3
  22. package/src/__tests__/channel-reply-delivery.test.ts +284 -5
  23. package/src/__tests__/channel-retry-sweep.test.ts +274 -1
  24. package/src/__tests__/checker.test.ts +6 -15
  25. package/src/__tests__/compaction-events.test.ts +2 -1
  26. package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
  27. package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
  28. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
  29. package/src/__tests__/computer-use-tools.test.ts +2 -4
  30. package/src/__tests__/config-watcher.test.ts +1 -1
  31. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  32. package/src/__tests__/context-token-estimator.test.ts +91 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
  34. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
  35. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
  36. package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
  37. package/src/__tests__/conversation-agent-loop.test.ts +188 -129
  38. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
  39. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
  40. package/src/__tests__/conversation-clean-command.test.ts +137 -0
  41. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  42. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
  43. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  44. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  45. package/src/__tests__/conversation-error.test.ts +31 -0
  46. package/src/__tests__/conversation-fork-crud.test.ts +324 -0
  47. package/src/__tests__/conversation-lifecycle.test.ts +53 -12
  48. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  49. package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
  50. package/src/__tests__/conversation-pairing.test.ts +2 -2
  51. package/src/__tests__/conversation-process-callsite.test.ts +1 -1
  52. package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
  53. package/src/__tests__/conversation-queue.test.ts +1 -1
  54. package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
  55. package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
  56. package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
  57. package/src/__tests__/conversation-seed-composer.test.ts +66 -4
  58. package/src/__tests__/conversation-skill-tools.test.ts +2 -5
  59. package/src/__tests__/conversation-slash-commands.test.ts +36 -8
  60. package/src/__tests__/conversation-slash-queue.test.ts +1 -1
  61. package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
  62. package/src/__tests__/conversation-speed-override.test.ts +1 -1
  63. package/src/__tests__/conversation-store.test.ts +1 -1
  64. package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
  65. package/src/__tests__/conversation-sync-tags.test.ts +99 -32
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
  67. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  69. package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
  70. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  71. package/src/__tests__/credential-security-invariants.test.ts +7 -0
  72. package/src/__tests__/credential-vault-unit.test.ts +2 -2
  73. package/src/__tests__/cu-unified-flow.test.ts +10 -1
  74. package/src/__tests__/dm-backfill.test.ts +64 -0
  75. package/src/__tests__/dm-persistence.test.ts +33 -0
  76. package/src/__tests__/document-find-replace.test.ts +501 -0
  77. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  78. package/src/__tests__/email-html-renderer.test.ts +12 -0
  79. package/src/__tests__/first-greeting.test.ts +23 -2
  80. package/src/__tests__/gateway-flag-listener.test.ts +237 -0
  81. package/src/__tests__/gemini-provider.test.ts +78 -0
  82. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  83. package/src/__tests__/guardian-outbound-http.test.ts +7 -5
  84. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  85. package/src/__tests__/headless-browser-navigate.test.ts +172 -0
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
  87. package/src/__tests__/heartbeat-service.test.ts +4 -0
  88. package/src/__tests__/host-bash-proxy.test.ts +6 -0
  89. package/src/__tests__/host-browser-proxy.test.ts +10 -0
  90. package/src/__tests__/host-cu-proxy.test.ts +8 -1
  91. package/src/__tests__/host-file-proxy.test.ts +8 -1
  92. package/src/__tests__/host-shell-tool.test.ts +1 -1
  93. package/src/__tests__/host-transfer-proxy.test.ts +8 -1
  94. package/src/__tests__/identity-routes.test.ts +57 -0
  95. package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
  96. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  97. package/src/__tests__/injector-chain.test.ts +2 -0
  98. package/src/__tests__/injector-document-comments.test.ts +378 -0
  99. package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
  100. package/src/__tests__/list-messages-attachments.test.ts +21 -17
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
  102. package/src/__tests__/list-messages-page-latest.test.ts +130 -14
  103. package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
  104. package/src/__tests__/llm-context-normalization.test.ts +0 -2
  105. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  106. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  107. package/src/__tests__/llm-resolver.test.ts +161 -9
  108. package/src/__tests__/llm-usage-store.test.ts +66 -0
  109. package/src/__tests__/log-export-routes.test.ts +99 -2
  110. package/src/__tests__/logger.test.ts +89 -0
  111. package/src/__tests__/mcp-abort-signal.test.ts +2 -2
  112. package/src/__tests__/media-generate-image.test.ts +31 -0
  113. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  114. package/src/__tests__/message-queue-steer.test.ts +114 -0
  115. package/src/__tests__/model-intents.test.ts +2 -4
  116. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  117. package/src/__tests__/onboarding-template-contract.test.ts +1 -1
  118. package/src/__tests__/openai-provider.test.ts +151 -0
  119. package/src/__tests__/openai-responses-provider.test.ts +118 -16
  120. package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
  121. package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
  122. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  123. package/src/__tests__/platform.test.ts +2 -5
  124. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  125. package/src/__tests__/plugin-bootstrap.test.ts +2 -2
  126. package/src/__tests__/plugin-source-watcher.test.ts +302 -0
  127. package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
  128. package/src/__tests__/plugin-types.test.ts +3 -2
  129. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  130. package/src/__tests__/pricing.test.ts +12 -0
  131. package/src/__tests__/process-message-background-slack.test.ts +1 -51
  132. package/src/__tests__/process-message-display-content.test.ts +21 -16
  133. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  134. package/src/__tests__/registry.test.ts +2 -8
  135. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  136. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  137. package/src/__tests__/server-history-render.test.ts +83 -4
  138. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  139. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  140. package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
  141. package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
  142. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  143. package/src/__tests__/steer-tool-repair.test.ts +249 -0
  144. package/src/__tests__/subagent-notify-parent.test.ts +1 -1
  145. package/src/__tests__/suggestion-routes.test.ts +1 -0
  146. package/src/__tests__/sync-message-contract.test.ts +59 -0
  147. package/src/__tests__/system-prompt.test.ts +161 -124
  148. package/src/__tests__/terminal-tools.test.ts +12 -2
  149. package/src/__tests__/thinking-block-replay.test.ts +113 -0
  150. package/src/__tests__/thread-backfill.test.ts +370 -22
  151. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  152. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  153. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  154. package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
  155. package/src/__tests__/tool-executor.test.ts +89 -53
  156. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  157. package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
  158. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  159. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  160. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  161. package/src/__tests__/twilio-routes.test.ts +1 -1
  162. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  163. package/src/__tests__/usage-routes.test.ts +3 -0
  164. package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
  165. package/src/__tests__/web-fetch.test.ts +2 -2
  166. package/src/__tests__/workspace-git-service.test.ts +94 -10
  167. package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
  168. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  169. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  170. package/src/acp/prepare-agent-env.ts +78 -0
  171. package/src/acp/session-manager.ts +1 -1
  172. package/src/agent/attachments.ts +1 -0
  173. package/src/agent/loop.ts +65 -20
  174. package/src/api/README.md +5 -0
  175. package/src/api/index.ts +4 -0
  176. package/src/api/package.json +10 -0
  177. package/src/background-wake/background-wake-routes.test.ts +233 -0
  178. package/src/background-wake/next-wake.test.ts +289 -0
  179. package/src/background-wake/next-wake.ts +172 -0
  180. package/src/background-wake/runtime-registry.ts +24 -0
  181. package/src/browser/operations.ts +15 -0
  182. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  183. package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
  184. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  185. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  186. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  187. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  188. package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
  189. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  190. package/src/cli/commands/browser.ts +247 -0
  191. package/src/cli/commands/conversations.ts +128 -1
  192. package/src/cli/commands/domain.ts +91 -41
  193. package/src/cli/commands/inference-providers.ts +147 -1
  194. package/src/cli/commands/inference.ts +93 -40
  195. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  196. package/src/cli/commands/memory-v2.ts +483 -0
  197. package/src/cli/commands/memory-v3-render.ts +344 -0
  198. package/src/cli/commands/memory-v3.ts +316 -0
  199. package/src/cli/commands/notifications.ts +24 -2
  200. package/src/cli/program.ts +2 -0
  201. package/src/cli/utils/conversation-id.ts +17 -5
  202. package/src/config/assistant-feature-flags.ts +21 -9
  203. package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
  204. package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
  205. package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
  206. package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
  207. package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
  208. package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
  209. package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
  210. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  211. package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
  212. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  213. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  214. package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
  215. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  216. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  217. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  218. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  219. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  220. package/src/config/bundled-skills/schedule/SKILL.md +8 -0
  221. package/src/config/bundled-tool-registry.ts +24 -12
  222. package/src/config/call-site-defaults.ts +20 -0
  223. package/src/config/feature-flag-registry.json +115 -3
  224. package/src/config/llm-resolver.ts +16 -2
  225. package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
  226. package/src/config/schemas/call-site-catalog.ts +35 -0
  227. package/src/config/schemas/llm.ts +14 -0
  228. package/src/config/schemas/memory-v2.ts +294 -1
  229. package/src/config/schemas/memory.ts +2 -1
  230. package/src/context/compactor.ts +60 -1
  231. package/src/context/token-estimator.ts +47 -4
  232. package/src/context/window-manager.ts +25 -0
  233. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  234. package/src/conversations/message-consolidation.ts +404 -0
  235. package/src/credential-health/credential-health-service.ts +34 -19
  236. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
  237. package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
  238. package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
  239. package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
  240. package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
  241. package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
  242. package/src/daemon/conversation-agent-loop.ts +307 -88
  243. package/src/daemon/conversation-error.ts +31 -1
  244. package/src/daemon/conversation-lifecycle.ts +149 -118
  245. package/src/daemon/conversation-messaging.ts +3 -0
  246. package/src/daemon/conversation-process.ts +273 -0
  247. package/src/daemon/conversation-queue-manager.ts +14 -0
  248. package/src/daemon/conversation-runtime-assembly.ts +145 -84
  249. package/src/daemon/conversation-slash.ts +37 -5
  250. package/src/daemon/conversation-surfaces.ts +45 -2
  251. package/src/daemon/conversation-tool-setup.ts +70 -3
  252. package/src/daemon/conversation-usage.ts +2 -0
  253. package/src/daemon/conversation.ts +54 -32
  254. package/src/daemon/disk-pressure-guard.ts +14 -2
  255. package/src/daemon/first-greeting.ts +10 -0
  256. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
  257. package/src/daemon/handlers/config-a2a.ts +160 -0
  258. package/src/daemon/handlers/config-model.test.ts +2 -0
  259. package/src/daemon/handlers/conversations.ts +90 -3
  260. package/src/daemon/handlers/shared.ts +92 -29
  261. package/src/daemon/host-bash-proxy.ts +1 -1
  262. package/src/daemon/host-browser-proxy.ts +5 -5
  263. package/src/daemon/host-cu-proxy.ts +5 -5
  264. package/src/daemon/host-file-proxy.ts +5 -5
  265. package/src/daemon/host-proxy-base.ts +4 -4
  266. package/src/daemon/host-transfer-proxy.ts +11 -11
  267. package/src/daemon/lifecycle.ts +40 -23
  268. package/src/daemon/meet-manifest-loader.ts +1 -7
  269. package/src/daemon/message-protocol.ts +4 -0
  270. package/src/daemon/message-types/conversations.ts +14 -9
  271. package/src/daemon/message-types/document-comments.ts +50 -0
  272. package/src/daemon/message-types/home.ts +1 -13
  273. package/src/daemon/message-types/messages.ts +66 -7
  274. package/src/daemon/message-types/surfaces.ts +3 -1
  275. package/src/daemon/message-types/sync.ts +14 -0
  276. package/src/daemon/message-types/web-activity.ts +57 -0
  277. package/src/daemon/plugin-source-watcher.ts +135 -3
  278. package/src/daemon/process-message.ts +69 -12
  279. package/src/daemon/shutdown-handlers.ts +24 -5
  280. package/src/daemon/switch-inference-profile-tool.ts +52 -0
  281. package/src/daemon/tool-setup-types.ts +13 -0
  282. package/src/daemon/trust-context.ts +6 -0
  283. package/src/documents/document-comments-store.test.ts +338 -0
  284. package/src/documents/document-comments-store.ts +237 -0
  285. package/src/documents/document-store.ts +202 -0
  286. package/src/events/relationship-state-updated.ts +25 -0
  287. package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
  288. package/src/heartbeat/heartbeat-service.ts +1 -0
  289. package/src/home/__tests__/suggested-prompts.test.ts +33 -2
  290. package/src/home/feed-types.ts +6 -1
  291. package/src/home/home-content-refresh.ts +52 -0
  292. package/src/home/home-greeting-cache.ts +69 -0
  293. package/src/home/home-greeting.ts +85 -0
  294. package/src/home/suggested-prompts.ts +168 -9
  295. package/src/ipc/gateway-flag-listener.ts +123 -0
  296. package/src/ipc/skill-routes/registries.ts +8 -12
  297. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  298. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  299. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
  300. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  301. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
  302. package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
  303. package/src/memory/auto-analysis-enqueue.ts +5 -1
  304. package/src/memory/conversation-crud.ts +191 -100
  305. package/src/memory/conversation-starters-cadence.ts +3 -1
  306. package/src/memory/conversation-title-service.ts +19 -3
  307. package/src/memory/db-async-query.ts +214 -0
  308. package/src/memory/db-init.ts +26 -0
  309. package/src/memory/db-maintenance.ts +30 -21
  310. package/src/memory/delivery-crud.ts +41 -0
  311. package/src/memory/delivery-status.ts +141 -15
  312. package/src/memory/external-conversation-store.ts +32 -1
  313. package/src/memory/graph/bootstrap.ts +8 -1
  314. package/src/memory/graph/capability-seed.ts +7 -3
  315. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  316. package/src/memory/graph/extraction.ts +1 -5
  317. package/src/memory/graph/graph-search.ts +7 -1
  318. package/src/memory/indexer.ts +28 -18
  319. package/src/memory/job-handlers/cleanup.ts +76 -18
  320. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  321. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  322. package/src/memory/jobs-store.ts +14 -0
  323. package/src/memory/jobs-worker.ts +68 -15
  324. package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
  325. package/src/memory/llm-request-log-source-local.ts +7 -0
  326. package/src/memory/llm-request-log-source.ts +9 -2
  327. package/src/memory/llm-request-log-store.ts +43 -1
  328. package/src/memory/llm-usage-store.ts +24 -0
  329. package/src/memory/memory-retrospective-constants.ts +28 -0
  330. package/src/memory/memory-retrospective-enqueue.ts +11 -3
  331. package/src/memory/memory-retrospective-job.ts +413 -18
  332. package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
  333. package/src/memory/memory-v2-activation-log-store.ts +41 -14
  334. package/src/memory/migrations/100-core-tables.ts +1 -0
  335. package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
  336. package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
  337. package/src/memory/migrations/253-document-comments.ts +47 -0
  338. package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
  339. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
  340. package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
  341. package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
  342. package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
  343. package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
  344. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  345. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  346. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  347. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  348. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  349. package/src/memory/migrations/index.ts +34 -0
  350. package/src/memory/migrations/registry.ts +58 -0
  351. package/src/memory/onboarding-events-store.ts +7 -0
  352. package/src/memory/schema/calls.ts +1 -0
  353. package/src/memory/schema/conversations.ts +3 -0
  354. package/src/memory/schema/infrastructure.ts +22 -0
  355. package/src/memory/tool-usage-store.ts +36 -8
  356. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  357. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  358. package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
  359. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  360. package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
  361. package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
  362. package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
  363. package/src/memory/v2/__tests__/injection.test.ts +158 -112
  364. package/src/memory/v2/__tests__/page-index.test.ts +365 -1
  365. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  366. package/src/memory/v2/__tests__/router.test.ts +660 -4
  367. package/src/memory/v2/consolidation-job.ts +14 -0
  368. package/src/memory/v2/harness/compare.ts +57 -0
  369. package/src/memory/v2/harness/metrics.ts +124 -0
  370. package/src/memory/v2/harness/oracle.ts +145 -0
  371. package/src/memory/v2/harness/replay-input.ts +224 -0
  372. package/src/memory/v2/harness/retriever.ts +74 -0
  373. package/src/memory/v2/harness/router-retriever.ts +43 -0
  374. package/src/memory/v2/harness/runner.ts +106 -0
  375. package/src/memory/v2/harness/trace.ts +58 -0
  376. package/src/memory/v2/injection-events.ts +101 -0
  377. package/src/memory/v2/injection.ts +42 -25
  378. package/src/memory/v2/page-index.ts +209 -7
  379. package/src/memory/v2/page-store.ts +18 -0
  380. package/src/memory/v2/prompts/router.ts +26 -1
  381. package/src/memory/v2/qdrant.ts +14 -2
  382. package/src/memory/v2/router.ts +369 -62
  383. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  384. package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
  385. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  386. package/src/memory/v3/__tests__/edges.test.ts +563 -0
  387. package/src/memory/v3/__tests__/filter.test.ts +512 -0
  388. package/src/memory/v3/__tests__/gate.test.ts +574 -0
  389. package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
  390. package/src/memory/v3/__tests__/loop.test.ts +530 -0
  391. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  392. package/src/memory/v3/__tests__/scouts.test.ts +440 -0
  393. package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
  394. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  395. package/src/memory/v3/__tests__/traversal.test.ts +469 -0
  396. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  397. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  398. package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
  399. package/src/memory/v3/__tests__/validate.test.ts +245 -0
  400. package/src/memory/v3/auto-edges.ts +223 -0
  401. package/src/memory/v3/coactivation-store.ts +124 -0
  402. package/src/memory/v3/consolidation-job.ts +323 -0
  403. package/src/memory/v3/edge-learning-job.ts +160 -0
  404. package/src/memory/v3/edges.ts +249 -0
  405. package/src/memory/v3/filter.ts +281 -0
  406. package/src/memory/v3/gate.ts +334 -0
  407. package/src/memory/v3/index-composition.ts +113 -0
  408. package/src/memory/v3/llm-capture.ts +46 -0
  409. package/src/memory/v3/loop.ts +382 -0
  410. package/src/memory/v3/maintenance.ts +144 -0
  411. package/src/memory/v3/prompt-context.ts +33 -0
  412. package/src/memory/v3/prompts/consolidation.ts +458 -0
  413. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  414. package/src/memory/v3/retriever.ts +33 -0
  415. package/src/memory/v3/scouts.ts +420 -0
  416. package/src/memory/v3/shadow-middleware.ts +305 -0
  417. package/src/memory/v3/traversal.ts +206 -0
  418. package/src/memory/v3/tree-index.ts +237 -0
  419. package/src/memory/v3/tree-store.ts +394 -0
  420. package/src/memory/v3/tree-walk.ts +351 -0
  421. package/src/memory/v3/types.ts +65 -0
  422. package/src/memory/v3/validate.ts +300 -0
  423. package/src/messaging/providers/index.ts +7 -1
  424. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
  425. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
  426. package/src/messaging/providers/slack/adapter.ts +178 -25
  427. package/src/messaging/providers/slack/api.test.ts +54 -0
  428. package/src/messaging/providers/slack/api.ts +119 -3
  429. package/src/messaging/providers/slack/client.ts +12 -0
  430. package/src/messaging/providers/slack/deep-link.ts +20 -1
  431. package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
  432. package/src/messaging/providers/slack/message-metadata.ts +156 -0
  433. package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
  434. package/src/messaging/providers/slack/render-transcript.ts +176 -49
  435. package/src/messaging/providers/slack/send.test.ts +77 -0
  436. package/src/messaging/providers/slack/send.ts +8 -2
  437. package/src/messaging/providers/slack/types.ts +14 -0
  438. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
  439. package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
  440. package/src/notifications/adapters/macos.ts +18 -1
  441. package/src/notifications/adapters/platform.ts +1 -1
  442. package/src/notifications/conversation-seed-composer.ts +14 -2
  443. package/src/notifications/decision-engine.ts +1 -4
  444. package/src/notifications/deferred-emit.ts +135 -0
  445. package/src/notifications/emit-signal.ts +38 -50
  446. package/src/notifications/home-feed-side-effect.ts +60 -30
  447. package/src/oauth/connect-orchestrator.ts +3 -0
  448. package/src/oauth/credential-token-resolver.ts +2 -0
  449. package/src/oauth/manual-token-connection.ts +19 -0
  450. package/src/oauth/oauth-store.ts +12 -0
  451. package/src/oauth/seed-providers.ts +22 -0
  452. package/src/permissions/prompter.ts +8 -5
  453. package/src/permissions/question-prompter.ts +5 -2
  454. package/src/permissions/secret-prompter.ts +6 -3
  455. package/src/plugin-api/index.ts +4 -0
  456. package/src/plugin-api/types.ts +7 -33
  457. package/src/plugins/defaults/index.ts +6 -0
  458. package/src/plugins/defaults/injectors.ts +100 -20
  459. package/src/plugins/external-plugin-loader.ts +5 -68
  460. package/src/plugins/types.ts +11 -16
  461. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  462. package/src/prompts/__tests__/system-prompt.test.ts +46 -2
  463. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  464. package/src/prompts/normalize-onboarding.ts +40 -0
  465. package/src/prompts/persona-resolver.ts +36 -21
  466. package/src/prompts/sections.ts +69 -19
  467. package/src/prompts/system-prompt.ts +118 -216
  468. package/src/prompts/template-detection.ts +37 -0
  469. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
  470. package/src/prompts/templates/BOOTSTRAP.md +10 -2
  471. package/src/prompts/templates/VOICE.md +3 -0
  472. package/src/prompts/templates/system-sections.ts +281 -9
  473. package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
  474. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  475. package/src/providers/anthropic/client.ts +159 -66
  476. package/src/providers/call-site-routing.ts +14 -2
  477. package/src/providers/connection-model-compat.ts +38 -0
  478. package/src/providers/connection-resolution.ts +16 -2
  479. package/src/providers/fireworks/client.ts +20 -2
  480. package/src/providers/gemini/client.ts +49 -6
  481. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
  482. package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
  483. package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
  484. package/src/providers/inference/adapter-factory.ts +18 -1
  485. package/src/providers/inference/auth.ts +3 -3
  486. package/src/providers/inference/codex-token-refresh.ts +128 -0
  487. package/src/providers/inference/resolve-auth.ts +49 -6
  488. package/src/providers/minimax/client.ts +106 -0
  489. package/src/providers/model-catalog.ts +91 -1
  490. package/src/providers/model-intents.ts +1 -1
  491. package/src/providers/openai/chat-completions-provider.ts +63 -23
  492. package/src/providers/openai/codex-models.ts +18 -0
  493. package/src/providers/openai/responses-provider.ts +86 -23
  494. package/src/providers/openrouter/client.ts +5 -1
  495. package/src/providers/provider-send-message.ts +7 -1
  496. package/src/providers/retry.ts +34 -3
  497. package/src/providers/thinking-config.ts +26 -1
  498. package/src/providers/types.ts +25 -0
  499. package/src/providers/usage-tracking.ts +2 -0
  500. package/src/runtime/AGENTS.md +2 -2
  501. package/src/runtime/__tests__/agent-wake.test.ts +214 -0
  502. package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
  503. package/src/runtime/agent-wake.ts +152 -56
  504. package/src/runtime/assistant-event-hub.ts +76 -6
  505. package/src/runtime/auth/route-policy.ts +43 -3
  506. package/src/runtime/background-job-runner.ts +26 -0
  507. package/src/runtime/btw-sidechain.ts +0 -6
  508. package/src/runtime/channel-reply-delivery.ts +182 -47
  509. package/src/runtime/channel-retry-sweep.ts +141 -16
  510. package/src/runtime/http-types.ts +7 -6
  511. package/src/runtime/migrations/vbundle-builder.ts +10 -3
  512. package/src/runtime/pending-interactions.ts +50 -8
  513. package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
  514. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
  515. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
  516. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
  517. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  518. package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
  519. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
  520. package/src/runtime/routes/acp-routes.test.ts +255 -6
  521. package/src/runtime/routes/acp-routes.ts +8 -1
  522. package/src/runtime/routes/approval-routes.ts +4 -1
  523. package/src/runtime/routes/avatar-routes.ts +10 -10
  524. package/src/runtime/routes/background-wake-routes.ts +188 -0
  525. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  526. package/src/runtime/routes/btw-routes.ts +0 -6
  527. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
  528. package/src/runtime/routes/content-source-routes.ts +78 -0
  529. package/src/runtime/routes/conversation-cli-routes.ts +147 -2
  530. package/src/runtime/routes/conversation-list-routes.ts +12 -4
  531. package/src/runtime/routes/conversation-management-routes.ts +77 -20
  532. package/src/runtime/routes/conversation-query-routes.ts +196 -31
  533. package/src/runtime/routes/conversation-routes.ts +472 -425
  534. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  535. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  536. package/src/runtime/routes/document-comments-routes.ts +287 -0
  537. package/src/runtime/routes/documents-routes.ts +33 -0
  538. package/src/runtime/routes/domain-routes.ts +60 -10
  539. package/src/runtime/routes/email-routes.ts +5 -2
  540. package/src/runtime/routes/events-routes.ts +54 -10
  541. package/src/runtime/routes/group-routes.ts +24 -8
  542. package/src/runtime/routes/home-feed-routes.ts +6 -3
  543. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  544. package/src/runtime/routes/host-browser-routes.ts +17 -2
  545. package/src/runtime/routes/host-cu-routes.ts +2 -2
  546. package/src/runtime/routes/identity-routes.ts +21 -0
  547. package/src/runtime/routes/inbound-message-handler.ts +288 -58
  548. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  549. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
  550. package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
  551. package/src/runtime/routes/index.ts +20 -4
  552. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  553. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  554. package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
  555. package/src/runtime/routes/integrations/a2a.ts +60 -1
  556. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  557. package/src/runtime/routes/log-export-routes.ts +39 -0
  558. package/src/runtime/routes/memory-item-routes.ts +8 -3
  559. package/src/runtime/routes/memory-v2-routes.ts +427 -0
  560. package/src/runtime/routes/memory-v3-routes.ts +316 -0
  561. package/src/runtime/routes/migration-routes.ts +21 -24
  562. package/src/runtime/routes/notification-routes.ts +19 -2
  563. package/src/runtime/routes/plugins-routes.ts +337 -0
  564. package/src/runtime/routes/question-routes.ts +4 -1
  565. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  566. package/src/runtime/routes/sanity-routes.ts +159 -0
  567. package/src/runtime/routes/secret-routes.ts +25 -5
  568. package/src/runtime/routes/settings-routes.ts +12 -11
  569. package/src/runtime/routes/slack-channel-routes.ts +188 -0
  570. package/src/runtime/routes/workspace-routes.ts +25 -10
  571. package/src/runtime/services/conversation-serializer.ts +30 -4
  572. package/src/runtime/sync/resource-sync-events.ts +106 -38
  573. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  574. package/src/runtime/sync/sync-publisher.ts +2 -1
  575. package/src/runtime/verification-outbound-actions.ts +73 -1
  576. package/src/schedule/integration-status.ts +3 -1
  577. package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
  578. package/src/security/oauth2-device-code.ts +307 -0
  579. package/src/security/oauth2.ts +26 -9
  580. package/src/security/secure-keys.ts +5 -0
  581. package/src/skills/catalog-install.ts +6 -2
  582. package/src/telemetry/types.ts +12 -0
  583. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  584. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  585. package/src/tools/acp/spawn.test.ts +119 -0
  586. package/src/tools/acp/spawn.ts +15 -2
  587. package/src/tools/apps/definitions.ts +2 -8
  588. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  589. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  590. package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
  591. package/src/tools/browser/browser-execution.ts +106 -0
  592. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  593. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
  594. package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
  595. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
  596. package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
  597. package/src/tools/browser/cdp-client/factory.ts +171 -4
  598. package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
  599. package/src/tools/browser/cdp-client/types.ts +101 -0
  600. package/src/tools/browser/pinned-tabs.ts +146 -0
  601. package/src/tools/computer-use/definitions.ts +22 -78
  602. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  603. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  604. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  605. package/src/tools/credentials/vault.ts +3 -9
  606. package/src/tools/document/document-comment-tool.test.ts +379 -0
  607. package/src/tools/document/document-comment-tool.ts +156 -0
  608. package/src/tools/document/document-tool.ts +187 -2
  609. package/src/tools/execution-target.ts +21 -23
  610. package/src/tools/executor.ts +6 -1
  611. package/src/tools/filesystem/edit.ts +3 -9
  612. package/src/tools/filesystem/list.ts +3 -9
  613. package/src/tools/filesystem/read.ts +3 -9
  614. package/src/tools/filesystem/write.ts +3 -9
  615. package/src/tools/host-filesystem/edit.ts +3 -9
  616. package/src/tools/host-filesystem/read.ts +3 -9
  617. package/src/tools/host-filesystem/transfer.ts +3 -9
  618. package/src/tools/host-filesystem/write.ts +3 -9
  619. package/src/tools/host-terminal/host-shell.ts +3 -9
  620. package/src/tools/mcp/mcp-tool-factory.ts +1 -8
  621. package/src/tools/memory/register.test.ts +1 -1
  622. package/src/tools/memory/register.ts +4 -9
  623. package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
  624. package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
  625. package/src/tools/network/domain-normalize.ts +17 -0
  626. package/src/tools/network/web-fetch.ts +216 -73
  627. package/src/tools/network/web-search.ts +216 -98
  628. package/src/tools/registry.ts +7 -23
  629. package/src/tools/schema-transforms.ts +1 -1
  630. package/src/tools/skills/execute.ts +3 -9
  631. package/src/tools/skills/load.ts +3 -9
  632. package/src/tools/skills/skill-tool-factory.ts +1 -8
  633. package/src/tools/subagent/notify-parent.ts +3 -9
  634. package/src/tools/system/request-permission.ts +3 -9
  635. package/src/tools/terminal/safe-env.ts +3 -2
  636. package/src/tools/terminal/shell.ts +3 -9
  637. package/src/tools/tool-approval-handler.ts +19 -12
  638. package/src/tools/tool-defaults.ts +94 -0
  639. package/src/tools/types.ts +31 -98
  640. package/src/tools/ui-surface/definitions.ts +9 -23
  641. package/src/types/onboarding-context.ts +4 -0
  642. package/src/usage/pricing.ts +23 -0
  643. package/src/usage/types.ts +12 -0
  644. package/src/util/__tests__/favicon.test.ts +84 -0
  645. package/src/util/favicon.ts +40 -0
  646. package/src/util/logger.ts +16 -7
  647. package/src/util/platform.ts +7 -7
  648. package/src/util/sqlite3-runtime.ts +65 -0
  649. package/src/workspace/git-service.ts +75 -4
  650. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  651. package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
  652. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  653. package/src/workspace/migrations/registry.ts +4 -0
  654. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  655. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  656. package/src/config/bundled-skills/document/SKILL.md +0 -54
  657. package/src/config/bundled-skills/document/TOOLS.json +0 -106
  658. package/src/daemon/seed-files.ts +0 -18
  659. package/src/prompts/cache-boundary.ts +0 -8
  660. package/src/runtime/routes/interface-routes.ts +0 -43
  661. /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
  662. /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
  663. /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
  664. /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
  665. /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
@@ -45,6 +45,13 @@ export interface CatalogModel {
45
45
  supportsVision?: boolean;
46
46
  supportsToolUse?: boolean;
47
47
  pricing?: CatalogModelPricing;
48
+ /**
49
+ * Upper bound for `reasoning_effort` accepted by this model's upstream API.
50
+ * Used by providers (e.g. Fireworks) to clamp Vellum's `xhigh`/`max` tiers
51
+ * down to whatever the model documents. Omit to inherit the provider
52
+ * default.
53
+ */
54
+ maxEffort?: "high" | "xhigh" | "max";
48
55
  /** When set, this model is only visible when the named feature flag is enabled. */
49
56
  featureFlag?: string;
50
57
  }
@@ -393,6 +400,21 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
393
400
  linkLabel: "Open Google AI Studio",
394
401
  },
395
402
  models: [
403
+ {
404
+ id: "gemini-3.5-flash",
405
+ displayName: "Gemini 3.5 Flash",
406
+ contextWindowTokens: 1048576,
407
+ maxOutputTokens: 65536,
408
+ supportsThinking: true,
409
+ supportsCaching: true,
410
+ supportsVision: true,
411
+ supportsToolUse: true,
412
+ pricing: {
413
+ inputPer1mTokens: 1.5,
414
+ outputPer1mTokens: 9.0,
415
+ cacheReadPer1mTokens: 0.15,
416
+ },
417
+ },
396
418
  {
397
419
  id: "gemini-3.1-pro-preview",
398
420
  displayName: "Gemini 3.1 Pro Preview",
@@ -471,6 +493,21 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
471
493
  cacheReadPer1mTokens: 0.025,
472
494
  },
473
495
  },
496
+ {
497
+ id: "gemini-3.1-flash-lite",
498
+ displayName: "Gemini 3.1 Flash-Lite",
499
+ contextWindowTokens: 1048576,
500
+ maxOutputTokens: 65536,
501
+ supportsThinking: true,
502
+ supportsCaching: true,
503
+ supportsVision: true,
504
+ supportsToolUse: true,
505
+ pricing: {
506
+ inputPer1mTokens: 0.25,
507
+ outputPer1mTokens: 1.5,
508
+ cacheReadPer1mTokens: 0.025,
509
+ },
510
+ },
474
511
  {
475
512
  id: "gemini-2.5-flash",
476
513
  displayName: "Gemini 2.5 Flash",
@@ -589,6 +626,7 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
589
626
  supportsCaching: true,
590
627
  supportsVision: true,
591
628
  supportsToolUse: true,
629
+ maxEffort: "high",
592
630
  pricing: {
593
631
  inputPer1mTokens: 0.95,
594
632
  outputPer1mTokens: 4.0,
@@ -636,10 +674,11 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
636
674
  displayName: "DeepSeek V4 Pro",
637
675
  contextWindowTokens: 1040000,
638
676
  maxOutputTokens: 131072,
639
- supportsThinking: false,
677
+ supportsThinking: true,
640
678
  supportsCaching: false,
641
679
  supportsVision: false,
642
680
  supportsToolUse: true,
681
+ maxEffort: "max",
643
682
  pricing: { inputPer1mTokens: 1.74, outputPer1mTokens: 3.48 },
644
683
  },
645
684
  ],
@@ -775,6 +814,17 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
775
814
  supportsToolUse: true,
776
815
  pricing: { inputPer1mTokens: 3, outputPer1mTokens: 15 },
777
816
  },
817
+ {
818
+ id: "x-ai/grok-4.3",
819
+ displayName: "Grok 4.3",
820
+ contextWindowTokens: 1000000,
821
+ maxOutputTokens: 16000,
822
+ supportsThinking: true,
823
+ supportsCaching: false,
824
+ supportsVision: true,
825
+ supportsToolUse: true,
826
+ pricing: { inputPer1mTokens: 1.25, outputPer1mTokens: 2.5 },
827
+ },
778
828
  {
779
829
  id: "x-ai/grok-4",
780
830
  displayName: "Grok 4",
@@ -1057,6 +1107,18 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
1057
1107
  supportsToolUse: true,
1058
1108
  pricing: { inputPer1mTokens: 0.8, outputPer1mTokens: 3.2 },
1059
1109
  },
1110
+ // Owl (OpenRouter first-party)
1111
+ {
1112
+ id: "openrouter/owl-alpha",
1113
+ displayName: "Owl Alpha",
1114
+ contextWindowTokens: 1048576,
1115
+ maxOutputTokens: 262144,
1116
+ supportsThinking: false,
1117
+ supportsCaching: false,
1118
+ supportsVision: false,
1119
+ supportsToolUse: true,
1120
+ pricing: { inputPer1mTokens: 0, outputPer1mTokens: 0 },
1121
+ },
1060
1122
  ],
1061
1123
  defaultModel: "x-ai/grok-4.20-beta",
1062
1124
  apiKeyUrl: "https://openrouter.ai/keys",
@@ -1075,6 +1137,34 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
1075
1137
  models: [],
1076
1138
  defaultModel: "",
1077
1139
  },
1140
+ {
1141
+ id: "minimax",
1142
+ displayName: "MiniMax",
1143
+ subtitle: "MiniMax AI models. Requires a MiniMax API key.",
1144
+ setupMode: "api-key",
1145
+ setupHint: "Enter your MiniMax API key to enable MiniMax models.",
1146
+ envVar: "MINIMAX_API_KEY",
1147
+ credentialsGuide: {
1148
+ description: "Sign in to the MiniMax dashboard and create an API key.",
1149
+ url: "https://platform.minimax.io/",
1150
+ linkLabel: "Open MiniMax Dashboard",
1151
+ },
1152
+ models: [
1153
+ {
1154
+ id: "MiniMax-M2.7",
1155
+ displayName: "MiniMax M2.7",
1156
+ contextWindowTokens: 200000,
1157
+ maxOutputTokens: 16384,
1158
+ supportsThinking: true,
1159
+ supportsCaching: true,
1160
+ supportsVision: false,
1161
+ supportsToolUse: true,
1162
+ },
1163
+ ],
1164
+ defaultModel: "MiniMax-M2.7",
1165
+ apiKeyUrl: "https://platform.minimax.io/",
1166
+ apiKeyPlaceholder: "sk-cp-...",
1167
+ },
1078
1168
  ];
1079
1169
 
1080
1170
  export const PROVIDER_CATALOG: ProviderCatalogEntry[] =
@@ -24,7 +24,7 @@ const PROVIDER_MODEL_INTENTS: Record<string, Record<ModelIntent, string>> = {
24
24
  },
25
25
  gemini: {
26
26
  balanced: "gemini-3-flash-preview",
27
- "latency-optimized": "gemini-3.1-flash-lite-preview",
27
+ "latency-optimized": "gemini-3.1-flash-lite",
28
28
  "quality-optimized": "gemini-3.1-pro-preview",
29
29
  "vision-optimized": "gemini-3-flash-preview",
30
30
  },
@@ -1,6 +1,5 @@
1
1
  import OpenAI from "openai";
2
2
 
3
- import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/cache-boundary.js";
4
3
  import { isAbortReason } from "../../util/abort-reasons.js";
5
4
  import { ProviderError } from "../../util/errors.js";
6
5
  import { extractRetryAfterMs } from "../../util/retry.js";
@@ -66,34 +65,56 @@ export interface OpenAIChatCompletionsProviderOptions {
66
65
  extraCreateParams?: Record<string, unknown>;
67
66
  /** Upper bound for `reasoning_effort` sent on the wire. Defaults to "xhigh"
68
67
  * (OpenAI's current ceiling). Compatibility providers whose APIs only
69
- * document `low|medium|high` (e.g. Fireworks) should set this to "high" so
70
- * Vellum's `xhigh`/`max` tiers don't 4xx upstream. */
71
- maxReasoningEffort?: "high" | "xhigh";
68
+ * document `low|medium|high` should set this to "high" so Vellum's
69
+ * `xhigh`/`max` tiers don't 4xx upstream. Set to "max" for providers like
70
+ * Fireworks DeepSeek V4 that accept the full effort range. Subclasses can
71
+ * override {@link OpenAIChatCompletionsProvider.resolveMaxReasoningEffort}
72
+ * for per-model ceilings. */
73
+ maxReasoningEffort?: "high" | "xhigh" | "max";
72
74
  /** Parse `<think>...</think>` tags from the content stream into thinking
73
75
  * blocks. MiniMax and similar providers embed reasoning inside XML-style
74
76
  * tags in the regular content field rather than using `reasoning_content`. */
75
77
  parseThinkTags?: boolean;
76
78
  }
77
79
 
78
- /** Map our internal effort values to OpenAI's reasoning_effort parameter.
79
- * OpenAI caps at "xhigh", so our "max" tier collapses to "xhigh". `"none"` is
80
- * passed through explicitly because OpenAI defaults `reasoning_effort` to
81
- * "medium" when the field is omitted the user's opt-out is only honored
82
- * when we send it on the wire. */
83
- export const EFFORT_TO_REASONING_EFFORT: Record<
84
- string,
85
- NonNullable<
86
- OpenAI.Chat.Completions.ChatCompletionCreateParams["reasoning_effort"]
87
- >
88
- > = {
80
+ /** Wire-level reasoning_effort values. The OpenAI SDK type doesn't include
81
+ * `"max"`, but Fireworks accepts it for DeepSeek V4; the assignment to
82
+ * `params.reasoning_effort` casts through this union. */
83
+ type ReasoningEffortWire = "none" | "low" | "medium" | "high" | "xhigh" | "max";
84
+
85
+ const REASONING_EFFORT_RANK: Record<ReasoningEffortWire, number> = {
86
+ none: 0,
87
+ low: 1,
88
+ medium: 2,
89
+ high: 3,
90
+ xhigh: 4,
91
+ max: 5,
92
+ };
93
+
94
+ /** Map our internal effort values to a reasoning_effort wire value. `"max"`
95
+ * is emitted raw — providers cap it down to their own ceiling
96
+ * ({@link OpenAIChatCompletionsProviderOptions.maxReasoningEffort}) at send
97
+ * time. `"none"` is passed through explicitly because OpenAI-compatible APIs
98
+ * default `reasoning_effort` to `"medium"` when the field is omitted, so the
99
+ * user's opt-out is only honored when we send it on the wire. */
100
+ export const EFFORT_TO_REASONING_EFFORT: Record<string, ReasoningEffortWire> = {
89
101
  none: "none",
90
102
  low: "low",
91
103
  medium: "medium",
92
104
  high: "high",
93
105
  xhigh: "xhigh",
94
- max: "xhigh",
106
+ max: "max",
95
107
  };
96
108
 
109
+ export function clampReasoningEffort(
110
+ value: ReasoningEffortWire,
111
+ ceiling: "high" | "xhigh" | "max",
112
+ ): ReasoningEffortWire {
113
+ return REASONING_EFFORT_RANK[value] > REASONING_EFFORT_RANK[ceiling]
114
+ ? ceiling
115
+ : value;
116
+ }
117
+
97
118
  const OPENAI_SUPPORTED_IMAGE_TYPES = new Set([
98
119
  "image/jpeg",
99
120
  "image/png",
@@ -122,7 +143,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
122
143
  private model: string;
123
144
  private streamTimeoutMs: number;
124
145
  private extraCreateParams: Record<string, unknown>;
125
- private maxReasoningEffort: "high" | "xhigh";
146
+ private maxReasoningEffort: "high" | "xhigh" | "max";
126
147
  private requestHeaders: Record<string, string>;
127
148
  private parseThinkTags: boolean;
128
149
 
@@ -133,12 +154,16 @@ export class OpenAIChatCompletionsProvider implements Provider {
133
154
  ) {
134
155
  this.name = options.providerName ?? "openai";
135
156
  this.providerLabel = options.providerLabel ?? "OpenAI";
157
+ this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
158
+ // Keep the SDK deadline behind our provider stream timeout so
159
+ // createStreamTimeout owns the user-facing timeout error.
160
+ const sdkTimeoutMs = this.streamTimeoutMs + 60_000;
136
161
  this.client = new OpenAI({
137
162
  apiKey,
138
163
  baseURL: options.baseURL,
164
+ timeout: sdkTimeoutMs,
139
165
  });
140
166
  this.model = model;
141
- this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
142
167
  this.extraCreateParams = options.extraCreateParams ?? {};
143
168
  this.maxReasoningEffort = options.maxReasoningEffort ?? "xhigh";
144
169
  this.requestHeaders = options.requestHeaders ?? {};
@@ -187,10 +212,13 @@ export class OpenAIChatCompletionsProvider implements Provider {
187
212
  ? EFFORT_TO_REASONING_EFFORT[effort]
188
213
  : undefined;
189
214
  if (reasoningEffort && typeof nestedReasoningEffort !== "string") {
190
- params.reasoning_effort =
191
- reasoningEffort === "xhigh" && this.maxReasoningEffort === "high"
192
- ? "high"
193
- : reasoningEffort;
215
+ const ceiling = this.resolveMaxReasoningEffort(
216
+ modelOverride ?? this.model,
217
+ );
218
+ params.reasoning_effort = clampReasoningEffort(
219
+ reasoningEffort,
220
+ ceiling,
221
+ ) as OpenAI.Chat.Completions.ChatCompletionCreateParams["reasoning_effort"];
194
222
  }
195
223
 
196
224
  if (tools && tools.length > 0) {
@@ -546,6 +574,18 @@ export class OpenAIChatCompletionsProvider implements Provider {
546
574
  return this.extraCreateParams;
547
575
  }
548
576
 
577
+ /**
578
+ * Per-request reasoning_effort ceiling. Defaults to the provider-wide
579
+ * `maxReasoningEffort` from constructor options. Subclasses (e.g. Fireworks)
580
+ * override to consult the model catalog so per-model accepted ranges are
581
+ * respected.
582
+ */
583
+ protected resolveMaxReasoningEffort(
584
+ _model: string,
585
+ ): "high" | "xhigh" | "max" {
586
+ return this.maxReasoningEffort;
587
+ }
588
+
549
589
  /** Convert neutral messages + system prompt to OpenAI message format. */
550
590
  private toOpenAIMessages(
551
591
  messages: Message[],
@@ -556,7 +596,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
556
596
  if (systemPrompt) {
557
597
  result.push({
558
598
  role: "system",
559
- content: systemPrompt.replaceAll(SYSTEM_PROMPT_CACHE_BOUNDARY, "\n"),
599
+ content: systemPrompt,
560
600
  });
561
601
  }
562
602
 
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Model IDs accepted by the ChatGPT Codex subscription endpoint
3
+ * (`https://chatgpt.com/backend-api/codex`).
4
+ *
5
+ * `oauth_subscription` OpenAI connections hard-route every request to that
6
+ * endpoint, which rejects any model outside this set with HTTP 400. The set
7
+ * gates whether such a connection may serve a given model during auto-
8
+ * resolution of an "Any active OpenAI connection" profile.
9
+ */
10
+ export const CODEX_SUBSCRIPTION_MODEL_IDS: ReadonlySet<string> = new Set([
11
+ "gpt-5.4",
12
+ "gpt-5.3-codex",
13
+ ]);
14
+
15
+ /** True when `model` is accepted by the Codex subscription endpoint. */
16
+ export function isCodexSubscriptionModel(model: string): boolean {
17
+ return CODEX_SUBSCRIPTION_MODEL_IDS.has(model);
18
+ }
@@ -1,8 +1,8 @@
1
1
  import OpenAI from "openai";
2
2
 
3
- import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/cache-boundary.js";
4
3
  import { isAbortReason } from "../../util/abort-reasons.js";
5
4
  import { ProviderError } from "../../util/errors.js";
5
+ import { getLogger } from "../../util/logger.js";
6
6
  import { extractRetryAfterMs } from "../../util/retry.js";
7
7
  import { escapeXmlAttr } from "../../util/xml.js";
8
8
  import { createStreamTimeout } from "../stream-timeout.js";
@@ -17,12 +17,17 @@ import type {
17
17
  import { ContextOverflowError } from "../types.js";
18
18
  import { detectOpenAICompatibleContextOverflow } from "./chat-completions-provider.js";
19
19
 
20
+ const log = getLogger("openai-responses");
21
+
20
22
  export interface OpenAIResponsesProviderOptions {
21
23
  baseURL?: string;
22
24
  providerName?: string;
23
25
  providerLabel?: string;
24
26
  streamTimeoutMs?: number;
25
27
  useNativeWebSearch?: boolean;
28
+ /** When true, target the Codex subscription endpoint and strip fields it
29
+ * rejects (`max_output_tokens`, `reasoning`, `text`, `tools`). */
30
+ codexSubscription?: boolean;
26
31
  }
27
32
 
28
33
  /** Map our internal effort values to the Responses API reasoning.effort parameter.
@@ -103,6 +108,8 @@ export class OpenAIResponsesProvider implements Provider {
103
108
  private model: string;
104
109
  private streamTimeoutMs: number;
105
110
  private useNativeWebSearch: boolean;
111
+ private codexSubscription: boolean;
112
+ private lastCodexErrorBody: string | undefined;
106
113
 
107
114
  constructor(
108
115
  apiKey: string,
@@ -111,12 +118,40 @@ export class OpenAIResponsesProvider implements Provider {
111
118
  ) {
112
119
  this.name = options.providerName ?? "openai";
113
120
  this.providerLabel = options.providerLabel ?? "OpenAI";
121
+ this.codexSubscription = options.codexSubscription ?? false;
122
+ this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
123
+ // Keep the SDK deadline behind our provider stream timeout so
124
+ // createStreamTimeout owns the user-facing timeout error.
125
+ const sdkTimeoutMs = this.streamTimeoutMs + 60_000;
114
126
  this.client = new OpenAI({
115
127
  apiKey,
116
- baseURL: options.baseURL,
128
+ baseURL: this.codexSubscription
129
+ ? "https://chatgpt.com/backend-api/codex"
130
+ : options.baseURL,
131
+ timeout: sdkTimeoutMs,
132
+ ...(this.codexSubscription
133
+ ? {
134
+ fetch: async (url: RequestInfo | URL, init?: RequestInit) => {
135
+ const res = await globalThis.fetch(url, init);
136
+ if (!res.ok) {
137
+ const body = await res.text();
138
+ this.lastCodexErrorBody = body;
139
+ log.warn(
140
+ { status: res.status, body, url: String(url) },
141
+ "Codex endpoint raw error response",
142
+ );
143
+ return new Response(body, {
144
+ status: res.status,
145
+ statusText: res.statusText,
146
+ headers: res.headers,
147
+ });
148
+ }
149
+ return res;
150
+ },
151
+ }
152
+ : {}),
117
153
  });
118
154
  this.model = model;
119
- this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
120
155
  this.useNativeWebSearch = options.useNativeWebSearch ?? false;
121
156
  }
122
157
 
@@ -142,36 +177,35 @@ export class OpenAIResponsesProvider implements Provider {
142
177
  const params: Record<string, unknown> = {
143
178
  model: modelOverride ?? this.model,
144
179
  input,
145
- store: false,
180
+ ...(this.codexSubscription ? { store: false } : {}),
146
181
  };
147
182
 
148
183
  if (systemPrompt) {
149
- params.instructions = systemPrompt.replaceAll(
150
- SYSTEM_PROMPT_CACHE_BOUNDARY,
151
- "\n",
152
- );
184
+ params.instructions = systemPrompt;
153
185
  }
154
186
 
155
- if (maxTokens) {
187
+ if (maxTokens && !this.codexSubscription) {
156
188
  params.max_output_tokens = maxTokens;
157
189
  }
158
190
 
159
- const reasoningEffort = effort
160
- ? EFFORT_TO_REASONING_EFFORT[effort]
161
- : undefined;
162
- if (reasoningEffort) {
163
- params.reasoning = { effort: reasoningEffort };
164
- }
191
+ if (!this.codexSubscription) {
192
+ const reasoningEffort = effort
193
+ ? EFFORT_TO_REASONING_EFFORT[effort]
194
+ : undefined;
195
+ if (reasoningEffort) {
196
+ params.reasoning = { effort: reasoningEffort };
197
+ }
165
198
 
166
- if (
167
- verbosity &&
168
- VALID_VERBOSITIES.has(verbosity) &&
169
- modelSupportsVerbosity(modelOverride ?? this.model)
170
- ) {
171
- params.text = { verbosity };
199
+ if (
200
+ verbosity &&
201
+ VALID_VERBOSITIES.has(verbosity) &&
202
+ modelSupportsVerbosity(modelOverride ?? this.model)
203
+ ) {
204
+ params.text = { verbosity };
205
+ }
172
206
  }
173
207
 
174
- if (tools && tools.length > 0) {
208
+ if (tools && tools.length > 0 && !this.codexSubscription) {
175
209
  if (
176
210
  this.useNativeWebSearch &&
177
211
  tools.some((t) => t.name === "web_search")
@@ -404,6 +438,21 @@ export class OpenAIResponsesProvider implements Provider {
404
438
  ? signal.reason
405
439
  : undefined;
406
440
  if (error instanceof OpenAI.APIError) {
441
+ // Temporary diagnostic: log the raw error shape for Codex 400 debugging
442
+ if (this.codexSubscription) {
443
+ log.warn(
444
+ {
445
+ status: error.status,
446
+ message: error.message,
447
+ code: error.code,
448
+ type: error.type,
449
+ param: error.param,
450
+ errorBody: error.error,
451
+ headers: Object.fromEntries(error.headers?.entries?.() ?? []),
452
+ },
453
+ "Codex subscription API error — raw details",
454
+ );
455
+ }
407
456
  const overflow = detectOpenAICompatibleContextOverflow(error);
408
457
  if (overflow) {
409
458
  throw new ContextOverflowError(
@@ -425,8 +474,22 @@ export class OpenAIResponsesProvider implements Provider {
425
474
  if (retryAfterMs !== undefined)
426
475
  errorOptions.retryAfterMs = retryAfterMs;
427
476
  if (abortReason) errorOptions.abortReason = abortReason;
477
+ let errorDetail = error.message;
478
+ if (this.lastCodexErrorBody) {
479
+ try {
480
+ const parsed = JSON.parse(this.lastCodexErrorBody);
481
+ if (parsed.detail) errorDetail = parsed.detail;
482
+ } catch {
483
+ errorDetail = this.lastCodexErrorBody.slice(0, 200);
484
+ }
485
+ this.lastCodexErrorBody = undefined;
486
+ }
487
+ const extras = [error.code, error.type, error.param]
488
+ .filter(Boolean)
489
+ .join(", ");
490
+ const extraSuffix = extras ? ` [${extras}]` : "";
428
491
  throw new ProviderError(
429
- `${this.providerLabel} API error (${error.status}): ${error.message}`,
492
+ `${this.providerLabel} API error (${error.status}): ${errorDetail}${extraSuffix}`,
430
493
  this.name,
431
494
  error.status,
432
495
  Object.keys(errorOptions).length > 0 ? errorOptions : undefined,
@@ -1,6 +1,7 @@
1
1
  import { ProviderError } from "../../util/errors.js";
2
2
  import { AnthropicProvider } from "../anthropic/client.js";
3
3
  import {
4
+ clampReasoningEffort,
4
5
  EFFORT_TO_REASONING_EFFORT,
5
6
  OpenAIChatCompletionsProvider,
6
7
  } from "../openai/chat-completions-provider.js";
@@ -200,7 +201,10 @@ export class OpenRouterProvider extends OpenAIChatCompletionsProvider {
200
201
  const summaryOverride = extractReasoningSummaryOverride(config);
201
202
  const reasoning: Record<string, unknown> = { enabled: thinkingEnabled };
202
203
  if (mappedEffort) {
203
- reasoning.effort = mappedEffort;
204
+ reasoning.effort = clampReasoningEffort(
205
+ mappedEffort,
206
+ this.resolveMaxReasoningEffort(this.resolveEffectiveModel(options)),
207
+ );
204
208
  }
205
209
  if (thinkingEnabled) {
206
210
  reasoning.summary = summaryOverride ?? "detailed";
@@ -9,6 +9,7 @@ import { getConfig } from "../config/loader.js";
9
9
  import type { LLMCallSite } from "../config/schemas/llm.js";
10
10
  import { getDb } from "../memory/db-connection.js";
11
11
  import { getLogger } from "../util/logger.js";
12
+ import { isConnectionCompatibleWithModel } from "./connection-model-compat.js";
12
13
  import { tryResolveProviderForConnectionName } from "./connection-resolution.js";
13
14
  import { listConnections } from "./inference/connections.js";
14
15
  import { initializeProviders, listProviders } from "./registry.js";
@@ -126,7 +127,11 @@ export async function resolveConfiguredProvider(
126
127
  const candidates = listConnections(getDb(), {
127
128
  provider: inferenceProvider,
128
129
  });
129
- const active = candidates.find((c) => c.status === "active");
130
+ const active = candidates.find(
131
+ (c) =>
132
+ c.status === "active" &&
133
+ isConnectionCompatibleWithModel(c, resolved.model),
134
+ );
130
135
  if (active) {
131
136
  connectionName = active.name;
132
137
  }
@@ -147,6 +152,7 @@ export async function resolveConfiguredProvider(
147
152
  connectionName,
148
153
  config,
149
154
  inferenceProvider,
155
+ resolved.model,
150
156
  );
151
157
  if (!connectionProvider) {
152
158
  // Soft credential failure — the connection resolved to no usable
@@ -47,9 +47,18 @@ const EFFORT_SUPPORTED_PROVIDERS = new Set([
47
47
  /**
48
48
  * Providers that consume the `thinking` config. Anthropic uses it directly on
49
49
  * the wire; OpenRouter either forwards it to its Anthropic-compatible path or
50
- * translates it into the unified `reasoning` parameter on OpenAI-compat calls.
50
+ * translates it into the unified `reasoning` parameter on OpenAI-compat calls;
51
+ * Gemini reads `thinking.level` to populate `thinkingConfig.thinkingLevel`.
51
52
  */
52
- const THINKING_AWARE_PROVIDERS = new Set(["anthropic", "openrouter"]);
53
+ const THINKING_AWARE_PROVIDERS = new Set(["anthropic", "openrouter", "gemini"]);
54
+
55
+ /**
56
+ * Providers that consume Gemini-only thinking extras (`level`,
57
+ * `streamThinking`). For other thinking-aware providers, we scrub these from
58
+ * the normalized wire payload because Anthropic's SDK rejects unknown keys
59
+ * inside the `thinking` object with "Extra inputs are not permitted".
60
+ */
61
+ const THINKING_EXTRA_FIELDS_AWARE_PROVIDERS = new Set(["gemini"]);
53
62
 
54
63
  /**
55
64
  * Providers that consume the `verbosity` config. Currently OpenAI (mapped to
@@ -289,7 +298,8 @@ function normalizeSendMessageOptions(
289
298
  }
290
299
 
291
300
  // thinking is Anthropic-specific on the wire; OpenRouter reads it as a
292
- // signal for its unified reasoning parameter. Strip it for other providers.
301
+ // signal for its unified reasoning parameter; Gemini reads `level` from it.
302
+ // Strip it for other providers.
293
303
  if (
294
304
  !THINKING_AWARE_PROVIDERS.has(providerName) &&
295
305
  nextConfig.thinking !== undefined
@@ -297,6 +307,27 @@ function normalizeSendMessageOptions(
297
307
  delete nextConfig.thinking;
298
308
  }
299
309
 
310
+ // Strip Gemini-only extras (`level`, `streamThinking`) from the wire
311
+ // `thinking` object for providers that don't read them. Anthropic in
312
+ // particular rejects unknown keys inside `thinking` with "Extra inputs are
313
+ // not permitted"; the OpenRouter Anthropic-compat path hits the same SDK.
314
+ if (
315
+ nextConfig.thinking !== undefined &&
316
+ !THINKING_EXTRA_FIELDS_AWARE_PROVIDERS.has(providerName) &&
317
+ typeof nextConfig.thinking === "object" &&
318
+ nextConfig.thinking !== null
319
+ ) {
320
+ const wire = nextConfig.thinking as Record<string, unknown>;
321
+ if (wire.level !== undefined || wire.streamThinking !== undefined) {
322
+ const scrubbed: Record<string, unknown> = {};
323
+ for (const [key, value] of Object.entries(wire)) {
324
+ if (key === "level" || key === "streamThinking") continue;
325
+ scrubbed[key] = value;
326
+ }
327
+ nextConfig.thinking = scrubbed;
328
+ }
329
+ }
330
+
300
331
  // Anthropic (and OpenRouter fronting Anthropic) rejects requests that
301
332
  // combine extended thinking with forced tool use (`tool_choice.type` of
302
333
  // `"tool"` or `"any"`). Strip thinking when both are present so the
@@ -1,20 +1,45 @@
1
+ import { THINKING_LEVELS, type ThinkingLevel } from "../config/schemas/llm.js";
2
+
1
3
  type ThinkingConfigRecord = Record<string, unknown>;
2
4
 
5
+ const THINKING_LEVEL_SET: ReadonlySet<string> = new Set(THINKING_LEVELS);
6
+
3
7
  function isRecord(value: unknown): value is ThinkingConfigRecord {
4
8
  return typeof value === "object" && value !== null && !Array.isArray(value);
5
9
  }
6
10
 
11
+ function pickGeminiExtras(thinking: ThinkingConfigRecord): {
12
+ level?: ThinkingLevel;
13
+ streamThinking?: boolean;
14
+ } {
15
+ const extras: { level?: ThinkingLevel; streamThinking?: boolean } = {};
16
+ if (
17
+ typeof thinking.level === "string" &&
18
+ THINKING_LEVEL_SET.has(thinking.level)
19
+ ) {
20
+ extras.level = thinking.level as ThinkingLevel;
21
+ }
22
+ if (typeof thinking.streamThinking === "boolean") {
23
+ extras.streamThinking = thinking.streamThinking;
24
+ }
25
+ return extras;
26
+ }
27
+
7
28
  export function normalizeThinkingConfigForWire(
8
29
  thinking: unknown,
9
30
  ): ThinkingConfigRecord | undefined {
10
31
  if (!isRecord(thinking)) return undefined;
11
32
 
33
+ // Already in wire shape — preserve as-is so re-normalization is idempotent
34
+ // and Gemini-only fields stay attached for the Gemini provider to read.
12
35
  if (typeof thinking.type === "string") {
13
36
  return thinking;
14
37
  }
15
38
 
39
+ const extras = pickGeminiExtras(thinking);
40
+
16
41
  if (thinking.enabled === true) {
17
- return { type: "adaptive" };
42
+ return { type: "adaptive", ...extras };
18
43
  }
19
44
 
20
45
  if (thinking.enabled === false) {