@bitkyc08/opencodex 2.84.0 → 2.87.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 (518) hide show
  1. package/README.md +0 -4
  2. package/bin/ocx.mjs +61 -3
  3. package/gui/dist/assets/App-ZfYbLHkB.js +58 -0
  4. package/gui/dist/assets/App-wT3mXqFz.css +1 -0
  5. package/gui/dist/assets/{Tray-C9TGtwad.js → Tray-DCd-A1az.js} +1 -1
  6. package/gui/dist/assets/index-CfYDMj34.js +94 -0
  7. package/gui/dist/assets/index-DPeB9HpV.css +1 -0
  8. package/gui/dist/assets/quota-summary-ChvmKGOk.js +1 -0
  9. package/gui/dist/index.html +2 -2
  10. package/package.json +1 -2
  11. package/src/adapters/anthropic/beta-allowlist.ts +91 -11
  12. package/src/adapters/anthropic/beta-body-pairs.ts +93 -0
  13. package/src/adapters/anthropic/client-identity.ts +1 -1
  14. package/src/adapters/anthropic/passthrough.ts +16 -3
  15. package/src/adapters/anthropic-progress.ts +84 -0
  16. package/src/adapters/anthropic.ts +108 -21
  17. package/src/adapters/azure.ts +19 -1
  18. package/src/adapters/base.ts +2 -0
  19. package/src/adapters/claude-cli/adapter.ts +111 -23
  20. package/src/adapters/claude-cli/profiles.ts +2 -1
  21. package/src/adapters/claude-cli/stable-replay.ts +108 -0
  22. package/src/adapters/claude-cli/usage-admission.ts +230 -0
  23. package/src/adapters/client-fingerprint.ts +24 -0
  24. package/src/adapters/coding-agent/protocol.ts +1 -1
  25. package/src/adapters/coding-agent/turn.ts +40 -11
  26. package/src/adapters/cursor/arg-codec.ts +17 -5
  27. package/src/adapters/cursor/catalog.ts +8 -0
  28. package/src/adapters/cursor/effort-map.ts +3 -0
  29. package/src/adapters/cursor/freeform-args.ts +75 -0
  30. package/src/adapters/cursor/protobuf-events.ts +36 -23
  31. package/src/adapters/dsh-account.ts +97 -0
  32. package/src/adapters/google-antigravity-wire.ts +22 -1
  33. package/src/adapters/google.ts +37 -10
  34. package/src/adapters/openai-chat/messages.ts +4 -3
  35. package/src/adapters/openai-chat/passthrough.ts +8 -2
  36. package/src/adapters/openai-chat/reasoning-replay.ts +52 -0
  37. package/src/adapters/openai-chat/response-events.ts +59 -1
  38. package/src/adapters/openai-chat.ts +8 -5
  39. package/src/adapters/openai-responses/compaction-search-history.ts +14 -7
  40. package/src/adapters/openai-responses/passthrough.ts +57 -125
  41. package/src/adapters/openai-responses/request-strips.ts +25 -3
  42. package/src/adapters/openai-responses/transport.ts +81 -0
  43. package/src/adapters/qoder/adapter.ts +44 -3
  44. package/src/adapters/registry.ts +5 -0
  45. package/src/adapters/zed.ts +26 -1
  46. package/src/advisor/activity.ts +55 -0
  47. package/src/advisor/budget.ts +62 -0
  48. package/src/advisor/consult.ts +223 -0
  49. package/src/advisor/context.ts +238 -0
  50. package/src/advisor/disclosure.ts +20 -0
  51. package/src/advisor/evidence-tool.ts +21 -0
  52. package/src/advisor/evidence.ts +117 -0
  53. package/src/advisor/runtime.ts +353 -0
  54. package/src/advisor/settings.ts +144 -0
  55. package/src/advisor/state.ts +369 -0
  56. package/src/advisor/synthetic-tool.ts +33 -0
  57. package/src/bridge/errors.ts +24 -1
  58. package/src/bridge/internal.ts +3 -1
  59. package/src/bridge/response-json.ts +18 -3
  60. package/src/bridge/sse.ts +58 -8
  61. package/src/bridge/terminal-refusal.ts +59 -0
  62. package/src/chat/inbound.ts +30 -6
  63. package/src/chat/outbound.ts +5 -0
  64. package/src/claude/desktop-3p-library.ts +72 -7
  65. package/src/claude/desktop-3p.ts +75 -19
  66. package/src/claude/desktop-first-party.ts +1 -1
  67. package/src/claude/desktop-picker-platform.ts +4 -0
  68. package/src/claude/desktop-picker-profile.ts +11 -4
  69. package/src/claude/desktop-picker.ts +15 -8
  70. package/src/claude/desktop-profile.ts +10 -1
  71. package/src/claude/desktop-remote-store-io.ts +5 -3
  72. package/src/claude/desktop-system-proxy.ts +50 -4
  73. package/src/claude/inbound-content-options.ts +11 -0
  74. package/src/claude/inbound.ts +154 -50
  75. package/src/claude/intercept/local-ca.ts +8 -1
  76. package/src/claude/intercept/picker-ca-startup.ts +2 -1
  77. package/src/claude/intercept/picker-runtime.ts +6 -5
  78. package/src/claude/intercept/picker-trust-windows.ts +338 -0
  79. package/src/claude/intercept/picker-trust.ts +19 -0
  80. package/src/claude/intercept/port-policy.ts +30 -0
  81. package/src/claude/intercept/runtime.ts +97 -94
  82. package/src/claude/model-default-settings.ts +154 -0
  83. package/src/claude/model-info.ts +7 -7
  84. package/src/claude/outbound.ts +51 -19
  85. package/src/cli/account-api.ts +1 -0
  86. package/src/cli/account-policy-dto.ts +6 -0
  87. package/src/cli/account-policy.ts +34 -5
  88. package/src/cli/account-preservation.ts +44 -0
  89. package/src/cli/account.ts +8 -2
  90. package/src/cli/advisor.ts +165 -0
  91. package/src/cli/auxiliary-listener-preflight.ts +37 -0
  92. package/src/cli/capabilities-accounts.ts +20 -1
  93. package/src/cli/capabilities-agents-routing.ts +23 -2
  94. package/src/cli/capabilities-base.ts +39 -11
  95. package/src/cli/capabilities-observe-system.ts +63 -3
  96. package/src/cli/capabilities-provider-models.ts +11 -0
  97. package/src/cli/chatgpt-command.ts +35 -14
  98. package/src/cli/claude.ts +46 -6
  99. package/src/cli/codex-cli-update.ts +151 -41
  100. package/src/cli/codex-provider.ts +44 -0
  101. package/src/cli/combo-input.ts +10 -1
  102. package/src/cli/combo-result.ts +1 -1
  103. package/src/cli/combo.ts +2 -1
  104. package/src/cli/cross-home-owner.ts +17 -14
  105. package/src/cli/dispatch.ts +30 -5
  106. package/src/cli/doctor.ts +15 -1
  107. package/src/cli/ensure-desktop-cold-start.ts +382 -0
  108. package/src/cli/export-command.ts +1 -1
  109. package/src/cli/help.ts +4 -2
  110. package/src/cli/index.ts +14 -5
  111. package/src/cli/integration-plan-dto.ts +3 -0
  112. package/src/cli/log-history.ts +172 -0
  113. package/src/cli/models-runtime-subcommands.ts +1 -0
  114. package/src/cli/models-runtime.ts +72 -8
  115. package/src/cli/observe-stream.ts +2 -0
  116. package/src/cli/observe.ts +16 -4
  117. package/src/cli/provider.ts +27 -5
  118. package/src/cli/registry.ts +41 -9
  119. package/src/cli/restart-scope.ts +3 -1
  120. package/src/cli/runtime-api.ts +5 -3
  121. package/src/cli/system-command.ts +40 -8
  122. package/src/cli/uninstall-client-state.ts +32 -0
  123. package/src/cli/usage-compare.ts +309 -0
  124. package/src/cli/usage-model-search.ts +4 -4
  125. package/src/cli/usage-report.ts +2 -2
  126. package/src/cli/v2.ts +1 -1
  127. package/src/client/machine-listener.ts +1 -3
  128. package/src/client/runtime.ts +1 -0
  129. package/src/clients/client-path.ts +51 -0
  130. package/src/clients/config-export/contracts.ts +3 -1
  131. package/src/clients/config-export/model-metadata.ts +3 -2
  132. package/src/clients/config-export/qoder.ts +93 -0
  133. package/src/clients/config-export.ts +35 -48
  134. package/src/clients/gentle-shell-path.ts +87 -0
  135. package/src/codex/account-auto-switch.ts +2 -0
  136. package/src/codex/account-identity.ts +29 -0
  137. package/src/codex/account-label.ts +1 -1
  138. package/src/codex/account-lifecycle.ts +21 -5
  139. package/src/codex/account-preservation.ts +28 -0
  140. package/src/codex/account-use-remaining.ts +23 -0
  141. package/src/codex/app-server-processes.ts +97 -7
  142. package/src/codex/app-server-restart-service.ts +55 -4
  143. package/src/codex/auth-api/account-list.ts +4 -0
  144. package/src/codex/auth-api/account-pause-group.ts +6 -50
  145. package/src/codex/auth-api/account-preservation.ts +57 -0
  146. package/src/codex/auth-api/pool-mode-gate.ts +5 -2
  147. package/src/codex/auth-api/routes.ts +8 -0
  148. package/src/codex/auth-api/use-remaining-route.ts +36 -0
  149. package/src/codex/auth-api.ts +0 -1
  150. package/src/codex/auth-context.ts +81 -7
  151. package/src/codex/autostart-health.ts +4 -0
  152. package/src/codex/catalog/auto-review.ts +20 -3
  153. package/src/codex/catalog/build-entries.ts +19 -2
  154. package/src/codex/catalog/combo-member.ts +14 -5
  155. package/src/codex/catalog/configured-tiers.ts +50 -0
  156. package/src/codex/catalog/effort.ts +4 -1
  157. package/src/codex/catalog/gather-capture.ts +2 -0
  158. package/src/codex/catalog/metadata.ts +11 -9
  159. package/src/codex/catalog/model-hints.ts +42 -19
  160. package/src/codex/catalog/model-visibility.ts +3 -1
  161. package/src/codex/catalog/native-ultrafast.ts +106 -0
  162. package/src/codex/catalog/parsing.ts +35 -86
  163. package/src/codex/catalog/provider-models.ts +40 -34
  164. package/src/codex/catalog/retained-sync.ts +2 -0
  165. package/src/codex/catalog/routed-gather.ts +33 -16
  166. package/src/codex/catalog/vendor-context.ts +82 -0
  167. package/src/codex/cli-install-provenance.ts +105 -17
  168. package/src/codex/cli-update-plan.ts +545 -0
  169. package/src/codex/config-write-lock.ts +63 -4
  170. package/src/codex/convergence.ts +2 -0
  171. package/src/codex/desktop-app/picker-freshness.ts +96 -0
  172. package/src/codex/desktop-app/types.ts +2 -0
  173. package/src/codex/desktop-app/windows.ts +29 -16
  174. package/src/codex/desktop-app-restart.ts +25 -2
  175. package/src/codex/desktop-compatibility/certificate-service.ts +99 -0
  176. package/src/codex/desktop-compatibility/certificate-store.ts +193 -0
  177. package/src/codex/desktop-compatibility/connection-store.ts +87 -0
  178. package/src/codex/desktop-compatibility/installed-build.ts +73 -0
  179. package/src/codex/desktop-compatibility/json-body.ts +29 -0
  180. package/src/codex/desktop-compatibility/native-identity.ts +62 -0
  181. package/src/codex/desktop-compatibility/relay-listener.ts +93 -0
  182. package/src/codex/desktop-compatibility/routing-binding.ts +10 -0
  183. package/src/codex/desktop-compatibility/routing-preflight.ts +69 -0
  184. package/src/codex/desktop-compatibility/runtime-ownership.ts +28 -0
  185. package/src/codex/desktop-compatibility/runtime.ts +182 -0
  186. package/src/codex/desktop-compatibility/service.ts +30 -0
  187. package/src/codex/desktop-compatibility/startup-settings.ts +50 -0
  188. package/src/codex/desktop-compatibility/usage-activation.ts +86 -0
  189. package/src/codex/desktop-compatibility/usage-controlled-fetch.ts +59 -0
  190. package/src/codex/desktop-compatibility/usage-controller.ts +107 -0
  191. package/src/codex/desktop-compatibility/usage-policy.ts +59 -0
  192. package/src/codex/desktop-compatibility/usage-refresh.ts +33 -0
  193. package/src/codex/desktop-compatibility/usage-sse-controller.ts +86 -0
  194. package/src/codex/desktop-compatibility/windows-activation-source.ts +44 -0
  195. package/src/codex/desktop-compatibility/windows-certificate-trust.ts +81 -0
  196. package/src/codex/desktop-compatibility/windows-key-protection.ts +165 -0
  197. package/src/codex/desktop-compatibility/windows-package-command.ts +86 -0
  198. package/src/codex/desktop-compatibility/windows-package-launch.ts +28 -0
  199. package/src/codex/features.ts +85 -45
  200. package/src/codex/history-provider.ts +1 -1
  201. package/src/codex/inject/config-write-section.ts +4 -1
  202. package/src/codex/inject/history-failure.ts +27 -0
  203. package/src/codex/inject/remove.ts +18 -6
  204. package/src/codex/inject/restore.ts +24 -2
  205. package/src/codex/inject/routing-classify.ts +4 -3
  206. package/src/codex/inject.ts +18 -27
  207. package/src/codex/journal.ts +16 -1
  208. package/src/codex/main-account-hard-lock.ts +30 -1
  209. package/src/codex/main-account.ts +99 -15
  210. package/src/codex/native-main-refresh-mode.ts +217 -0
  211. package/src/codex/native-profile-startup.ts +1 -1
  212. package/src/codex/ocx-compaction-history.ts +12 -10
  213. package/src/codex/paths.ts +86 -1
  214. package/src/codex/provider-routing.ts +174 -0
  215. package/src/codex/refresh.ts +2 -2
  216. package/src/codex/routing/health-store.ts +2 -2
  217. package/src/codex/routing/pool-recovery.ts +79 -0
  218. package/src/codex/routing/selection.ts +4 -3
  219. package/src/codex/routing/thread-affinity.ts +1 -1
  220. package/src/codex/shim-diagnostics.ts +6 -0
  221. package/src/codex/shim-overlay.ts +7 -2
  222. package/src/codex/signed-in-identity.ts +43 -0
  223. package/src/codex/subagent-model-fallback.ts +1 -1
  224. package/src/codex/sync.ts +6 -1
  225. package/src/codex/user-identity.ts +16 -5
  226. package/src/codex/windows-local-appdata.ts +84 -0
  227. package/src/combos/failover.ts +6 -1
  228. package/src/combos/index.ts +1 -0
  229. package/src/combos/resolve.ts +46 -10
  230. package/src/combos/types.ts +15 -0
  231. package/src/config/diagnostics.ts +35 -7
  232. package/src/config/live-reconcile.ts +51 -2
  233. package/src/config/load-degrade.ts +23 -1
  234. package/src/config/opencode-wire-upgrade.ts +54 -0
  235. package/src/config/opencode-zen-upgrade.ts +52 -0
  236. package/src/config/owner-registry.ts +22 -17
  237. package/src/config/paths.ts +10 -3
  238. package/src/config/provider-validation.ts +45 -2
  239. package/src/config/schema/config-schema.ts +39 -0
  240. package/src/config/schema/desktop-compatibility.ts +9 -0
  241. package/src/config/schema/leaf-validators.ts +39 -9
  242. package/src/config/schema/main-account-hard-lock-fallback.ts +26 -0
  243. package/src/config/schema/native-reasoning-retention.ts +26 -0
  244. package/src/config.ts +2 -0
  245. package/src/generated/compatibility-version.json +962 -350
  246. package/src/generated/model-metadata.ts +1 -1
  247. package/src/grok/sync.ts +1 -1
  248. package/src/images/loop.ts +46 -8
  249. package/src/integrations/catalog-refresh.ts +1 -1
  250. package/src/integrations/config-io.ts +20 -2
  251. package/src/integrations/journal.ts +15 -1
  252. package/src/integrations/mutation-plan.ts +2 -0
  253. package/src/integrations/registry.ts +15 -0
  254. package/src/integrations/store.ts +3 -0
  255. package/src/integrations/writer.ts +10 -1
  256. package/src/lib/advisor-activation.ts +16 -0
  257. package/src/lib/background-work.ts +65 -0
  258. package/src/lib/bounded-file-read.ts +58 -0
  259. package/src/lib/bun-path-runtime.d.mts +10 -1
  260. package/src/lib/bun-path-runtime.mjs +62 -3
  261. package/src/lib/codex-restart-contract.ts +15 -0
  262. package/src/lib/desktop-proxy-route.ts +30 -0
  263. package/src/lib/desktop-upstream-tunnel.ts +72 -0
  264. package/src/lib/empty-tool-catalog.ts +62 -0
  265. package/src/lib/errors.ts +26 -3
  266. package/src/lib/gcp-adc.ts +96 -9
  267. package/src/lib/gcp-credential-input.ts +12 -0
  268. package/src/lib/lab-live-route-production.ts +5 -0
  269. package/src/lib/local-internal-call-capability.ts +55 -0
  270. package/src/lib/opaque-proxy-tunnel.ts +217 -0
  271. package/src/lib/package-tree-integrity.ts +2 -2
  272. package/src/lib/redact.ts +2 -2
  273. package/src/lib/socks5-fetch.ts +48 -71
  274. package/src/lib/socks5-handshake.ts +112 -0
  275. package/src/lib/translator-budget.ts +7 -1
  276. package/src/oauth/account-quota-rank.ts +69 -2
  277. package/src/oauth/anthropic-account-refusal.ts +20 -2
  278. package/src/oauth/anthropic-oauth-definitions.ts +3 -1
  279. package/src/oauth/anthropic-routing.ts +1 -21
  280. package/src/oauth/anthropic.ts +38 -7
  281. package/src/oauth/callback-server.ts +27 -1
  282. package/src/oauth/chatgpt-device.ts +1 -1
  283. package/src/oauth/chatgpt-shared.ts +83 -0
  284. package/src/oauth/chatgpt.ts +8 -72
  285. package/src/oauth/dsh.ts +203 -0
  286. package/src/oauth/generic-account-failover.ts +62 -12
  287. package/src/oauth/generic-session-affinity.ts +125 -0
  288. package/src/oauth/index.ts +188 -111
  289. package/src/oauth/kiro-device-login.ts +2 -1
  290. package/src/oauth/kiro.ts +7 -1
  291. package/src/oauth/local-token-detect.ts +21 -1
  292. package/src/oauth/login-cli-errors.ts +44 -0
  293. package/src/oauth/login-cli.ts +69 -7
  294. package/src/oauth/login-flow-state.ts +371 -23
  295. package/src/oauth/meta-muse-errors.ts +41 -0
  296. package/src/oauth/meta-muse-keychain.ts +52 -0
  297. package/src/oauth/meta-muse.ts +51 -84
  298. package/src/oauth/model-discovery-auth.ts +3 -0
  299. package/src/oauth/pool-settings-capability.ts +4 -2
  300. package/src/oauth/refresh-flight-retirement.ts +48 -0
  301. package/src/oauth/session-affinity-key.ts +23 -0
  302. package/src/oauth/store-anthropic-instance.ts +9 -2
  303. package/src/oauth/store.ts +12 -5
  304. package/src/protocols/codecs/chat-ir.ts +467 -0
  305. package/src/protocols/codecs/chat.ts +10 -1
  306. package/src/protocols/codecs/messages-ir.ts +500 -0
  307. package/src/protocols/encoders/adapter-events.ts +5 -4
  308. package/src/protocols/encoders/messages.ts +9 -6
  309. package/src/protocols/features.ts +10 -2
  310. package/src/protocols/path.ts +11 -1
  311. package/src/protocols/plan-snapshot.ts +39 -16
  312. package/src/protocols/plan.ts +9 -1
  313. package/src/protocols/provider-summary.ts +2 -1
  314. package/src/protocols/settings.ts +8 -0
  315. package/src/providers/antigravity-account-roster.ts +102 -0
  316. package/src/providers/antigravity-models.ts +85 -7
  317. package/src/providers/api-key-cooldowns.ts +49 -0
  318. package/src/providers/api-key-resolve.ts +11 -6
  319. package/src/providers/api-key-response-ownership.ts +57 -0
  320. package/src/providers/api-key-selection.ts +31 -6
  321. package/src/providers/api-keys.ts +214 -3
  322. package/src/providers/claude-cli-usage.ts +96 -0
  323. package/src/providers/dsh-account-destination.ts +31 -0
  324. package/src/providers/dsh-account-models.ts +41 -0
  325. package/src/providers/gcp-credential-cleanup.ts +59 -0
  326. package/src/providers/key-failover.ts +54 -50
  327. package/src/providers/key-store.ts +7 -2
  328. package/src/providers/model-rename-fields.ts +5 -0
  329. package/src/providers/model-rename-migration.ts +7 -5
  330. package/src/providers/openai-tiers-destination.ts +11 -2
  331. package/src/providers/openai-tiers.ts +5 -12
  332. package/src/providers/opencode-go-transport.ts +3 -1
  333. package/src/providers/quota/account-cache.ts +6 -5
  334. package/src/providers/quota/account-row.ts +34 -0
  335. package/src/providers/quota/antigravity.ts +28 -7
  336. package/src/providers/quota/dsh-account.ts +70 -0
  337. package/src/providers/quota/vendor-probes-oauth.ts +1 -93
  338. package/src/providers/quota-types.ts +2 -0
  339. package/src/providers/quota.ts +14 -20
  340. package/src/providers/registry/entries-core.ts +44 -14
  341. package/src/providers/registry/entries-extended.ts +19 -0
  342. package/src/providers/registry/types.ts +1 -1
  343. package/src/providers/request-pacing.ts +77 -19
  344. package/src/providers/routed-config.ts +339 -0
  345. package/src/providers/service-tier.ts +2 -1
  346. package/src/quota/window-mapping.ts +5 -2
  347. package/src/responses/anthropic-progress.ts +34 -0
  348. package/src/responses/assistant-replay.ts +35 -0
  349. package/src/responses/compaction-history-framing.ts +65 -0
  350. package/src/responses/compaction.ts +6 -1
  351. package/src/responses/incomplete-reason.ts +31 -0
  352. package/src/responses/parser.ts +78 -22
  353. package/src/responses/reasoning-envelope.ts +4 -0
  354. package/src/responses/reasoning-replay-cache.ts +24 -2
  355. package/src/responses/reasoning-retention.ts +173 -0
  356. package/src/responses/retained-compaction.ts +46 -0
  357. package/src/responses/schema.ts +23 -0
  358. package/src/responses/state.ts +32 -29
  359. package/src/router.ts +8 -321
  360. package/src/routing/health.ts +37 -22
  361. package/src/routing/history/build-file.ts +92 -0
  362. package/src/routing/history/indexer.ts +254 -221
  363. package/src/routing/history/ingest.ts +242 -0
  364. package/src/routing/history/rebuild-job.ts +111 -0
  365. package/src/routing/history/rebuild-protocol.ts +15 -0
  366. package/src/routing/history/rebuild-worker.ts +34 -0
  367. package/src/routing/profile.ts +1 -1
  368. package/src/server/admission-model-scope.ts +21 -1
  369. package/src/server/antigravity-direct-eligibility.ts +208 -0
  370. package/src/server/auth-cors.ts +15 -0
  371. package/src/server/chat-completions.ts +82 -10
  372. package/src/server/chat-native-reasoning.ts +123 -0
  373. package/src/server/chat-native-sse.ts +110 -7
  374. package/src/server/chat-native.ts +76 -17
  375. package/src/server/claude-messages.ts +164 -433
  376. package/src/server/effort-policy.ts +1 -1
  377. package/src/server/images.ts +15 -2
  378. package/src/server/index/desktop-compatibility-startup.ts +56 -0
  379. package/src/server/index/model-alias-id.ts +36 -0
  380. package/src/server/index/optional-listeners.ts +2 -0
  381. package/src/server/index/serve-options.ts +11 -3
  382. package/src/server/index/startup-warnings.ts +11 -0
  383. package/src/server/index/websocket-handler.ts +9 -0
  384. package/src/server/index.ts +14 -11
  385. package/src/server/inference/advisor-diagnostics.ts +31 -0
  386. package/src/server/inference/client-encoder-delivery.ts +6 -5
  387. package/src/server/login-shell-path.ts +146 -0
  388. package/src/server/management/advisor-routes.ts +202 -0
  389. package/src/server/management/agent-settings-routes.ts +22 -4
  390. package/src/server/management/claude-desktop-picker-routes.ts +1 -1
  391. package/src/server/management/combo-routes.ts +176 -50
  392. package/src/server/management/companion-routes.ts +4 -0
  393. package/src/server/management/config-routes.ts +77 -6
  394. package/src/server/management/context.ts +4 -0
  395. package/src/server/management/cursor-integration-routes.ts +1 -1
  396. package/src/server/management/desktop-compatibility-routes.ts +46 -0
  397. package/src/server/management/desktop-compatibility-runtime-routes.ts +46 -0
  398. package/src/server/management/desktop-compatibility-settings-routes.ts +27 -0
  399. package/src/server/management/model-routes.ts +13 -8
  400. package/src/server/management/model-rows.ts +14 -0
  401. package/src/server/management/native-integration-routes.ts +2 -7
  402. package/src/server/management/native-reasoning-retention-routes.ts +41 -0
  403. package/src/server/management/oauth-account-routes.ts +87 -14
  404. package/src/server/management/protocol-settings-patch.ts +1 -0
  405. package/src/server/management/provider-gcp-credential-routes.ts +29 -0
  406. package/src/server/management/provider-key-pacing-routes.ts +31 -0
  407. package/src/server/management/provider-overwrite-carry.ts +7 -0
  408. package/src/server/management/provider-routes.ts +25 -30
  409. package/src/server/management/route-registry.ts +21 -1
  410. package/src/server/management/sibling-guard.ts +1 -0
  411. package/src/server/management-api.ts +9 -1
  412. package/src/server/messages-antigravity-direct.ts +195 -0
  413. package/src/server/messages-native-tool-guard.ts +185 -0
  414. package/src/server/messages-native.ts +106 -22
  415. package/src/server/messages-shared.ts +431 -0
  416. package/src/server/relay.ts +1 -1
  417. package/src/server/request-log-terminal-status.ts +1 -1
  418. package/src/server/request-log.ts +13 -1
  419. package/src/server/responses/account-change-state.ts +8 -2
  420. package/src/server/responses/adapter-continuation.ts +48 -19
  421. package/src/server/responses/adapter-delivery.ts +43 -8
  422. package/src/server/responses/adapter-dispatch.ts +48 -4
  423. package/src/server/responses/advisor-plan-slot.ts +27 -0
  424. package/src/server/responses/advisor-retention.ts +117 -0
  425. package/src/server/responses/advisor-slot.ts +368 -0
  426. package/src/server/responses/code-mode-collab-surface.ts +116 -8
  427. package/src/server/responses/codex-ws-wire.ts +15 -8
  428. package/src/server/responses/compact.ts +303 -125
  429. package/src/server/responses/compaction-recovery.ts +18 -10
  430. package/src/server/responses/compaction-retention.ts +61 -0
  431. package/src/server/responses/context-overflow.ts +11 -6
  432. package/src/server/responses/core-auth.ts +6 -0
  433. package/src/server/responses/core-codex-account.ts +11 -1
  434. package/src/server/responses/core-combo-failure.ts +12 -1
  435. package/src/server/responses/core-combo.ts +141 -36
  436. package/src/server/responses/core-errors.ts +3 -3
  437. package/src/server/responses/core-lifetime.ts +7 -2
  438. package/src/server/responses/core-normalize.ts +11 -0
  439. package/src/server/responses/core-opaque-recovery.ts +35 -0
  440. package/src/server/responses/core-options.ts +51 -0
  441. package/src/server/responses/core-pipeline.ts +141 -0
  442. package/src/server/responses/core-replay.ts +25 -6
  443. package/src/server/responses/core.ts +3 -116
  444. package/src/server/responses/fetch-helpers.ts +73 -19
  445. package/src/server/responses/main-hard-lock-routing.ts +109 -0
  446. package/src/server/responses/native-response-control.ts +4 -2
  447. package/src/server/responses/passthrough-delivery.ts +19 -11
  448. package/src/server/responses/passthrough-dispatch.ts +29 -16
  449. package/src/server/responses/request-prepare.ts +144 -17
  450. package/src/server/responses/request-sidecar-auth.ts +2 -2
  451. package/src/server/responses/request-transport.ts +120 -27
  452. package/src/server/responses/response-effects.ts +1 -0
  453. package/src/server/responses/run-turn-execution.ts +166 -38
  454. package/src/server/responses/sidecar-execution.ts +98 -5
  455. package/src/server/responses/terminal-guard.ts +4 -17
  456. package/src/server/responses-undeclared-tool-guard.ts +30 -9
  457. package/src/server/startup-action-control.ts +16 -2
  458. package/src/server/startup-health-cache.ts +1 -0
  459. package/src/service/auth-preflight.ts +71 -0
  460. package/src/service/cli.ts +4 -2
  461. package/src/service/definition.ts +97 -0
  462. package/src/service/desktop-startup.ts +14 -0
  463. package/src/service/guards.ts +1 -61
  464. package/src/service/health-sentinel-linux.ts +112 -0
  465. package/src/service/health-sentinel-main.ts +99 -61
  466. package/src/service/health-sentinel-probe.ts +24 -7
  467. package/src/service/health.ts +5 -89
  468. package/src/service/launchd.ts +27 -7
  469. package/src/service/logging.ts +135 -0
  470. package/src/service/repair.ts +2 -1
  471. package/src/service/state.ts +7 -8
  472. package/src/service/systemd.ts +1 -1
  473. package/src/service/windows-guarded-manager.ts +2 -1
  474. package/src/service/windows-ops.ts +1 -1
  475. package/src/service/windows-scheduler.ts +2 -7
  476. package/src/service/windows-taskxml.ts +2 -2
  477. package/src/service/windows-wscript.ts +14 -0
  478. package/src/service.ts +4 -2
  479. package/src/sidecar/auth.ts +2 -0
  480. package/src/tray/windows-tray.ps1 +43 -24
  481. package/src/types/config.ts +124 -6
  482. package/src/types/opencode-go.ts +61 -0
  483. package/src/types/opencode-zen.ts +29 -0
  484. package/src/types/provider.ts +39 -6
  485. package/src/types/request.ts +38 -2
  486. package/src/types/tools.ts +2 -0
  487. package/src/types/wire.ts +29 -37
  488. package/src/types.ts +1 -0
  489. package/src/update/async-check.ts +1 -1
  490. package/src/update/badge.ts +2 -2
  491. package/src/update/index.ts +88 -15
  492. package/src/update/job-supervised-restart.ts +107 -0
  493. package/src/update/job.ts +32 -32
  494. package/src/update/notify.ts +1 -1
  495. package/src/update/npm-invocation.mjs +12 -2
  496. package/src/update/refresh-scheduler.ts +2 -2
  497. package/src/update/supervised-recovery.d.mts +27 -0
  498. package/src/update/supervised-recovery.mjs +157 -0
  499. package/src/usage/cache-diagnostic.ts +2 -0
  500. package/src/usage/cost.ts +48 -12
  501. package/src/usage/expected-prices.ts +15 -0
  502. package/src/usage/ledger-retention.ts +2 -1
  503. package/src/usage/ledger-scanner.ts +6 -5
  504. package/src/usage/log.ts +17 -8
  505. package/src/usage/summary.ts +22 -9
  506. package/src/usage/user-cost-overlays.ts +14 -19
  507. package/src/usage/user-cost-validation.ts +38 -0
  508. package/src/vision/eligibility.ts +13 -0
  509. package/src/web-search/gemini-executor.ts +2 -2
  510. package/src/web-search/loop.ts +55 -5
  511. package/src/web-search/progress-stream.ts +4 -1
  512. package/src/web-search/run-turn-loop.ts +9 -1
  513. package/assets/sponsors/packycode.png +0 -0
  514. package/gui/dist/assets/App-CSJvmjNs.css +0 -1
  515. package/gui/dist/assets/App-CZtqiGcw.js +0 -56
  516. package/gui/dist/assets/index-BB6uK6tU.css +0 -1
  517. package/gui/dist/assets/index-CTm4l-HQ.js +0 -94
  518. package/gui/dist/assets/quota-summary-BbEeRfPY.js +0 -1
@@ -48,7 +48,8 @@ import { NATIVE_RESERVE_MODEL } from "./native-models";
48
48
  import { isReserveCatalogProjection, type ReserveCatalogProjection } from "./reserve";
49
49
  import { deriveEntry, finishUpstreamNativeEntry, isExactComboCatalogEntry } from "./derive-entry";
50
50
  import { PICKER_ORDER_PRIORITY_BASE, SPAWN_PRIORITY_FIELD } from "./subagent-roster";
51
- import { preserveOperatorUltraFastTiers } from "./operator-tiers";
51
+ import { applyConfiguredUltraFast, configuredUltraFastSlugs } from "./configured-tiers";
52
+ import { applyNativeUltraFastTier } from "./native-ultrafast";
52
53
 
53
54
  export interface ObservedCatalogEntryBuildInput {
54
55
  readonly template: RawEntry | null;
@@ -110,6 +111,14 @@ export function buildCatalogEntries(
110
111
  accountNativeSlugs,
111
112
  accountNativeSlugsBySelector,
112
113
  });
114
+ // Live discovery does not run the disk merge; use the same captured declarations and row fences.
115
+ const configured = configuredUltraFastSlugs(goModels);
116
+ for (const entry of entries) {
117
+ if (typeof entry.slug !== "string" || !entry.slug.includes("/")
118
+ || isNativeAliasCatalogEntry(entry) || isExactComboCatalogEntry(entry, exactComboSlugs)
119
+ || trustedAccountBoundNativeCatalogSlug(entry) !== undefined) continue;
120
+ applyConfiguredUltraFast(entry, undefined, configured.has(entry.slug), false);
121
+ }
113
122
  applyFullModelPickerOrder(entries, modelPickerOrder);
114
123
  return entries;
115
124
  }
@@ -473,6 +482,8 @@ export function applyFullModelPickerOrder(entries: RawEntry[], order: readonly s
473
482
  export interface ObservedCatalogMergeInput {
474
483
  /** Preserve operator-supplied Ultra Fast only from the exact persisted routed row. */
475
484
  readonly ultraFastTier?: boolean;
485
+ /** Current captured wire declarations; disk rows and templates never populate this set. */
486
+ readonly configuredUltraFastSlugs?: ReadonlySet<string>;
476
487
  readonly catalogModels: readonly RawEntry[];
477
488
  readonly baselineCatalogModels: readonly RawEntry[];
478
489
  readonly routedEntries: readonly RawEntry[];
@@ -514,6 +525,7 @@ export interface ObservedCatalogMergeInput {
514
525
  */
515
526
  export function mergeCatalogEntriesFromObservedState({
516
527
  ultraFastTier = false,
528
+ configuredUltraFastSlugs = new Set(),
517
529
  catalogModels,
518
530
  baselineCatalogModels,
519
531
  routedEntries,
@@ -865,7 +877,7 @@ export function mergeCatalogEntriesFromObservedState({
865
877
  if (typeof entry.slug !== "string" || !entry.slug.includes("/")
866
878
  || isNativeAliasCatalogEntry(entry) || isExactComboCatalogEntry(entry, exactComboSlugs)
867
879
  || trustedAccountBoundNativeCatalogSlug(entry) !== undefined) continue;
868
- preserveOperatorUltraFastTiers(entry, operatorRows.get(entry.slug), ultraFastTier);
880
+ applyConfiguredUltraFast(entry, operatorRows.get(entry.slug), configuredUltraFastSlugs.has(entry.slug), ultraFastTier);
869
881
  }
870
882
  const finalRoutedEntrySet = new Set(finalRoutedEntries);
871
883
  const degradedPreservedCount = preservedRoutedEntries.filter(entry => {
@@ -932,6 +944,11 @@ export function mergeCatalogEntriesFromObservedState({
932
944
  );
933
945
  }
934
946
  }
947
+ // Native Astra/Sol rows (bare and account-bound) gain or lose the documented Ultrafast
948
+ // choice with the switch; aliases, combos and reserve projections keep their own tiers.
949
+ if (!reserveProjection && !exactCombo && m.owned_by !== COMBO_NAMESPACE && !isNativeAliasCatalogEntry(e)) {
950
+ applyNativeUltraFastTier(e, ultraFastTier);
951
+ }
935
952
  if (wsEnabled) e.supports_websockets = true;
936
953
  else {
937
954
  delete e.supports_websockets;
@@ -100,7 +100,7 @@ import type {
100
100
  CatalogSourceEvidence,
101
101
  CatalogTrustedOpenAiApiPolicySnapshot,
102
102
  } from "../convergence-types";
103
- import { applyProviderConfigHints, configuredAutoCompactTokenLimit, positiveSafeInteger } from "./model-hints";
103
+ import { applyProviderConfigHints, configuredAutoCompactTokenLimit, positiveSafeInteger, withVisionSidecarInput } from "./model-hints";
104
104
 
105
105
  /** Model ids each provider must retain for combo catalog derivation (OCX-111). */
106
106
  export function configuredComboTargetModelsByProvider(
@@ -219,6 +219,7 @@ export function resolveComboCatalogMember(
219
219
  callerFallback?: ComboCatalogMemberFallback,
220
220
  metadataModelIdCaseFold?: boolean,
221
221
  metadataConfigDir?: string,
222
+ visionSidecarEnabled = true,
222
223
  ): CatalogModel | undefined {
223
224
  const existing = memberByKey.get(targetKey(target));
224
225
  const prov = providers.get(target.provider);
@@ -227,6 +228,16 @@ export function resolveComboCatalogMember(
227
228
  // is unusable for catalog derivation while the provider is off.
228
229
  if (prov?.disabled === true) return undefined;
229
230
 
231
+ /** Preserve custom modality overrides while filling missing provider metadata. */
232
+ const withProviderHints = (model: CatalogModel): CatalogModel => {
233
+ const hinted = prov
234
+ ? applyProviderConfigHints(target.provider, prov, model, contextCap, metadataModelIdCaseFold, undefined, metadataConfigDir, visionSidecarEnabled)
235
+ : model;
236
+ return model.catalogKind === CODEX_CUSTOM_MODEL_CATALOG_KIND && model.inputModalities !== undefined
237
+ ? withVisionSidecarInput({ ...hinted, inputModalities: [...model.inputModalities] }, prov, visionSidecarEnabled)
238
+ : hinted;
239
+ };
240
+
230
241
  const withFallbackMetadata = (member: CatalogModel): CatalogModel => {
231
242
  const contextWindow = typeof member.contextWindow === "number" && member.contextWindow > 0
232
243
  ? member.contextWindow
@@ -276,7 +287,7 @@ export function resolveComboCatalogMember(
276
287
  // supplies a vision sidecar. Apply the same provider hints used for thin
277
288
  // rows before deriving a combo from this complete row.
278
289
  const hinted = prov && isModelVisionSidecarConsumer(prov, existing.id)
279
- ? applyProviderConfigHints(target.provider, prov, existing, contextCap, metadataModelIdCaseFold, undefined, metadataConfigDir)
290
+ ? withProviderHints(existing)
280
291
  : existing;
281
292
  const capped = applyProviderContextCap(hinted.contextWindow, contextCap);
282
293
  if (capped === undefined || capped === existing.contextWindow) {
@@ -298,9 +309,7 @@ export function resolveComboCatalogMember(
298
309
  id: target.model,
299
310
  provider: target.provider,
300
311
  };
301
- const hinted = prov
302
- ? applyProviderConfigHints(target.provider, prov, base, contextCap, metadataModelIdCaseFold, undefined, metadataConfigDir)
303
- : base;
312
+ const hinted = withProviderHints(base);
304
313
  const hintedContext = typeof hinted.contextWindow === "number" && hinted.contextWindow > 0
305
314
  ? hinted.contextWindow
306
315
  : undefined;
@@ -0,0 +1,50 @@
1
+ import { COMBO_NAMESPACE } from "../../combos";
2
+ import type { ResolvedFastPolicy } from "../../providers/fastwire";
3
+ import { catalogModelSlug, type CatalogModel, type RawEntry } from "./parsing";
4
+ import { preserveOperatorUltraFastTiers } from "./operator-tiers";
5
+
6
+ const MANAGED_ULTRAFAST = "opencodex_managed_ultrafast";
7
+
8
+ /** Advertise Ultra Fast only when the eligible final wire explicitly maps that exact tier. */
9
+ export function supportsConfiguredUltraFast(policy: ResolvedFastPolicy | undefined): boolean {
10
+ return policy?.eligibility === "eligible"
11
+ && policy.fastWire?.kind === "service-tier"
12
+ && policy.fastWire.canonicalToWire.ultrafast === "ultrafast";
13
+ }
14
+
15
+ /** Carry captured capability to catalog projection without treating persisted metadata as authority. */
16
+ export function configuredUltraFastSlugs(models: readonly CatalogModel[]): ReadonlySet<string> {
17
+ const declarations = new Map<string, boolean>();
18
+ for (const model of models) {
19
+ const slug = catalogModelSlug(model);
20
+ const supported = model.provider !== COMBO_NAMESPACE && model.nativeAlias !== true
21
+ && model.supportsServiceTier === true && model.supportsUltraFastTier === true;
22
+ // A conflicting duplicate cannot lend its capability to the surviving row.
23
+ declarations.set(slug, supported && declarations.get(slug) !== false);
24
+ }
25
+ return new Set([...declarations].filter(([, supported]) => supported).map(([slug]) => slug));
26
+ }
27
+
28
+ /** Apply current configuration, or retain an independently supplied exact-row operator tier. */
29
+ export function applyConfiguredUltraFast(
30
+ entry: RawEntry,
31
+ previous: RawEntry | undefined,
32
+ configured: boolean,
33
+ retainOperatorTier: boolean,
34
+ ): void {
35
+ // This marker only rejects stale generated metadata; it never authorizes a new tier.
36
+ const wasManaged = previous?.[MANAGED_ULTRAFAST] === entry.slug;
37
+ preserveOperatorUltraFastTiers(entry, wasManaged || configured ? undefined : previous, retainOperatorTier);
38
+ delete entry[MANAGED_ULTRAFAST];
39
+ if (!configured) return;
40
+ entry.service_tiers = [...(Array.isArray(entry.service_tiers) ? entry.service_tiers : []), {
41
+ id: "ultrafast",
42
+ name: "Ultra Fast",
43
+ description: "Higher speed and usage; provider access required",
44
+ }];
45
+ entry.additional_speed_tiers = [
46
+ ...(Array.isArray(entry.additional_speed_tiers) ? entry.additional_speed_tiers : []), "ultrafast",
47
+ ];
48
+ // Advertising a selectable capability does not opt the user into its increased usage.
49
+ entry[MANAGED_ULTRAFAST] = entry.slug;
50
+ }
@@ -204,6 +204,8 @@ export function applyCatalogModelMetadata(entry: RawEntry, model?: CatalogModel)
204
204
  * Two real sources exist and both are consulted here, in the same precedence the
205
205
  * writers use (`applyCatalogMetadata` runs first, the model's own fields
206
206
  * overwrite it): the `CatalogModel` and the generated jawcode metadata table.
207
+ * Vendor-ID fallback windows are estimates for client budgets, recorded separately rather
208
+ * than promoted to serving-provider assertions.
207
209
  * Reading only the model would silently drop every provider whose capabilities
208
210
  * live in that table.
209
211
  */
@@ -230,7 +232,8 @@ function stampCapabilityProvenance(entry: RawEntry, model: CatalogModel): void {
230
232
  entry.opencodex_capability_provenance = {
231
233
  provider: model.provider,
232
234
  model_id: model.id,
233
- ...(contextWindow !== undefined ? { context_window: contextWindow } : {}),
235
+ ...(contextWindow !== undefined && !model.contextWindowInference ? { context_window: contextWindow } : {}),
236
+ ...(model.contextWindowInference ? { inferred_context_window: contextWindow, context_window_inference: { ...model.contextWindowInference } } : {}),
234
237
  ...(inputModalities !== undefined ? { input_modalities: [...inputModalities] } : {}),
235
238
  ...(Array.isArray(model.capabilities) && model.capabilities.length > 0
236
239
  ? { capabilities: [...model.capabilities] }
@@ -564,6 +564,7 @@ function providerCatalogFingerprint(name: string, prov: OcxProviderConfig): Reco
564
564
  };
565
565
  }
566
566
 
567
+ /** Coalesce only gathers with the same model inventory and effective sidecar visibility policy. */
567
568
  export function gatherFlightKey(config: OcxConfig): string {
568
569
  const providers = Object.entries(config.providers)
569
570
  .filter(([, prov]) => prov.disabled !== true)
@@ -571,6 +572,7 @@ export function gatherFlightKey(config: OcxConfig): string {
571
572
  .sort((a, b) => String(a.n).localeCompare(String(b.n)));
572
573
  const assembly = stableJson({
573
574
  providers,
575
+ visionSidecarEnabled: config.visionSidecar?.enabled !== false,
574
576
  disabledModels: [...(config.disabledModels ?? [])].sort(),
575
577
  combos: config.combos ?? {},
576
578
  customModels: (config.customModels ?? []).map((cm) => ({
@@ -276,6 +276,14 @@ function asLimits(input: NativeContextLimitsInput): NativeContextLimits {
276
276
  return typeof input === "number" ? { cap: input } : input;
277
277
  }
278
278
 
279
+ /** Configured hard ceiling only; an advertised default window is not a user limit. */
280
+ export function nativeOpenAiConfiguredContextLimit(slug: string, input?: NativeContextLimitsInput): number | undefined {
281
+ const limits = asLimits(input);
282
+ const overlay = positiveInt(limits.modelWindows?.[slug]) ?? positiveInt(limits.providerWindow);
283
+ const cap = positiveInt(limits.cap);
284
+ return overlay === undefined ? cap : cap === undefined ? overlay : Math.min(overlay, cap);
285
+ }
286
+
279
287
  /** Read both levers out of a config once, for call sites that hold one. */
280
288
  export function nativeContextLimits(
281
289
  config: Pick<OcxConfig, "providers" | "providerContextCaps">,
@@ -326,18 +334,12 @@ function longWindowOptInCeiling(slug: string): number | undefined {
326
334
 
327
335
  function narrowToLimits(raw: number | undefined, slug: string, input: NativeContextLimitsInput): number | undefined {
328
336
  if (raw === undefined) return undefined;
329
- const limits = asLimits(input);
330
- const overlay = positiveInt(limits.modelWindows?.[slug]) ?? positiveInt(limits.providerWindow);
331
- const cap = positiveInt(limits.cap);
337
+ const limit = nativeOpenAiConfiguredContextLimit(slug, input);
332
338
  const optInCeiling = longWindowOptInCeiling(slug);
333
339
  if (optInCeiling !== undefined) {
334
- const ceiling = optInCeiling;
335
- const chosen = overlay ?? cap ?? raw;
336
- const window = Math.min(chosen, ceiling);
337
- return overlay !== undefined && cap !== undefined ? Math.min(window, cap) : window;
340
+ return Math.min(limit ?? raw, optInCeiling);
338
341
  }
339
- const narrowed = overlay === undefined ? raw : Math.min(raw, overlay);
340
- return applyProviderContextCap(narrowed, cap) ?? narrowed;
342
+ return applyProviderContextCap(raw, limit);
341
343
  }
342
344
 
343
345
  export function nativeOpenAiContextWindow(slug: string, limits?: NativeContextLimitsInput): number | undefined {
@@ -1,5 +1,7 @@
1
+ import { canInferVendorContext, vendorContextInference } from "./vendor-context";
1
2
  import { effectiveProviderAlias, effectiveProviderAliasDecision } from "../../providers/default-aliases";
2
3
  import { initialModelSelectionPending } from "../../providers/initial-model-selection";
4
+ import { supportsConfiguredUltraFast } from "./configured-tiers";
3
5
  import { execFileSync } from "node:child_process";
4
6
  import { createHash, createHmac, randomBytes } from "node:crypto";
5
7
  import { copyFileSync, existsSync, mkdirSync, readFileSync, realpathSync } from "node:fs";
@@ -250,6 +252,18 @@ export function configuredReasoningSummarySupport(prov: OcxProviderConfig | unde
250
252
  return modelRecordValue(prov.modelReasoningSummaryDelivery, id) !== undefined ? true : undefined;
251
253
  }
252
254
 
255
+ /** Add attachment metadata at publication time, independently of cached provider evidence. */
256
+ export function withVisionSidecarInput(
257
+ model: CatalogModel,
258
+ provider: OcxProviderConfig | undefined,
259
+ enabled = true,
260
+ ): CatalogModel {
261
+ if (!enabled || !provider || !isModelVisionSidecarConsumer(provider, model.id)) return model;
262
+ const modalities = model.inputModalities ?? ["text"];
263
+ return modalities.includes("image") ? model : { ...model, inputModalities: [...modalities, "image"] };
264
+ }
265
+
266
+ /** Reapply configured limits and captured wire capabilities without trusting stale discovery hints. */
253
267
  export function applyProviderConfigHints(
254
268
  name: string,
255
269
  prov: OcxProviderConfig,
@@ -258,6 +272,7 @@ export function applyProviderConfigHints(
258
272
  metadataModelIdCaseFold?: boolean,
259
273
  effectiveAlias?: string | null,
260
274
  metadataConfigDir?: string,
275
+ includeVisionSidecar = true,
261
276
  ): CatalogModel {
262
277
  const staticPolicy = resolveModelPolicy({
263
278
  providerName: name,
@@ -286,18 +301,7 @@ export function applyProviderConfigHints(
286
301
  // Removing an exact capability row therefore returns this projection to legacy-map inference.
287
302
  const resolvedModalities = staticPolicy.model.inputModalities ?? model.inputModalities
288
303
  ?? (azureMetadata?.input ? modelInputModalities({ id: model.id, input_modalities: azureMetadata.input }, undefined) : undefined);
289
- let inputModalities = resolvedModalities ? [...resolvedModalities] : undefined;
290
- // The shared vision-sidecar consumer predicate keeps catalog advertisement and request-time
291
- // planning aligned. The catalog must still advertise image input — the Codex app
292
- // gates attachments client-side on input_modalities, and a text-only entry would block images
293
- // before the sidecar ever runs ("This model does not support image inputs"). Discovery-derived
294
- // text-only rows stay untouched: the runtime predicate only reads these two config sources, so
295
- // it would not convert those.
296
- const sidecarCovered = isModelVisionSidecarConsumer(prov, model.id);
297
- if (sidecarCovered) {
298
- const base = inputModalities ?? model.inputModalities ?? ["text"];
299
- inputModalities = base.includes("image") ? [...base] : [...base, "image"];
300
- }
304
+ const inputModalities = resolvedModalities ? [...resolvedModalities] : undefined;
301
305
  const reasoningEfforts = configuredReasoningEfforts(prov, model.id);
302
306
  const suppressSyntheticMax = modelRecordValue(prov.modelSuppressSyntheticMax, model.id)
303
307
  ?? (model.antigravityEffortWireModelIds !== undefined);
@@ -309,7 +313,12 @@ export function applyProviderConfigHints(
309
313
  // owns catalog publication, including an explicit provider-level false.
310
314
  const supportsServiceTier = serviceTierSupportFromPolicy(fastPolicy);
311
315
  const {
316
+ contextWindowInference: _staleContextInference,
317
+ contextWindow: _previousContextWindow,
318
+ contextCap: previousContextCap,
319
+ contextCapped: previousContextCapped,
312
320
  supportsServiceTier: _staleServiceTier,
321
+ supportsUltraFastTier: _staleUltraFastTier,
313
322
  fastTierDescription: _staleFastTierDescription,
314
323
  providerAlias: _staleProviderAlias,
315
324
  suppressSyntheticMax: _staleSuppressSyntheticMax,
@@ -317,16 +326,23 @@ export function applyProviderConfigHints(
317
326
  } = model;
318
327
  // 已发现窗口只允许被配置值压低;缺窗口时,已开的 Context cap 就是实际窗口。
319
328
  const discoveredWindow = githubCopilotCatalogContextWindow(name, prov, model.id,
320
- typeof model.contextWindow === "number" && model.contextWindow > 0 ? model.contextWindow : undefined);
329
+ !model.contextWindowInference && typeof model.contextWindow === "number" && model.contextWindow > 0 ? model.contextWindow : undefined);
321
330
  const projectedLimits = clampObservedModelLimits(staticPolicy.model, {
322
331
  ...(discoveredWindow !== undefined ? { contextWindow: discoveredWindow } : {}),
323
332
  ...(typeof model.maxInputTokens === "number" && model.maxInputTokens > 0 ? { maxInputTokens: model.maxInputTokens } : {}),
324
333
  });
334
+ const azureWindow = positiveSafeInteger(azureMetadata?.contextWindow);
335
+ const inferredWindow = projectedLimits.contextWindow === undefined && azureWindow === undefined && canInferVendorContext(name, prov)
336
+ ? vendorContextInference(model.id) : undefined;
325
337
  const hintedWindow = projectedLimits.contextWindow
326
- ?? positiveSafeInteger(azureMetadata?.contextWindow)
338
+ ?? azureWindow
339
+ ?? inferredWindow?.contextWindow
327
340
  ?? (providerCap !== undefined ? resolveUnknownRoutedContextWindow(providerCap) : undefined);
328
- const hinted = {
341
+ const hinted = withVisionSidecarInput({
329
342
  ...modelWithoutServiceTier,
343
+ ...(!model.contextWindowInference && previousContextCap !== undefined
344
+ ? { contextCap: previousContextCap, contextCapped: previousContextCapped } : {}),
345
+ ...(inferredWindow ? { contextWindowInference: inferredWindow } : {}),
330
346
  ...(displayName !== undefined ? { displayName } : {}),
331
347
  ...(providerAlias !== undefined ? { providerAlias } : {}),
332
348
  ...(hintedWindow !== undefined ? { contextWindow: hintedWindow } : {}),
@@ -343,6 +359,7 @@ export function applyProviderConfigHints(
343
359
  ...(typeof supportsReasoningSummaries === "boolean" ? { supportsReasoningSummaries } : {}),
344
360
  ...(typeof supportsVerbosity === "boolean" ? { supportsVerbosity } : {}),
345
361
  ...(typeof supportsServiceTier === "boolean" ? { supportsServiceTier } : {}),
362
+ supportsUltraFastTier: supportsConfiguredUltraFast(fastPolicy),
346
363
  ...(supportsServiceTier === true && fastPolicy.fastTierDescription !== undefined
347
364
  ? { fastTierDescription: fastPolicy.fastTierDescription }
348
365
  : {}),
@@ -352,7 +369,7 @@ export function applyProviderConfigHints(
352
369
  ? { parallelToolCalls: true }
353
370
  : {}),
354
371
  ...(prov.codexToolMode !== undefined ? { codexToolMode: prov.codexToolMode } : {}),
355
- };
372
+ }, prov, includeVisionSidecar);
356
373
  const capped = applyProviderContextCap(hinted.contextWindow, providerCap);
357
374
  const withCap = providerCap !== undefined
358
375
  ? capped !== hinted.contextWindow
@@ -381,6 +398,7 @@ export function applyProviderConfigHints(
381
398
  };
382
399
  }
383
400
 
401
+ /** Project a configured row, optionally deferring sidecar attachment metadata until publication. */
384
402
  export function catalogHintsFromProviderConfig(
385
403
  name: string,
386
404
  prov: OcxProviderConfig,
@@ -389,12 +407,14 @@ export function catalogHintsFromProviderConfig(
389
407
  metadataModelIdCaseFold?: boolean,
390
408
  effectiveAlias?: string | null,
391
409
  metadataConfigDir?: string,
410
+ includeVisionSidecar = true,
392
411
  ): Partial<CatalogModel> {
393
- const hinted = applyProviderConfigHints(name, prov, { id, provider: name }, contextCap, metadataModelIdCaseFold, effectiveAlias, metadataConfigDir);
412
+ const hinted = applyProviderConfigHints(name, prov, { id, provider: name }, contextCap, metadataModelIdCaseFold, effectiveAlias, metadataConfigDir, includeVisionSidecar);
394
413
  const { provider: _provider, id: _id, ...hints } = hinted;
395
414
  return hints;
396
415
  }
397
416
 
417
+ /** Reapply current hints to cached rows without mutating their provider evidence. */
398
418
  export function applyConfigHintsToCachedModels(
399
419
  name: string,
400
420
  prov: OcxProviderConfig,
@@ -403,8 +423,9 @@ export function applyConfigHintsToCachedModels(
403
423
  metadataModelIdCaseFold?: boolean,
404
424
  effectiveAlias?: string | null,
405
425
  metadataConfigDir?: string,
426
+ includeVisionSidecar = true,
406
427
  ): CatalogModel[] {
407
- return models.map(model => applyProviderConfigHints(name, prov, model, contextCap, metadataModelIdCaseFold, effectiveAlias, metadataConfigDir));
428
+ return models.map(model => applyProviderConfigHints(name, prov, model, contextCap, metadataModelIdCaseFold, effectiveAlias, metadataConfigDir, includeVisionSidecar));
408
429
  }
409
430
 
410
431
  /** Catalog slugs whose configured model must not gain a missing synthetic max rung. */
@@ -431,7 +452,9 @@ export function suppressedSyntheticMaxCatalogSlugs(
431
452
  }
432
453
  return slugs;
433
454
  }
434
- export const QUIET_AUTHORITATIVE_CATALOG_PROVIDERS = new Set(["kimi", "xai"]);
455
+ // google-antigravity: the static lineup is an entitlement superset (Claude 5.5 and Gemini 4 Argon
456
+ // are per-account), so a live roster that omits some of it is the expected case, not drift.
457
+ export const QUIET_AUTHORITATIVE_CATALOG_PROVIDERS = new Set(["kimi", "xai", "google-antigravity"]);
435
458
 
436
459
  export const CALLABLE_CONFIGURED_COMPATIBILITY_MODELS: Readonly<Record<string, ReadonlySet<string>>> = {
437
460
  // CodeBuddy's vendor defaults are real callable selectors — both the bundled manifests
@@ -231,6 +231,7 @@ export function mergeConfiguredModelsIntoLiveCatalog(opts: {
231
231
  retainComboTargets?: boolean;
232
232
  metadataModelIdCaseFold?: boolean;
233
233
  metadataConfigDir?: string;
234
+ includeVisionSidecar?: boolean;
234
235
  }): { models: CatalogModel[]; droppedConfiguredIds: string[] } {
235
236
  const {
236
237
  name,
@@ -242,6 +243,7 @@ export function mergeConfiguredModelsIntoLiveCatalog(opts: {
242
243
  retainComboTargets = true,
243
244
  metadataModelIdCaseFold,
244
245
  metadataConfigDir,
246
+ includeVisionSidecar,
245
247
  } = opts;
246
248
  const out = [...opts.models];
247
249
  const present = new Set(out.map(model => model.id));
@@ -250,7 +252,7 @@ export function mergeConfiguredModelsIntoLiveCatalog(opts: {
250
252
  if (present.has(candidate.id)) continue;
251
253
  const dated = out.find(live => isDatedVariantId(live.id, candidate.id));
252
254
  if (dated) {
253
- out.push(applyProviderConfigHints(name, prov, { ...dated, id: candidate.id }, contextCap, metadataModelIdCaseFold, undefined, metadataConfigDir));
255
+ out.push(applyProviderConfigHints(name, prov, { ...dated, id: candidate.id }, contextCap, metadataModelIdCaseFold, undefined, metadataConfigDir, includeVisionSidecar));
254
256
  present.add(candidate.id);
255
257
  continue;
256
258
  }
@@ -0,0 +1,106 @@
1
+ import type { RawEntry } from "./parsing";
2
+ import { trustedAccountBoundNativeCatalogSlug } from "./account-models";
3
+ import { NATIVE_GPT6_ASTRA_MODEL, NATIVE_GPT61_SOL_MODEL } from "./native-models";
4
+
5
+ /**
6
+ * The Ultrafast speed choice OpenAI documents for GPT-6 Astra and GPT-6.1 Sol
7
+ * (https://developers.openai.com/api/docs/guides/ultrafast-mode and
8
+ * https://learn.chatgpt.com/docs/agent-configuration/speed, checked 2026-10-13).
9
+ *
10
+ * The upstream bundled catalog lists only `priority` for both models; ChatGPT's live model
11
+ * list adds Ultrafast for eligible plans. Codex stops consulting that live list once
12
+ * `model_catalog_json` points at our generated catalog, so without this row the speed picker
13
+ * never offers Ultrafast. The `ultraFastTier` switch is the operator's statement that their
14
+ * plan is eligible; the description still says the tier requires one.
15
+ */
16
+ export const NATIVE_ULTRAFAST_SERVICE_TIER: Readonly<{ id: string; name: string; description: string }> = Object.freeze({
17
+ id: "ultrafast",
18
+ name: "Ultrafast",
19
+ description: "Lower latency, increased usage; requires an eligible plan",
20
+ });
21
+
22
+ export const NATIVE_ULTRAFAST_MODELS: ReadonlySet<string> = new Set([NATIVE_GPT6_ASTRA_MODEL, NATIVE_GPT61_SOL_MODEL]);
23
+
24
+ function isUltraFastId(value: unknown): boolean {
25
+ return typeof value === "string" && value.trim().toLowerCase() === "ultrafast";
26
+ }
27
+
28
+ function isUltraFastDescriptor(value: unknown): boolean {
29
+ return value !== null && typeof value === "object" && "id" in value && isUltraFastId((value as { id: unknown }).id);
30
+ }
31
+
32
+ /**
33
+ * Provenance marker naming the tier fields this module added to a row. Ownership is never
34
+ * inferred from a descriptor's text: an operator may have written the very same entry, and only
35
+ * a row carrying this marker has anything for the switch to withdraw.
36
+ */
37
+ export const NATIVE_ULTRAFAST_PROVENANCE_FIELD = "opencodex_generated_service_tiers";
38
+ type TierField = "service_tiers" | "additional_speed_tiers";
39
+
40
+ function generatedFields(entry: RawEntry): Set<TierField> {
41
+ const raw = entry[NATIVE_ULTRAFAST_PROVENANCE_FIELD];
42
+ const fields = new Set<TierField>();
43
+ if (Array.isArray(raw)) {
44
+ for (const value of raw) if (value === "service_tiers" || value === "additional_speed_tiers") fields.add(value);
45
+ }
46
+ return fields;
47
+ }
48
+
49
+ function isGeneratedDescriptor(value: unknown): boolean {
50
+ if (!isUltraFastDescriptor(value)) return false;
51
+ const tier = value as Record<string, unknown>;
52
+ return Object.keys(tier).length === 3
53
+ && tier.id === NATIVE_ULTRAFAST_SERVICE_TIER.id
54
+ && tier.name === NATIVE_ULTRAFAST_SERVICE_TIER.name
55
+ && tier.description === NATIVE_ULTRAFAST_SERVICE_TIER.description;
56
+ }
57
+
58
+ /** Bare native rows and trusted account-bound clones of the two Ultrafast models. */
59
+ export function nativeUltraFastSlug(entry: RawEntry): string | undefined {
60
+ const slug = trustedAccountBoundNativeCatalogSlug(entry)
61
+ ?? (typeof entry.slug === "string" && !entry.slug.includes("/") ? entry.slug : undefined);
62
+ return slug !== undefined && NATIVE_ULTRAFAST_MODELS.has(slug) ? slug : undefined;
63
+ }
64
+
65
+ /**
66
+ * Add (enabled) or withdraw (disabled) the documented Ultrafast choice on an eligible native row.
67
+ *
68
+ * Enabling appends the descriptor to `service_tiers` and "ultrafast" to the deprecated
69
+ * `additional_speed_tiers` mirror, after the existing Fast tier and only when absent, and records
70
+ * each field it filled in the provenance marker. A repeated sync is a no-op and an
71
+ * operator-written Ultrafast entry wins. Disabling removes only what the marker names (and only
72
+ * the unedited generated descriptor), then drops the marker; rows without it are left as they
73
+ * are. The catalog default tier is never set.
74
+ */
75
+ export function applyNativeUltraFastTier(entry: RawEntry, enabled: boolean): void {
76
+ const owned = generatedFields(entry);
77
+ if (nativeUltraFastSlug(entry) === undefined) {
78
+ delete entry[NATIVE_ULTRAFAST_PROVENANCE_FIELD];
79
+ return;
80
+ }
81
+ const tiers = Array.isArray(entry.service_tiers) ? entry.service_tiers : undefined;
82
+ const speeds = Array.isArray(entry.additional_speed_tiers) ? entry.additional_speed_tiers : undefined;
83
+ if (enabled) {
84
+ if (!tiers?.some(isUltraFastDescriptor)) {
85
+ entry.service_tiers = [...(tiers ?? []), { ...NATIVE_ULTRAFAST_SERVICE_TIER }];
86
+ owned.add("service_tiers");
87
+ }
88
+ if (!speeds?.some(isUltraFastId)) {
89
+ entry.additional_speed_tiers = [...(speeds ?? []), NATIVE_ULTRAFAST_SERVICE_TIER.id];
90
+ owned.add("additional_speed_tiers");
91
+ }
92
+ if (owned.size > 0) entry[NATIVE_ULTRAFAST_PROVENANCE_FIELD] = [...owned].sort();
93
+ return;
94
+ }
95
+ delete entry[NATIVE_ULTRAFAST_PROVENANCE_FIELD];
96
+ if (owned.has("service_tiers") && tiers) {
97
+ const kept = tiers.filter(tier => !isGeneratedDescriptor(tier));
98
+ if (kept.length > 0) entry.service_tiers = kept;
99
+ else delete entry.service_tiers;
100
+ }
101
+ if (owned.has("additional_speed_tiers") && speeds) {
102
+ const kept = speeds.filter(speed => !isUltraFastId(speed));
103
+ if (kept.length > 0) entry.additional_speed_tiers = kept;
104
+ else delete entry.additional_speed_tiers;
105
+ }
106
+ }