@iislee/opencodex 2.11.0 → 2.31.0

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 (675) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +114 -19
  3. package/bin/ocx.mjs +164 -36
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-BF38heuV.js +104 -0
  6. package/gui/dist/assets/index-DMiI18Kv.css +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +19 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +376 -52
  44. package/src/adapters/base.ts +54 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +601 -0
  48. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  49. package/src/adapters/cursor/cursor-errors.ts +129 -6
  50. package/src/adapters/cursor/discovery.ts +61 -4
  51. package/src/adapters/cursor/effort-map.ts +27 -3
  52. package/src/adapters/cursor/framing.ts +39 -0
  53. package/src/adapters/cursor/h2-pool.ts +123 -0
  54. package/src/adapters/cursor/http1-bidi.ts +361 -0
  55. package/src/adapters/cursor/images.ts +704 -0
  56. package/src/adapters/cursor/live-models.ts +174 -58
  57. package/src/adapters/cursor/live-transport.ts +609 -170
  58. package/src/adapters/cursor/native-exec-common.ts +23 -2
  59. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  60. package/src/adapters/cursor/native-exec-network.ts +1 -1
  61. package/src/adapters/cursor/native-exec-shell.ts +0 -1
  62. package/src/adapters/cursor/native-exec.ts +101 -14
  63. package/src/adapters/cursor/protobuf-events.ts +829 -11
  64. package/src/adapters/cursor/protobuf-request.ts +383 -65
  65. package/src/adapters/cursor/request-builder.ts +237 -31
  66. package/src/adapters/cursor/tool-definitions.ts +242 -12
  67. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  68. package/src/adapters/cursor/transport.ts +22 -0
  69. package/src/adapters/cursor/types.ts +28 -1
  70. package/src/adapters/cursor.ts +133 -7
  71. package/src/adapters/google-antigravity-replay.ts +558 -34
  72. package/src/adapters/google-antigravity-wire.ts +43 -10
  73. package/src/adapters/google-http.ts +38 -10
  74. package/src/adapters/google-tool-schema.ts +80 -15
  75. package/src/adapters/google-truncation.ts +11 -0
  76. package/src/adapters/google.ts +618 -74
  77. package/src/adapters/identity.ts +39 -6
  78. package/src/adapters/kiro-errors.ts +11 -0
  79. package/src/adapters/kiro-events.ts +19 -1
  80. package/src/adapters/kiro-thinking.ts +18 -2
  81. package/src/adapters/kiro-tools.ts +10 -1
  82. package/src/adapters/kiro.ts +92 -54
  83. package/src/adapters/mimo-free.ts +17 -0
  84. package/src/adapters/openai-chat-url.ts +11 -0
  85. package/src/adapters/openai-chat.ts +1311 -336
  86. package/src/adapters/openai-responses-url.ts +16 -0
  87. package/src/adapters/openai-responses.ts +830 -56
  88. package/src/adapters/registry.ts +175 -0
  89. package/src/adapters/responses-tool-schema.ts +67 -0
  90. package/src/adapters/tool-call-id.ts +119 -0
  91. package/src/adapters/tool-catalog-nudge.ts +104 -21
  92. package/src/adapters/xai-web-search.ts +185 -0
  93. package/src/bridge.ts +428 -61
  94. package/src/chat/inbound.ts +43 -19
  95. package/src/chat/outbound.ts +82 -26
  96. package/src/claude/agents-inject.ts +32 -9
  97. package/src/claude/context-windows.ts +21 -5
  98. package/src/claude/desktop-3p.ts +243 -9
  99. package/src/claude/gateway-cache.ts +41 -4
  100. package/src/claude/inbound.ts +72 -3
  101. package/src/claude/model-info.ts +38 -15
  102. package/src/claude/outbound.ts +70 -16
  103. package/src/cli/account-api.ts +35 -1
  104. package/src/cli/account-auth.ts +33 -6
  105. package/src/cli/account-catalog-refresh.ts +14 -0
  106. package/src/cli/account-extended.ts +389 -2
  107. package/src/cli/account-main.ts +317 -0
  108. package/src/cli/account.ts +30 -6
  109. package/src/cli/agent.ts +45 -1
  110. package/src/cli/claude-agent-startup-sync.ts +73 -0
  111. package/src/cli/claude-desktop.ts +29 -4
  112. package/src/cli/claude.ts +103 -34
  113. package/src/cli/codex-log-guard-doctor.ts +103 -0
  114. package/src/cli/codex-shim-autorestore.ts +2 -0
  115. package/src/cli/codex-shim-readiness.ts +76 -0
  116. package/src/cli/combo.ts +8 -0
  117. package/src/cli/config-command.ts +74 -10
  118. package/src/cli/dispatch.ts +593 -0
  119. package/src/cli/doctor.ts +315 -43
  120. package/src/cli/ensure-desired-integrations.ts +152 -0
  121. package/src/cli/export-command.ts +46 -20
  122. package/src/cli/help.ts +20 -271
  123. package/src/cli/index.ts +378 -519
  124. package/src/cli/init.ts +4 -17
  125. package/src/cli/integrations.ts +120 -2
  126. package/src/cli/lab.ts +607 -0
  127. package/src/cli/launcher-context.ts +77 -0
  128. package/src/cli/minimax.ts +497 -0
  129. package/src/cli/models-runtime.ts +35 -2
  130. package/src/cli/models.ts +100 -14
  131. package/src/cli/observe.ts +92 -3
  132. package/src/cli/opencode.ts +4 -2
  133. package/src/cli/provider-runtime.ts +18 -1
  134. package/src/cli/provider.ts +24 -3
  135. package/src/cli/ready.ts +301 -0
  136. package/src/cli/registry.ts +437 -0
  137. package/src/cli/root.ts +86 -0
  138. package/src/cli/route-policy.ts +92 -0
  139. package/src/cli/runtime-api.ts +6 -3
  140. package/src/cli/star-prompt.ts +71 -15
  141. package/src/cli/status.ts +10 -3
  142. package/src/cli/system-restart-client.ts +146 -0
  143. package/src/cli/tray-proxy.ts +153 -6
  144. package/src/cli/v2.ts +105 -10
  145. package/src/cli.ts +1 -1
  146. package/src/clients/config-export.ts +1358 -21
  147. package/src/codex/account-label.ts +14 -1
  148. package/src/codex/account-lifecycle.ts +130 -13
  149. package/src/codex/account-namespaces.ts +49 -3
  150. package/src/codex/account-priority.ts +83 -0
  151. package/src/codex/account-store.ts +29 -2
  152. package/src/codex/account-usability.ts +25 -2
  153. package/src/codex/admission.ts +256 -0
  154. package/src/codex/affinity-debug.ts +162 -0
  155. package/src/codex/app-server-processes.ts +493 -106
  156. package/src/codex/app-server-restart-service.ts +232 -0
  157. package/src/codex/auth-api.ts +849 -242
  158. package/src/codex/auth-collision.ts +5 -3
  159. package/src/codex/auth-context.ts +345 -32
  160. package/src/codex/autostart-health.ts +8 -1
  161. package/src/codex/catalog/account-models.ts +67 -0
  162. package/src/codex/catalog/aggregation.ts +68 -10
  163. package/src/codex/catalog/bundled.ts +331 -33
  164. package/src/codex/catalog/effort.ts +121 -30
  165. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  166. package/src/codex/catalog/kinds.ts +2 -0
  167. package/src/codex/catalog/metadata.ts +529 -45
  168. package/src/codex/catalog/native-models.ts +72 -0
  169. package/src/codex/catalog/parsing.ts +224 -30
  170. package/src/codex/catalog/provider-fetch.ts +1460 -134
  171. package/src/codex/catalog/sync.ts +1449 -186
  172. package/src/codex/catalog-admission.ts +199 -0
  173. package/src/codex/catalog-refresh-status.ts +105 -0
  174. package/src/codex/catalog-write-serialization.ts +242 -0
  175. package/src/codex/catalog.ts +6 -3
  176. package/src/codex/codex-write-lock.ts +384 -0
  177. package/src/codex/convergence-types.ts +614 -0
  178. package/src/codex/convergence.ts +651 -0
  179. package/src/codex/coordinator-doctor.ts +332 -0
  180. package/src/codex/custom-model-catalog-migration.ts +176 -0
  181. package/src/codex/desired-state.ts +230 -0
  182. package/src/codex/features.ts +636 -39
  183. package/src/codex/generation.ts +202 -0
  184. package/src/codex/history-job.ts +407 -0
  185. package/src/codex/history-lock.ts +242 -0
  186. package/src/codex/history-migration-guardian.ts +26 -20
  187. package/src/codex/history-provider.ts +231 -28
  188. package/src/codex/history-transition.ts +105 -0
  189. package/src/codex/history-worker.ts +220 -0
  190. package/src/codex/inject-coordination.ts +290 -0
  191. package/src/codex/inject.ts +1073 -152
  192. package/src/codex/injected-marker.ts +37 -3
  193. package/src/codex/integration-record.ts +266 -0
  194. package/src/codex/internal/catalog-writer.ts +203 -0
  195. package/src/codex/internal/history-writer.ts +80 -0
  196. package/src/codex/journal.ts +66 -4
  197. package/src/codex/log-guard/inspect.ts +506 -0
  198. package/src/codex/log-guard/lock.ts +150 -0
  199. package/src/codex/log-guard/maintenance.ts +403 -0
  200. package/src/codex/log-guard/path-safety.ts +88 -0
  201. package/src/codex/log-guard/policy.ts +44 -0
  202. package/src/codex/log-guard/processes.ts +205 -0
  203. package/src/codex/log-guard/protection.ts +489 -0
  204. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  205. package/src/codex/main-account-cache.ts +24 -0
  206. package/src/codex/main-account.ts +29 -1
  207. package/src/codex/management-convergence.ts +167 -0
  208. package/src/codex/model-cache.ts +56 -10
  209. package/src/codex/model-entitlements.ts +353 -0
  210. package/src/codex/native-main-admission.ts +47 -0
  211. package/src/codex/native-main-auth-temp.ts +187 -0
  212. package/src/codex/native-main-claim.ts +178 -0
  213. package/src/codex/native-main-lock-file.ts +162 -0
  214. package/src/codex/native-main-owner.ts +329 -0
  215. package/src/codex/native-profile-api.ts +247 -0
  216. package/src/codex/native-profile-manager.ts +1531 -0
  217. package/src/codex/native-profile-processes.ts +121 -0
  218. package/src/codex/native-profile-recovery.ts +99 -0
  219. package/src/codex/native-profile-stage-store.ts +387 -0
  220. package/src/codex/native-profile-startup.ts +492 -0
  221. package/src/codex/native-profile-store.ts +855 -0
  222. package/src/codex/native-profile-types.ts +120 -0
  223. package/src/codex/native-residue.ts +682 -0
  224. package/src/codex/paths.ts +80 -1
  225. package/src/codex/plan-from-token.ts +140 -0
  226. package/src/codex/plan.ts +40 -0
  227. package/src/codex/plugins-doctor.ts +1 -1
  228. package/src/codex/pool-rotation.ts +74 -4
  229. package/src/codex/project-config-warnings.ts +20 -6
  230. package/src/codex/prompt-journal.ts +352 -0
  231. package/src/codex/prompt-layers.ts +967 -0
  232. package/src/codex/prompt-lock.ts +143 -0
  233. package/src/codex/quota-rejection.ts +298 -0
  234. package/src/codex/quota.ts +175 -13
  235. package/src/codex/refresh.ts +11 -2
  236. package/src/codex/reset-credit-recovery.ts +1044 -0
  237. package/src/codex/routing.ts +505 -94
  238. package/src/codex/runtime.ts +159 -38
  239. package/src/codex/shim.ts +1009 -28
  240. package/src/codex/subagent-model-fallback.ts +350 -35
  241. package/src/codex/sync.ts +191 -2
  242. package/src/codex/transition-state.ts +612 -0
  243. package/src/codex/upstream-host-health.ts +368 -0
  244. package/src/codex/user-identity.ts +557 -0
  245. package/src/codex/warmup.ts +187 -81
  246. package/src/codex/write-coordination.ts +114 -0
  247. package/src/combos/failover.ts +20 -0
  248. package/src/combos/index.ts +4 -0
  249. package/src/combos/request.ts +32 -0
  250. package/src/combos/types.ts +81 -9
  251. package/src/config/provider-name.ts +24 -0
  252. package/src/config.ts +1762 -140
  253. package/src/generated/compatibility-version.json +3164 -0
  254. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  255. package/src/grok/inject.ts +16 -5
  256. package/src/grok/inspect.ts +45 -0
  257. package/src/grok/sync.ts +2 -2
  258. package/src/images/loop.ts +152 -29
  259. package/src/images/plan.ts +23 -13
  260. package/src/integrations/config-io.ts +269 -0
  261. package/src/integrations/journal.ts +315 -0
  262. package/src/integrations/merge.ts +135 -0
  263. package/src/integrations/mutation-flight.ts +71 -0
  264. package/src/integrations/native/ownership-preflight.ts +202 -0
  265. package/src/integrations/omp-yaml-source.ts +358 -0
  266. package/src/integrations/owned-refresh.ts +74 -0
  267. package/src/integrations/ownership.ts +111 -0
  268. package/src/integrations/registry.ts +159 -0
  269. package/src/integrations/serialize.ts +314 -0
  270. package/src/integrations/state.ts +361 -0
  271. package/src/integrations/store.ts +103 -0
  272. package/src/integrations/writer-lock.ts +98 -0
  273. package/src/integrations/writer.ts +691 -0
  274. package/src/lab/artifacts/sanitize.ts +586 -0
  275. package/src/lab/artifacts/secure-fs.ts +475 -0
  276. package/src/lab/artifacts/store.ts +310 -0
  277. package/src/lab/automation/budgets.ts +78 -0
  278. package/src/lab/automation/config-persistence.ts +256 -0
  279. package/src/lab/automation/constants.ts +39 -0
  280. package/src/lab/automation/cooldown.ts +103 -0
  281. package/src/lab/automation/dispatch.ts +211 -0
  282. package/src/lab/automation/index.ts +13 -0
  283. package/src/lab/automation/orchestrator.ts +499 -0
  284. package/src/lab/automation/persistence.ts +512 -0
  285. package/src/lab/automation/planner.ts +371 -0
  286. package/src/lab/automation/policy.ts +136 -0
  287. package/src/lab/automation/queue.ts +191 -0
  288. package/src/lab/automation/recovery.ts +24 -0
  289. package/src/lab/automation/route-context.ts +21 -0
  290. package/src/lab/automation/run-key.ts +44 -0
  291. package/src/lab/automation/runs-query.ts +34 -0
  292. package/src/lab/automation/types.ts +160 -0
  293. package/src/lab/conformance/assertion.ts +325 -0
  294. package/src/lab/conformance/digest.ts +22 -0
  295. package/src/lab/conformance/executor.ts +741 -0
  296. package/src/lab/conformance/fixture-provider.ts +27 -0
  297. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  298. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  299. package/src/lab/conformance/harness-budget.ts +47 -0
  300. package/src/lab/conformance/index.ts +5 -0
  301. package/src/lab/conformance/jcs.ts +64 -0
  302. package/src/lab/conformance/json-pointer.ts +39 -0
  303. package/src/lab/conformance/manifest.ts +180 -0
  304. package/src/lab/conformance/mcp-stub.ts +179 -0
  305. package/src/lab/conformance/negative-controls.ts +164 -0
  306. package/src/lab/conformance/observation.ts +355 -0
  307. package/src/lab/conformance/runner.ts +68 -0
  308. package/src/lab/conformance/sse-normalize.ts +59 -0
  309. package/src/lab/conformance/suite-manifest.ts +78 -0
  310. package/src/lab/conformance/types.ts +214 -0
  311. package/src/lab/constants.ts +126 -0
  312. package/src/lab/digest.ts +64 -0
  313. package/src/lab/events/errors.ts +9 -0
  314. package/src/lab/events/limits.ts +117 -0
  315. package/src/lab/events/types.ts +229 -0
  316. package/src/lab/events/validate.ts +781 -0
  317. package/src/lab/fabric/constants.ts +40 -0
  318. package/src/lab/fabric/executor.ts +492 -0
  319. package/src/lab/fabric/index.ts +80 -0
  320. package/src/lab/fabric/manifest.ts +222 -0
  321. package/src/lab/fabric/observe.ts +489 -0
  322. package/src/lab/fabric/patch.ts +79 -0
  323. package/src/lab/fabric/producer-child.ts +139 -0
  324. package/src/lab/fabric/producer-isolate.ts +276 -0
  325. package/src/lab/fabric/producer-protocol.ts +61 -0
  326. package/src/lab/fabric/scratch.ts +439 -0
  327. package/src/lab/fabric/subject.ts +106 -0
  328. package/src/lab/fabric/types.ts +134 -0
  329. package/src/lab/fabric/verifier.ts +98 -0
  330. package/src/lab/index.ts +54 -0
  331. package/src/lab/ledger/artifact-refs.ts +127 -0
  332. package/src/lab/ledger/invalidation.ts +136 -0
  333. package/src/lab/ledger/purge.ts +310 -0
  334. package/src/lab/ledger/store.ts +532 -0
  335. package/src/lab/live/credential-lease.ts +53 -0
  336. package/src/lab/live/destination.ts +155 -0
  337. package/src/lab/live/executor.ts +336 -0
  338. package/src/lab/live/inert-tools.ts +56 -0
  339. package/src/lab/live/manifest.ts +85 -0
  340. package/src/lab/live/mcp-loopback.ts +57 -0
  341. package/src/lab/live/runner.ts +19 -0
  342. package/src/lab/live/sandbox.ts +61 -0
  343. package/src/lab/live/suite-manifest.ts +41 -0
  344. package/src/lab/live/transport.ts +118 -0
  345. package/src/lab/live/types.ts +197 -0
  346. package/src/lab/observe/from-conformance.ts +301 -0
  347. package/src/lab/observe/from-live.ts +117 -0
  348. package/src/lab/paths.ts +153 -0
  349. package/src/lab/projection/rebuild.ts +495 -0
  350. package/src/lab/projection/schema.ts +135 -0
  351. package/src/lab/projection/verdicts.ts +474 -0
  352. package/src/lab/projection/verification.ts +412 -0
  353. package/src/lab/public/bundle.ts +217 -0
  354. package/src/lab/public/community-authority.ts +175 -0
  355. package/src/lab/public/community-files.ts +29 -0
  356. package/src/lab/public/community.ts +479 -0
  357. package/src/lab/public/file-safety.ts +155 -0
  358. package/src/lab/public/ids.ts +26 -0
  359. package/src/lab/public/index.ts +16 -0
  360. package/src/lab/public/mutation-lock.ts +424 -0
  361. package/src/lab/public/operator.ts +353 -0
  362. package/src/lab/public/origin-purge.ts +79 -0
  363. package/src/lab/public/origin.ts +203 -0
  364. package/src/lab/public/privacy.ts +143 -0
  365. package/src/lab/public/private-file.ts +261 -0
  366. package/src/lab/public/project.ts +124 -0
  367. package/src/lab/public/purge-test-fault.ts +21 -0
  368. package/src/lab/public/purge.ts +223 -0
  369. package/src/lab/public/registry.ts +44 -0
  370. package/src/lab/public/revocation.ts +252 -0
  371. package/src/lab/public/signature.ts +243 -0
  372. package/src/lab/public/storage.ts +105 -0
  373. package/src/lab/public/strict-json.ts +206 -0
  374. package/src/lab/public/time.ts +26 -0
  375. package/src/lab/public/types.ts +172 -0
  376. package/src/lab/public/validate.ts +391 -0
  377. package/src/lab/query/catalog.ts +101 -0
  378. package/src/lab/query/connection.ts +107 -0
  379. package/src/lab/query/constants.ts +4 -0
  380. package/src/lab/query/cursor.ts +132 -0
  381. package/src/lab/query/dto-map.ts +277 -0
  382. package/src/lab/query/errors.ts +22 -0
  383. package/src/lab/query/freshness.ts +53 -0
  384. package/src/lab/query/index.ts +45 -0
  385. package/src/lab/query/latest-observation.ts +59 -0
  386. package/src/lab/query/passive-production.ts +159 -0
  387. package/src/lab/query/queries.ts +444 -0
  388. package/src/lab/query/types.ts +266 -0
  389. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  390. package/src/lab/subject/installation-salt.ts +112 -0
  391. package/src/lab/subject/protocol-subject.ts +80 -0
  392. package/src/lab/subject/route-subject.ts +74 -0
  393. package/src/lib/app-owned-memory-stores.ts +22 -0
  394. package/src/lib/bounded-body.ts +153 -9
  395. package/src/lib/bun-runtime.ts +125 -12
  396. package/src/lib/bun-stream-caps.ts +13 -9
  397. package/src/lib/codex-restart-contract.ts +120 -0
  398. package/src/lib/config-ownership.ts +6 -2
  399. package/src/lib/destination-policy.ts +65 -1
  400. package/src/lib/errors.ts +44 -2
  401. package/src/lib/fabric-task-execution-authority.ts +7 -0
  402. package/src/lib/fabric-task-host.ts +29 -0
  403. package/src/lib/lab-activation.ts +223 -0
  404. package/src/lib/lab-live-execution-authority.ts +13 -0
  405. package/src/lib/lab-live-host.ts +30 -0
  406. package/src/lib/lab-live-pinned-sender.ts +56 -0
  407. package/src/lib/lab-live-route-production.ts +130 -0
  408. package/src/lib/lab-passive-linker-registration.ts +26 -0
  409. package/src/lib/local-management-attestation.ts +51 -0
  410. package/src/lib/local-management-capability.ts +100 -0
  411. package/src/lib/local-provider-reload-contract.ts +100 -0
  412. package/src/lib/optional-shutdown-hooks.ts +57 -0
  413. package/src/lib/pinned-http.ts +145 -26
  414. package/src/lib/process-control.ts +4 -1
  415. package/src/lib/provider-outbound.ts +49 -9
  416. package/src/lib/redact.ts +419 -3
  417. package/src/lib/self-launch-argv.ts +15 -0
  418. package/src/lib/server-resource-ownership.ts +71 -0
  419. package/src/lib/shadow-call.ts +35 -4
  420. package/src/lib/sse-decoder.ts +41 -0
  421. package/src/lib/state-store-registrations.ts +10 -2
  422. package/src/lib/system-restart-contract.ts +73 -0
  423. package/src/lib/token-estimate.ts +19 -2
  424. package/src/lib/tool-argument-integers.ts +202 -0
  425. package/src/lib/translator-budget.ts +44 -0
  426. package/src/lib/upstream-http-version.ts +57 -0
  427. package/src/lib/upstream-reachability.ts +95 -0
  428. package/src/lib/upstream-retry.ts +156 -3
  429. package/src/lib/windows-atomic-replace.ts +155 -0
  430. package/src/lib/windows-elevation.ts +70 -2
  431. package/src/lib/windows-secret-acl.ts +409 -69
  432. package/src/lib/windows-service-wrappers.ts +72 -0
  433. package/src/lib/windows-text.ts +106 -0
  434. package/src/lib/windows-user-principal.ts +341 -0
  435. package/src/lib/winsw.ts +33 -5
  436. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  437. package/src/oauth/account-import/index.ts +15 -0
  438. package/src/oauth/account-import/parser.ts +83 -0
  439. package/src/oauth/account-import/registry.ts +18 -0
  440. package/src/oauth/account-import/service.ts +75 -0
  441. package/src/oauth/account-import/types.ts +91 -0
  442. package/src/oauth/anthropic.ts +12 -1
  443. package/src/oauth/callback-server.ts +8 -2
  444. package/src/oauth/chatgpt.ts +12 -1
  445. package/src/oauth/command-code.ts +239 -0
  446. package/src/oauth/cursor.ts +46 -5
  447. package/src/oauth/google-antigravity.ts +35 -3
  448. package/src/oauth/health.ts +20 -12
  449. package/src/oauth/index.ts +398 -66
  450. package/src/oauth/key-providers.ts +16 -0
  451. package/src/oauth/kimi.ts +16 -2
  452. package/src/oauth/kiro.ts +50 -6
  453. package/src/oauth/local-token-detect.ts +11 -2
  454. package/src/oauth/log.ts +3 -1
  455. package/src/oauth/login-cli.ts +88 -28
  456. package/src/oauth/nous.ts +798 -0
  457. package/src/oauth/store.ts +119 -21
  458. package/src/oauth/token-guardian.ts +9 -3
  459. package/src/pi/models.ts +2 -2
  460. package/src/providers/alibaba-region-migration.ts +1 -1
  461. package/src/providers/antigravity-models.ts +521 -31
  462. package/src/providers/base-url-choices.ts +10 -0
  463. package/src/providers/codex-capacity.ts +292 -0
  464. package/src/providers/command-code-efforts.ts +144 -0
  465. package/src/providers/context-cap.ts +22 -5
  466. package/src/providers/cursor-pool.ts +72 -0
  467. package/src/providers/derive.ts +253 -6
  468. package/src/providers/fastwire.ts +501 -0
  469. package/src/providers/free-directory.ts +10 -7
  470. package/src/providers/google-vertex-location.ts +14 -0
  471. package/src/providers/key-failover.ts +71 -3
  472. package/src/providers/label.ts +1 -1
  473. package/src/providers/model-discovery-limits.ts +16 -0
  474. package/src/providers/model-discovery.ts +115 -22
  475. package/src/providers/model-rename-migration.ts +255 -0
  476. package/src/providers/model-rename-startup.ts +28 -0
  477. package/src/providers/openai-sidecar.ts +72 -4
  478. package/src/providers/openai-tier-startup.ts +31 -2
  479. package/src/providers/openai-tiers.ts +119 -4
  480. package/src/providers/openai-virtual-models.ts +1 -0
  481. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  482. package/src/providers/provider-id-rewrite.ts +29 -0
  483. package/src/providers/quota.ts +1319 -38
  484. package/src/providers/registry.ts +1429 -111
  485. package/src/providers/request-pacing.ts +310 -0
  486. package/src/providers/service-tier.ts +277 -0
  487. package/src/providers/slug-codec.ts +42 -6
  488. package/src/providers/static-model-discovery.ts +86 -0
  489. package/src/providers/xai-responses-opt-in.ts +15 -0
  490. package/src/providers/xai-transport.ts +11 -4
  491. package/src/reasoning-effort.ts +49 -1
  492. package/src/responses/compaction.ts +26 -1
  493. package/src/responses/custom-tool-compat.ts +266 -0
  494. package/src/responses/hosted-tool-policy.ts +9 -0
  495. package/src/responses/namespace-tool-compat.ts +355 -0
  496. package/src/responses/parser.ts +220 -38
  497. package/src/responses/provider-continuation.ts +98 -0
  498. package/src/responses/provider-opaque-metadata.ts +73 -0
  499. package/src/responses/reasoning-envelope.ts +9 -1
  500. package/src/responses/reasoning-replay-cache.ts +426 -0
  501. package/src/responses/schema.ts +7 -1
  502. package/src/responses/spill-store.ts +75 -10
  503. package/src/responses/state.ts +565 -27
  504. package/src/responses/thought-signature-replay.ts +347 -0
  505. package/src/responses/tool-search-compat.ts +301 -0
  506. package/src/responses/truncated-stop-reason.ts +60 -0
  507. package/src/router.ts +366 -30
  508. package/src/routing/analytics.ts +378 -0
  509. package/src/routing/capability.ts +244 -0
  510. package/src/routing/compatibility/assemble.ts +73 -0
  511. package/src/routing/compatibility/behavior.ts +278 -0
  512. package/src/routing/compatibility/catalog.ts +99 -0
  513. package/src/routing/compatibility/endpoint.ts +52 -0
  514. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  515. package/src/routing/compatibility/policy.ts +181 -0
  516. package/src/routing/compatibility/provider-slot.ts +56 -0
  517. package/src/routing/compatibility/reader.ts +110 -0
  518. package/src/routing/compatibility/subject.ts +191 -0
  519. package/src/routing/compatibility/types.ts +64 -0
  520. package/src/routing/compatibility/version.ts +104 -0
  521. package/src/routing/cost.ts +77 -0
  522. package/src/routing/evaluator.ts +495 -0
  523. package/src/routing/health.ts +412 -0
  524. package/src/routing/history/cursor.ts +43 -0
  525. package/src/routing/history/indexer.ts +605 -0
  526. package/src/routing/history/schema.ts +72 -0
  527. package/src/routing/profile-namespace.ts +15 -0
  528. package/src/routing/profile.ts +547 -0
  529. package/src/routing/quota.ts +145 -0
  530. package/src/routing/request-evidence.ts +45 -0
  531. package/src/routing/trace.ts +776 -0
  532. package/src/server/adapter-resolve.ts +2 -29
  533. package/src/server/auth-cors.ts +267 -46
  534. package/src/server/background-lifecycle.ts +182 -0
  535. package/src/server/chat-completions.ts +130 -56
  536. package/src/server/chat-native-sse.ts +331 -0
  537. package/src/server/chat-native.ts +426 -0
  538. package/src/server/claude-messages.ts +159 -43
  539. package/src/server/direct-local-http.ts +347 -0
  540. package/src/server/effort-policy.ts +18 -0
  541. package/src/server/github-copilot-responses-repair.ts +338 -0
  542. package/src/server/gui-static.ts +39 -10
  543. package/src/server/images.ts +94 -12
  544. package/src/server/index.ts +865 -181
  545. package/src/server/lifecycle.ts +284 -13
  546. package/src/server/live.ts +136 -17
  547. package/src/server/local-management-read-client.ts +90 -0
  548. package/src/server/local-provider-reload-client.ts +137 -0
  549. package/src/server/management/agent-settings-routes.ts +398 -103
  550. package/src/server/management/api-key-usage.ts +31 -5
  551. package/src/server/management/body.ts +6 -0
  552. package/src/server/management/combo-routes.ts +62 -24
  553. package/src/server/management/config-routes.ts +464 -51
  554. package/src/server/management/context.ts +80 -2
  555. package/src/server/management/integration-routes.ts +498 -0
  556. package/src/server/management/lab-automation-routes.ts +206 -0
  557. package/src/server/management/lab-routes.ts +563 -0
  558. package/src/server/management/logs-usage-routes.ts +101 -32
  559. package/src/server/management/model-routes.ts +189 -131
  560. package/src/server/management/model-rows.ts +163 -0
  561. package/src/server/management/native-integration-routes.ts +769 -0
  562. package/src/server/management/oauth-account-routes.ts +80 -4
  563. package/src/server/management/provider-capability-config.ts +48 -0
  564. package/src/server/management/provider-routes.ts +764 -157
  565. package/src/server/management/request-history-routes.ts +191 -0
  566. package/src/server/management/routing-analytics-routes.ts +74 -0
  567. package/src/server/management/routing-profile-routes.ts +380 -0
  568. package/src/server/management/shared.ts +27 -11
  569. package/src/server/management/sidebar-routes.ts +47 -31
  570. package/src/server/management/storage-log-guard-routes.ts +186 -0
  571. package/src/server/management/sync-response.ts +69 -0
  572. package/src/server/management/system-restart.ts +288 -32
  573. package/src/server/management/system-routes.ts +77 -0
  574. package/src/server/management/usage-summary-cache.ts +9 -1
  575. package/src/server/management/vision-sidecar-options.ts +167 -0
  576. package/src/server/management/web-search-sidecar-options.ts +120 -0
  577. package/src/server/management-api.ts +115 -14
  578. package/src/server/management-auth.ts +220 -5
  579. package/src/server/passive-route-linker.ts +66 -0
  580. package/src/server/ports.ts +41 -1
  581. package/src/server/proxy-liveness.ts +132 -5
  582. package/src/server/readiness.ts +99 -0
  583. package/src/server/relay-eager.ts +82 -42
  584. package/src/server/relay.ts +236 -76
  585. package/src/server/request-decompress.ts +113 -6
  586. package/src/server/request-log.ts +235 -22
  587. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  588. package/src/server/responses/agent-task-recovery.ts +465 -0
  589. package/src/server/responses/collaboration.ts +204 -35
  590. package/src/server/responses/compact.ts +442 -55
  591. package/src/server/responses/core.ts +2872 -331
  592. package/src/server/responses/empty-completion-guard.ts +276 -0
  593. package/src/server/responses/encrypted-payload.ts +62 -39
  594. package/src/server/responses/fetch-helpers.ts +79 -4
  595. package/src/server/responses/input-admission.ts +185 -0
  596. package/src/server/responses/pacing-overload.ts +13 -0
  597. package/src/server/responses/policy-fallback.ts +178 -0
  598. package/src/server/responses/responses-field-backfill.ts +251 -0
  599. package/src/server/responses/terminal-guard.ts +26 -5
  600. package/src/server/responses/upstream-error.ts +5 -0
  601. package/src/server/responses/ws-upstream.ts +308 -0
  602. package/src/server/responses-custom-tool-repair.ts +282 -0
  603. package/src/server/responses-item-id-repair.ts +54 -6
  604. package/src/server/responses-json-events.ts +90 -0
  605. package/src/server/responses-model-rewrite.ts +29 -0
  606. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  607. package/src/server/responses-snapshot-repair.ts +621 -0
  608. package/src/server/responses-terminal-repair.ts +342 -0
  609. package/src/server/responses-tool-search-repair.ts +267 -0
  610. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  611. package/src/server/responses.ts +18 -2
  612. package/src/server/search.ts +78 -13
  613. package/src/server/sse-frame-buffer.ts +292 -0
  614. package/src/server/sse-payload-rewrite.ts +110 -22
  615. package/src/server/startup-action-control.ts +8 -1
  616. package/src/server/startup-health-cache.ts +19 -1
  617. package/src/server/system-env.ts +80 -9
  618. package/src/server/ws-bridge.ts +39 -38
  619. package/src/service-manager-probe.ts +892 -0
  620. package/src/service.ts +1111 -90
  621. package/src/sidecar/auth.ts +92 -0
  622. package/src/sidecar/candidates.ts +83 -0
  623. package/src/storage/cleanup.ts +2 -2
  624. package/src/storage/scanner.ts +1 -1
  625. package/src/storage/worker-lifecycle.ts +14 -14
  626. package/src/tray/windows-tray.ps1 +83 -9
  627. package/src/tray/windows.ts +43 -16
  628. package/src/types/accounts.ts +37 -0
  629. package/src/types/config.ts +845 -0
  630. package/src/types/provider.ts +545 -0
  631. package/src/types/request.ts +384 -0
  632. package/src/types/tools.ts +131 -0
  633. package/src/types/wire.ts +80 -0
  634. package/src/types.ts +104 -1236
  635. package/src/update/index.ts +32 -19
  636. package/src/update/job.ts +442 -67
  637. package/src/update/notify.ts +12 -6
  638. package/src/update/npm-cache-preflight.d.mts +47 -0
  639. package/src/update/npm-cache-preflight.mjs +201 -0
  640. package/src/update/transactional-install.d.mts +22 -0
  641. package/src/update/transactional-install.mjs +259 -0
  642. package/src/usage/cost.ts +0 -0
  643. package/src/usage/expected-prices.ts +268 -16
  644. package/src/usage/log.ts +606 -41
  645. package/src/usage/summary.ts +177 -9
  646. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  647. package/src/usage/user-cost-overlays.ts +314 -0
  648. package/src/vision/anthropic-describe.ts +10 -6
  649. package/src/vision/backends.ts +97 -0
  650. package/src/vision/describe.ts +9 -3
  651. package/src/vision/eligibility.ts +250 -0
  652. package/src/vision/index.ts +238 -24
  653. package/src/vision/reasoning.ts +55 -0
  654. package/src/vision/routed-describe.ts +175 -0
  655. package/src/vision/timeout-bounds.ts +9 -0
  656. package/src/web-search/anthropic-executor.ts +13 -7
  657. package/src/web-search/backends.ts +108 -0
  658. package/src/web-search/exa-executor.ts +88 -0
  659. package/src/web-search/executor.ts +11 -3
  660. package/src/web-search/gemini-executor.ts +141 -0
  661. package/src/web-search/index.ts +150 -15
  662. package/src/web-search/loop.ts +279 -50
  663. package/src/web-search/parse.ts +125 -30
  664. package/src/web-search/sources.ts +60 -0
  665. package/src/web-search/xai-executor.ts +219 -0
  666. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  667. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  668. package/gui/dist/provider-icons/antigravity.svg +0 -1
  669. package/gui/dist/provider-icons/claude.svg +0 -1
  670. package/gui/dist/provider-icons/copilot.svg +0 -1
  671. package/gui/dist/provider-icons/cursor.svg +0 -2
  672. package/gui/dist/provider-icons/gemini.svg +0 -1
  673. package/gui/dist/provider-icons/grok-color.svg +0 -1
  674. package/gui/dist/provider-icons/kiro.svg +0 -14
  675. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,501 @@
1
+ import type {
2
+ AttemptTierOutcome,
3
+ FastWire,
4
+ OcxProviderConfig,
5
+ TierDecision,
6
+ TierObservationContext,
7
+ } from "../types";
8
+ import { MODEL_ADAPTER_OVERRIDE_ALLOWED } from "../types";
9
+ import { sanitizeLogMetadataString } from "../lib/redact";
10
+ import type { InboundWire, ModelWireDefault, ProviderAuthKind } from "./registry";
11
+
12
+ const SERVICE_TIER_ADAPTERS = new Set(["openai-chat", "openai-responses"]);
13
+ const FAST_WIRE_ADAPTERS: Readonly<Record<FastWire["kind"], ReadonlySet<string>>> = {
14
+ "service-tier": SERVICE_TIER_ADAPTERS,
15
+ // A1 deliberately has no adapter implementation for Anthropic speed.
16
+ "anthropic-speed": new Set(),
17
+ };
18
+
19
+ const DEFAULT_SERVICE_TIER_FAST_WIRE: FastWire = Object.freeze({
20
+ kind: "service-tier" as const,
21
+ canonicalToWire: Object.freeze({ priority: "priority" }),
22
+ foreignCallerTiers: "verbatim" as const,
23
+ });
24
+
25
+ export type FastPolicyAuthTransport =
26
+ | "oauth_bearer"
27
+ | "forwarded_authorization"
28
+ | "none"
29
+ | "x_api_key"
30
+ | "authorization_bearer";
31
+
32
+ export interface FastPolicyAuthority {
33
+ readonly providerAdapter: string;
34
+ readonly providerAuthMode?: ProviderAuthKind;
35
+ readonly fastWireDeclaration: FastWire | null | undefined;
36
+ readonly fastTierDescription?: string;
37
+ readonly modelWireOverrideAllowed: boolean;
38
+ readonly authTransport: FastPolicyAuthTransport;
39
+ readonly capability: {
40
+ readonly provider?: boolean;
41
+ readonly models: Readonly<Record<string, boolean>>;
42
+ readonly chatServiceTier?: boolean;
43
+ };
44
+ readonly modelAdapters: Readonly<Record<string, string>>;
45
+ readonly hardPins: Readonly<Record<string, string>>;
46
+ readonly registryWireDefaults: Readonly<Record<string, ModelWireDefault>>;
47
+ }
48
+
49
+ export interface ResolvedFastPolicy {
50
+ readonly capability: boolean | undefined;
51
+ readonly eligibility:
52
+ | "eligible"
53
+ | "capability-unsupported"
54
+ | "unclassified"
55
+ | "wire-unavailable"
56
+ | "pin-unavailable";
57
+ readonly adapter: string;
58
+ readonly fastWire: FastWire | null;
59
+ readonly fastTierDescription?: string;
60
+ readonly forwardCallerTier: boolean;
61
+ }
62
+
63
+ /** Adapter-owned response observer paired with the exact body that adapter serialized. */
64
+ export interface AdapterTierMetadata {
65
+ readonly outcome: AttemptTierOutcome;
66
+ observeResponseServiceTier(value: unknown): void;
67
+ markResponseUnparseable(): void;
68
+ }
69
+
70
+ /** Detach a FastWire declaration from config or registry ownership. */
71
+ export function cloneFastWire(
72
+ value: FastWire | null | undefined,
73
+ options: { freeze?: boolean } = {},
74
+ ): FastWire | null | undefined {
75
+ if (value === null || value === undefined) return value;
76
+ const canonicalToWire = { ...value.canonicalToWire };
77
+ const betas = value.betas ? [...value.betas] : undefined;
78
+ if (options.freeze) {
79
+ Object.freeze(canonicalToWire);
80
+ if (betas) Object.freeze(betas);
81
+ }
82
+ const clone: FastWire = {
83
+ ...value,
84
+ canonicalToWire,
85
+ ...(betas ? { betas } : {}),
86
+ };
87
+ return options.freeze ? Object.freeze(clone) : clone;
88
+ }
89
+
90
+ function exactModelValue<T>(record: Readonly<Record<string, T>>, modelId: string): T | undefined {
91
+ if (Object.prototype.hasOwnProperty.call(record, modelId)) return record[modelId];
92
+ const folded = modelId.toLowerCase();
93
+ for (const [key, value] of Object.entries(record)) {
94
+ if (key.toLowerCase() === folded) return value;
95
+ }
96
+ return undefined;
97
+ }
98
+
99
+ export function resolveProviderAuthTransport(
100
+ adapter: string,
101
+ mode: NonNullable<OcxProviderConfig["authMode"]>,
102
+ apiKeyTransport?: OcxProviderConfig["apiKeyTransport"],
103
+ ): FastPolicyAuthTransport {
104
+ if (mode === "oauth") return "oauth_bearer";
105
+ if (mode === "forward") return "forwarded_authorization";
106
+ if (mode === "local") return "none";
107
+ if (adapter === "anthropic" && apiKeyTransport !== "bearer") return "x_api_key";
108
+ return "authorization_bearer";
109
+ }
110
+
111
+ /** Adapter-derived declaration. This runs only after the final model wire is known. */
112
+ export function defaultFastWireForAdapter(adapter: string): FastWire | null {
113
+ return SERVICE_TIER_ADAPTERS.has(adapter) ? DEFAULT_SERVICE_TIER_FAST_WIRE : null;
114
+ }
115
+
116
+ function registryDefaultForModel(
117
+ defaults: Readonly<Record<string, ModelWireDefault>>,
118
+ modelId: string,
119
+ inbound: InboundWire,
120
+ authMode: ProviderAuthKind | undefined,
121
+ ): { adapter: string; forwardCallerServiceTier?: boolean } | undefined {
122
+ const normalizedModelId = modelId.trim().toLowerCase();
123
+ if (!Object.hasOwn(defaults, normalizedModelId)) return undefined;
124
+ const declared = defaults[normalizedModelId];
125
+ if (declared === undefined) return undefined;
126
+ if (typeof declared !== "string") {
127
+ if (!declared.inbound.includes(inbound)) return undefined;
128
+ if (declared.authModes && (authMode === undefined || !declared.authModes.includes(authMode))) {
129
+ return undefined;
130
+ }
131
+ }
132
+ const wire = typeof declared === "string" ? declared : declared.wire;
133
+ if (!MODEL_ADAPTER_OVERRIDE_ALLOWED.has(wire)) return undefined;
134
+ return {
135
+ adapter: wire,
136
+ ...(typeof declared !== "string" && declared.forwardCallerServiceTier !== undefined
137
+ ? { forwardCallerServiceTier: declared.forwardCallerServiceTier }
138
+ : {}),
139
+ };
140
+ }
141
+
142
+ function resolvePolicyAdapter(
143
+ authority: FastPolicyAuthority,
144
+ modelId: string,
145
+ inbound: InboundWire,
146
+ ): { adapter: string; hardPinned: boolean; forwardCallerServiceTier?: boolean } {
147
+ // Hard pins and configured overrides deliberately use the same exact-key semantics as
148
+ // resolveWireProtocolOverride(). Registry route policy normalizes ids at its boundary.
149
+ const hardPin = Object.hasOwn(authority.hardPins, modelId)
150
+ ? authority.hardPins[modelId]
151
+ : undefined;
152
+ if (typeof hardPin === "string") return { adapter: hardPin, hardPinned: true };
153
+ if (authority.modelWireOverrideAllowed) {
154
+ const registryDefault = MODEL_ADAPTER_OVERRIDE_ALLOWED.has(authority.providerAdapter)
155
+ ? registryDefaultForModel(
156
+ authority.registryWireDefaults,
157
+ modelId,
158
+ inbound,
159
+ authority.providerAuthMode,
160
+ )
161
+ : undefined;
162
+ const configured = Object.hasOwn(authority.modelAdapters, modelId)
163
+ ? authority.modelAdapters[modelId]
164
+ : undefined;
165
+ if (typeof configured === "string" && MODEL_ADAPTER_OVERRIDE_ALLOWED.has(configured)) {
166
+ return {
167
+ adapter: configured,
168
+ hardPinned: false,
169
+ ...(registryDefault?.forwardCallerServiceTier === false
170
+ ? { forwardCallerServiceTier: false }
171
+ : {}),
172
+ };
173
+ }
174
+ if (registryDefault !== undefined) {
175
+ return {
176
+ adapter: registryDefault.adapter,
177
+ hardPinned: false,
178
+ ...(registryDefault.forwardCallerServiceTier !== undefined
179
+ ? { forwardCallerServiceTier: registryDefault.forwardCallerServiceTier }
180
+ : {}),
181
+ };
182
+ }
183
+ }
184
+ return { adapter: authority.providerAdapter, hardPinned: false };
185
+ }
186
+
187
+ export function resolveFastPolicy(
188
+ authority: FastPolicyAuthority,
189
+ modelId: string,
190
+ inbound: InboundWire = "responses",
191
+ ): ResolvedFastPolicy {
192
+ const { adapter, hardPinned, forwardCallerServiceTier } = resolvePolicyAdapter(
193
+ authority,
194
+ modelId,
195
+ inbound,
196
+ );
197
+ const exactCapability = exactModelValue(authority.capability.models, modelId);
198
+ const capability = authority.capability.provider === false
199
+ ? false
200
+ : exactCapability ?? authority.capability.provider;
201
+ const fastWire = authority.fastWireDeclaration === undefined
202
+ ? defaultFastWireForAdapter(adapter)
203
+ : authority.fastWireDeclaration;
204
+ const wireAvailable = fastWire !== null && FAST_WIRE_ADAPTERS[fastWire.kind].has(adapter);
205
+ // Explicit null disables Fast injection, but the defensive true+null branch still preserves
206
+ // a caller tier on an existing OpenAI service-tier wire.
207
+ const callerWireAvailable = wireAvailable
208
+ || (fastWire === null && SERVICE_TIER_ADAPTERS.has(adapter));
209
+ // On classified routes this permission applies only to a caller's foreign tier: proxy-owned
210
+ // canonical Fast has already passed capability validation. On unclassified routes every caller
211
+ // tier still needs the final wire's forwarding permission.
212
+ const forwardCallerTier = capability !== false
213
+ && callerWireAvailable
214
+ && forwardCallerServiceTier !== false
215
+ && (adapter !== "openai-chat" || authority.capability.chatServiceTier === true);
216
+
217
+ let eligibility: ResolvedFastPolicy["eligibility"];
218
+ if (capability === false) eligibility = "capability-unsupported";
219
+ else if (!wireAvailable) {
220
+ eligibility = hardPinned && authority.fastWireDeclaration !== null
221
+ ? "pin-unavailable"
222
+ : "wire-unavailable";
223
+ }
224
+ else if (capability === undefined) eligibility = "unclassified";
225
+ else eligibility = "eligible";
226
+
227
+ return {
228
+ capability,
229
+ eligibility,
230
+ adapter,
231
+ fastWire,
232
+ ...(authority.fastTierDescription !== undefined
233
+ ? { fastTierDescription: authority.fastTierDescription }
234
+ : {}),
235
+ forwardCallerTier,
236
+ };
237
+ }
238
+
239
+ export function canonicalFastTierMarker(callerTier: string | undefined): "priority" | undefined {
240
+ const folded = callerTier?.trim().toLowerCase();
241
+ return folded === "priority" || folded === "fast" ? "priority" : undefined;
242
+ }
243
+
244
+ /** Capture Fast demand before the final A1 serialization action rewrites the parsed tier view. */
245
+ export function tierObservationContext(
246
+ policy: ResolvedFastPolicy,
247
+ fastMode: boolean | undefined,
248
+ callerTier: string | undefined,
249
+ ): TierObservationContext {
250
+ return {
251
+ capability: policy.capability,
252
+ eligibility: policy.eligibility,
253
+ fastWire: policy.fastWire,
254
+ demandDecision: fastMode === true ? "force-fast" : fastMode === false ? "force-default" : "inherit",
255
+ ...(callerTier !== undefined ? { callerTier } : {}),
256
+ };
257
+ }
258
+
259
+ function canonicalFromWire(
260
+ fastWire: FastWire | null,
261
+ wireValue: string,
262
+ ): string | undefined {
263
+ if (!fastWire) return undefined;
264
+ for (const [canonical, mapped] of Object.entries(fastWire.canonicalToWire)) {
265
+ if (mapped === wireValue) return canonical;
266
+ }
267
+ return undefined;
268
+ }
269
+
270
+ function downgradeReasonForUnavailable(
271
+ context: TierObservationContext,
272
+ ): AttemptTierOutcome["fastDowngradeReason"] {
273
+ if (context.capability === false || context.eligibility === "capability-unsupported") {
274
+ return "route-unsupported";
275
+ }
276
+ return "wire-unavailable";
277
+ }
278
+
279
+ /**
280
+ * Build the mutable observation record only after an adapter has completed serialization.
281
+ * `wireKind`/`wireValue` describe the field the adapter actually emitted, never a route guess.
282
+ */
283
+ export function createAdapterTierMetadata(
284
+ context: TierObservationContext | undefined,
285
+ decision: TierDecision | undefined,
286
+ wireKind: FastWire["kind"] | null,
287
+ wireValue: string | null,
288
+ ): AdapterTierMetadata | undefined {
289
+ if (!context || !decision) return undefined;
290
+
291
+ const callerCanonicalFast = canonicalFastTierMarker(context.callerTier) === "priority";
292
+ const callerTierDropped = context.callerTier !== undefined
293
+ && !callerCanonicalFast
294
+ && wireValue === null;
295
+ const callerFastSuppressedByConfig = context.capability !== undefined
296
+ && context.demandDecision === "force-default"
297
+ && callerCanonicalFast;
298
+ const loggedWireValue = wireValue === null ? null : sanitizeLogMetadataString(wireValue);
299
+ const outcome: AttemptTierOutcome = {
300
+ wireKind,
301
+ ...(wireValue === null
302
+ ? { wireValue: null }
303
+ : loggedWireValue ? { wireValue: loggedWireValue } : {}),
304
+ fastOutcome: "unknown",
305
+ confirmation: "unknown",
306
+ ...(callerTierDropped ? { callerTierDropped: true } : {}),
307
+ ...(callerFastSuppressedByConfig ? { callerFastSuppressedByConfig: true } : {}),
308
+ };
309
+
310
+ // A0/A1 deliberately make fastMode inert for unclassified routes. Preserve that uncertainty:
311
+ // do not infer demand, suppression, or a canonical tier from a verbatim caller passthrough.
312
+ if (context.capability === undefined || context.eligibility === "unclassified") {
313
+ delete outcome.callerFastSuppressedByConfig;
314
+ return {
315
+ outcome,
316
+ observeResponseServiceTier(value: unknown) {
317
+ const sanitized = sanitizeLogMetadataString(value);
318
+ if (sanitized) outcome.responseServiceTier = sanitized;
319
+ },
320
+ markResponseUnparseable() {},
321
+ };
322
+ }
323
+
324
+ const effectiveFastRequested = context.capability === true
325
+ && context.fastWire !== null
326
+ && (context.demandDecision === "force-fast"
327
+ || (context.demandDecision === "inherit" && callerCanonicalFast));
328
+ // Known-unsupported routes still need a downgrade when the caller/config expressed Fast intent,
329
+ // but they are deliberately outside the effective-demand calculation above.
330
+ const fastIntent = context.demandDecision === "force-fast"
331
+ || (context.demandDecision === "inherit" && callerCanonicalFast);
332
+
333
+ if (!fastIntent) {
334
+ outcome.fastOutcome = "not-requested";
335
+ } else if (!effectiveFastRequested || context.eligibility !== "eligible" || wireValue === null) {
336
+ outcome.fastOutcome = "downgraded";
337
+ outcome.fastDowngradeReason = downgradeReasonForUnavailable(context);
338
+ outcome.confirmation = "downgraded";
339
+ } else if (canonicalFromWire(context.fastWire, wireValue) === "priority") {
340
+ outcome.canonical = "priority";
341
+ outcome.fastOutcome = "applied";
342
+ outcome.confirmation = "assumed";
343
+ }
344
+
345
+ const responseCanConfirmFast = effectiveFastRequested
346
+ && context.eligibility === "eligible"
347
+ && wireValue !== null;
348
+ return {
349
+ outcome,
350
+ observeResponseServiceTier(value: unknown) {
351
+ if (typeof value !== "string" || !value.trim()) {
352
+ if (value !== undefined && responseCanConfirmFast) {
353
+ delete outcome.canonical;
354
+ delete outcome.fastDowngradeReason;
355
+ outcome.fastOutcome = "unknown";
356
+ outcome.confirmation = "unknown";
357
+ }
358
+ return;
359
+ }
360
+ const sanitized = sanitizeLogMetadataString(value);
361
+ if (sanitized) outcome.responseServiceTier = sanitized;
362
+ if (!responseCanConfirmFast) return;
363
+ if (canonicalFromWire(context.fastWire, value) === "priority") {
364
+ outcome.canonical = "priority";
365
+ delete outcome.fastDowngradeReason;
366
+ outcome.fastOutcome = "applied";
367
+ outcome.confirmation = "confirmed";
368
+ } else {
369
+ delete outcome.canonical;
370
+ outcome.fastOutcome = "downgraded";
371
+ outcome.fastDowngradeReason = "response-declined";
372
+ outcome.confirmation = "downgraded";
373
+ }
374
+ },
375
+ markResponseUnparseable() {
376
+ if (!responseCanConfirmFast) return;
377
+ delete outcome.canonical;
378
+ delete outcome.fastDowngradeReason;
379
+ delete outcome.responseServiceTier;
380
+ outcome.fastOutcome = "unknown";
381
+ outcome.confirmation = "unknown";
382
+ },
383
+ };
384
+ }
385
+
386
+ /** Pure tier state machine. B1 normalizes canonical Fast on classified inherit routes. */
387
+ export function decideTier(
388
+ policy: ResolvedFastPolicy,
389
+ fastMode: boolean | undefined,
390
+ callerTier: string | undefined,
391
+ ): TierDecision {
392
+ if (policy.capability === false) return { kind: "drop" };
393
+ if (policy.capability === undefined) {
394
+ return policy.forwardCallerTier ? { kind: "forward-caller" } : { kind: "drop" };
395
+ }
396
+ if (policy.fastWire === null) {
397
+ return policy.forwardCallerTier ? { kind: "forward-caller" } : { kind: "drop" };
398
+ }
399
+ if (policy.eligibility !== "eligible") return { kind: "drop" };
400
+ if (fastMode === true) {
401
+ const value = policy.fastWire.canonicalToWire.priority;
402
+ return typeof value === "string" && value.length > 0
403
+ ? { kind: "set", value }
404
+ : { kind: "drop" };
405
+ }
406
+ if (fastMode === false) return { kind: "drop" };
407
+ const callerCanonicalFast = canonicalFastTierMarker(callerTier);
408
+ if (callerCanonicalFast !== undefined) {
409
+ const value = policy.fastWire.canonicalToWire[callerCanonicalFast];
410
+ return typeof value === "string" && value.length > 0
411
+ ? { kind: "set", value }
412
+ : { kind: "drop" };
413
+ }
414
+ if (callerTier !== undefined && !policy.forwardCallerTier) return { kind: "drop" };
415
+ if (
416
+ callerTier !== undefined
417
+ && policy.fastWire.foreignCallerTiers === "drop"
418
+ ) {
419
+ return { kind: "drop" };
420
+ }
421
+ return { kind: "forward-caller" };
422
+ }
423
+
424
+ export function tierValueAfterDecision(
425
+ decision: TierDecision,
426
+ callerTier: string | undefined,
427
+ ): string | undefined {
428
+ if (decision.kind === "set") return decision.value;
429
+ if (decision.kind === "drop") return undefined;
430
+ return callerTier;
431
+ }
432
+
433
+ function isPlainRecord(value: unknown): value is Record<string, unknown> {
434
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
435
+ const prototype = Object.getPrototypeOf(value);
436
+ return prototype === Object.prototype || prototype === null;
437
+ }
438
+
439
+ export function hasFastWireCapabilityConflict(source: {
440
+ readonly fastWire?: unknown;
441
+ readonly supportsServiceTier?: unknown;
442
+ readonly modelSupportsServiceTier?: unknown;
443
+ }): boolean {
444
+ if (source.fastWire !== null) return false;
445
+ if (source.supportsServiceTier === false) return false;
446
+ if (source.supportsServiceTier === true) return true;
447
+ return isPlainRecord(source.modelSupportsServiceTier)
448
+ && Object.values(source.modelSupportsServiceTier).some(value => value === true);
449
+ }
450
+
451
+ /** Runtime registry validation; config uses the equivalent Zod shape at its boundary. */
452
+ export function fastWireDeclarationError(source: {
453
+ readonly fastWire?: unknown;
454
+ readonly supportsServiceTier?: unknown;
455
+ readonly modelSupportsServiceTier?: unknown;
456
+ }): string | null {
457
+ const value = source.fastWire;
458
+ if (value === undefined) return null;
459
+ if (hasFastWireCapabilityConflict(source)) {
460
+ return "fastWire=null conflicts with supportsServiceTier=true";
461
+ }
462
+ if (value === null) return null;
463
+ if (!isPlainRecord(value)) return "fastWire must be an object, null, or absent";
464
+ if (value.kind !== "service-tier" && value.kind !== "anthropic-speed") {
465
+ return "fastWire.kind must be service-tier or anthropic-speed";
466
+ }
467
+ if (value.foreignCallerTiers !== "verbatim" && value.foreignCallerTiers !== "drop") {
468
+ return "fastWire.foreignCallerTiers must be verbatim or drop";
469
+ }
470
+ if (!isPlainRecord(value.canonicalToWire)) return "fastWire.canonicalToWire must be an object";
471
+ if (!Object.prototype.hasOwnProperty.call(value.canonicalToWire, "priority")) {
472
+ return "fastWire.canonicalToWire must include priority";
473
+ }
474
+ const wireValues: string[] = [];
475
+ for (const [canonicalTier, wireValue] of Object.entries(value.canonicalToWire)) {
476
+ if (canonicalTier.trim().length === 0) {
477
+ return "fastWire.canonicalToWire keys must be nonblank strings";
478
+ }
479
+ if (typeof wireValue !== "string" || wireValue.trim().length === 0 || wireValue.trim().length > 64) {
480
+ return "fastWire.canonicalToWire values must be nonblank strings of at most 64 characters";
481
+ }
482
+ wireValues.push(wireValue.trim());
483
+ }
484
+ if (new Set(wireValues).size !== wireValues.length) {
485
+ return "fastWire.canonicalToWire values must be unique";
486
+ }
487
+ if (value.betas !== undefined) {
488
+ if (!Array.isArray(value.betas) || value.betas.length > 16) {
489
+ return "fastWire.betas must be an array of at most 16 values";
490
+ }
491
+ const betas: string[] = [];
492
+ for (const beta of value.betas) {
493
+ if (typeof beta !== "string" || beta.trim().length === 0) {
494
+ return "fastWire.betas values must be nonblank strings";
495
+ }
496
+ betas.push(beta.trim());
497
+ }
498
+ if (new Set(betas).size !== betas.length) return "fastWire.betas values must be unique";
499
+ }
500
+ return null;
501
+ }
@@ -45,6 +45,8 @@ export interface FreeDirectoryProvider {
45
45
  keyOptional?: boolean;
46
46
  models?: string[];
47
47
  liveModels: boolean;
48
+ /** Anthropic-compatible gateways that may close streams before terminal frames. */
49
+ anthropicEofTolerance?: boolean;
48
50
  note?: string;
49
51
  googleMode?: "ai-studio" | "vertex";
50
52
  }
@@ -80,7 +82,7 @@ const CONNECTABLE: Record<string, ConnectableOverride> = {
80
82
  "cloudflare-ai": openAi("https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1", "https://dash.cloudflare.com/?to=/:account/ai/workers-ai", { supportLevel: "supported", verification: "official", documentationUrl: "https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/", discovery: "static", liveModels: false, models: ["@cf/meta/llama-3.3-70b-instruct-fp8-fast", "@cf/qwen/qwq-32b"] }),
81
83
  cohere: openAi("https://api.cohere.com/compatibility/v1", "https://dashboard.cohere.com/api-keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.cohere.com/reference/list-models", modelsUrl: "https://api.cohere.com/compatibility/v1/models" }),
82
84
  friendliai: openAi("https://api.friendli.ai/serverless/v1", "https://suite.friendli.ai", { modelsUrl: "https://api.friendli.ai/serverless/v1/models" }),
83
- gemini: { baseUrl: "https://generativelanguage.googleapis.com", dashboardUrl: "https://aistudio.google.com/apikey", adapter: "google", authKind: "key", supportLevel: "supported", verification: "official", documentationUrl: "https://ai.google.dev/api/models", lastVerified: LAST_VERIFIED, discovery: "live", liveModels: true, googleMode: "ai-studio", models: ["gemini-3.6-flash", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.1-pro-preview"] },
85
+ gemini: { baseUrl: "https://generativelanguage.googleapis.com", dashboardUrl: "https://aistudio.google.com/apikey", adapter: "google", authKind: "key", supportLevel: "supported", verification: "official", documentationUrl: "https://ai.google.dev/api/models", lastVerified: LAST_VERIFIED, discovery: "live", liveModels: true, googleMode: "ai-studio", models: ["gemini-3.7-flash", "gemini-3.6-flash", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.1-pro-preview"] },
84
86
  "github-models": openAi("https://models.github.ai/inference", "https://github.com/settings/tokens", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.github.com/en/github-models/prototyping-with-ai-models", discovery: "static", liveModels: false, models: ["openai/gpt-4.1", "meta/llama-4-scout-17b-16e-instruct"] }),
85
87
  groq: openAi("https://api.groq.com/openai/v1", "https://console.groq.com/keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://console.groq.com/docs/api-reference#models" }),
86
88
  hackclub: openAi("https://ai.hackclub.com/proxy/v1", "https://ai.hackclub.com", { modelsUrl: "https://ai.hackclub.com/proxy/v1/models" }),
@@ -97,7 +99,7 @@ const CONNECTABLE: Record<string, ConnectableOverride> = {
97
99
  ovhcloud: openAi("https://oai.endpoints.kepler.ai.cloud.ovh.net/v1", "https://console.ovhcloud.com", { keyOptional: true, modelsUrl: "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1/models" }),
98
100
  pollinations: openAi("https://gen.pollinations.ai/v1", "https://pollinations.ai", { keyOptional: true }),
99
101
  reka: openAi("https://api.reka.ai/v1", "https://platform.reka.ai"),
100
- sambanova: openAi("https://api.sambanova.ai/v1", "https://cloud.sambanova.ai/apis", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.sambanova.ai/cloud/docs/api-reference/models" }),
102
+ sambanova: openAi("https://api.sambanova.ai/v1", "https://cloud.sambanova.ai/apis", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.sambanova.ai/docs/en/get-started/api-keys-urls", modelsUrl: "https://api.sambanova.ai/v1/models", lastVerified: "2026-08-02" }),
101
103
  sparkdesk: openAi("https://spark-api-open.xf-yun.com/v1", "https://console.xfyun.cn", { verification: "official", documentationUrl: "https://www.xfyun.cn/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html" }),
102
104
  agnes: openAi("https://apihub.agnes-ai.com/v1", "https://agnes-ai.com"),
103
105
  ainative: openAi("https://api.ainative.studio/api/v1", "https://ainative.studio", { modelsUrl: "https://api.ainative.studio/api/v1/models" }),
@@ -116,7 +118,7 @@ const CONNECTABLE: Record<string, ConnectableOverride> = {
116
118
  // `unverified` and drops the shared verification date rather than borrowing it.
117
119
  bytez: openAi("https://api.bytez.com/models/v2/openai/v1", "https://bytez.com", { verification: "unverified", lastVerified: undefined, documentationUrl: "https://docs.bytez.com/", discovery: "static", liveModels: false, models: ["meta-llama/Llama-3.3-70B-Instruct", "mistralai/Mistral-7B-Instruct-v0.3", "Qwen/Qwen2.5-72B-Instruct"], note: "The recurring-credit classification is retained from the requested catalog, but the current reset terms could not be independently verified." }),
118
120
  "nous-research": openAi("https://inference-api.nousresearch.com/v1", "https://portal.nousresearch.com", { discovery: "static", liveModels: false, models: ["Hermes-4-405B", "Hermes-4-70B"] }),
119
- agentrouter: { baseUrl: "https://agentrouter.org", dashboardUrl: "https://agentrouter.org", adapter: "anthropic", authKind: "key", supportLevel: "experimental", verification: "primary", modelsUrl: "https://agentrouter.org/v1/models", lastVerified: LAST_VERIFIED, discovery: "live", liveModels: true },
121
+ agentrouter: { baseUrl: "https://agentrouter.org", dashboardUrl: "https://agentrouter.org", adapter: "anthropic", authKind: "key", supportLevel: "experimental", verification: "primary", modelsUrl: "https://agentrouter.org/v1/models", lastVerified: LAST_VERIFIED, discovery: "live", liveModels: true, anthropicEofTolerance: true },
120
122
  ai21: openAi("https://api.ai21.com/studio/v1", "https://studio.ai21.com/account/api-key", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.ai21.com/reference/models" }),
121
123
  baichuan: openAi("https://api.baichuan-ai.com/v1", "https://platform.baichuan-ai.com/console/apikey", { verification: "official" }),
122
124
  // Verified end-to-end 2026-07-30: /v1/models returns the OpenAI-shaped live catalog (13 models),
@@ -130,12 +132,12 @@ const CONNECTABLE: Record<string, ConnectableOverride> = {
130
132
  hyperbolic: openAi("https://api.hyperbolic.xyz/v1", "https://app.hyperbolic.xyz/settings", { verification: "official" }),
131
133
  longcat: openAi("https://api.longcat.chat/openai/v1", "https://longcat.chat", { verification: "official", discovery: "static", liveModels: false, models: ["LongCat-2.0"] }),
132
134
  monsterapi: openAi("https://api.monsterapi.ai/v1", "https://monsterapi.ai", { verification: "official" }),
133
- nebius: openAi("https://api.tokenfactory.nebius.com/v1", "https://studio.nebius.com", { verification: "official" }),
135
+ nebius: openAi("https://api.tokenfactory.nebius.com/v1", "https://tokenfactory.nebius.com", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.tokenfactory.nebius.com/quickstart", modelsUrl: "https://api.tokenfactory.nebius.com/v1/models?verbose=true", lastVerified: "2026-08-02" }),
134
136
  novita: openAi("https://api.novita.ai/openai/v1", "https://novita.ai/settings/key-management", { supportLevel: "supported", verification: "official", modelsUrl: "https://api.novita.ai/openai/v1/models" }),
135
- nscale: openAi("https://inference.api.nscale.com/v1", "https://console.nscale.com", { verification: "official" }),
137
+ nscale: openAi("https://inference.api.nscale.com/v1", "https://console.nscale.com", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.nscale.com/docs/use-cases/chat", modelsUrl: "https://inference.api.nscale.com/v1/models", lastVerified: "2026-08-03" }),
136
138
  nvidia: openAi("https://integrate.api.nvidia.com/v1", "https://build.nvidia.com", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.api.nvidia.com/nim/reference/llm-apis" }),
137
139
  publicai: openAi("https://api.publicai.co/v1", "https://publicai.co"),
138
- scaleway: openAi("https://api.scaleway.ai/v1", "https://console.scaleway.com/generative-api", { verification: "official" }),
140
+ scaleway: openAi("https://api.scaleway.ai/v1", "https://console.scaleway.com/generative-api", { supportLevel: "supported", verification: "official", documentationUrl: "https://www.scaleway.com/en/docs/generative-apis/api-cli/using-generative-apis/", modelsUrl: "https://api.scaleway.ai/v1/models", lastVerified: "2026-08-01" }),
139
141
  sensenova: openAi("https://token.sensenova.cn/v1", "https://console.sensenova.cn", { verification: "official" }),
140
142
  stepfun: openAi("https://api.stepfun.com/v1", "https://platform.stepfun.com", { verification: "official" }),
141
143
  together: openAi("https://api.together.xyz/v1", "https://api.together.xyz/settings/api-keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.together.ai/reference/models-1" }),
@@ -153,7 +155,8 @@ const LABELS: Record<string, string> = {
153
155
  glm: "Z.AI GLM", "glm-cn": "BigModel GLM (CN)", "kilo-gateway": "Kilo Gateway", "opencode-zen": "OpenCode Zen",
154
156
  sealion: "SEA-LION", bytez: "Bytez", "nous-research": "Nous Research", agentrouter: "AgentRouter",
155
157
  ai21: "AI21", baichuan: "Baichuan", deepinfra: "DeepInfra", deepseek: "DeepSeek", doubao: "Doubao",
156
- "freemodel-dev": "FreeModel.dev", nebius: "Nebius", novita: "Novita", nscale: "Nscale", nvidia: "NVIDIA NIM",
158
+ "freemodel-dev": "FreeModel.dev", sambanova: "SambaNova Cloud", nebius: "Nebius Token Factory",
159
+ novita: "Novita", nscale: "Nscale", nvidia: "NVIDIA NIM",
157
160
  publicai: "PublicAI", qoder: "Qoder", sensenova: "SenseNova", stepfun: "StepFun", vertex: "Google Vertex AI",
158
161
  };
159
162
 
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Vertex regional hosts are formed as `<location>-aiplatform.googleapis.com`.
3
+ * Restricting the location to one lowercase DNS label keeps user configuration
4
+ * from changing the request authority while remaining forward-compatible with
5
+ * new Google regions and multi-regions.
6
+ */
7
+ const GOOGLE_VERTEX_LOCATION_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
8
+
9
+ export function googleVertexLocationConfigError(location: unknown): string | null {
10
+ if (typeof location !== "string" || !GOOGLE_VERTEX_LOCATION_LABEL.test(location)) {
11
+ return "Vertex AI location must be a single lowercase Google Cloud location label (for example, us-central1 or global)";
12
+ }
13
+ return null;
14
+ }