@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
@@ -1,4 +1,5 @@
1
1
  import { isCodexReasoningEffort } from "../reasoning-effort";
2
+ import { SUPPORTED_NATIVE_OPENAI_SLUGS } from "../codex/catalog/native-models";
2
3
  import type {
3
4
  OcxComboConfig,
4
5
  OcxComboDefaultEffort,
@@ -24,11 +25,7 @@ const COMBO_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
24
25
  * `combo/` prefix. Codex-facing slugs tolerate at most one "/", so deeper paths reject.
25
26
  */
26
27
  const COMBO_ALIAS_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}(?:\/[A-Za-z0-9][A-Za-z0-9._-]{0,63})?$/;
27
- /**
28
- * Bare aliases in the OpenAI native family (gpt-*, o1-*, o3-*, o4-*, codex-*) are
29
- * rejected: they collide with native catalog rows and the canonical-OpenAI routing
30
- * branch, which cannot be shadowed honestly.
31
- */
28
+ /** Bare aliases in this family require the explicit `nativeAlias` opt-in below. */
32
29
  const NATIVE_OPENAI_FAMILY_PATTERN = /^(?:gpt-|o1-|o3-|o4-|codex-)/;
33
30
 
34
31
  export interface ComboValidationIssue {
@@ -40,11 +37,26 @@ export interface NormalizedComboConfig {
40
37
  strategy: OcxComboStrategy;
41
38
  stickyLimit: number;
42
39
  defaultEffort: OcxComboDefaultEffort | null;
40
+ /** Disable image input; `auto` preserves the intersection derived from all targets. */
41
+ imageInput: "auto" | "disabled";
43
42
  /** Trimmed public alias, or null when the combo keeps the default `combo/<id>` slug. */
44
43
  alias: string | null;
44
+ /** Explicit native-family alias opt-in. */
45
+ nativeAlias: boolean;
46
+ /** Display-only label for the catalog row, or null when unset. */
47
+ displayName: string | null;
45
48
  targets: Array<Required<OcxComboTarget>>;
46
49
  }
47
50
 
51
+ /** True only for an explicitly opted-in bare native-family alias. */
52
+ export function isNativeAliasCombo(
53
+ combo: { alias?: string | null; nativeAlias?: boolean },
54
+ ): boolean {
55
+ const alias = typeof combo.alias === "string" ? combo.alias.trim() : "";
56
+ return combo.nativeAlias === true
57
+ && SUPPORTED_NATIVE_OPENAI_SLUGS.has(alias);
58
+ }
59
+
48
60
  export function targetKey(target: Pick<OcxComboTarget, "provider" | "model">): string {
49
61
  return `${target.provider}/${target.model}`;
50
62
  }
@@ -66,6 +78,27 @@ export function comboPublicModelId(id: string, combo: { alias?: string | null })
66
78
  return alias || comboModelId(id);
67
79
  }
68
80
 
81
+ /**
82
+ * Persisted selector that hides a combo from discovery. Native aliases keep the canonical
83
+ * `combo/<id>` selector because their bare public id remains the native OpenAI disable key.
84
+ */
85
+ export function comboDisabledModelId(
86
+ id: string,
87
+ combo: { alias?: string | null; nativeAlias?: boolean },
88
+ ): string {
89
+ return isNativeAliasCombo(combo) ? comboModelId(id) : comboPublicModelId(id, combo);
90
+ }
91
+
92
+ /** Every persisted selector that can refer to this combo in `disabledModels`. */
93
+ export function comboDisabledModelSelectors(
94
+ id: string,
95
+ combo: { alias?: string | null; nativeAlias?: boolean },
96
+ ): string[] {
97
+ const canonical = comboModelId(id);
98
+ const preferred = comboDisabledModelId(id, combo);
99
+ return preferred === canonical ? [canonical] : [canonical, preferred];
100
+ }
101
+
69
102
  /**
70
103
  * Resolve a client-requested model id to a combo config key. The canonical `combo/<id>`
71
104
  * form wins first (back-compat); otherwise an exact alias match across configured combos.
@@ -94,7 +127,7 @@ export function comboAliasIssues(
94
127
  id: string,
95
128
  alias: string,
96
129
  combos: Record<string, OcxComboConfig> | undefined,
97
- options: { excludeComboId?: string } = {},
130
+ options: { excludeComboId?: string; allowNativeAlias?: boolean } = {},
98
131
  ): ComboValidationIssue[] {
99
132
  const issues: ComboValidationIssue[] = [];
100
133
  if (!COMBO_ALIAS_PATTERN.test(alias)) {
@@ -110,10 +143,12 @@ export function comboAliasIssues(
110
143
  message: `alias must not use the reserved "${COMBO_NAMESPACE}/" namespace`,
111
144
  });
112
145
  }
113
- if (!alias.includes("/") && NATIVE_OPENAI_FAMILY_PATTERN.test(alias)) {
146
+ if (!alias.includes("/")
147
+ && NATIVE_OPENAI_FAMILY_PATTERN.test(alias)
148
+ && options.allowNativeAlias !== true) {
114
149
  issues.push({
115
150
  path: ["alias"],
116
- message: "bare aliases in the OpenAI native family (gpt-*, o1-*, o3-*, o4-*, codex-*) are not allowed",
151
+ message: "bare aliases in the OpenAI native family require nativeAlias=true",
117
152
  });
118
153
  }
119
154
  for (const [otherId, other] of Object.entries(combos ?? {})) {
@@ -168,6 +203,16 @@ export function comboConfigIssues(
168
203
  }
169
204
 
170
205
  const body = raw as Record<string, unknown>;
206
+ if (typeof body.alias === "string") {
207
+ const alias = body.alias.toLowerCase();
208
+ for (const [providerName, provider] of Object.entries(providers)) {
209
+ if (provider.alias?.toLowerCase() === alias) {
210
+ issues.push({ path: ["alias"], message: `alias "${body.alias}" is already used by provider "${providerName}"` });
211
+ }
212
+ const model = Object.entries(provider.modelAliases ?? {}).find(([, value]) => value.toLowerCase() === alias);
213
+ if (model) issues.push({ path: ["alias"], message: `alias "${body.alias}" is already used by model "${providerName}/${model[0]}"` });
214
+ }
215
+ }
171
216
  if (body.strategy !== undefined
172
217
  && body.strategy !== "failover"
173
218
  && body.strategy !== "round-robin") {
@@ -187,15 +232,48 @@ export function comboConfigIssues(
187
232
  message: "defaultEffort must be one of: low, medium, high, xhigh, max, ultra",
188
233
  });
189
234
  }
235
+ if (body.imageInput !== undefined && body.imageInput !== "auto" && body.imageInput !== "disabled") {
236
+ issues.push({ path: ["imageInput"], message: 'imageInput must be "auto" or "disabled"' });
237
+ }
190
238
 
191
239
  if (body.alias !== undefined) {
192
240
  if (typeof body.alias !== "string") {
193
241
  issues.push({ path: ["alias"], message: "alias must be a string" });
194
242
  } else {
195
243
  const alias = body.alias.trim();
196
- if (alias) issues.push(...comboAliasIssues(id, alias, options.combos, options));
244
+ if (alias) {
245
+ issues.push(...comboAliasIssues(id, alias, options.combos, {
246
+ ...options,
247
+ allowNativeAlias: body.nativeAlias === true,
248
+ }));
249
+ }
250
+ }
251
+ }
252
+
253
+ if (body.nativeAlias !== undefined && typeof body.nativeAlias !== "boolean") {
254
+ issues.push({ path: ["nativeAlias"], message: "nativeAlias must be a boolean" });
255
+ }
256
+ if (body.displayName !== undefined) {
257
+ if (typeof body.displayName !== "string") {
258
+ issues.push({ path: ["displayName"], message: "displayName must be a string" });
259
+ } else if (body.displayName.trim().length > 128 || /[\u0000-\u001f\u007f]/.test(body.displayName)) {
260
+ issues.push({
261
+ path: ["displayName"],
262
+ message: "displayName must be at most 128 characters and contain no control characters",
263
+ });
197
264
  }
198
265
  }
266
+ const alias = typeof body.alias === "string" ? body.alias.trim() : "";
267
+ const nativeAlias = body.nativeAlias === true;
268
+ if (nativeAlias && !SUPPORTED_NATIVE_OPENAI_SLUGS.has(alias)) {
269
+ issues.push({
270
+ path: ["nativeAlias"],
271
+ message: "nativeAlias requires a currently supported bare OpenAI-native model alias",
272
+ });
273
+ }
274
+ if (nativeAlias && (typeof body.displayName !== "string" || body.displayName.trim().length === 0)) {
275
+ issues.push({ path: ["displayName"], message: "displayName is required for native aliases" });
276
+ }
199
277
 
200
278
  if (!Array.isArray(body.targets) || body.targets.length === 0) {
201
279
  issues.push({ path: ["targets"], message: "targets must be a non-empty array" });
@@ -271,11 +349,15 @@ export function comboConfigError(
271
349
 
272
350
  export function normalizeComboConfig(raw: OcxComboConfig): NormalizedComboConfig {
273
351
  const alias = typeof raw.alias === "string" ? raw.alias.trim() : "";
352
+ const displayName = typeof raw.displayName === "string" ? raw.displayName.trim() : "";
274
353
  return {
275
354
  strategy: raw.strategy ?? "failover",
276
355
  stickyLimit: raw.stickyLimit ?? 1,
277
356
  defaultEffort: raw.defaultEffort ?? null,
357
+ imageInput: raw.imageInput === "disabled" ? "disabled" : "auto",
278
358
  alias: alias || null,
359
+ nativeAlias: raw.nativeAlias === true,
360
+ displayName: displayName || null,
279
361
  targets: raw.targets.map(target => ({
280
362
  provider: target.provider.trim(),
281
363
  model: target.model.trim(),
@@ -0,0 +1,26 @@
1
+ import { OPENAI_CODEX_FORWARD_GPT56_SOL_MANIFEST } from "./openai-responses";
2
+ import type { CompatibilityManifestV1 } from "./manifest";
3
+
4
+ export {
5
+ COMPATIBILITY_DISPOSITIONS,
6
+ COMPATIBILITY_MANIFEST_SCHEMA_VERSION,
7
+ compatibilityManifestIssues,
8
+ defineCompatibilityManifest,
9
+ } from "./manifest";
10
+ export type {
11
+ CompatibilityClaimV1,
12
+ CompatibilityDisposition,
13
+ CompatibilityEvidenceKind,
14
+ CompatibilityEvidenceRefV1,
15
+ CompatibilityManifestV1,
16
+ CompatibilitySubjectV1,
17
+ } from "./manifest";
18
+ export { OPENAI_CODEX_FORWARD_GPT56_SOL_MANIFEST } from "./openai-responses";
19
+
20
+ export const COMPATIBILITY_MANIFESTS: readonly CompatibilityManifestV1[] = Object.freeze([
21
+ OPENAI_CODEX_FORWARD_GPT56_SOL_MANIFEST,
22
+ ]);
23
+
24
+ export function getCompatibilityManifest(id: string): CompatibilityManifestV1 | undefined {
25
+ return COMPATIBILITY_MANIFESTS.find(manifest => manifest.id === id);
26
+ }
@@ -0,0 +1,253 @@
1
+ export const COMPATIBILITY_MANIFEST_SCHEMA_VERSION = 1 as const;
2
+
3
+ export const COMPATIBILITY_DISPOSITIONS = [
4
+ "passthrough",
5
+ "translated",
6
+ "degraded",
7
+ "unsupported",
8
+ ] as const;
9
+
10
+ export type CompatibilityDisposition = typeof COMPATIBILITY_DISPOSITIONS[number];
11
+ export type CompatibilityEvidenceKind = "fixture" | "lab-scenario";
12
+
13
+ export interface CompatibilityEvidenceRefV1 {
14
+ kind: CompatibilityEvidenceKind;
15
+ id: string;
16
+ /** Exact fixture assertions that prove this claim. Required for fixture evidence. */
17
+ assertionIds?: readonly string[];
18
+ }
19
+
20
+ export interface CompatibilityClaimV1 {
21
+ /** Stable manifest-local claim id. */
22
+ id: string;
23
+ /** Stable public feature key, such as `request.previous_response_id`. */
24
+ feature: string;
25
+ disposition: CompatibilityDisposition;
26
+ summary: string;
27
+ /** Required when behavior is not byte/semantic passthrough. */
28
+ limitation?: string;
29
+ evidence: readonly CompatibilityEvidenceRefV1[];
30
+ }
31
+
32
+ export interface CompatibilitySubjectV1 {
33
+ providerId: string;
34
+ /** Exact normalized provider base URL; destination changes require a new subject/version. */
35
+ baseUrl: string;
36
+ adapterId: string;
37
+ authMode: "forward" | "key" | "oauth" | "local";
38
+ inboundProtocol: "responses" | "chat" | "messages";
39
+ upstreamProtocol: string;
40
+ /** Claims apply only to these exact wire model ids. */
41
+ modelIds: readonly string[];
42
+ }
43
+
44
+ export interface CompatibilityManifestV1 {
45
+ schemaVersion: typeof COMPATIBILITY_MANIFEST_SCHEMA_VERSION;
46
+ id: string;
47
+ version: string;
48
+ subject: CompatibilitySubjectV1;
49
+ claims: readonly CompatibilityClaimV1[];
50
+ }
51
+
52
+ const ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,127}$/;
53
+ const FEATURE_PATTERN = /^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)+$/;
54
+ const DISPOSITIONS = new Set<string>(COMPATIBILITY_DISPOSITIONS);
55
+ const EVIDENCE_KINDS = new Set<string>(["fixture", "lab-scenario"]);
56
+
57
+ function isRecord(value: unknown): value is Record<string, unknown> {
58
+ return !!value && typeof value === "object" && !Array.isArray(value);
59
+ }
60
+
61
+ function checkKnownKeys(
62
+ value: Record<string, unknown>,
63
+ allowed: readonly string[],
64
+ path: string,
65
+ issues: string[],
66
+ ): void {
67
+ const allowedSet = new Set(allowed);
68
+ for (const key of Object.keys(value)) {
69
+ if (!allowedSet.has(key)) issues.push(`${path}${path ? "." : ""}${key} is not allowed by schema v1`);
70
+ }
71
+ }
72
+
73
+ function checkId(value: unknown, path: string, issues: string[]): value is string {
74
+ if (typeof value !== "string" || !ID_PATTERN.test(value)) {
75
+ issues.push(`${path} must match ${ID_PATTERN}`);
76
+ return false;
77
+ }
78
+ return true;
79
+ }
80
+
81
+ function checkNonBlank(value: unknown, path: string, issues: string[]): value is string {
82
+ if (typeof value !== "string" || value.trim().length === 0) {
83
+ issues.push(`${path} must be a non-blank string`);
84
+ return false;
85
+ }
86
+ return true;
87
+ }
88
+
89
+ function checkNormalizedBaseUrl(value: unknown, path: string, issues: string[]): value is string {
90
+ if (typeof value !== "string") {
91
+ issues.push(`${path} must be a normalized absolute HTTP(S) base URL`);
92
+ return false;
93
+ }
94
+ try {
95
+ const parsed = new URL(value);
96
+ if (
97
+ (parsed.protocol !== "https:" && parsed.protocol !== "http:")
98
+ || parsed.username
99
+ || parsed.password
100
+ || parsed.search
101
+ || parsed.hash
102
+ ) {
103
+ issues.push(`${path} must be a normalized absolute HTTP(S) base URL without credentials, query, or fragment`);
104
+ return false;
105
+ }
106
+ const normalizedPath = parsed.pathname.replace(/\/+$/, "");
107
+ const normalized = `${parsed.origin}${normalizedPath}`;
108
+ if (value !== normalized) {
109
+ issues.push(`${path} must be normalized as ${normalized}`);
110
+ return false;
111
+ }
112
+ return true;
113
+ } catch {
114
+ issues.push(`${path} must be a normalized absolute HTTP(S) base URL`);
115
+ return false;
116
+ }
117
+ }
118
+
119
+ function checkSortedUniqueStrings(
120
+ value: unknown,
121
+ path: string,
122
+ issues: string[],
123
+ options: { nonEmpty?: boolean } = {},
124
+ ): value is string[] {
125
+ if (!Array.isArray(value) || (options.nonEmpty === true && value.length === 0)) {
126
+ issues.push(`${path} must be${options.nonEmpty === true ? " a non-empty" : " an"} array`);
127
+ return false;
128
+ }
129
+ if (value.some(item => typeof item !== "string" || item.trim().length === 0)) {
130
+ issues.push(`${path} must contain only non-blank strings`);
131
+ return false;
132
+ }
133
+ const strings = value as string[];
134
+ if (new Set(strings).size !== strings.length) issues.push(`${path} must not contain duplicates`);
135
+ const sorted = [...strings].sort();
136
+ if (strings.some((item, index) => item !== sorted[index])) issues.push(`${path} must be sorted`);
137
+ return true;
138
+ }
139
+
140
+ function checkEvidence(value: unknown, path: string, issues: string[]): void {
141
+ if (!Array.isArray(value) || value.length === 0) {
142
+ issues.push(`${path} must be a non-empty array`);
143
+ return;
144
+ }
145
+ const seen = new Set<string>();
146
+ value.forEach((raw, index) => {
147
+ const evidencePath = `${path}[${index}]`;
148
+ if (!isRecord(raw)) {
149
+ issues.push(`${evidencePath} must be an object`);
150
+ return;
151
+ }
152
+ checkKnownKeys(raw, ["kind", "id", "assertionIds"], evidencePath, issues);
153
+ if (!EVIDENCE_KINDS.has(String(raw.kind))) {
154
+ issues.push(`${evidencePath}.kind must be fixture or lab-scenario`);
155
+ }
156
+ const id = checkId(raw.id, `${evidencePath}.id`, issues) ? raw.id : "";
157
+ const assertionIds = raw.assertionIds;
158
+ if (raw.kind === "fixture") {
159
+ checkSortedUniqueStrings(assertionIds, `${evidencePath}.assertionIds`, issues, { nonEmpty: true });
160
+ } else if (assertionIds !== undefined) {
161
+ checkSortedUniqueStrings(assertionIds, `${evidencePath}.assertionIds`, issues, { nonEmpty: true });
162
+ }
163
+ const key = `${String(raw.kind)}:${id}:${JSON.stringify(assertionIds ?? [])}`;
164
+ if (seen.has(key)) issues.push(`${evidencePath} duplicates an earlier evidence reference`);
165
+ seen.add(key);
166
+ });
167
+ }
168
+
169
+ /**
170
+ * Validate one versioned compatibility manifest without importing provider or Lab state.
171
+ * Keeping this as a leaf lets future CLI/GUI readers load contracts without activating Lab.
172
+ */
173
+ export function compatibilityManifestIssues(value: unknown): string[] {
174
+ const issues: string[] = [];
175
+ if (!isRecord(value)) return ["manifest must be an object"];
176
+ checkKnownKeys(value, ["schemaVersion", "id", "version", "subject", "claims"], "", issues);
177
+ if (value.schemaVersion !== COMPATIBILITY_MANIFEST_SCHEMA_VERSION) {
178
+ issues.push(`schemaVersion must be ${COMPATIBILITY_MANIFEST_SCHEMA_VERSION}`);
179
+ }
180
+ checkId(value.id, "id", issues);
181
+ checkNonBlank(value.version, "version", issues);
182
+
183
+ if (!isRecord(value.subject)) {
184
+ issues.push("subject must be an object");
185
+ } else {
186
+ checkKnownKeys(
187
+ value.subject,
188
+ ["providerId", "baseUrl", "adapterId", "authMode", "inboundProtocol", "upstreamProtocol", "modelIds"],
189
+ "subject",
190
+ issues,
191
+ );
192
+ checkId(value.subject.providerId, "subject.providerId", issues);
193
+ checkNormalizedBaseUrl(value.subject.baseUrl, "subject.baseUrl", issues);
194
+ checkId(value.subject.adapterId, "subject.adapterId", issues);
195
+ if (!["forward", "key", "oauth", "local"].includes(String(value.subject.authMode))) {
196
+ issues.push("subject.authMode must be forward, key, oauth, or local");
197
+ }
198
+ if (!["responses", "chat", "messages"].includes(String(value.subject.inboundProtocol))) {
199
+ issues.push("subject.inboundProtocol must be responses, chat, or messages");
200
+ }
201
+ checkNonBlank(value.subject.upstreamProtocol, "subject.upstreamProtocol", issues);
202
+ checkSortedUniqueStrings(value.subject.modelIds, "subject.modelIds", issues, { nonEmpty: true });
203
+ }
204
+
205
+ if (!Array.isArray(value.claims) || value.claims.length === 0) {
206
+ issues.push("claims must be a non-empty array");
207
+ return issues;
208
+ }
209
+ const claimIds = new Set<string>();
210
+ const claimFeatures = new Set<string>();
211
+ value.claims.forEach((raw, index) => {
212
+ const path = `claims[${index}]`;
213
+ if (!isRecord(raw)) {
214
+ issues.push(`${path} must be an object`);
215
+ return;
216
+ }
217
+ checkKnownKeys(raw, ["id", "feature", "disposition", "summary", "limitation", "evidence"], path, issues);
218
+ const id = checkId(raw.id, `${path}.id`, issues) ? raw.id : "";
219
+ if (id && claimIds.has(id)) issues.push(`${path}.id duplicates ${id}`);
220
+ if (id) claimIds.add(id);
221
+ if (typeof raw.feature !== "string" || !FEATURE_PATTERN.test(raw.feature)) {
222
+ issues.push(`${path}.feature must be a dotted stable feature key`);
223
+ } else if (claimFeatures.has(raw.feature)) {
224
+ issues.push(`${path}.feature duplicates ${raw.feature}`);
225
+ } else {
226
+ claimFeatures.add(raw.feature);
227
+ }
228
+ if (!DISPOSITIONS.has(String(raw.disposition))) {
229
+ issues.push(`${path}.disposition is invalid`);
230
+ }
231
+ checkNonBlank(raw.summary, `${path}.summary`, issues);
232
+ if (raw.disposition !== "passthrough") {
233
+ checkNonBlank(raw.limitation, `${path}.limitation`, issues);
234
+ } else if (raw.limitation !== undefined) {
235
+ issues.push(`${path}.limitation must be omitted for passthrough claims`);
236
+ }
237
+ checkEvidence(raw.evidence, `${path}.evidence`, issues);
238
+ });
239
+ return issues;
240
+ }
241
+
242
+ function deepFreeze<T>(value: T, seen = new WeakSet<object>()): Readonly<T> {
243
+ if (!value || typeof value !== "object" || seen.has(value)) return value;
244
+ seen.add(value);
245
+ for (const nested of Object.values(value as Record<string, unknown>)) deepFreeze(nested, seen);
246
+ return Object.freeze(value);
247
+ }
248
+
249
+ export function defineCompatibilityManifest<T extends CompatibilityManifestV1>(manifest: T): Readonly<T> {
250
+ const issues = compatibilityManifestIssues(manifest);
251
+ if (issues.length > 0) throw new TypeError(`Invalid compatibility manifest ${manifest.id}: ${issues.join("; ")}`);
252
+ return deepFreeze(manifest);
253
+ }
@@ -0,0 +1,121 @@
1
+ import { defineCompatibilityManifest } from "./manifest";
2
+
3
+ const FIXTURE_ID = "openai-codex-forward-gpt56-sol-v1";
4
+
5
+ /**
6
+ * First deliberately narrow compatibility slice: one exact native Codex-login model.
7
+ * Broader model/provider claims require their own fixtures instead of inheriting this row.
8
+ */
9
+ export const OPENAI_CODEX_FORWARD_GPT56_SOL_MANIFEST = defineCompatibilityManifest({
10
+ schemaVersion: 1,
11
+ id: "openai.codex-forward.gpt-5-6-sol.responses",
12
+ version: "1.3.0",
13
+ subject: {
14
+ providerId: "openai",
15
+ baseUrl: "https://chatgpt.com/backend-api/codex",
16
+ adapterId: "openai-responses",
17
+ authMode: "forward",
18
+ inboundProtocol: "responses",
19
+ upstreamProtocol: "openai-responses",
20
+ modelIds: ["gpt-5.6-sol"],
21
+ },
22
+ claims: [
23
+ {
24
+ id: "custom-tools",
25
+ feature: "request.custom_tools",
26
+ disposition: "passthrough",
27
+ summary: "Native custom-tool declarations retain their Responses representation.",
28
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["custom-tool-preserved"] }],
29
+ },
30
+ {
31
+ id: "prompt-cache-key",
32
+ feature: "request.prompt_cache_key",
33
+ disposition: "passthrough",
34
+ summary: "The caller's prompt cache key is forwarded unchanged.",
35
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["prompt-cache-key-preserved"] }],
36
+ },
37
+ {
38
+ id: "previous-response-id",
39
+ feature: "request.previous_response_id",
40
+ disposition: "translated",
41
+ summary: "Continuation is owned by the proxy rather than the ChatGPT backend field.",
42
+ limitation: "OpenCodex expands remembered input locally and removes previous_response_id before dispatch.",
43
+ evidence: [
44
+ { kind: "fixture", id: FIXTURE_ID, assertionIds: ["previous-response-id-removed"] },
45
+ { kind: "lab-scenario", id: "codex-core.protocol.previous-response-replay" },
46
+ ],
47
+ },
48
+ {
49
+ id: "orphan-tool-output",
50
+ feature: "continuation.orphan_tool_output",
51
+ disposition: "degraded",
52
+ summary: "An output whose prior call is unavailable remains visible to the model.",
53
+ limitation: "The orphan output is converted to user text because the forward backend cannot accept the unmatched item.",
54
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["orphan-output-converted"] }],
55
+ },
56
+ {
57
+ id: "max-output-tokens",
58
+ feature: "request.max_output_tokens",
59
+ disposition: "unsupported",
60
+ summary: "The ChatGPT Codex forward route does not receive max_output_tokens.",
61
+ limitation: "The field is removed before dispatch to avoid a backend parameter rejection.",
62
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["max-output-tokens-removed"] }],
63
+ },
64
+ {
65
+ id: "metadata",
66
+ feature: "request.metadata",
67
+ disposition: "unsupported",
68
+ summary: "Caller metadata is not forwarded to the ChatGPT Codex backend.",
69
+ limitation: "The field is removed before dispatch.",
70
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["metadata-removed"] }],
71
+ },
72
+ {
73
+ id: "system-input-messages",
74
+ feature: "request.input.system_messages",
75
+ disposition: "translated",
76
+ summary: "Text-only input system messages are folded into top-level instructions.",
77
+ limitation: "The destination does not accept system-role input items; multimodal system messages stay unchanged rather than being dropped.",
78
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["system-message-folded", "system-message-removed"] }],
79
+ },
80
+ {
81
+ id: "truncation",
82
+ feature: "request.truncation",
83
+ disposition: "unsupported",
84
+ summary: "The ChatGPT Codex forward route does not receive truncation.",
85
+ limitation: "The field is removed only for the canonical forward destination; public and custom Responses providers keep it.",
86
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["truncation-removed"] }],
87
+ },
88
+ {
89
+ id: "prompt-cache-breakpoint",
90
+ feature: "request.prompt_cache_breakpoint",
91
+ disposition: "unsupported",
92
+ summary: "Client-only prompt cache breakpoint markers do not reach the forward backend.",
93
+ limitation: "Markers are removed recursively from input within bounded depth and node budgets.",
94
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["prompt-cache-breakpoint-removed"] }],
95
+ },
96
+ {
97
+ id: "unstored-item-reference",
98
+ feature: "continuation.item_reference",
99
+ disposition: "degraded",
100
+ summary: "Unpersisted item references are omitted from store-false continuations.",
101
+ limitation: "The referenced item cannot exist at the backend when store is false; tool call_id pairs remain unchanged.",
102
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["unstored-item-reference-removed"] }],
103
+ },
104
+ {
105
+ id: "prompt-cache-retention",
106
+ feature: "request.prompt_cache_retention",
107
+ disposition: "unsupported",
108
+ summary: "The retired retention field is not sent for gpt-5.6-sol.",
109
+ limitation: "The field is removed without inventing a replacement prompt_cache_options value.",
110
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["prompt-cache-retention-removed"] }],
111
+ },
112
+ {
113
+ id: "prompt-cache-options",
114
+ feature: "request.prompt_cache_options",
115
+ disposition: "unsupported",
116
+ summary: "The ChatGPT Codex forward route does not receive public prompt cache options.",
117
+ limitation: "The field is removed only for the canonical forward destination; public and custom Responses providers keep it.",
118
+ evidence: [{ kind: "fixture", id: FIXTURE_ID, assertionIds: ["prompt-cache-options-removed"] }],
119
+ },
120
+ ],
121
+ } as const);