diff --git a/crates/codegen/kigi-models/src/lib.rs b/crates/codegen/kigi-models/src/lib.rs index 941cf54..50fadc1 100644 --- a/crates/codegen/kigi-models/src/lib.rs +++ b/crates/codegen/kigi-models/src/lib.rs @@ -1286,8 +1286,8 @@ const OPENAI_CODEX_SPEC: PlatformSpec = PlatformSpec { strip_listing_id_prefix: None, }; -/// The platform registry. Platforms are compiled-in spec rows; there is no -/// dynamic provider registration (PRD F2). +/// The platform registry. Platforms are compiled-in spec rows; user-declared +/// providers live in [`custom`], never here. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum PlatformId { /// Kimi Code subscription (OAuth bearer from the F1 device flow). @@ -1571,8 +1571,8 @@ impl PlatformId { /// The compiled-in catalog for a platform that serves NO live `/models` /// listing (openai-codex), or `None` when the catalog comes from the wire. /// - /// openai-codex's 7 models are HARDCODED (read from the Codex backend - /// catalog on 2026-09-22, the `visibility=="list"` AND + /// openai-codex's 8 models are HARDCODED (read from the Codex backend + /// catalog on 2026-09-29, the `visibility=="list"` AND /// `supported_in_api==true` set) because OpenAI exposes no stable public /// models endpoint for the /// ChatGPT Codex backend. Each entry carries context window + per-model @@ -1608,8 +1608,8 @@ fn codex_wire_model(slug: &str, display_name: &str, efforts: &[&str], default: & } } -/// The HARDCODED openai-codex catalog: exactly the 7 `visibility=="list"` AND -/// `supported_in_api==true` models the Codex backend served on 2026-09-22, in +/// The HARDCODED openai-codex catalog: exactly the 8 `visibility=="list"` AND +/// `supported_in_api==true` models the Codex backend served on 2026-09-29, in /// its own priority order. `gpt-reserve` and `codex-auto-review` /// (visibility="hide") are deliberately EXCLUDED — they are not user-facing /// (fail-fast: never advertise a model the backend rejects). Several models @@ -1617,6 +1617,12 @@ fn codex_wire_model(slug: &str, display_name: &str, efforts: &[&str], default: & /// is not listed here. fn openai_codex_wire_models() -> Vec { vec![ + codex_wire_model( + "gpt-6.1-sol", + "GPT-6.1-Sol", + &["low", "medium", "high", "xhigh", "max"], + "low", + ), codex_wire_model( "gpt-6-astra", "GPT-6-Astra", @@ -2674,13 +2680,13 @@ mod tests { assert_eq!(c.base_url(), "https://mock.codex/codex"); } - /// The HARDCODED openai-codex catalog is exactly the 7 supported+listed + /// The HARDCODED openai-codex catalog is exactly the 8 supported+listed /// models, keyed by slug, ctx 272000, each exposing its exact supported /// efforts (incl. the codex-only `xhigh`/`max` tiers). The hidden models /// are absent. Every other platform serves NO hardcoded catalog (its /// models come from the live wire). #[test] - fn openai_codex_hardcoded_catalog_is_the_seven_supported_models() { + fn openai_codex_hardcoded_catalog_is_the_eight_supported_models() { let catalog = PlatformId::OpenaiCodex .hardcoded_catalog() .expect("openai-codex serves a hardcoded catalog"); @@ -2688,6 +2694,7 @@ mod tests { assert_eq!( ids, vec![ + "gpt-6.1-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", @@ -2696,7 +2703,7 @@ mod tests { "gpt-5.6-luna", "gpt-5.5" ], - "exactly the 7 visibility=list AND supported_in_api=true models" + "exactly the 8 visibility=list AND supported_in_api=true models" ); // Excluded: hidden models never appear. for absent in ["gpt-reserve", "codex-auto-review"] { @@ -2729,6 +2736,10 @@ mod tests { ["low", "medium", "high", "xhigh", "max"], "`ultra` is advertised above `max` but kigi has no such level" ); + assert_eq!( + efforts("gpt-6.1-sol"), + ["low", "medium", "high", "xhigh", "max"] + ); assert_eq!( efforts("gpt-6-sol"), ["low", "medium", "high", "xhigh", "max"] @@ -2762,6 +2773,7 @@ mod tests { .default_effort .clone() }; + assert_eq!(default("gpt-6.1-sol").as_deref(), Some("low")); assert_eq!(default("gpt-6-astra").as_deref(), Some("medium")); assert_eq!(default("gpt-6-sol").as_deref(), Some("medium")); assert_eq!(default("gpt-6-luna").as_deref(), Some("medium")); diff --git a/crates/codegen/kigi-sampling-types/src/types.rs b/crates/codegen/kigi-sampling-types/src/types.rs index 2c4f69a..25f9b16 100644 --- a/crates/codegen/kigi-sampling-types/src/types.rs +++ b/crates/codegen/kigi-sampling-types/src/types.rs @@ -1202,7 +1202,7 @@ pub const CODEX_OPENAI_BETA: &str = "responses=experimental"; /// openai-codex-gated). The Codex backend does not strictly validate the UA /// string (Pi ships its own and it works), so this is a stable best-effort /// identity, not a pinned build. -pub const CODEX_USER_AGENT: &str = "codex_cli_rs/0.156.0"; +pub const CODEX_USER_AGENT: &str = "codex_cli_rs/0.159.0"; /// JWT payload claim namespace carrying the ChatGPT account id. const CODEX_JWT_AUTH_CLAIM: &str = "https://api.openai.com/auth"; diff --git a/crates/codegen/kigi-shell/src/agent/models_fetch.rs b/crates/codegen/kigi-shell/src/agent/models_fetch.rs index 950ebd2..371448b 100644 --- a/crates/codegen/kigi-shell/src/agent/models_fetch.rs +++ b/crates/codegen/kigi-shell/src/agent/models_fetch.rs @@ -1559,6 +1559,7 @@ mod tests { .map(|m| m.id.as_deref().unwrap_or_default()) .collect::>(), vec![ + "openai-codex/gpt-6.1-sol", "openai-codex/gpt-6-astra", "openai-codex/gpt-6-sol", "openai-codex/gpt-6-luna", @@ -1567,7 +1568,7 @@ mod tests { "openai-codex/gpt-5.6-luna", "openai-codex/gpt-5.5", ], - "exactly the 7 hardcoded models, keyed openai-codex/" + "exactly the 8 hardcoded models, keyed openai-codex/" ); // Excluded models never appear. for absent in ["openai-codex/gpt-reserve", "openai-codex/codex-auto-review"] { @@ -1579,9 +1580,9 @@ mod tests { "{absent} must be absent from the hardcoded catalog" ); } - let astra = &result.models[0]; - assert_eq!(astra.name.as_deref(), Some("GPT-6-Astra")); - assert_eq!(astra.context_window.get(), 272_000); + let first = &result.models[0]; + assert_eq!(first.name.as_deref(), Some("GPT-6.1-Sol")); + assert_eq!(first.context_window.get(), 272_000); let sol = result .models .iter()