@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,16 +1,56 @@
1
+ import { isValidModelDiscoveryModelId, MODEL_DISCOVERY_MAX_MODELS } from "./model-discovery-limits";
2
+ import { isModelCacheGenerationCurrent } from "../codex/model-cache";
3
+
1
4
  // Google Antigravity (Cloud Code Assist) bundled model list.
2
5
  //
3
6
  // Single source of truth: the Antigravity `:fetchAvailableModels` backend, the same one the `agy`
4
7
  // CLI resolves labels against. The ids below separate CCA wire ids, collapsed picker entries,
5
8
  // and hidden compatibility aliases for saved selections. The CCA envelope's `model` field must
6
9
  // receive the wire id (for example "Gemini 3.1 Pro (High)" => gemini-pro-agent), while the
7
- // picker exposes collapsed base models with reasoning-effort routing.
10
+ // picker exposes collapsed known base models only when CCA returns every known tier; unknown
11
+ // returned wire ids remain visible so they stay directly routable.
8
12
 
9
13
  // ── Wire IDs (what CCA :fetchAvailableModels returns) ──
14
+
15
+ /** Current Antigravity Flash generation. */
16
+ const GEMINI_FLASH_CURRENT = "gemini-3.7-flash";
17
+
18
+ /**
19
+ * Wire ID that CCA actually accepts for the current Flash generation.
20
+ * Google renamed the model to include a `-tiered` suffix; the picker-visible
21
+ * ID stays `gemini-3.7-flash` (stripped by `pickerModelIdForDiscoveredWireId`).
22
+ */
23
+ const GEMINI_FLASH_WIRE_ID = "gemini-3.7-flash-tiered";
24
+
25
+ /**
26
+ * Retired Flash ids → the reasoning tier they used to encode.
27
+ *
28
+ * Google pulls the previous Flash model from CCA almost immediately when the next
29
+ * one ships, so a saved selection cannot keep pointing at it. A flat alias would
30
+ * strand the user's tier: `resolveAntigravityEffortWireModel` rule 1 treats any
31
+ * alias as "the suffix IS the effort" and deliberately sends no thinkingConfig, so
32
+ * `gemini-3.6-flash-high` would silently become an untiered 3.7 call. Carrying the
33
+ * level here preserves what the user actually chose.
34
+ *
35
+ * 3.7 exposes tiers through `thinkingLevel` on ONE wire id rather than through
36
+ * suffixed wire ids, which is why the mapping is id → level and not id → id.
37
+ */
38
+ const RETIRED_FLASH_TIERS: Record<string, string> = {
39
+ // 3.6 generation.
40
+ "gemini-3.6-flash": "medium", // bare base carried a medium default
41
+ "gemini-3.6-flash-low": "low",
42
+ "gemini-3.6-flash-medium": "medium",
43
+ "gemini-3.6-flash-high": "high",
44
+ // 3.5 generation — these already pointed at 3.6 wire ids, which are now dead too.
45
+ "gemini-3.5-flash-extra-low": "low",
46
+ "gemini-3.5-flash-low": "medium",
47
+ "gemini-3.5-flash-mid": "medium",
48
+ "gemini-3.5-flash-high": "high",
49
+ "gemini-3-flash-agent": "high",
50
+ };
51
+
10
52
  const ANTIGRAVITY_WIRE_MODELS = [
11
- "gemini-3.6-flash-low",
12
- "gemini-3.6-flash-medium",
13
- "gemini-3.6-flash-high",
53
+ "gemini-3.7-flash-tiered",
14
54
  "gemini-3.1-pro-low",
15
55
  "gemini-pro-agent",
16
56
  "gemini-3.1-flash-image",
@@ -19,11 +59,91 @@ const ANTIGRAVITY_WIRE_MODELS = [
19
59
  "gpt-oss-120b-medium",
20
60
  ];
21
61
 
62
+ const ANTIGRAVITY_PICKER_MODEL_BY_WIRE_ID: Record<string, string> = {
63
+ "gemini-3.1-pro-low": "gemini-3.1-pro",
64
+ "gemini-pro-agent": "gemini-3.1-pro",
65
+ };
66
+
67
+ const ANTIGRAVITY_WIRE_IDS_BY_PICKER_MODEL: Record<string, string[]> = Object.entries(
68
+ ANTIGRAVITY_PICKER_MODEL_BY_WIRE_ID,
69
+ ).reduce<Record<string, string[]>>((out, [wireId, pickerId]) => {
70
+ (out[pickerId] ??= []).push(wireId);
71
+ return out;
72
+ }, {});
73
+
74
+ const ANTIGRAVITY_DISCOVERY_EFFORTS = ["low", "medium", "high"] as const;
75
+ type AntigravityDiscoveryEffort = typeof ANTIGRAVITY_DISCOVERY_EFFORTS[number];
76
+ type AntigravityEffortWireModelIds = Partial<Record<AntigravityDiscoveryEffort, string>>;
77
+
78
+ function isAntigravityDiscoveryEffort(value: string): value is AntigravityDiscoveryEffort {
79
+ return (ANTIGRAVITY_DISCOVERY_EFFORTS as readonly string[]).includes(value);
80
+ }
81
+
82
+ function pickerModelIdForDiscoveredWireId(
83
+ wireId: string,
84
+ info: Record<string, unknown>,
85
+ available: ReadonlyMap<string, Record<string, unknown>>,
86
+ ): string {
87
+ const explicitPickerId = Object.hasOwn(ANTIGRAVITY_PICKER_MODEL_BY_WIRE_ID, wireId)
88
+ ? ANTIGRAVITY_PICKER_MODEL_BY_WIRE_ID[wireId]
89
+ : undefined;
90
+ if (explicitPickerId) {
91
+ const requiredWireIds = Object.hasOwn(ANTIGRAVITY_WIRE_IDS_BY_PICKER_MODEL, explicitPickerId)
92
+ ? ANTIGRAVITY_WIRE_IDS_BY_PICKER_MODEL[explicitPickerId] ?? []
93
+ : [];
94
+ if (requiredWireIds.every(id => available.has(id))) return explicitPickerId;
95
+ }
96
+
97
+ // CCA uses a single `-tiered` row for models whose effort levels ride on the
98
+ // request's thinkingLevel field. Keep this generic so new tiered models do not
99
+ // require another provider-specific ID mapping.
100
+ if (wireId.endsWith("-tiered")) {
101
+ const baseId = wireId.slice(0, -"-tiered".length);
102
+ if (isKnownAntigravityPickerModelId(baseId)) return baseId;
103
+ }
104
+
105
+ const effortMatch = /^(.*)-(low|medium|high)$/.exec(wireId);
106
+ if (effortMatch) {
107
+ const baseId = effortMatch[1]!;
108
+ if (isKnownAntigravityPickerModelId(baseId)
109
+ && ANTIGRAVITY_DISCOVERY_EFFORTS.every(effort => available.has(`${baseId}-${effort}`))) {
110
+ return baseId;
111
+ }
112
+ }
113
+
114
+ // Display labels are a LAST resort, never a first one. CCA labels a tier row
115
+ // "Gemini 3.7 Flash (High)", which slugs to `gemini-3.7-flash-high` — a per-tier
116
+ // picker row that re-splits exactly the ladder the collapse rules above just
117
+ // joined, and that carries no effort ladder of its own. Consulting the label
118
+ // first (the #1897 regression) turned every collapsed base model back into three
119
+ // suffix rows and stripped reasoning-effort control from the picker.
120
+ //
121
+ // The label still earns its keep where nothing else can speak: an id Google has
122
+ // renamed on the wire while keeping a stable public name.
123
+ const displayModelId = antigravityDisplayModelId(info.displayName, wireId);
124
+ if (displayModelId && !collapsesIntoKnownPickerModel(displayModelId)) return displayModelId;
125
+
126
+ return wireId;
127
+ }
128
+
129
+ /**
130
+ * Whether a display-derived id is really a tier of a picker-visible base model.
131
+ *
132
+ * `gemini-3.7-flash-high` looks like a model id and is not one: it is the "high"
133
+ * rung of `gemini-3.7-flash`, whose ladder lives in ANTIGRAVITY_MODEL_EFFORTS.
134
+ * Publishing it as its own row is what breaks effort selection.
135
+ */
136
+ function collapsesIntoKnownPickerModel(candidateId: string): boolean {
137
+ const effortMatch = /^(.*)-(low|medium|high)$/.exec(candidateId);
138
+ const baseId = effortMatch?.[1];
139
+ return baseId !== undefined && isKnownAntigravityPickerModelId(baseId);
140
+ }
141
+
22
142
  // ── Effort ladders per collapsed base model ──
23
143
  // Gemini models: effort → wire model suffix (official agy UI pattern).
24
144
  // Claude Opus: effort → thinkingConfig.thinkingLevel (CLIProxyAPI proven pattern).
25
145
  export const ANTIGRAVITY_MODEL_EFFORTS: Record<string, string[]> = {
26
- "gemini-3.6-flash": ["low", "medium", "high"],
146
+ "gemini-3.7-flash": ["low", "medium", "high"],
27
147
  "gemini-3.1-pro": ["low", "high"],
28
148
  "claude-sonnet-4-6": ["low", "medium", "high", "max"],
29
149
  "claude-opus-4-6-thinking": ["low", "medium", "high", "max"],
@@ -31,24 +151,60 @@ export const ANTIGRAVITY_MODEL_EFFORTS: Record<string, string[]> = {
31
151
 
32
152
  // ── Effort → wire model map for Gemini base models ──
33
153
  const ANTIGRAVITY_EFFORT_WIRE_MAP: Record<string, Record<string, string>> = {
34
- "gemini-3.6-flash": {
35
- low: "gemini-3.6-flash-low",
36
- medium: "gemini-3.6-flash-medium",
37
- high: "gemini-3.6-flash-high",
38
- },
39
154
  "gemini-3.1-pro": {
40
155
  low: "gemini-3.1-pro-low",
41
156
  high: "gemini-pro-agent",
42
157
  },
43
158
  };
44
159
 
160
+ function completeDiscoveredEffortWireModelIds(
161
+ pickerId: string,
162
+ available: ReadonlyMap<string, Record<string, unknown>>,
163
+ ): AntigravityEffortWireModelIds | undefined {
164
+ const explicitEffortMap = ANTIGRAVITY_EFFORT_WIRE_MAP[pickerId];
165
+ if (explicitEffortMap && Object.values(explicitEffortMap).every(wireId => available.has(wireId))) {
166
+ return { ...explicitEffortMap };
167
+ }
168
+
169
+ if (!isKnownAntigravityPickerModelId(pickerId)) return undefined;
170
+ const suffixEffortMap: AntigravityEffortWireModelIds = {};
171
+ for (const effort of ANTIGRAVITY_DISCOVERY_EFFORTS) {
172
+ const wireId = `${pickerId}-${effort}`;
173
+ if (!available.has(wireId)) return undefined;
174
+ suffixEffortMap[effort] = wireId;
175
+ }
176
+ return suffixEffortMap;
177
+ }
178
+
45
179
  // ── Default effort per Gemini base model ──
46
180
  const ANTIGRAVITY_DEFAULT_EFFORT: Record<string, string> = {
47
- "gemini-3.6-flash": "medium",
48
181
  "gemini-3.1-pro": "high",
49
182
  };
50
183
 
51
- const ANTIGRAVITY_THINKING_LEVELS = new Set(["minimal", "low", "medium", "high"]);
184
+ /**
185
+ * Gemini base models whose efforts ride on `thinkingLevel` against a single wire id
186
+ * instead of suffixed wire ids, with the level applied when the caller names none.
187
+ */
188
+ const ANTIGRAVITY_THINKING_LEVEL_MODELS: Record<string, string> = {
189
+ "gemini-3.7-flash": "medium",
190
+ };
191
+
192
+ // `minimal` is deliberately absent: Google documents it as unsupported for the current
193
+ // Flash generation, where it is an error rather than a quieter tier.
194
+ const ANTIGRAVITY_THINKING_LEVELS = new Set(["low", "medium", "high"]);
195
+
196
+ /**
197
+ * Picker-visible model IDs whose CCA wire ID differs (the `-tiered` rename).
198
+ * Models not listed here use themselves as the wire ID.
199
+ */
200
+ const ANTIGRAVITY_PICKER_TO_WIRE: Record<string, string> = {
201
+ "gemini-3.7-flash": GEMINI_FLASH_WIRE_ID,
202
+ };
203
+
204
+ /** Map a picker-visible base model to its CCA wire ID. Identity when no mapping exists. */
205
+ function pickerToWireId(pickerId: string): string {
206
+ return ANTIGRAVITY_PICKER_TO_WIRE[pickerId] ?? pickerId;
207
+ }
52
208
 
53
209
  function resolveAntigravityThinkingLevel(effort: string): string | undefined {
54
210
  if (effort === "xhigh" || effort === "max" || effort === "ultra") return "high";
@@ -65,16 +221,17 @@ const ANTIGRAVITY_VISIBLE_MODEL_ALIASES: Record<string, string> = {
65
221
  // Wire suffix IDs are identity aliases — they resolve to themselves so saved configs
66
222
  // with explicit suffixes (e.g. gemini-3.6-flash-low) continue to work.
67
223
  const ANTIGRAVITY_COMPATIBILITY_MODEL_ALIASES: Record<string, string> = {
68
- "gemini-3.6-flash-low": "gemini-3.6-flash-low",
69
- "gemini-3.6-flash-medium": "gemini-3.6-flash-medium",
70
- "gemini-3.6-flash-high": "gemini-3.6-flash-high",
71
224
  "gemini-3.1-pro-low": "gemini-3.1-pro-low",
72
225
  "gemini-pro-agent": "gemini-pro-agent",
73
- "gemini-3.5-flash-extra-low": "gemini-3.6-flash-low",
74
- "gemini-3.5-flash-low": "gemini-3.6-flash-medium",
75
- "gemini-3.5-flash-mid": "gemini-3.6-flash-medium",
76
- "gemini-3.5-flash-high": "gemini-3.6-flash-high",
77
- "gemini-3-flash-agent": "gemini-3.6-flash-high",
226
+ // ── Retired Flash generations ──
227
+ // Google takes the previous Antigravity Flash model offline almost immediately
228
+ // once its successor ships, so 3.6 (and the 3.5 ids that used to land on it)
229
+ // route to 3.7. These stay in the alias map — not only in the tier map below —
230
+ // because `parseAntigravityAvailableModels` uses THIS map to keep a stale CCA
231
+ // payload from republishing a dead wire id as a picker row.
232
+ ...Object.fromEntries(
233
+ Object.keys(RETIRED_FLASH_TIERS).map(retired => [retired, GEMINI_FLASH_WIRE_ID]),
234
+ ),
78
235
  };
79
236
 
80
237
  export const ANTIGRAVITY_MODEL_ALIASES: Record<string, string> = {
@@ -84,7 +241,7 @@ export const ANTIGRAVITY_MODEL_ALIASES: Record<string, string> = {
84
241
 
85
242
  // Picker-visible: collapsed base models only.
86
243
  export const ANTIGRAVITY_MODELS = [
87
- "gemini-3.6-flash",
244
+ GEMINI_FLASH_CURRENT,
88
245
  "gemini-3.1-pro",
89
246
  "gemini-3.1-flash-image",
90
247
  "claude-sonnet-4-6",
@@ -92,22 +249,24 @@ export const ANTIGRAVITY_MODELS = [
92
249
  "gpt-oss-120b-medium",
93
250
  ];
94
251
 
252
+ function isKnownAntigravityPickerModelId(value: string): boolean {
253
+ return isValidModelDiscoveryModelId(value) && ANTIGRAVITY_MODELS.includes(value);
254
+ }
255
+
95
256
  // Context windows from the upstream `:fetchAvailableModels` maxTokens per model.
96
257
  const ANTIGRAVITY_WIRE_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
97
- "gemini-3.6-flash-low": 1_048_576,
98
- "gemini-3.6-flash-medium": 1_048_576,
99
- "gemini-3.6-flash-high": 1_048_576,
258
+ "gemini-3.7-flash-tiered": 1_048_576,
100
259
  "gemini-3.1-pro-low": 1_048_576,
101
260
  "gemini-pro-agent": 1_048_576,
102
261
  "gemini-3.1-flash-image": 1_048_576,
103
- "claude-sonnet-4-6": 200_000,
104
- "claude-opus-4-6-thinking": 1_000_000,
262
+ "claude-sonnet-4-6": 250_000,
263
+ "claude-opus-4-6-thinking": 250_000,
105
264
  "gpt-oss-120b-medium": 131_072,
106
265
  };
107
266
 
108
267
  export const ANTIGRAVITY_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
109
268
  // Collapsed base IDs — explicit entries for the picker.
110
- "gemini-3.6-flash": 1_048_576,
269
+ "gemini-3.7-flash": 1_048_576,
111
270
  "gemini-3.1-pro": 1_048_576,
112
271
  // Wire IDs and aliases via derivation.
113
272
  ...ANTIGRAVITY_WIRE_MODEL_CONTEXT_WINDOWS,
@@ -119,8 +278,281 @@ export const ANTIGRAVITY_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
119
278
  ),
120
279
  };
121
280
 
122
- export function resolveAntigravityWireModelId(modelId: string): string {
123
- return ANTIGRAVITY_MODEL_ALIASES[modelId] ?? modelId;
281
+ export const ANTIGRAVITY_MODEL_INPUT_MODALITIES: Record<string, string[]> = {
282
+ // Google documents 3.7 Flash as also accepting video, audio and PDF, but this proxy
283
+ // carries only text and image parts (`OcxImageContent`, src/types.ts) and the Codex
284
+ // catalog normalizes `input_modalities` against a closed enum. Advertising a modality
285
+ // the wire cannot carry would be a promise we break at request time.
286
+ "gemini-3.7-flash": ["text", "image"],
287
+ "gemini-3.1-pro": ["text", "image"],
288
+ "gemini-3.1-flash-image": ["text", "image"],
289
+ "claude-sonnet-4-6": ["text", "image"],
290
+ "claude-opus-4-6-thinking": ["text", "image"],
291
+ "gpt-oss-120b-medium": ["text"],
292
+ };
293
+
294
+ export interface AntigravityAvailableModel {
295
+ id: string;
296
+ /** CCA model id used by the agent envelope when `id` comes from display metadata. */
297
+ wireModelId: string;
298
+ /** Complete effort-to-wire mapping retained for collapsed discovered tier sets. */
299
+ effortWireModelIds?: AntigravityEffortWireModelIds;
300
+ contextWindow?: number;
301
+ inputModalities?: string[];
302
+ }
303
+
304
+ function antigravityRecord(value: unknown): Record<string, unknown> | undefined {
305
+ return value !== null && typeof value === "object" && !Array.isArray(value)
306
+ ? value as Record<string, unknown>
307
+ : undefined;
308
+ }
309
+
310
+ function antigravityPositiveInteger(value: unknown): number | undefined {
311
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : undefined;
312
+ }
313
+
314
+ interface DiscoveredWireModelMapping {
315
+ readonly models: ReadonlyMap<string, string>;
316
+ readonly effortModels: ReadonlyMap<string, AntigravityEffortWireModelIds>;
317
+ readonly generation?: { provider: string; cacheGeneration: string };
318
+ }
319
+
320
+ const discoveredWireModelsByBaseUrl = new Map<string, DiscoveredWireModelMapping>();
321
+
322
+ /**
323
+ * Strip trailing slashes without a backtracking regex.
324
+ *
325
+ * `/\/+$/` is polynomial-ReDoS on attacker-influenceable input (CodeQL js/polynomial-redos):
326
+ * a long run of slashes makes the engine retry every suffix. The base URL comes from provider
327
+ * config, which is not hostile in the ordinary case — but "not hostile today" is a property of
328
+ * the caller, not of this function, and a linear scan costs nothing.
329
+ */
330
+ function stripTrailingSlashes(value: string): string {
331
+ let end = value.length;
332
+ while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;
333
+ return end === value.length ? value : value.slice(0, end);
334
+ }
335
+
336
+ function antigravityBaseUrlKey(baseUrl: string | undefined): string | undefined {
337
+ if (typeof baseUrl !== "string" || !baseUrl.trim()) return undefined;
338
+ const trimmed = stripTrailingSlashes(baseUrl.trim());
339
+ try {
340
+ const url = new URL(trimmed);
341
+ url.hash = "";
342
+ url.search = "";
343
+ return stripTrailingSlashes(url.toString()).toLowerCase();
344
+ } catch {
345
+ return trimmed.toLowerCase();
346
+ }
347
+ }
348
+
349
+ /** Remember the wire ids returned by one live CCA discovery for request routing. */
350
+ export function registerAntigravityDiscoveredWireModels(
351
+ baseUrl: string | undefined,
352
+ models: readonly AntigravityAvailableModel[],
353
+ generation?: { provider: string; cacheGeneration: string },
354
+ ): void {
355
+ const key = antigravityBaseUrlKey(baseUrl);
356
+ if (!key) return;
357
+ const wireModels = new Map<string, string>();
358
+ const effortModels = new Map<string, AntigravityEffortWireModelIds>();
359
+ for (const model of models) {
360
+ wireModels.set(model.id, model.wireModelId);
361
+ if (model.effortWireModelIds) effortModels.set(model.id, { ...model.effortWireModelIds });
362
+ }
363
+ discoveredWireModelsByBaseUrl.set(key, {
364
+ models: wireModels,
365
+ effortModels,
366
+ ...(generation ? { generation } : {}),
367
+ });
368
+ }
369
+
370
+ function discoveredAntigravityMapping(
371
+ baseUrl: string | undefined,
372
+ ): DiscoveredWireModelMapping | undefined {
373
+ const key = antigravityBaseUrlKey(baseUrl);
374
+ if (!key) return undefined;
375
+ const mapping = discoveredWireModelsByBaseUrl.get(key);
376
+ if (!mapping) return undefined;
377
+ if (mapping.generation
378
+ && !isModelCacheGenerationCurrent(mapping.generation.provider, mapping.generation.cacheGeneration)) {
379
+ discoveredWireModelsByBaseUrl.delete(key);
380
+ return undefined;
381
+ }
382
+ return mapping;
383
+ }
384
+
385
+ function discoveredAntigravityWireModelId(
386
+ modelId: string,
387
+ baseUrl: string | undefined,
388
+ ): string | undefined {
389
+ return discoveredAntigravityMapping(baseUrl)?.models.get(modelId);
390
+ }
391
+
392
+ function discoveredAntigravityEffortWireModelId(
393
+ modelId: string,
394
+ effort: string | undefined,
395
+ baseUrl: string | undefined,
396
+ ): string | undefined {
397
+ const effortMap = discoveredAntigravityMapping(baseUrl)?.effortModels.get(modelId);
398
+ if (!effortMap) return undefined;
399
+
400
+ const requestedEffort = effort ? resolveAntigravityThinkingLevel(effort) : undefined;
401
+ if (requestedEffort && isAntigravityDiscoveryEffort(requestedEffort) && effortMap[requestedEffort]) {
402
+ return effortMap[requestedEffort];
403
+ }
404
+
405
+ const defaultEffort = ANTIGRAVITY_DEFAULT_EFFORT[modelId]
406
+ ?? ANTIGRAVITY_THINKING_LEVEL_MODELS[modelId];
407
+ if (defaultEffort && isAntigravityDiscoveryEffort(defaultEffort) && effortMap[defaultEffort]) {
408
+ return effortMap[defaultEffort];
409
+ }
410
+ return Object.values(effortMap)[0];
411
+ }
412
+
413
+ /**
414
+ * Convert the CCA display label used by `agy` into its public model selector.
415
+ *
416
+ * The wire id is authoritative for requests, while the label is authoritative for the
417
+ * user-facing selector when Google has renamed or re-tiered a model. Keep both instead
418
+ * of maintaining a provider-specific list of known model names.
419
+ */
420
+ function antigravityDisplayModelId(displayName: unknown, wireId: string): string | undefined {
421
+ if (typeof displayName !== "string") return undefined;
422
+ const label = displayName.trim();
423
+ if (!label || label.length > 512) return undefined;
424
+ const slug = (replaceDots: boolean): string => label
425
+ .normalize("NFKC")
426
+ .toLowerCase()
427
+ .replace(replaceDots ? /\./g : /\s+/g, replaceDots ? "-" : " ")
428
+ .replace(/[^a-z0-9.-]+/g, "-")
429
+ .replace(/-+/g, "-")
430
+ .replace(/^-|-$/g, "");
431
+ const preserved = slug(false);
432
+ const compact = slug(true);
433
+ if (!isValidModelDiscoveryModelId(preserved) && !isValidModelDiscoveryModelId(compact)) return undefined;
434
+ if (preserved === wireId || compact === wireId
435
+ || preserved === `${wireId}-thinking` || compact === `${wireId}-thinking`) {
436
+ return wireId;
437
+ }
438
+ return isValidModelDiscoveryModelId(preserved) ? preserved : compact;
439
+ }
440
+
441
+ /**
442
+ * Extract the CCA models that are valid for agent requests. The endpoint also returns tab,
443
+ * command, commit-message, transcription, and standalone image-generation models; those are not
444
+ * callable through the CCA agent envelope and must not be published to the Codex catalog.
445
+ */
446
+ export function parseAntigravityAvailableModels(
447
+ payload: unknown,
448
+ maxModels = MODEL_DISCOVERY_MAX_MODELS,
449
+ ): AntigravityAvailableModel[] | null {
450
+ const limit = Number.isSafeInteger(maxModels) && maxModels > 0
451
+ ? Math.min(maxModels, MODEL_DISCOVERY_MAX_MODELS)
452
+ : MODEL_DISCOVERY_MAX_MODELS;
453
+ const body = antigravityRecord(payload);
454
+ if (!body) return null;
455
+ const models = antigravityRecord(body?.models);
456
+ const sorts = Array.isArray(body?.agentModelSorts) ? body.agentModelSorts : undefined;
457
+ if (!models || !sorts) return null;
458
+
459
+ const ids: string[] = [];
460
+ for (const sort of sorts) {
461
+ const groups = antigravityRecord(sort)?.groups;
462
+ if (!Array.isArray(groups)) return null;
463
+ for (const group of groups) {
464
+ const modelIds = antigravityRecord(group)?.modelIds;
465
+ if (!Array.isArray(modelIds)) return null;
466
+ for (const id of modelIds) {
467
+ if (!isValidModelDiscoveryModelId(id)
468
+ || !Object.hasOwn(models, id)
469
+ || !antigravityRecord(models[id])
470
+ || ids.length >= limit) return null;
471
+ ids.push(id);
472
+ }
473
+ }
474
+ }
475
+ // This model is exposed by Antigravity's agent chat surface even though the discovery
476
+ // response groups it under image generation, so it never appears in agentModelSorts.
477
+ if (Array.isArray(body.imageGenerationModelIds)
478
+ && body.imageGenerationModelIds.includes("gemini-3.1-flash-image")
479
+ && Object.hasOwn(models, "gemini-3.1-flash-image")
480
+ && antigravityRecord(models["gemini-3.1-flash-image"])
481
+ && !ids.includes("gemini-3.1-flash-image")) {
482
+ if (ids.length >= limit) return null;
483
+ ids.push("gemini-3.1-flash-image");
484
+ }
485
+ // Newer CCA responses identify tiered Flash models through this index instead of
486
+ // adding their synthetic wire ids to agentModelSorts.
487
+ const tieredModelIds = antigravityRecord(body.tieredModelIds);
488
+ const flashTieredIds = tieredModelIds?.flash;
489
+ if (Array.isArray(flashTieredIds)) {
490
+ for (const id of flashTieredIds) {
491
+ if (!isValidModelDiscoveryModelId(id)
492
+ || !Object.hasOwn(models, id)
493
+ || !antigravityRecord(models[id])
494
+ || ids.length >= limit) return null;
495
+ const baseId = id.endsWith("-tiered") ? id.slice(0, -"-tiered".length) : id;
496
+ if (ids.some(agentId =>
497
+ agentId === id
498
+ || agentId === baseId
499
+ || ANTIGRAVITY_DISCOVERY_EFFORTS.some(effort => agentId === `${baseId}-${effort}`)
500
+ )) continue;
501
+ ids.push(id);
502
+ }
503
+ }
504
+
505
+ const available = new Map<string, Record<string, unknown>>();
506
+ for (const wireId of ids) {
507
+ const info = antigravityRecord(models[wireId]);
508
+ if (!info || available.has(wireId)) continue;
509
+ // Compatibility aliases are deliberately routed to NEWER wire ids for saved
510
+ // selections. CCA keeps serving retired generations (3.5/3.6 Flash tiers) in its
511
+ // agent list long after they stop being the model anyone should pick, so admitting
512
+ // them as independently discovered rows republishes exactly the dead tiers the
513
+ // alias map exists to retire. Routing for a saved id still works — it resolves
514
+ // through ANTIGRAVITY_MODEL_ALIASES — it just no longer gets its own picker row.
515
+ const alias = Object.hasOwn(ANTIGRAVITY_MODEL_ALIASES, wireId)
516
+ ? ANTIGRAVITY_MODEL_ALIASES[wireId]
517
+ : undefined;
518
+ if (alias && alias !== wireId) continue;
519
+ available.set(wireId, info);
520
+ }
521
+
522
+ const out: AntigravityAvailableModel[] = [];
523
+ const seen = new Set<string>();
524
+ for (const [wireId, info] of available) {
525
+ const id = pickerModelIdForDiscoveredWireId(wireId, info, available);
526
+ if (seen.has(id)) continue;
527
+ seen.add(id);
528
+ const effortWireModelIds = completeDiscoveredEffortWireModelIds(id, available);
529
+ out.push({
530
+ id,
531
+ wireModelId: wireId,
532
+ ...(effortWireModelIds ? { effortWireModelIds } : {}),
533
+ ...(antigravityPositiveInteger(info.maxTokens) ? { contextWindow: antigravityPositiveInteger(info.maxTokens) } : {}),
534
+ // Tri-state, deliberately not a ternary: `true` asserts image support,
535
+ // `false` asserts against it, and ABSENT is unknown. Collapsing absent into
536
+ // `["text"]` let routing read it as a confident `image: false` (#1796). The
537
+ // strict catalog still receives its `["text"]` compatibility default
538
+ // downstream via ensureStrictCatalogFields; only the routing-evidence
539
+ // channel stays honest about what was never asserted.
540
+ ...(info.supportsImages === true
541
+ ? { inputModalities: ["text", "image"] as string[] }
542
+ : info.supportsImages === false
543
+ ? { inputModalities: ["text"] as string[] }
544
+ : {}),
545
+ });
546
+ }
547
+ return out;
548
+ }
549
+
550
+ export function resolveAntigravityWireModelId(modelId: string, baseUrl?: string): string {
551
+ const discovered = discoveredAntigravityWireModelId(modelId, baseUrl);
552
+ if (discovered) return discovered;
553
+ return Object.hasOwn(ANTIGRAVITY_MODEL_ALIASES, modelId)
554
+ ? ANTIGRAVITY_MODEL_ALIASES[modelId]
555
+ : modelId;
124
556
  }
125
557
 
126
558
  /**
@@ -132,6 +564,11 @@ export function isAntigravitySuffixModelId(modelId: string): boolean {
132
564
  return !(ANTIGRAVITY_MODELS as string[]).includes(modelId);
133
565
  }
134
566
 
567
+ /** The reasoning tier a retired Flash id used to encode, if it is one. */
568
+ export function retiredAntigravityFlashTier(modelId: string): string | undefined {
569
+ return Object.hasOwn(RETIRED_FLASH_TIERS, modelId) ? RETIRED_FLASH_TIERS[modelId] : undefined;
570
+ }
571
+
135
572
  /**
136
573
  * Resolve a picker-visible base model + optional reasoning effort to the CCA wire model ID.
137
574
  *
@@ -145,10 +582,57 @@ export function isAntigravitySuffixModelId(modelId: string): boolean {
145
582
  export function resolveAntigravityEffortWireModel(
146
583
  modelId: string,
147
584
  effort?: string,
585
+ baseUrl?: string,
148
586
  ): { wireModelId: string; thinkingLevel?: string } {
587
+ const discoveredEffortWireModelId = discoveredAntigravityEffortWireModelId(modelId, effort, baseUrl);
588
+ if (discoveredEffortWireModelId) return { wireModelId: discoveredEffortWireModelId };
589
+
590
+ // A collapsed picker row reports ONE representative wire id (whichever tier CCA
591
+ // listed first), so live discovery cannot describe a ladder — it can only name a
592
+ // single rung. Letting it answer for a base model we already have a ladder for
593
+ // collapses every effort onto that one rung: `gemini-3.1-pro` low and high both
594
+ // became `gemini-pro-agent`, and `gemini-3.7-flash` sent thinkingLevel=low against
595
+ // the `-high` wire id, a request that contradicts itself. Rules 1b/2/3 below own
596
+ // these models; discovery answers only for ids no rule knows.
597
+ const hasOwnEffortLadder = Object.hasOwn(ANTIGRAVITY_THINKING_LEVEL_MODELS, modelId)
598
+ || Object.hasOwn(ANTIGRAVITY_EFFORT_WIRE_MAP, modelId);
599
+ const discoveredWireModelId = hasOwnEffortLadder
600
+ ? undefined
601
+ : discoveredAntigravityWireModelId(modelId, baseUrl);
602
+ if (discoveredWireModelId && (discoveredWireModelId !== modelId || isAntigravitySuffixModelId(modelId))) {
603
+ const defaultLevel = ANTIGRAVITY_THINKING_LEVEL_MODELS[modelId];
604
+ return {
605
+ wireModelId: discoveredWireModelId,
606
+ ...(defaultLevel
607
+ ? { thinkingLevel: effort ? resolveAntigravityThinkingLevel(effort) ?? defaultLevel : defaultLevel }
608
+ : {}),
609
+ };
610
+ }
611
+
612
+ // Rule 0: retired Flash id — Google has taken the wire id offline, so route to the
613
+ // current generation and carry the tier the retired id encoded. This runs BEFORE the
614
+ // suffix check because those ids are aliases, and rule 1 would drop the tier.
615
+ const retiredTier = retiredAntigravityFlashTier(modelId);
616
+ if (retiredTier) {
617
+ return {
618
+ wireModelId: GEMINI_FLASH_WIRE_ID,
619
+ thinkingLevel: effort ? resolveAntigravityThinkingLevel(effort) ?? retiredTier : retiredTier,
620
+ };
621
+ }
622
+
149
623
  // Rule 1: suffix/compat alias — suffix IS the effort.
150
624
  if (isAntigravitySuffixModelId(modelId)) {
151
- return { wireModelId: resolveAntigravityWireModelId(modelId) };
625
+ return { wireModelId: resolveAntigravityWireModelId(modelId, baseUrl) };
626
+ }
627
+
628
+ // Rule 1b: single-wire-id Gemini model whose tiers ride on thinkingLevel. Without
629
+ // this the model falls to rule 5 and silently loses reasoning control entirely.
630
+ const defaultLevel = ANTIGRAVITY_THINKING_LEVEL_MODELS[modelId];
631
+ if (defaultLevel) {
632
+ return {
633
+ wireModelId: pickerToWireId(modelId),
634
+ thinkingLevel: effort ? resolveAntigravityThinkingLevel(effort) ?? defaultLevel : defaultLevel,
635
+ };
152
636
  }
153
637
 
154
638
  // Rule 2/3: mapped Gemini base model.
@@ -168,7 +652,7 @@ export function resolveAntigravityEffortWireModel(
168
652
  }
169
653
 
170
654
  // Rule 5: everything else.
171
- return { wireModelId: resolveAntigravityWireModelId(modelId) };
655
+ return { wireModelId: resolveAntigravityWireModelId(modelId, baseUrl) };
172
656
  }
173
657
 
174
658
 
@@ -189,6 +673,12 @@ const ANTIGRAVITY_USAGE_BASE_BY_ID: Record<string, string> = (() => {
189
673
  // If alias is itself a base/wire already mapped, keep that mapping.
190
674
  else if (rev[wire]) rev[alias] = rev[wire]!;
191
675
  }
676
+ // Retired ids keep their OWN identity for usage aggregation, overriding the alias
677
+ // pass above. Routing sends new 3.6 calls to 3.7, but a usage row written months ago
678
+ // records a model the user actually called: relabelling it would move historical spend
679
+ // onto a model that did not exist then, and away from the 3.6 price row that still
680
+ // prices it correctly. Retirement changes what we CALL, not what we RECORD.
681
+ for (const retired of Object.keys(RETIRED_FLASH_TIERS)) rev[retired] = retired;
192
682
  // Visible aliases that only appear in ANTIGRAVITY_VISIBLE_MODEL_ALIASES are already
193
683
  // included via ANTIGRAVITY_MODEL_ALIASES. Identity bases without effort maps remain.
194
684
  return rev;