@iislee/opencodex 2.11.0 → 2.35.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 (733) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +117 -22
  3. package/bin/ocx.mjs +245 -88
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-Be1sDpWw.css +1 -0
  6. package/gui/dist/assets/index-D4OKgUV4.js +114 -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 +21 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +475 -62
  44. package/src/adapters/base.ts +82 -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 +637 -0
  48. package/src/adapters/cursor/call-id.ts +44 -0
  49. package/src/adapters/cursor/catalog.ts +541 -0
  50. package/src/adapters/cursor/checkpoint-store.ts +308 -0
  51. package/src/adapters/cursor/cursor-errors.ts +144 -6
  52. package/src/adapters/cursor/discovery.ts +122 -14
  53. package/src/adapters/cursor/effort-map.ts +106 -4
  54. package/src/adapters/cursor/envelope-echo.ts +290 -0
  55. package/src/adapters/cursor/framing.ts +39 -0
  56. package/src/adapters/cursor/h2-pool.ts +123 -0
  57. package/src/adapters/cursor/http1-bidi.ts +361 -0
  58. package/src/adapters/cursor/images.ts +704 -0
  59. package/src/adapters/cursor/live-models.ts +180 -59
  60. package/src/adapters/cursor/live-transport.ts +623 -170
  61. package/src/adapters/cursor/message-mapper.ts +4 -1
  62. package/src/adapters/cursor/native-exec-common.ts +23 -2
  63. package/src/adapters/cursor/native-exec-desktop.ts +23 -0
  64. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  65. package/src/adapters/cursor/native-exec-network.ts +1 -1
  66. package/src/adapters/cursor/native-exec-shell.ts +5 -3
  67. package/src/adapters/cursor/native-exec.ts +121 -14
  68. package/src/adapters/cursor/protobuf-events.ts +829 -11
  69. package/src/adapters/cursor/protobuf-request.ts +447 -75
  70. package/src/adapters/cursor/request-builder.ts +271 -35
  71. package/src/adapters/cursor/tool-definitions.ts +252 -12
  72. package/src/adapters/cursor/tool-result-normalize.ts +115 -0
  73. package/src/adapters/cursor/transport.ts +22 -0
  74. package/src/adapters/cursor/types.ts +48 -1
  75. package/src/adapters/cursor.ts +336 -39
  76. package/src/adapters/exec-tool-result-normalize.ts +99 -0
  77. package/src/adapters/google-antigravity-replay.ts +713 -41
  78. package/src/adapters/google-antigravity-wire.ts +48 -10
  79. package/src/adapters/google-errors.ts +44 -12
  80. package/src/adapters/google-http.ts +38 -10
  81. package/src/adapters/google-tool-schema.ts +80 -15
  82. package/src/adapters/google-truncation.ts +11 -0
  83. package/src/adapters/google.ts +742 -86
  84. package/src/adapters/identity.ts +39 -6
  85. package/src/adapters/image.ts +1 -1
  86. package/src/adapters/kiro-constants.ts +27 -0
  87. package/src/adapters/kiro-errors.ts +11 -0
  88. package/src/adapters/kiro-events.ts +19 -1
  89. package/src/adapters/kiro-thinking.ts +18 -2
  90. package/src/adapters/kiro-tools.ts +65 -17
  91. package/src/adapters/kiro.ts +270 -73
  92. package/src/adapters/mimo-free.ts +17 -0
  93. package/src/adapters/openai-chat-url.ts +11 -0
  94. package/src/adapters/openai-chat.ts +1377 -344
  95. package/src/adapters/openai-responses-url.ts +16 -0
  96. package/src/adapters/openai-responses.ts +1164 -64
  97. package/src/adapters/registry.ts +175 -0
  98. package/src/adapters/responses-tool-schema.ts +67 -0
  99. package/src/adapters/run-turn-queue.ts +36 -1
  100. package/src/adapters/tool-call-id.ts +119 -0
  101. package/src/adapters/tool-catalog-nudge.ts +105 -21
  102. package/src/adapters/xai-tool-schema.ts +436 -0
  103. package/src/adapters/xai-web-search.ts +186 -0
  104. package/src/bridge.ts +512 -92
  105. package/src/chat/inbound.ts +57 -20
  106. package/src/chat/outbound.ts +97 -33
  107. package/src/claude/agents-inject.ts +40 -10
  108. package/src/claude/context-windows.ts +37 -14
  109. package/src/claude/desktop-3p.ts +243 -9
  110. package/src/claude/gateway-cache.ts +41 -4
  111. package/src/claude/inbound.ts +72 -3
  112. package/src/claude/model-info.ts +38 -15
  113. package/src/claude/outbound.ts +88 -21
  114. package/src/cli/access.ts +46 -3
  115. package/src/cli/account-api.ts +150 -19
  116. package/src/cli/account-auth.ts +33 -6
  117. package/src/cli/account-catalog-refresh.ts +14 -0
  118. package/src/cli/account-extended.ts +648 -28
  119. package/src/cli/account-main.ts +317 -0
  120. package/src/cli/account.ts +97 -19
  121. package/src/cli/agent.ts +53 -2
  122. package/src/cli/alias.ts +66 -0
  123. package/src/cli/capabilities-command.ts +94 -0
  124. package/src/cli/capabilities.ts +496 -0
  125. package/src/cli/claude-agent-startup-sync.ts +73 -0
  126. package/src/cli/claude-desktop.ts +60 -15
  127. package/src/cli/claude.ts +129 -35
  128. package/src/cli/codex-log-guard-doctor.ts +103 -0
  129. package/src/cli/codex-shim-autorestore.ts +2 -0
  130. package/src/cli/codex-shim-readiness.ts +76 -0
  131. package/src/cli/combo.ts +8 -0
  132. package/src/cli/config-command.ts +74 -10
  133. package/src/cli/dispatch.ts +821 -0
  134. package/src/cli/doctor.ts +440 -56
  135. package/src/cli/ensure-desired-integrations.ts +152 -0
  136. package/src/cli/export-command.ts +46 -20
  137. package/src/cli/help.ts +34 -274
  138. package/src/cli/index.ts +417 -528
  139. package/src/cli/init.ts +5 -17
  140. package/src/cli/inspect.ts +230 -0
  141. package/src/cli/integrations.ts +120 -2
  142. package/src/cli/lab.ts +607 -0
  143. package/src/cli/launcher-context.ts +77 -0
  144. package/src/cli/minimax.ts +497 -0
  145. package/src/cli/models-runtime.ts +130 -2
  146. package/src/cli/models.ts +118 -16
  147. package/src/cli/observe.ts +123 -11
  148. package/src/cli/opencode.ts +4 -2
  149. package/src/cli/provider-runtime.ts +34 -3
  150. package/src/cli/provider.ts +25 -3
  151. package/src/cli/ready.ts +301 -0
  152. package/src/cli/registry.ts +476 -0
  153. package/src/cli/root.ts +86 -0
  154. package/src/cli/route-policy.ts +92 -0
  155. package/src/cli/runtime-api.ts +57 -10
  156. package/src/cli/star-prompt.ts +71 -15
  157. package/src/cli/status.ts +51 -4
  158. package/src/cli/storage.ts +234 -0
  159. package/src/cli/system-command.ts +16 -0
  160. package/src/cli/system-restart-client.ts +146 -0
  161. package/src/cli/tray-proxy.ts +153 -6
  162. package/src/cli/usage-report.ts +184 -0
  163. package/src/cli/v2.ts +137 -18
  164. package/src/cli/version-skew.ts +46 -0
  165. package/src/cli.ts +1 -1
  166. package/src/clients/config-export.ts +1442 -23
  167. package/src/clients/effective-status.ts +30 -2
  168. package/src/clients/probes/cline.ts +81 -0
  169. package/src/codex/account-label.ts +35 -1
  170. package/src/codex/account-lifecycle.ts +130 -13
  171. package/src/codex/account-namespaces.ts +49 -3
  172. package/src/codex/account-pause.ts +2 -1
  173. package/src/codex/account-priority.ts +84 -0
  174. package/src/codex/account-store.ts +29 -2
  175. package/src/codex/account-usability.ts +25 -2
  176. package/src/codex/admission.ts +256 -0
  177. package/src/codex/affinity-debug.ts +162 -0
  178. package/src/codex/app-server-processes.ts +570 -107
  179. package/src/codex/app-server-restart-service.ts +232 -0
  180. package/src/codex/auth-api.ts +893 -246
  181. package/src/codex/auth-collision.ts +5 -3
  182. package/src/codex/auth-context.ts +348 -32
  183. package/src/codex/autostart-health.ts +24 -1
  184. package/src/codex/catalog/account-models.ts +67 -0
  185. package/src/codex/catalog/aggregation.ts +86 -10
  186. package/src/codex/catalog/bundled.ts +331 -33
  187. package/src/codex/catalog/effort.ts +138 -32
  188. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  189. package/src/codex/catalog/kinds.ts +2 -0
  190. package/src/codex/catalog/metadata.ts +555 -45
  191. package/src/codex/catalog/native-models.ts +75 -0
  192. package/src/codex/catalog/parsing.ts +269 -30
  193. package/src/codex/catalog/provider-fetch.ts +1626 -144
  194. package/src/codex/catalog/sync.ts +1576 -187
  195. package/src/codex/catalog-admission.ts +199 -0
  196. package/src/codex/catalog-refresh-status.ts +105 -0
  197. package/src/codex/catalog-write-serialization.ts +242 -0
  198. package/src/codex/catalog.ts +6 -3
  199. package/src/codex/codex-write-lock.ts +386 -0
  200. package/src/codex/convergence-types.ts +614 -0
  201. package/src/codex/convergence.ts +676 -0
  202. package/src/codex/coordinator-doctor.ts +332 -0
  203. package/src/codex/custom-model-catalog-migration.ts +176 -0
  204. package/src/codex/desired-state.ts +230 -0
  205. package/src/codex/desktop-app-restart.ts +355 -0
  206. package/src/codex/features.ts +636 -39
  207. package/src/codex/generation.ts +202 -0
  208. package/src/codex/history-job.ts +436 -0
  209. package/src/codex/history-lock.ts +242 -0
  210. package/src/codex/history-manifest.ts +112 -0
  211. package/src/codex/history-migration-guardian.ts +30 -24
  212. package/src/codex/history-provider.ts +1016 -235
  213. package/src/codex/history-transition.ts +105 -0
  214. package/src/codex/history-worker.ts +223 -0
  215. package/src/codex/inject-coordination.ts +373 -0
  216. package/src/codex/inject.ts +1114 -152
  217. package/src/codex/injected-marker.ts +37 -3
  218. package/src/codex/integration-record.ts +266 -0
  219. package/src/codex/internal/catalog-writer.ts +203 -0
  220. package/src/codex/internal/history-writer.ts +81 -0
  221. package/src/codex/journal.ts +66 -4
  222. package/src/codex/log-guard/inspect.ts +524 -0
  223. package/src/codex/log-guard/lock.ts +150 -0
  224. package/src/codex/log-guard/maintenance.ts +403 -0
  225. package/src/codex/log-guard/path-safety.ts +88 -0
  226. package/src/codex/log-guard/policy.ts +44 -0
  227. package/src/codex/log-guard/processes.ts +205 -0
  228. package/src/codex/log-guard/protection.ts +489 -0
  229. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  230. package/src/codex/main-account-cache.ts +24 -0
  231. package/src/codex/main-account.ts +29 -1
  232. package/src/codex/management-convergence.ts +167 -0
  233. package/src/codex/model-cache.ts +56 -10
  234. package/src/codex/model-entitlements.ts +360 -0
  235. package/src/codex/native-main-admission.ts +47 -0
  236. package/src/codex/native-main-auth-temp.ts +187 -0
  237. package/src/codex/native-main-claim.ts +178 -0
  238. package/src/codex/native-main-lock-file.ts +162 -0
  239. package/src/codex/native-main-owner.ts +329 -0
  240. package/src/codex/native-profile-api.ts +247 -0
  241. package/src/codex/native-profile-manager.ts +1531 -0
  242. package/src/codex/native-profile-processes.ts +121 -0
  243. package/src/codex/native-profile-recovery.ts +99 -0
  244. package/src/codex/native-profile-stage-store.ts +387 -0
  245. package/src/codex/native-profile-startup.ts +622 -0
  246. package/src/codex/native-profile-store.ts +855 -0
  247. package/src/codex/native-profile-types.ts +120 -0
  248. package/src/codex/native-residue.ts +675 -0
  249. package/src/codex/paths.ts +80 -1
  250. package/src/codex/plan-from-token.ts +140 -0
  251. package/src/codex/plan.ts +40 -0
  252. package/src/codex/plugins-doctor.ts +1 -1
  253. package/src/codex/pool-rotation.ts +74 -4
  254. package/src/codex/project-config-warnings.ts +20 -6
  255. package/src/codex/prompt-journal.ts +352 -0
  256. package/src/codex/prompt-layers.ts +1313 -0
  257. package/src/codex/prompt-lock.ts +143 -0
  258. package/src/codex/prompt-text-probe.ts +238 -0
  259. package/src/codex/quota-rejection.ts +298 -0
  260. package/src/codex/quota.ts +264 -21
  261. package/src/codex/refresh.ts +11 -2
  262. package/src/codex/reset-credit-recovery.ts +1044 -0
  263. package/src/codex/routing.ts +514 -94
  264. package/src/codex/runtime.ts +159 -38
  265. package/src/codex/shim.ts +1065 -31
  266. package/src/codex/subagent-model-fallback.ts +437 -43
  267. package/src/codex/sync.ts +191 -2
  268. package/src/codex/transition-state.ts +720 -0
  269. package/src/codex/upstream-host-health.ts +368 -0
  270. package/src/codex/user-identity.ts +557 -0
  271. package/src/codex/warmup.ts +187 -81
  272. package/src/codex/write-coordination.ts +114 -0
  273. package/src/combos/failover.ts +47 -0
  274. package/src/combos/index.ts +4 -0
  275. package/src/combos/request.ts +32 -0
  276. package/src/combos/types.ts +91 -9
  277. package/src/compatibility/index.ts +26 -0
  278. package/src/compatibility/manifest.ts +253 -0
  279. package/src/compatibility/openai-responses.ts +121 -0
  280. package/src/config/atomic-write.ts +219 -0
  281. package/src/config/paths.ts +40 -0
  282. package/src/config/process-state.ts +309 -0
  283. package/src/config/provider-name.ts +24 -0
  284. package/src/config/provider-validation.ts +177 -0
  285. package/src/config/rebase-provenance.ts +68 -0
  286. package/src/config.ts +1713 -709
  287. package/src/generated/compatibility-version.json +3324 -0
  288. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  289. package/src/grok/inject.ts +16 -5
  290. package/src/grok/inspect.ts +45 -0
  291. package/src/grok/sync.ts +2 -2
  292. package/src/images/loop.ts +157 -33
  293. package/src/images/plan.ts +24 -13
  294. package/src/integrations/config-io.ts +269 -0
  295. package/src/integrations/journal.ts +315 -0
  296. package/src/integrations/merge.ts +135 -0
  297. package/src/integrations/mutation-flight.ts +71 -0
  298. package/src/integrations/native/ownership-preflight.ts +202 -0
  299. package/src/integrations/omp-yaml-source.ts +358 -0
  300. package/src/integrations/owned-refresh.ts +74 -0
  301. package/src/integrations/ownership-policy.ts +160 -0
  302. package/src/integrations/ownership.ts +155 -0
  303. package/src/integrations/registry.ts +166 -0
  304. package/src/integrations/serialize.ts +314 -0
  305. package/src/integrations/state.ts +433 -0
  306. package/src/integrations/store.ts +103 -0
  307. package/src/integrations/writer-lock.ts +98 -0
  308. package/src/integrations/writer.ts +715 -0
  309. package/src/lab/artifacts/sanitize.ts +586 -0
  310. package/src/lab/artifacts/secure-fs.ts +475 -0
  311. package/src/lab/artifacts/store.ts +310 -0
  312. package/src/lab/automation/budgets.ts +78 -0
  313. package/src/lab/automation/config-persistence.ts +256 -0
  314. package/src/lab/automation/constants.ts +39 -0
  315. package/src/lab/automation/cooldown.ts +103 -0
  316. package/src/lab/automation/dispatch.ts +211 -0
  317. package/src/lab/automation/index.ts +13 -0
  318. package/src/lab/automation/orchestrator.ts +499 -0
  319. package/src/lab/automation/persistence.ts +512 -0
  320. package/src/lab/automation/planner.ts +371 -0
  321. package/src/lab/automation/policy.ts +136 -0
  322. package/src/lab/automation/queue.ts +191 -0
  323. package/src/lab/automation/recovery.ts +24 -0
  324. package/src/lab/automation/route-context.ts +21 -0
  325. package/src/lab/automation/run-key.ts +44 -0
  326. package/src/lab/automation/runs-query.ts +34 -0
  327. package/src/lab/automation/types.ts +160 -0
  328. package/src/lab/conformance/assertion.ts +325 -0
  329. package/src/lab/conformance/digest.ts +22 -0
  330. package/src/lab/conformance/executor.ts +741 -0
  331. package/src/lab/conformance/fixture-provider.ts +27 -0
  332. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  333. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  334. package/src/lab/conformance/harness-budget.ts +47 -0
  335. package/src/lab/conformance/index.ts +5 -0
  336. package/src/lab/conformance/jcs.ts +64 -0
  337. package/src/lab/conformance/json-pointer.ts +39 -0
  338. package/src/lab/conformance/manifest.ts +180 -0
  339. package/src/lab/conformance/mcp-stub.ts +179 -0
  340. package/src/lab/conformance/negative-controls.ts +164 -0
  341. package/src/lab/conformance/observation.ts +355 -0
  342. package/src/lab/conformance/runner.ts +68 -0
  343. package/src/lab/conformance/sse-normalize.ts +59 -0
  344. package/src/lab/conformance/suite-manifest.ts +78 -0
  345. package/src/lab/conformance/types.ts +214 -0
  346. package/src/lab/constants.ts +126 -0
  347. package/src/lab/digest.ts +64 -0
  348. package/src/lab/events/errors.ts +9 -0
  349. package/src/lab/events/limits.ts +117 -0
  350. package/src/lab/events/types.ts +229 -0
  351. package/src/lab/events/validate.ts +781 -0
  352. package/src/lab/fabric/constants.ts +40 -0
  353. package/src/lab/fabric/executor.ts +492 -0
  354. package/src/lab/fabric/index.ts +80 -0
  355. package/src/lab/fabric/manifest.ts +222 -0
  356. package/src/lab/fabric/observe.ts +489 -0
  357. package/src/lab/fabric/patch.ts +79 -0
  358. package/src/lab/fabric/producer-child.ts +139 -0
  359. package/src/lab/fabric/producer-isolate.ts +276 -0
  360. package/src/lab/fabric/producer-protocol.ts +61 -0
  361. package/src/lab/fabric/scratch.ts +439 -0
  362. package/src/lab/fabric/subject.ts +106 -0
  363. package/src/lab/fabric/types.ts +134 -0
  364. package/src/lab/fabric/verifier.ts +98 -0
  365. package/src/lab/index.ts +54 -0
  366. package/src/lab/ledger/artifact-refs.ts +127 -0
  367. package/src/lab/ledger/invalidation.ts +136 -0
  368. package/src/lab/ledger/purge.ts +310 -0
  369. package/src/lab/ledger/store.ts +532 -0
  370. package/src/lab/live/credential-lease.ts +53 -0
  371. package/src/lab/live/destination.ts +155 -0
  372. package/src/lab/live/executor.ts +336 -0
  373. package/src/lab/live/inert-tools.ts +56 -0
  374. package/src/lab/live/manifest.ts +85 -0
  375. package/src/lab/live/mcp-loopback.ts +57 -0
  376. package/src/lab/live/runner.ts +19 -0
  377. package/src/lab/live/sandbox.ts +61 -0
  378. package/src/lab/live/suite-manifest.ts +41 -0
  379. package/src/lab/live/transport.ts +118 -0
  380. package/src/lab/live/types.ts +197 -0
  381. package/src/lab/observe/from-conformance.ts +301 -0
  382. package/src/lab/observe/from-live.ts +117 -0
  383. package/src/lab/paths.ts +153 -0
  384. package/src/lab/projection/rebuild.ts +495 -0
  385. package/src/lab/projection/schema.ts +135 -0
  386. package/src/lab/projection/verdicts.ts +474 -0
  387. package/src/lab/projection/verification.ts +412 -0
  388. package/src/lab/public/bundle.ts +217 -0
  389. package/src/lab/public/community-authority.ts +175 -0
  390. package/src/lab/public/community-files.ts +29 -0
  391. package/src/lab/public/community.ts +479 -0
  392. package/src/lab/public/file-safety.ts +155 -0
  393. package/src/lab/public/ids.ts +26 -0
  394. package/src/lab/public/index.ts +16 -0
  395. package/src/lab/public/mutation-lock.ts +424 -0
  396. package/src/lab/public/operator.ts +353 -0
  397. package/src/lab/public/origin-purge.ts +79 -0
  398. package/src/lab/public/origin.ts +203 -0
  399. package/src/lab/public/privacy.ts +143 -0
  400. package/src/lab/public/private-file.ts +261 -0
  401. package/src/lab/public/project.ts +124 -0
  402. package/src/lab/public/purge-test-fault.ts +21 -0
  403. package/src/lab/public/purge.ts +223 -0
  404. package/src/lab/public/registry.ts +44 -0
  405. package/src/lab/public/revocation.ts +252 -0
  406. package/src/lab/public/signature.ts +243 -0
  407. package/src/lab/public/storage.ts +105 -0
  408. package/src/lab/public/strict-json.ts +206 -0
  409. package/src/lab/public/time.ts +26 -0
  410. package/src/lab/public/types.ts +172 -0
  411. package/src/lab/public/validate.ts +391 -0
  412. package/src/lab/query/catalog.ts +101 -0
  413. package/src/lab/query/connection.ts +107 -0
  414. package/src/lab/query/constants.ts +4 -0
  415. package/src/lab/query/cursor.ts +132 -0
  416. package/src/lab/query/dto-map.ts +277 -0
  417. package/src/lab/query/errors.ts +22 -0
  418. package/src/lab/query/freshness.ts +53 -0
  419. package/src/lab/query/index.ts +45 -0
  420. package/src/lab/query/latest-observation.ts +59 -0
  421. package/src/lab/query/passive-production.ts +159 -0
  422. package/src/lab/query/queries.ts +444 -0
  423. package/src/lab/query/types.ts +266 -0
  424. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  425. package/src/lab/subject/installation-salt.ts +112 -0
  426. package/src/lab/subject/protocol-subject.ts +80 -0
  427. package/src/lab/subject/route-subject.ts +74 -0
  428. package/src/lib/admin-secrets.ts +24 -0
  429. package/src/lib/app-owned-memory-stores.ts +22 -0
  430. package/src/lib/bounded-body.ts +167 -11
  431. package/src/lib/bun-runtime.ts +125 -12
  432. package/src/lib/bun-stream-caps.ts +13 -9
  433. package/src/lib/codex-restart-contract.ts +120 -0
  434. package/src/lib/config-ownership.ts +26 -2
  435. package/src/lib/destination-policy.ts +65 -1
  436. package/src/lib/errors.ts +80 -5
  437. package/src/lib/fabric-task-execution-authority.ts +7 -0
  438. package/src/lib/fabric-task-host.ts +29 -0
  439. package/src/lib/lab-activation.ts +223 -0
  440. package/src/lib/lab-live-execution-authority.ts +13 -0
  441. package/src/lib/lab-live-host.ts +30 -0
  442. package/src/lib/lab-live-pinned-sender.ts +56 -0
  443. package/src/lib/lab-live-route-production.ts +130 -0
  444. package/src/lib/lab-passive-linker-registration.ts +26 -0
  445. package/src/lib/local-management-attestation.ts +51 -0
  446. package/src/lib/local-management-capability.ts +100 -0
  447. package/src/lib/local-provider-reload-contract.ts +100 -0
  448. package/src/lib/optional-shutdown-hooks.ts +57 -0
  449. package/src/lib/package-tree-integrity.ts +101 -0
  450. package/src/lib/pinned-http.ts +145 -26
  451. package/src/lib/process-control.ts +6 -2
  452. package/src/lib/provider-outbound.ts +49 -9
  453. package/src/lib/redact.ts +419 -3
  454. package/src/lib/self-launch-argv.ts +15 -0
  455. package/src/lib/server-resource-ownership.ts +71 -0
  456. package/src/lib/service-secrets.ts +15 -0
  457. package/src/lib/shadow-call.ts +35 -4
  458. package/src/lib/sse-decoder.ts +41 -0
  459. package/src/lib/state-store-registrations.ts +10 -2
  460. package/src/lib/system-restart-contract.ts +73 -0
  461. package/src/lib/token-estimate.ts +19 -2
  462. package/src/lib/tool-argument-integers.ts +253 -0
  463. package/src/lib/translator-budget.ts +44 -0
  464. package/src/lib/upstream-http-version.ts +57 -0
  465. package/src/lib/upstream-reachability.ts +95 -0
  466. package/src/lib/upstream-retry.ts +156 -3
  467. package/src/lib/windows-atomic-replace.ts +155 -0
  468. package/src/lib/windows-elevation.ts +70 -2
  469. package/src/lib/windows-secret-acl.ts +409 -69
  470. package/src/lib/windows-service-wrappers.ts +72 -0
  471. package/src/lib/windows-text.ts +106 -0
  472. package/src/lib/windows-user-principal.ts +341 -0
  473. package/src/lib/winsw.ts +33 -5
  474. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  475. package/src/oauth/account-import/index.ts +15 -0
  476. package/src/oauth/account-import/parser.ts +83 -0
  477. package/src/oauth/account-import/registry.ts +18 -0
  478. package/src/oauth/account-import/service.ts +75 -0
  479. package/src/oauth/account-import/types.ts +91 -0
  480. package/src/oauth/anthropic.ts +12 -1
  481. package/src/oauth/callback-server.ts +30 -4
  482. package/src/oauth/chatgpt.ts +12 -1
  483. package/src/oauth/cline.ts +203 -0
  484. package/src/oauth/command-code.ts +239 -0
  485. package/src/oauth/cursor.ts +46 -5
  486. package/src/oauth/generic-account-failover.ts +231 -0
  487. package/src/oauth/google-antigravity.ts +35 -3
  488. package/src/oauth/health.ts +20 -12
  489. package/src/oauth/index.ts +462 -71
  490. package/src/oauth/key-providers.ts +25 -0
  491. package/src/oauth/kimi.ts +25 -3
  492. package/src/oauth/kiro.ts +95 -6
  493. package/src/oauth/local-token-detect.ts +13 -2
  494. package/src/oauth/log.ts +3 -1
  495. package/src/oauth/login-cli.ts +88 -28
  496. package/src/oauth/nous.ts +798 -0
  497. package/src/oauth/open-browser-choice.ts +26 -0
  498. package/src/oauth/store.ts +133 -26
  499. package/src/oauth/token-guardian.ts +9 -3
  500. package/src/oauth/types.ts +15 -0
  501. package/src/pi/models.ts +2 -2
  502. package/src/providers/alibaba-region-migration.ts +1 -1
  503. package/src/providers/antigravity-models.ts +521 -31
  504. package/src/providers/auto-compact-budget.ts +65 -0
  505. package/src/providers/base-url-choices.ts +10 -0
  506. package/src/providers/codex-capacity.ts +292 -0
  507. package/src/providers/command-code-efforts.ts +176 -0
  508. package/src/providers/context-cap.ts +26 -8
  509. package/src/providers/cursor-pool.ts +72 -0
  510. package/src/providers/default-aliases.ts +65 -0
  511. package/src/providers/derive.ts +281 -6
  512. package/src/providers/fastwire.ts +507 -0
  513. package/src/providers/free-directory.ts +10 -7
  514. package/src/providers/google-vertex-location.ts +14 -0
  515. package/src/providers/key-failover.ts +71 -3
  516. package/src/providers/label.ts +35 -2
  517. package/src/providers/model-discovery-limits.ts +16 -0
  518. package/src/providers/model-discovery.ts +115 -22
  519. package/src/providers/model-presets.ts +119 -0
  520. package/src/providers/model-rename-migration.ts +255 -0
  521. package/src/providers/model-rename-startup.ts +28 -0
  522. package/src/providers/new-model-policy.ts +146 -0
  523. package/src/providers/openai-sidecar.ts +72 -4
  524. package/src/providers/openai-tier-startup.ts +31 -2
  525. package/src/providers/openai-tiers.ts +119 -4
  526. package/src/providers/openai-virtual-models.ts +1 -0
  527. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  528. package/src/providers/provider-id-rewrite.ts +30 -0
  529. package/src/providers/quota.ts +1379 -40
  530. package/src/providers/registry.ts +1545 -112
  531. package/src/providers/request-pacing.ts +310 -0
  532. package/src/providers/service-tier.ts +277 -0
  533. package/src/providers/slug-codec.ts +94 -6
  534. package/src/providers/static-model-discovery.ts +86 -0
  535. package/src/providers/xai-responses-opt-in.ts +15 -0
  536. package/src/providers/xai-transport.ts +32 -4
  537. package/src/reasoning-effort.ts +68 -3
  538. package/src/responses/apply-patch-envelope.ts +63 -0
  539. package/src/responses/code-mode-helper-compat.ts +50 -0
  540. package/src/responses/compaction.ts +26 -1
  541. package/src/responses/custom-tool-compat.ts +384 -0
  542. package/src/responses/hosted-tool-policy.ts +9 -0
  543. package/src/responses/namespace-tool-compat.ts +435 -0
  544. package/src/responses/parser.ts +225 -38
  545. package/src/responses/provider-continuation.ts +98 -0
  546. package/src/responses/provider-opaque-metadata.ts +73 -0
  547. package/src/responses/reasoning-envelope.ts +9 -1
  548. package/src/responses/reasoning-replay-cache.ts +504 -0
  549. package/src/responses/schema.ts +12 -2
  550. package/src/responses/spill-store.ts +75 -10
  551. package/src/responses/state.ts +659 -31
  552. package/src/responses/thought-signature-replay.ts +364 -0
  553. package/src/responses/tool-search-compat.ts +301 -0
  554. package/src/responses/truncated-stop-reason.ts +60 -0
  555. package/src/responses/turn-termination.ts +107 -0
  556. package/src/router.ts +405 -31
  557. package/src/routing/analytics.ts +379 -0
  558. package/src/routing/capability.ts +244 -0
  559. package/src/routing/compatibility/assemble.ts +73 -0
  560. package/src/routing/compatibility/behavior.ts +278 -0
  561. package/src/routing/compatibility/catalog.ts +99 -0
  562. package/src/routing/compatibility/endpoint.ts +52 -0
  563. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  564. package/src/routing/compatibility/policy.ts +181 -0
  565. package/src/routing/compatibility/provider-slot.ts +56 -0
  566. package/src/routing/compatibility/reader.ts +110 -0
  567. package/src/routing/compatibility/subject.ts +191 -0
  568. package/src/routing/compatibility/types.ts +64 -0
  569. package/src/routing/compatibility/version.ts +104 -0
  570. package/src/routing/cost.ts +77 -0
  571. package/src/routing/evaluator.ts +495 -0
  572. package/src/routing/health.ts +412 -0
  573. package/src/routing/history/cursor.ts +43 -0
  574. package/src/routing/history/indexer.ts +605 -0
  575. package/src/routing/history/schema.ts +72 -0
  576. package/src/routing/profile-namespace.ts +15 -0
  577. package/src/routing/profile.ts +547 -0
  578. package/src/routing/quota.ts +155 -0
  579. package/src/routing/request-evidence.ts +45 -0
  580. package/src/routing/trace.ts +776 -0
  581. package/src/server/adapter-resolve.ts +2 -29
  582. package/src/server/auth-cors.ts +289 -48
  583. package/src/server/background-lifecycle.ts +182 -0
  584. package/src/server/chat-completions.ts +154 -72
  585. package/src/server/chat-native-sse.ts +331 -0
  586. package/src/server/chat-native.ts +445 -0
  587. package/src/server/claude-messages.ts +160 -44
  588. package/src/server/direct-local-http.ts +347 -0
  589. package/src/server/effort-policy.ts +18 -0
  590. package/src/server/github-copilot-responses-repair.ts +338 -0
  591. package/src/server/gui-static.ts +39 -10
  592. package/src/server/images.ts +94 -12
  593. package/src/server/index.ts +1021 -190
  594. package/src/server/lifecycle.ts +336 -14
  595. package/src/server/live.ts +136 -17
  596. package/src/server/local-management-read-client.ts +90 -0
  597. package/src/server/local-provider-reload-client.ts +137 -0
  598. package/src/server/management/agent-settings-routes.ts +433 -116
  599. package/src/server/management/api-key-usage.ts +31 -5
  600. package/src/server/management/body.ts +6 -0
  601. package/src/server/management/codex-prompt-routes.ts +570 -0
  602. package/src/server/management/combo-routes.ts +64 -25
  603. package/src/server/management/config-routes.ts +511 -51
  604. package/src/server/management/context.ts +89 -2
  605. package/src/server/management/integration-routes.ts +498 -0
  606. package/src/server/management/lab-automation-routes.ts +206 -0
  607. package/src/server/management/lab-routes.ts +563 -0
  608. package/src/server/management/logs-usage-routes.ts +127 -52
  609. package/src/server/management/model-routes.ts +461 -133
  610. package/src/server/management/model-rows.ts +167 -0
  611. package/src/server/management/native-integration-routes.ts +770 -0
  612. package/src/server/management/oauth-account-routes.ts +90 -8
  613. package/src/server/management/provider-capability-config.ts +48 -0
  614. package/src/server/management/provider-routes.ts +836 -159
  615. package/src/server/management/request-history-routes.ts +191 -0
  616. package/src/server/management/route-registry.ts +332 -0
  617. package/src/server/management/routing-analytics-routes.ts +74 -0
  618. package/src/server/management/routing-profile-routes.ts +380 -0
  619. package/src/server/management/shared.ts +27 -11
  620. package/src/server/management/sidebar-routes.ts +47 -31
  621. package/src/server/management/storage-log-guard-routes.ts +186 -0
  622. package/src/server/management/sync-response.ts +69 -0
  623. package/src/server/management/system-restart.ts +289 -33
  624. package/src/server/management/system-routes.ts +77 -0
  625. package/src/server/management/usage-summary-cache.ts +9 -1
  626. package/src/server/management/vision-sidecar-options.ts +167 -0
  627. package/src/server/management/web-search-sidecar-options.ts +120 -0
  628. package/src/server/management-api.ts +126 -23
  629. package/src/server/management-auth.ts +220 -5
  630. package/src/server/passive-route-linker.ts +66 -0
  631. package/src/server/port-reclaim.ts +1 -1
  632. package/src/server/ports.ts +41 -1
  633. package/src/server/proxy-liveness.ts +161 -10
  634. package/src/server/readiness.ts +99 -0
  635. package/src/server/relay-eager.ts +221 -54
  636. package/src/server/relay.ts +479 -87
  637. package/src/server/request-decompress.ts +113 -6
  638. package/src/server/request-log-conversation.ts +51 -0
  639. package/src/server/request-log.ts +298 -31
  640. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  641. package/src/server/responses/agent-task-recovery.ts +465 -0
  642. package/src/server/responses/codex-auth-error.ts +55 -0
  643. package/src/server/responses/collaboration.ts +239 -36
  644. package/src/server/responses/combo-stream-preflight.ts +178 -0
  645. package/src/server/responses/compact.ts +444 -72
  646. package/src/server/responses/core.ts +3579 -436
  647. package/src/server/responses/empty-completion-guard.ts +333 -0
  648. package/src/server/responses/encrypted-payload.ts +62 -39
  649. package/src/server/responses/fetch-helpers.ts +89 -99
  650. package/src/server/responses/input-admission.ts +187 -0
  651. package/src/server/responses/pacing-overload.ts +13 -0
  652. package/src/server/responses/passthrough-error.ts +33 -9
  653. package/src/server/responses/policy-fallback.ts +178 -0
  654. package/src/server/responses/responses-field-backfill.ts +343 -0
  655. package/src/server/responses/terminal-guard.ts +26 -5
  656. package/src/server/responses/upstream-error.ts +5 -0
  657. package/src/server/responses/ws-upstream.ts +381 -0
  658. package/src/server/responses-custom-tool-repair.ts +363 -0
  659. package/src/server/responses-item-id-repair.ts +54 -6
  660. package/src/server/responses-json-events.ts +90 -0
  661. package/src/server/responses-model-rewrite.ts +29 -0
  662. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  663. package/src/server/responses-snapshot-repair.ts +621 -0
  664. package/src/server/responses-terminal-repair.ts +363 -0
  665. package/src/server/responses-tool-search-repair.ts +267 -0
  666. package/src/server/responses-undeclared-tool-guard.ts +376 -0
  667. package/src/server/responses.ts +18 -2
  668. package/src/server/search.ts +78 -13
  669. package/src/server/sse-frame-buffer.ts +319 -0
  670. package/src/server/sse-payload-rewrite.ts +110 -22
  671. package/src/server/startup-action-control.ts +8 -1
  672. package/src/server/startup-health-cache.ts +19 -1
  673. package/src/server/system-env.ts +80 -9
  674. package/src/server/ws-bridge.ts +53 -40
  675. package/src/service-manager-probe.ts +892 -0
  676. package/src/service.ts +1153 -94
  677. package/src/sidecar/auth.ts +92 -0
  678. package/src/sidecar/candidates.ts +83 -0
  679. package/src/storage/cleanup.ts +2 -2
  680. package/src/storage/policy-job.ts +14 -4
  681. package/src/storage/policy.ts +88 -23
  682. package/src/storage/scanner.ts +1 -1
  683. package/src/storage/worker-lifecycle.ts +14 -14
  684. package/src/tray/windows-tray.ps1 +83 -9
  685. package/src/tray/windows.ts +43 -16
  686. package/src/types/accounts.ts +37 -0
  687. package/src/types/config.ts +911 -0
  688. package/src/types/provider.ts +614 -0
  689. package/src/types/request.ts +397 -0
  690. package/src/types/tools.ts +236 -0
  691. package/src/types/wire.ts +80 -0
  692. package/src/types.ts +107 -1237
  693. package/src/update/index.ts +37 -23
  694. package/src/update/job.ts +445 -68
  695. package/src/update/notify.ts +12 -6
  696. package/src/update/npm-cache-preflight.d.mts +47 -0
  697. package/src/update/npm-cache-preflight.mjs +201 -0
  698. package/src/update/transactional-install.d.mts +22 -0
  699. package/src/update/transactional-install.mjs +266 -0
  700. package/src/usage/cost.ts +0 -0
  701. package/src/usage/expected-prices.ts +287 -16
  702. package/src/usage/log.ts +666 -50
  703. package/src/usage/summary.ts +388 -17
  704. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  705. package/src/usage/user-cost-overlays.ts +314 -0
  706. package/src/vision/anthropic-describe.ts +10 -6
  707. package/src/vision/backends.ts +97 -0
  708. package/src/vision/describe.ts +27 -16
  709. package/src/vision/eligibility.ts +250 -0
  710. package/src/vision/index.ts +238 -24
  711. package/src/vision/reasoning.ts +55 -0
  712. package/src/vision/routed-describe.ts +175 -0
  713. package/src/vision/timeout-bounds.ts +9 -0
  714. package/src/web-search/anthropic-executor.ts +13 -7
  715. package/src/web-search/backends.ts +108 -0
  716. package/src/web-search/exa-executor.ts +119 -0
  717. package/src/web-search/executor.ts +21 -6
  718. package/src/web-search/gemini-executor.ts +141 -0
  719. package/src/web-search/index.ts +150 -15
  720. package/src/web-search/loop.ts +284 -54
  721. package/src/web-search/parse.ts +125 -30
  722. package/src/web-search/sources.ts +60 -0
  723. package/src/web-search/xai-executor.ts +219 -0
  724. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  725. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  726. package/gui/dist/provider-icons/antigravity.svg +0 -1
  727. package/gui/dist/provider-icons/claude.svg +0 -1
  728. package/gui/dist/provider-icons/copilot.svg +0 -1
  729. package/gui/dist/provider-icons/cursor.svg +0 -2
  730. package/gui/dist/provider-icons/gemini.svg +0 -1
  731. package/gui/dist/provider-icons/grok-color.svg +0 -1
  732. package/gui/dist/provider-icons/kiro.svg +0 -14
  733. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Weighted credential routing for Cursor accounts.
3
+ *
4
+ * Transfer from yelixir-dev/cursor-ai-proxy-bridge credentials.ts:
5
+ * weighted round-robin selection with per-credential auth-failure cooldown
6
+ * and one-retry failover on a different account before surfacing the error.
7
+ *
8
+ * OpenCodex already has JWT-based multi-account identification (src/oauth/cursor.ts)
9
+ * and Anthropic-specific 429 rotation; this module adds Cursor-aware weighted
10
+ * routing on top of those primitives.
11
+ */
12
+
13
+ export interface CursorCredential {
14
+ readonly id: string;
15
+ weight: number;
16
+ }
17
+
18
+ interface CredentialState {
19
+ readonly credential: CursorCredential;
20
+ currentWeight: number;
21
+ disabledUntil: number;
22
+ }
23
+
24
+ export class NoAvailableCursorCredentialError extends Error {
25
+ constructor(message = "No available Cursor credentials") { super(message); }
26
+ }
27
+
28
+ export class CursorCredentialRouter {
29
+ private states: CredentialState[] = [];
30
+ private readonly cooldownMs: number;
31
+
32
+ constructor(credentials: ReadonlyArray<CursorCredential>, cooldownMs = 300_000) {
33
+ this.cooldownMs = cooldownMs;
34
+ this.replace(credentials);
35
+ }
36
+
37
+ replace(credentials: ReadonlyArray<CursorCredential>): void {
38
+ this.states = credentials.map(c => ({
39
+ credential: { ...c, weight: Math.max(1, c.weight || 1) },
40
+ currentWeight: 0,
41
+ disabledUntil: 0,
42
+ }));
43
+ }
44
+
45
+ pick(excludeIds: ReadonlySet<string> = new Set()): CursorCredential {
46
+ const now = Date.now();
47
+ const candidates = this.states.filter(s =>
48
+ !excludeIds.has(s.credential.id) && s.disabledUntil <= now,
49
+ );
50
+ if (candidates.length === 0) throw new NoAvailableCursorCredentialError();
51
+ let selected: CredentialState | undefined;
52
+ let totalWeight = 0;
53
+ for (const state of candidates) {
54
+ state.currentWeight += state.credential.weight;
55
+ totalWeight += state.credential.weight;
56
+ if (!selected || state.currentWeight > selected.currentWeight) selected = state;
57
+ }
58
+ if (!selected) throw new NoAvailableCursorCredentialError();
59
+ selected.currentWeight -= totalWeight;
60
+ return { ...selected.credential };
61
+ }
62
+
63
+ disable(id: string): void {
64
+ const state = this.states.find(s => s.credential.id === id);
65
+ if (state) state.disabledUntil = Date.now() + this.cooldownMs;
66
+ }
67
+
68
+ get snapshot(): ReadonlyArray<{ id: string; disabled: boolean }> {
69
+ const now = Date.now();
70
+ return this.states.map(s => ({ id: s.credential.id, disabled: s.disabledUntil > now }));
71
+ }
72
+ }
@@ -0,0 +1,65 @@
1
+ import type { OcxConfig, OcxProviderConfig } from "../types";
2
+
3
+ export const MODEL_ALIAS_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
4
+
5
+ /** Ordered, most-specific-first built-in aliases. Updated with the provider registry. */
6
+ export const DEFAULT_MODEL_ALIASES: ReadonlyArray<{ match: RegExp; alias: string }> = [
7
+ { match: /^claude-opus-5/, alias: "opus" },
8
+ { match: /^claude-sonnet-5/, alias: "sonnet" },
9
+ { match: /^claude-haiku/, alias: "haiku" },
10
+ { match: /^gemini-3(?:\.\d+)?-pro/, alias: "g3p" },
11
+ { match: /^gemini-3(?:\.\d+)?-flash/, alias: "g3f" },
12
+ { match: /^deepseek-v4/, alias: "ds4" },
13
+ { match: /^grok-4/, alias: "grok" },
14
+ ];
15
+
16
+ export interface EffectiveModelAlias { alias: string; source: "user" | "builtin" }
17
+
18
+ function builtinRule(id: string): { match: RegExp; alias: string } | undefined {
19
+ const tail = id.slice(id.lastIndexOf("/") + 1);
20
+ return DEFAULT_MODEL_ALIASES.find(rule => rule.match.test(id) || rule.match.test(tail));
21
+ }
22
+
23
+ export function defaultAliasesEnabled(config: Pick<OcxConfig, "defaultModelAliases">, provider: OcxProviderConfig): boolean {
24
+ return provider.defaultAliases ?? config.defaultModelAliases ?? false;
25
+ }
26
+
27
+ export function effectiveModelAliases(
28
+ config: Pick<OcxConfig, "defaultModelAliases">,
29
+ provider: OcxProviderConfig,
30
+ knownIds: Iterable<string>,
31
+ ): Map<string, EffectiveModelAlias> {
32
+ const result = new Map<string, EffectiveModelAlias>();
33
+ for (const [id, alias] of Object.entries(provider.modelAliases ?? {})) {
34
+ if (typeof alias === "string" && MODEL_ALIAS_PATTERN.test(alias)) result.set(id, { alias, source: "user" });
35
+ }
36
+ if (!defaultAliasesEnabled(config, provider)) return result;
37
+ const claims = new Map<string, string[]>();
38
+ for (const id of knownIds) {
39
+ if (result.has(id)) continue;
40
+ const rule = builtinRule(id);
41
+ if (!rule) continue;
42
+ const key = rule.alias.toLowerCase();
43
+ claims.set(key, [...(claims.get(key) ?? []), id]);
44
+ }
45
+ for (const [alias, ids] of claims) {
46
+ if (ids.length !== 1) continue;
47
+ const id = ids[0]!;
48
+ // Catalog drift must skip, never shadow, a native id or explicit user alias.
49
+ if ([...knownIds].some(candidate => candidate.toLowerCase() === alias)) continue;
50
+ if ([...result.values()].some(value => value.alias.toLowerCase() === alias)) continue;
51
+ result.set(id, { alias: builtinRule(id)!.alias, source: "builtin" });
52
+ }
53
+ return result;
54
+ }
55
+
56
+ export function resolveModelAlias(
57
+ config: Pick<OcxConfig, "defaultModelAliases">,
58
+ provider: OcxProviderConfig,
59
+ knownIds: Iterable<string>,
60
+ requested: string,
61
+ ): string | undefined {
62
+ const needle = requested.toLowerCase();
63
+ return [...effectiveModelAliases(config, provider, knownIds)]
64
+ .find(([, value]) => value.alias.toLowerCase() === needle)?.[0];
65
+ }
@@ -1,11 +1,23 @@
1
1
  import type { CodexAccountMode, OcxProviderConfig } from "../types";
2
- import { PROVIDER_REGISTRY, providerMatchesRegistryTransport, type ProviderRegistryEntry } from "./registry";
2
+ import { cloneFastWire } from "./fastwire";
3
+ import {
4
+ PROVIDER_REGISTRY,
5
+ registryEntryForProviderDestination,
6
+ registryModelServiceTierCapabilityApplies,
7
+ type ProviderRegistryEntry,
8
+ } from "./registry";
9
+ import {
10
+ providerMatchesRegistryTransportWithStaticGuards,
11
+ registryEntrySupportsLiveModelDiscovery,
12
+ repairStaticModelCatalogProvider,
13
+ } from "./static-model-discovery";
3
14
 
4
15
  export interface DerivedKeyLoginProvider {
5
16
  label: string;
6
17
  baseUrl: string;
7
18
  responsesPath?: string;
8
19
  adapter: string;
20
+ apiKeyValidation?: "unknown";
9
21
  apiKeyTransport?: OcxProviderConfig["apiKeyTransport"];
10
22
  dashboardUrl: string;
11
23
  models?: string[];
@@ -22,6 +34,7 @@ export interface DerivedKeyLoginProvider {
22
34
  modelDefaultReasoningEfforts?: Record<string, string>;
23
35
  reasoningEffortMap?: Record<string, string>;
24
36
  modelReasoningEffortMap?: Record<string, Record<string, string>>;
37
+ reasoningWireFormat?: OcxProviderConfig["reasoningWireFormat"];
25
38
  noVisionModels?: string[];
26
39
  noReasoningModels?: string[];
27
40
  noTemperatureModels?: string[];
@@ -29,10 +42,12 @@ export interface DerivedKeyLoginProvider {
29
42
  noPenaltyModels?: string[];
30
43
  autoToolChoiceOnlyModels?: string[];
31
44
  preserveReasoningContentModels?: string[];
45
+ requiresReasoningPlaceholderModels?: string[];
32
46
  reasoningSplitModels?: string[];
33
47
  thinkingToggleModels?: string[];
34
48
  thinkingBudgetModels?: string[];
35
49
  escapeBuiltinToolNames?: boolean;
50
+ openaiChatEofTolerance?: boolean;
36
51
  googleMode?: "ai-studio" | "vertex" | "cloud-code-assist";
37
52
  project?: string;
38
53
  location?: string;
@@ -102,13 +117,109 @@ function cloneNestedRecord(input: Record<string, Record<string, string>>): Recor
102
117
  return Object.fromEntries(Object.entries(input).map(([key, value]) => [key, { ...value }]));
103
118
  }
104
119
 
120
+ function sameStringArray(left: readonly string[] | undefined, right: readonly string[]): boolean {
121
+ return left?.length === right.length && left.every((value, index) => value === right[index]);
122
+ }
123
+
124
+ type DirectReasoningEffortOverrides = Pick<
125
+ OcxProviderConfig,
126
+ "thinkingBudgetModels" | "modelReasoningEfforts" | "modelDefaultReasoningEfforts" | "modelReasoningEffortMap"
127
+ >;
128
+
129
+ function fillFoldedModelDefault<T>(
130
+ merged: Record<string, T> | undefined,
131
+ explicit: Record<string, T> | undefined,
132
+ model: string,
133
+ registryDefault: T | undefined,
134
+ clone: (value: T) => T,
135
+ ): Record<string, T> | undefined {
136
+ const folded = model.toLowerCase();
137
+ const explicitEntries = Object.entries(explicit ?? {}).filter(([key]) => key.toLowerCase() === folded);
138
+ if (explicitEntries.length === 0) {
139
+ return registryDefault === undefined ? merged : { ...(merged ?? {}), [model]: clone(registryDefault) };
140
+ }
141
+
142
+ const next = Object.fromEntries(
143
+ Object.entries(merged ?? {}).filter(([key]) => key.toLowerCase() !== folded),
144
+ ) as Record<string, T>;
145
+ for (const [key, value] of explicitEntries) next[key] = clone(value);
146
+ return next;
147
+ }
148
+
149
+ /**
150
+ * Apply a registry-owned direct `reasoning_effort` contract after user/seed metadata is merged.
151
+ *
152
+ * Provider presets are persisted with capability metadata, so an existing config can retain an
153
+ * obsolete thinking-budget classification after the registry learns that a model has a native
154
+ * effort field. The registry opts only verified model contracts into this repair; providers that
155
+ * do not resolve through the matching registry entry keep their user-supplied classification.
156
+ */
157
+ export function applyDirectReasoningEffortContracts(
158
+ entry: ProviderRegistryEntry,
159
+ prov: OcxProviderConfig,
160
+ explicit: DirectReasoningEffortOverrides = prov,
161
+ ): void {
162
+ const models = entry.directReasoningEffortModels;
163
+ if (!models || models.length === 0) return;
164
+
165
+ for (const model of models) {
166
+ // Old generated presets persisted the direct model at the front of the registry's budget
167
+ // list. Routing merges registry-first, which moves that one stale entry to the end. Repair
168
+ // only those two exact generated shapes; any partial, reordered, or case-varied list is a
169
+ // deliberate user value and remains untouched.
170
+ const currentBudgetModels = entry.thinkingBudgetModels ?? [];
171
+ const staleSeedShape = [model, ...currentBudgetModels];
172
+ const staleRoutedShape = [...currentBudgetModels, model];
173
+ if (sameStringArray(explicit.thinkingBudgetModels, staleSeedShape)
174
+ || sameStringArray(explicit.thinkingBudgetModels, staleRoutedShape)) {
175
+ prov.thinkingBudgetModels = [...currentBudgetModels];
176
+ }
177
+
178
+ const efforts = entry.modelReasoningEfforts?.[model];
179
+ prov.modelReasoningEfforts = fillFoldedModelDefault(
180
+ prov.modelReasoningEfforts,
181
+ explicit.modelReasoningEfforts,
182
+ model,
183
+ efforts,
184
+ value => [...value],
185
+ );
186
+
187
+ const defaultEffort = entry.modelDefaultReasoningEfforts?.[model];
188
+ prov.modelDefaultReasoningEfforts = fillFoldedModelDefault(
189
+ prov.modelDefaultReasoningEfforts,
190
+ explicit.modelDefaultReasoningEfforts,
191
+ model,
192
+ defaultEffort,
193
+ value => value,
194
+ );
195
+
196
+ // An explicit empty model map masks any provider-wide aliases. Without it, a stale global
197
+ // mapping such as xhigh -> max would win before the verified direct ladder can clamp it.
198
+ prov.modelReasoningEffortMap = fillFoldedModelDefault(
199
+ prov.modelReasoningEffortMap,
200
+ explicit.modelReasoningEffortMap,
201
+ model,
202
+ {},
203
+ value => ({ ...value }),
204
+ );
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Build the provider config a registry entry contributes when a preset is materialized.
210
+ * The registry auth kind is preserved verbatim (including `"local"`) so fail-closed gates
211
+ * keep distinguishing local runtimes from API-key providers after the seed round-trip.
212
+ */
105
213
  export function providerConfigSeed(entry: ProviderRegistryEntry): OcxProviderConfig {
214
+ const liveModels = registryEntrySupportsLiveModelDiscovery(entry) ? entry.liveModels : false;
106
215
  return {
107
216
  adapter: entry.adapter,
108
217
  baseUrl: entry.baseUrl,
109
218
  ...(entry.apiKeyTransport !== undefined ? { apiKeyTransport: entry.apiKeyTransport } : {}),
110
219
  ...(entry.responsesPath ? { responsesPath: entry.responsesPath } : {}),
111
- authMode: entry.authKind === "local" ? undefined : entry.authKind,
220
+ // Preserve the registry auth kind verbatim (including "local") so fail-closed gates that
221
+ // distinguish local runtimes from API-key providers keep working after the seed round-trip.
222
+ authMode: entry.authKind,
112
223
  ...(entry.codexAccountMode ? { codexAccountMode: entry.codexAccountMode } : {}),
113
224
  ...(entry.keyOptional !== undefined ? { keyOptional: entry.keyOptional } : {}),
114
225
  ...(entry.freeTier !== undefined ? { freeTier: entry.freeTier } : {}),
@@ -116,7 +227,7 @@ export function providerConfigSeed(entry: ProviderRegistryEntry): OcxProviderCon
116
227
  ...(entry.staticHeaders ? { headers: { ...entry.staticHeaders } } : {}),
117
228
  ...(entry.defaultModel ? { defaultModel: entry.defaultModel } : {}),
118
229
  ...(entry.models ? { models: [...entry.models] } : {}),
119
- ...(entry.liveModels !== undefined ? { liveModels: entry.liveModels } : {}),
230
+ ...(liveModels !== undefined ? { liveModels } : {}),
120
231
  ...(entry.contextWindow !== undefined ? { contextWindow: entry.contextWindow } : {}),
121
232
  ...(entry.modelContextWindows ? { modelContextWindows: { ...entry.modelContextWindows } } : {}),
122
233
  ...(entry.modelInputModalities ? { modelInputModalities: cloneRecordOfArrays(entry.modelInputModalities) } : {}),
@@ -128,6 +239,7 @@ export function providerConfigSeed(entry: ProviderRegistryEntry): OcxProviderCon
128
239
  ...(entry.modelDefaultReasoningEfforts ? { modelDefaultReasoningEfforts: { ...entry.modelDefaultReasoningEfforts } } : {}),
129
240
  ...(entry.reasoningEffortMap ? { reasoningEffortMap: { ...entry.reasoningEffortMap } } : {}),
130
241
  ...(entry.modelReasoningEffortMap ? { modelReasoningEffortMap: cloneNestedRecord(entry.modelReasoningEffortMap) } : {}),
242
+ ...(entry.reasoningWireFormat ? { reasoningWireFormat: entry.reasoningWireFormat } : {}),
131
243
  ...(entry.noVisionModels ? { noVisionModels: [...entry.noVisionModels] } : {}),
132
244
  ...(entry.noReasoningModels ? { noReasoningModels: [...entry.noReasoningModels] } : {}),
133
245
  ...(entry.noTemperatureModels ? { noTemperatureModels: [...entry.noTemperatureModels] } : {}),
@@ -135,10 +247,16 @@ export function providerConfigSeed(entry: ProviderRegistryEntry): OcxProviderCon
135
247
  ...(entry.noPenaltyModels ? { noPenaltyModels: [...entry.noPenaltyModels] } : {}),
136
248
  ...(entry.parallelToolCalls !== undefined ? { parallelToolCalls: entry.parallelToolCalls } : {}),
137
249
  ...(entry.promptCacheKey !== undefined ? { promptCacheKey: entry.promptCacheKey } : {}),
250
+ ...(entry.chatServiceTier !== undefined ? { chatServiceTier: entry.chatServiceTier } : {}),
251
+ ...(entry.openaiChatEofTolerance !== undefined ? { openaiChatEofTolerance: entry.openaiChatEofTolerance } : {}),
138
252
  ...(entry.responsesPath !== undefined ? { responsesPath: entry.responsesPath } : {}),
139
253
  ...(entry.statelessResponses !== undefined ? { statelessResponses: entry.statelessResponses } : {}),
254
+ ...(entry.requiresAdjacentResponsesToolResults !== undefined
255
+ ? { requiresAdjacentResponsesToolResults: entry.requiresAdjacentResponsesToolResults }
256
+ : {}),
140
257
  ...(entry.autoToolChoiceOnlyModels ? { autoToolChoiceOnlyModels: [...entry.autoToolChoiceOnlyModels] } : {}),
141
258
  ...(entry.preserveReasoningContentModels ? { preserveReasoningContentModels: [...entry.preserveReasoningContentModels] } : {}),
259
+ ...(entry.requiresReasoningPlaceholderModels ? { requiresReasoningPlaceholderModels: [...entry.requiresReasoningPlaceholderModels] } : {}),
142
260
  ...(entry.reasoningSplitModels ? { reasoningSplitModels: [...entry.reasoningSplitModels] } : {}),
143
261
  ...(entry.thinkingToggleModels ? { thinkingToggleModels: [...entry.thinkingToggleModels] } : {}),
144
262
  ...(entry.thinkingBudgetModels ? { thinkingBudgetModels: [...entry.thinkingBudgetModels] } : {}),
@@ -154,15 +272,17 @@ export function deriveKeyLoginMap(): Record<string, DerivedKeyLoginProvider> {
154
272
  for (const entry of PROVIDER_REGISTRY) {
155
273
  if (entry.authKind !== "key") continue;
156
274
  if (!entry.dashboardUrl) throw new Error(`Registry key provider missing dashboardUrl: ${entry.id}`);
275
+ const liveModels = registryEntrySupportsLiveModelDiscovery(entry) ? entry.liveModels : false;
157
276
  out[entry.id] = {
158
277
  label: entry.label,
159
278
  baseUrl: entry.baseUrl,
160
279
  ...(entry.responsesPath ? { responsesPath: entry.responsesPath } : {}),
161
280
  adapter: entry.adapter,
281
+ ...(entry.apiKeyValidation !== undefined ? { apiKeyValidation: entry.apiKeyValidation } : {}),
162
282
  ...(entry.apiKeyTransport !== undefined ? { apiKeyTransport: entry.apiKeyTransport } : {}),
163
283
  dashboardUrl: entry.dashboardUrl,
164
284
  ...(entry.models ? { models: [...entry.models] } : {}),
165
- ...(entry.liveModels !== undefined ? { liveModels: entry.liveModels } : {}),
285
+ ...(liveModels !== undefined ? { liveModels } : {}),
166
286
  ...(entry.defaultModel ? { defaultModel: entry.defaultModel } : {}),
167
287
  ...(entry.contextWindow !== undefined ? { contextWindow: entry.contextWindow } : {}),
168
288
  ...(entry.modelContextWindows ? { modelContextWindows: { ...entry.modelContextWindows } } : {}),
@@ -175,6 +295,7 @@ export function deriveKeyLoginMap(): Record<string, DerivedKeyLoginProvider> {
175
295
  ...(entry.modelDefaultReasoningEfforts ? { modelDefaultReasoningEfforts: { ...entry.modelDefaultReasoningEfforts } } : {}),
176
296
  ...(entry.reasoningEffortMap ? { reasoningEffortMap: { ...entry.reasoningEffortMap } } : {}),
177
297
  ...(entry.modelReasoningEffortMap ? { modelReasoningEffortMap: cloneNestedRecord(entry.modelReasoningEffortMap) } : {}),
298
+ ...(entry.reasoningWireFormat ? { reasoningWireFormat: entry.reasoningWireFormat } : {}),
178
299
  ...(entry.noVisionModels ? { noVisionModels: [...entry.noVisionModels] } : {}),
179
300
  ...(entry.noReasoningModels ? { noReasoningModels: [...entry.noReasoningModels] } : {}),
180
301
  ...(entry.noTemperatureModels ? { noTemperatureModels: [...entry.noTemperatureModels] } : {}),
@@ -182,10 +303,12 @@ export function deriveKeyLoginMap(): Record<string, DerivedKeyLoginProvider> {
182
303
  ...(entry.noPenaltyModels ? { noPenaltyModels: [...entry.noPenaltyModels] } : {}),
183
304
  ...(entry.autoToolChoiceOnlyModels ? { autoToolChoiceOnlyModels: [...entry.autoToolChoiceOnlyModels] } : {}),
184
305
  ...(entry.preserveReasoningContentModels ? { preserveReasoningContentModels: [...entry.preserveReasoningContentModels] } : {}),
306
+ ...(entry.requiresReasoningPlaceholderModels ? { requiresReasoningPlaceholderModels: [...entry.requiresReasoningPlaceholderModels] } : {}),
185
307
  ...(entry.reasoningSplitModels ? { reasoningSplitModels: [...entry.reasoningSplitModels] } : {}),
186
308
  ...(entry.thinkingToggleModels ? { thinkingToggleModels: [...entry.thinkingToggleModels] } : {}),
187
309
  ...(entry.thinkingBudgetModels ? { thinkingBudgetModels: [...entry.thinkingBudgetModels] } : {}),
188
310
  ...(entry.escapeBuiltinToolNames !== undefined ? { escapeBuiltinToolNames: entry.escapeBuiltinToolNames } : {}),
311
+ ...(entry.openaiChatEofTolerance !== undefined ? { openaiChatEofTolerance: entry.openaiChatEofTolerance } : {}),
189
312
  ...(entry.googleMode ? { googleMode: entry.googleMode } : {}),
190
313
  ...(entry.project ? { project: entry.project } : {}),
191
314
  ...(entry.location ? { location: entry.location } : {}),
@@ -227,10 +350,119 @@ export function deriveProviderPresets(): DerivedProviderPreset[] {
227
350
  return [...dedupePresets(presets), customPreset()];
228
351
  }
229
352
 
353
+ /**
354
+ * Merge registry reasoning-summary defaults PER KEY, letting explicit user values win.
355
+ *
356
+ * Not a whole-Record `=== undefined` fill like the scalars around it: a user who sets one
357
+ * model's flag creates a defined Record, and a whole-object check would then suppress every
358
+ * registry default for that provider. Spreading registry-first also preserves an explicit
359
+ * `false` — someone who disabled summaries for a model because their backend 400s on it keeps
360
+ * that. The result is a fresh object, so saved config never aliases the registry constant.
361
+ */
362
+ function applyReasoningSummaryDefaults(
363
+ prov: OcxProviderConfig,
364
+ defaults: Readonly<Record<string, boolean>> | undefined,
365
+ ): void {
366
+ if (!defaults) return;
367
+ prov.modelSupportsReasoningSummaries = {
368
+ ...defaults,
369
+ ...(prov.modelSupportsReasoningSummaries ?? {}),
370
+ };
371
+ }
372
+
373
+ function applyServiceTierModelDefaults(
374
+ prov: OcxProviderConfig,
375
+ defaults: Readonly<Record<string, boolean>> | undefined,
376
+ ): void {
377
+ if (!defaults) return;
378
+ prov.modelSupportsServiceTier = {
379
+ ...defaults,
380
+ ...(prov.modelSupportsServiceTier ?? {}),
381
+ };
382
+ }
383
+
384
+ function serviceTierModelDefaultsFor(
385
+ entry: ProviderRegistryEntry | undefined,
386
+ prov: OcxProviderConfig,
387
+ ): Readonly<Record<string, boolean>> | undefined {
388
+ return entry && registryModelServiceTierCapabilityApplies(entry, prov)
389
+ ? entry.modelSupportsServiceTier
390
+ : undefined;
391
+ }
392
+
393
+ /**
394
+ * Materialize the registry's verbosity opt-out into the provider config at seed/enrich time.
395
+ *
396
+ * The catalog hint pass must not read PROVIDER_REGISTRY: a gather flight captures its registry
397
+ * authority up front and forbids any later read, so consulting the registry per model turned
398
+ * every hint pass into a post-lookup read and dropped a custom-destination flight's own
399
+ * discovery result (tests/codex-gather-authority.test.ts).
400
+ *
401
+ * Registry values go in first so an explicit user entry still wins, matching
402
+ * `applyReasoningSummaryDefaults`. `supportsVerbosity` is the provider-wide default, expanded
403
+ * across the seeded model list so an id discovered later still inherits it through the same
404
+ * Record the hint pass already reads.
405
+ */
406
+ function applyVerbosityDefaults(prov: OcxProviderConfig, entry: ProviderRegistryEntry | undefined): void {
407
+ if (!entry) return;
408
+ const perModel = entry.modelSupportsVerbosity;
409
+ if (!perModel && entry.supportsVerbosity === undefined) return;
410
+ prov.modelSupportsVerbosity = {
411
+ ...(perModel ?? {}),
412
+ ...(prov.modelSupportsVerbosity ?? {}),
413
+ };
414
+ if (entry.supportsVerbosity !== undefined) {
415
+ prov.supportsVerbosity ??= entry.supportsVerbosity;
416
+ }
417
+ }
418
+
419
+ /**
420
+ * Last-resort enrichment for a provider whose NAME matches no registry id.
421
+ *
422
+ * #1100 was reported against a hand-added provider called "GLM" pointing at a vendor endpoint
423
+ * we recognize. Routing worked, so the row looked healthy, but every piece of registry metadata
424
+ * was skipped and the reasoning ladder was advertised without summary support — exactly the
425
+ * inconsistency that makes Codex drop the inbound reasoning object.
426
+ *
427
+ * Deliberately narrow: only the reasoning-summary map, and only via
428
+ * `registryEntryForProviderDestination`, which matches fixed key destinations and refuses
429
+ * templated or overridable base URLs. A custom row keeps its own identity for everything else.
430
+ */
431
+ function enrichReasoningSummariesByDestination(prov: OcxProviderConfig): void {
432
+ const destination = registryEntryForProviderDestination(prov);
433
+ applyReasoningSummaryDefaults(prov, destination?.modelSupportsReasoningSummaries);
434
+ }
435
+
436
+ /** Repair the exact low-only ClinePass ladder generated by older key-login presets. */
437
+ export function hasLegacyClinePassReasoningEfforts(name: string, prov: OcxProviderConfig): boolean {
438
+ return name === "cline-pass"
439
+ && prov.reasoningWireFormat === "gateway-object"
440
+ && prov.reasoningEfforts?.length === 1
441
+ && prov.reasoningEfforts[0] === "low";
442
+ }
443
+
230
444
  export function enrichProviderFromRegistry(name: string, prov: OcxProviderConfig): void {
231
445
  const entry = PROVIDER_REGISTRY.find(row => row.id === name);
232
- if (!entry || !providerMatchesRegistryTransport(name, prov)) return;
446
+ if (!entry || !providerMatchesRegistryTransportWithStaticGuards(name, prov)) {
447
+ // Name lookup failed, but the row may still point at a vendor route we know. #1100 was
448
+ // reported against a hand-added provider literally named "GLM": routing worked, yet every
449
+ // piece of registry metadata was skipped because no registry id is called "GLM".
450
+ // `registryEntryForProviderDestination` answers the question that actually matters here —
451
+ // which vendor endpoint is this row talking to — and is already restricted to fixed key
452
+ // destinations, so a templated or overridable base URL cannot be claimed by it.
453
+ enrichReasoningSummariesByDestination(prov);
454
+ applyServiceTierModelDefaults(prov, serviceTierModelDefaultsFor(registryEntryForProviderDestination(prov), prov));
455
+ applyVerbosityDefaults(prov, registryEntryForProviderDestination(prov));
456
+ return;
457
+ }
458
+ const explicitDirectReasoning: DirectReasoningEffortOverrides = {
459
+ thinkingBudgetModels: prov.thinkingBudgetModels,
460
+ modelReasoningEfforts: prov.modelReasoningEfforts,
461
+ modelDefaultReasoningEfforts: prov.modelDefaultReasoningEfforts,
462
+ modelReasoningEffortMap: prov.modelReasoningEffortMap,
463
+ };
233
464
  const seed = providerConfigSeed(entry);
465
+ repairStaticModelCatalogProvider(name, prov);
234
466
  if (prov.apiKeyTransport === undefined && seed.apiKeyTransport !== undefined) prov.apiKeyTransport = seed.apiKeyTransport;
235
467
  if (!prov.defaultModel && seed.defaultModel) prov.defaultModel = seed.defaultModel;
236
468
  if (prov.responsesPath === undefined && seed.responsesPath !== undefined) prov.responsesPath = seed.responsesPath;
@@ -243,11 +475,14 @@ export function enrichProviderFromRegistry(name: string, prov: OcxProviderConfig
243
475
  if (seed.modelInputModalities) prov.modelInputModalities = fillRecordOfArrays(seed.modelInputModalities, prov.modelInputModalities);
244
476
  if (prov.defaultMaxOutputTokens === undefined && seed.defaultMaxOutputTokens !== undefined) prov.defaultMaxOutputTokens = seed.defaultMaxOutputTokens;
245
477
  if (!prov.modelMaxOutputTokens && seed.modelMaxOutputTokens) prov.modelMaxOutputTokens = { ...seed.modelMaxOutputTokens };
246
- if (!prov.reasoningEfforts && seed.reasoningEfforts) prov.reasoningEfforts = [...seed.reasoningEfforts];
478
+ if ((!prov.reasoningEfforts || hasLegacyClinePassReasoningEfforts(name, prov)) && seed.reasoningEfforts) {
479
+ prov.reasoningEfforts = [...seed.reasoningEfforts];
480
+ }
247
481
  if (!prov.modelReasoningEfforts && seed.modelReasoningEfforts) prov.modelReasoningEfforts = cloneRecordOfArrays(seed.modelReasoningEfforts);
248
482
  if (!prov.modelDefaultReasoningEfforts && seed.modelDefaultReasoningEfforts) prov.modelDefaultReasoningEfforts = { ...seed.modelDefaultReasoningEfforts };
249
483
  if (!prov.reasoningEffortMap && seed.reasoningEffortMap) prov.reasoningEffortMap = { ...seed.reasoningEffortMap };
250
484
  if (!prov.modelReasoningEffortMap && seed.modelReasoningEffortMap) prov.modelReasoningEffortMap = cloneNestedRecord(seed.modelReasoningEffortMap);
485
+ if (prov.reasoningWireFormat === undefined && seed.reasoningWireFormat !== undefined) prov.reasoningWireFormat = seed.reasoningWireFormat;
251
486
  if (!prov.noVisionModels && seed.noVisionModels) prov.noVisionModels = [...seed.noVisionModels];
252
487
  if (!prov.noReasoningModels && seed.noReasoningModels) prov.noReasoningModels = [...seed.noReasoningModels];
253
488
  if (!prov.noTemperatureModels && seed.noTemperatureModels) prov.noTemperatureModels = [...seed.noTemperatureModels];
@@ -255,12 +490,51 @@ export function enrichProviderFromRegistry(name: string, prov: OcxProviderConfig
255
490
  if (!prov.noPenaltyModels && seed.noPenaltyModels) prov.noPenaltyModels = [...seed.noPenaltyModels];
256
491
  if (prov.parallelToolCalls === undefined && seed.parallelToolCalls !== undefined) prov.parallelToolCalls = seed.parallelToolCalls;
257
492
  if (prov.promptCacheKey === undefined && seed.promptCacheKey !== undefined) prov.promptCacheKey = seed.promptCacheKey;
493
+ if (prov.chatServiceTier === undefined && seed.chatServiceTier !== undefined) prov.chatServiceTier = seed.chatServiceTier;
494
+ if (prov.openaiChatEofTolerance === undefined && seed.openaiChatEofTolerance !== undefined) {
495
+ prov.openaiChatEofTolerance = seed.openaiChatEofTolerance;
496
+ }
258
497
  // Fill-only: a hand-edited path must survive, and a config saved before the registry
259
498
  // learned this route still gets backfilled.
260
499
  if (prov.responsesPath === undefined && seed.responsesPath !== undefined) prov.responsesPath = seed.responsesPath;
261
500
  if (prov.statelessResponses === undefined && seed.statelessResponses !== undefined) prov.statelessResponses = seed.statelessResponses;
501
+ if (prov.requiresAdjacentResponsesToolResults === undefined && seed.requiresAdjacentResponsesToolResults !== undefined) {
502
+ prov.requiresAdjacentResponsesToolResults = seed.requiresAdjacentResponsesToolResults;
503
+ }
504
+ // Registry-only metadata (never seeded into saved config): backfill straight from
505
+ // the entry so an explicit user value stays distinguishable from the default.
506
+ if (prov.fastWire === undefined && entry.fastWire !== undefined) {
507
+ prov.fastWire = cloneFastWire(entry.fastWire);
508
+ }
509
+ if (prov.supportsServiceTier === undefined && entry.supportsServiceTier !== undefined) prov.supportsServiceTier = entry.supportsServiceTier;
510
+ if (prov.supportsOpenAiWebSearchToolFields === undefined && entry.supportsOpenAiWebSearchToolFields !== undefined) {
511
+ prov.supportsOpenAiWebSearchToolFields = entry.supportsOpenAiWebSearchToolFields;
512
+ }
513
+ if (prov.supportsResponsesCustomTools === undefined && entry.supportsResponsesCustomTools !== undefined) {
514
+ prov.supportsResponsesCustomTools = entry.supportsResponsesCustomTools;
515
+ }
516
+ if (prov.preserveResponsesReasoningContent === undefined && entry.preserveResponsesReasoningContent !== undefined) prov.preserveResponsesReasoningContent = entry.preserveResponsesReasoningContent;
517
+ applyReasoningSummaryDefaults(prov, entry.modelSupportsReasoningSummaries);
518
+ applyServiceTierModelDefaults(prov, serviceTierModelDefaultsFor(entry, prov));
519
+ applyVerbosityDefaults(prov, entry);
520
+ // Registry-only repair policy (#938): fill only when the runtime provider has
521
+ // no explicit policy, and deep-clone so saved/user values never alias the
522
+ // registry constant.
523
+ if (prov.responsesItemIdRepair === undefined && entry.responsesItemIdRepair) {
524
+ prov.responsesItemIdRepair = {
525
+ ...(entry.responsesItemIdRepair.message ? { message: [...entry.responsesItemIdRepair.message] } : {}),
526
+ ...(entry.responsesItemIdRepair.reasoning ? { reasoning: [...entry.responsesItemIdRepair.reasoning] } : {}),
527
+ ...(entry.responsesItemIdRepair.repairMissingTerminalIds !== undefined
528
+ ? { repairMissingTerminalIds: entry.responsesItemIdRepair.repairMissingTerminalIds }
529
+ : {}),
530
+ ...(entry.responsesItemIdRepair.repairInvalidIds !== undefined
531
+ ? { repairInvalidIds: entry.responsesItemIdRepair.repairInvalidIds }
532
+ : {}),
533
+ };
534
+ }
262
535
  if (!prov.autoToolChoiceOnlyModels && seed.autoToolChoiceOnlyModels) prov.autoToolChoiceOnlyModels = [...seed.autoToolChoiceOnlyModels];
263
536
  if (!prov.preserveReasoningContentModels && seed.preserveReasoningContentModels) prov.preserveReasoningContentModels = [...seed.preserveReasoningContentModels];
537
+ if (!prov.requiresReasoningPlaceholderModels && seed.requiresReasoningPlaceholderModels) prov.requiresReasoningPlaceholderModels = [...seed.requiresReasoningPlaceholderModels];
264
538
  if (!prov.reasoningSplitModels && seed.reasoningSplitModels) prov.reasoningSplitModels = [...seed.reasoningSplitModels];
265
539
  if (!prov.thinkingToggleModels && seed.thinkingToggleModels) prov.thinkingToggleModels = [...seed.thinkingToggleModels];
266
540
  if (!prov.thinkingBudgetModels && seed.thinkingBudgetModels) prov.thinkingBudgetModels = [...seed.thinkingBudgetModels];
@@ -269,6 +543,7 @@ export function enrichProviderFromRegistry(name: string, prov: OcxProviderConfig
269
543
  if (prov.freeTier === undefined && seed.freeTier !== undefined) prov.freeTier = seed.freeTier;
270
544
  if (prov.modelSuffixBracketStrip === undefined && seed.modelSuffixBracketStrip !== undefined) prov.modelSuffixBracketStrip = seed.modelSuffixBracketStrip;
271
545
  if (!prov.headers && seed.headers) prov.headers = { ...seed.headers };
546
+ applyDirectReasoningEffortContracts(entry, prov, explicitDirectReasoning);
272
547
  }
273
548
 
274
549
  export function deriveFeaturedProviderIds(): string[] {