diff --git a/crates/codegen/kigi-models/src/lib.rs b/crates/codegen/kigi-models/src/lib.rs index 54fd1d2..5732151 100644 --- a/crates/codegen/kigi-models/src/lib.rs +++ b/crates/codegen/kigi-models/src/lib.rs @@ -1574,7 +1574,7 @@ impl PlatformId { /// `models_cache.json`, 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 - /// selectable reasoning efforts (incl. the codex-only `xhigh`/`max`/`ultra` + /// selectable reasoning efforts (incl. the codex-only `xhigh`/`max` /// tiers), so the fetch path maps them through the SAME /// `platform_wire_model_to_entry` output as a live listing — no new type. pub fn hardcoded_catalog(self) -> Option> { @@ -1617,13 +1617,13 @@ fn openai_codex_wire_models() -> Vec { codex_wire_model( "gpt-5.6-sol", "GPT-5.6-Sol", - &["low", "medium", "high", "xhigh", "max", "ultra"], + &["low", "medium", "high", "xhigh", "max"], "low", ), codex_wire_model( "gpt-5.6-terra", "GPT-5.6-Terra", - &["low", "medium", "high", "xhigh", "max", "ultra"], + &["low", "medium", "high", "xhigh", "max"], "medium", ), codex_wire_model( @@ -2655,7 +2655,7 @@ mod tests { /// The HARDCODED openai-codex catalog is exactly the 4 supported+listed /// models, keyed by slug, ctx 272000, each exposing its exact supported - /// efforts (incl. the codex-only `xhigh`/`max`/`ultra` tiers). The + /// efforts (incl. the codex-only `xhigh`/`max` tiers). The /// list-but-broken / hidden models are absent. Every other platform serves /// NO hardcoded catalog (its models come from the live wire). #[test] @@ -2702,11 +2702,11 @@ mod tests { }; assert_eq!( efforts("gpt-5.6-sol"), - ["low", "medium", "high", "xhigh", "max", "ultra"] + ["low", "medium", "high", "xhigh", "max"] ); assert_eq!( efforts("gpt-5.6-terra"), - ["low", "medium", "high", "xhigh", "max", "ultra"] + ["low", "medium", "high", "xhigh", "max"] ); assert_eq!( efforts("gpt-5.6-luna"), diff --git a/crates/codegen/kigi-sampling-types/src/types.rs b/crates/codegen/kigi-sampling-types/src/types.rs index b5d44a4..0fcbf21 100644 --- a/crates/codegen/kigi-sampling-types/src/types.rs +++ b/crates/codegen/kigi-sampling-types/src/types.rs @@ -911,11 +911,6 @@ pub enum ReasoningEffort { /// Messages both accept `xhigh` AND `max` as separate levels in 2026; /// the Kimi wire spells its top tier `max` with no `xhigh`). Max, - /// Codex-only top tier above `max` (the ChatGPT Codex backend exposes an - /// `ultra` reasoning effort on its flagship models). Reachable ONLY via a - /// model's server-declared effort menu (openai-codex); no built-in fallback - /// menu offers it, so other providers never emit it. - Ultra, } impl ReasoningEffort { @@ -944,15 +939,12 @@ impl ReasoningEffort { Self::High => "high", Self::Xhigh => "xhigh", Self::Max => "max", - Self::Ultra => "ultra", } } /// Anthropic Messages API effort string; `None` for unsupported variants. /// `xhigh` and `max` are distinct levels on the 2026 Messages API (both - /// appear in `GET /v1/models` `capabilities.effort`). `ultra` is codex-only - /// and never selected on an Anthropic model, but maps to its own string for - /// completeness (the Responses path writes effort via `as_str`, not this). + /// appear in `GET /v1/models` `capabilities.effort`). pub fn to_messages_api(self) -> Option<&'static str> { match self { Self::None | Self::Minimal => None, @@ -961,7 +953,6 @@ impl ReasoningEffort { Self::High => Some("high"), Self::Xhigh => Some("xhigh"), Self::Max => Some("max"), - Self::Ultra => Some("ultra"), } } } @@ -984,9 +975,8 @@ impl std::str::FromStr for ReasoningEffort { "high" => Ok(Self::High), "xhigh" => Ok(Self::Xhigh), "max" => Ok(Self::Max), - "ultra" => Ok(Self::Ultra), _ => Err(format!( - "invalid reasoning effort: {s:?} (expected one of: none, minimal, low, medium, high, xhigh, max, ultra)" + "invalid reasoning effort: {s:?} (expected one of: none, minimal, low, medium, high, xhigh, max)" )), } } @@ -1878,30 +1868,16 @@ mod tests { assert_eq!(ReasoningEffort::Max.to_messages_api(), Some("max")); } - /// The codex-only `ultra` tier parses, serializes, and patches onto a - /// Responses body as `reasoning.effort = "ultra"` (the crux of surfacing a - /// codex model's full thinking menu). It is a DISTINCT level above `max`. + /// `ultra` is not a tier any backend accepts. + /// + /// The Codex Responses endpoint rejects it with a 400 listing its menu, + /// which tops out at `max`. Parsing it would only send it again. #[test] - fn reasoning_effort_ultra_is_a_distinct_codex_tier() { - assert_eq!( - "ultra".parse::().unwrap(), - ReasoningEffort::Ultra - ); - assert_eq!( - "ULTRA".parse::().unwrap(), - ReasoningEffort::Ultra - ); - assert_ne!(ReasoningEffort::Ultra, ReasoningEffort::Max); - assert_eq!(ReasoningEffort::Ultra.as_str(), "ultra"); - let json = serde_json::to_string(&ReasoningEffort::Ultra).unwrap(); - assert_eq!(json, "\"ultra\""); - assert_eq!( - serde_json::from_str::("\"ultra\"").unwrap(), - ReasoningEffort::Ultra - ); - let mut body = serde_json::json!({ "model": "gpt-5.6-sol" }); - patch_reasoning_effort(&mut body, Some(ReasoningEffort::Ultra)); - assert_eq!(body["reasoning"]["effort"], "ultra"); + fn reasoning_effort_ultra_is_not_a_tier() { + assert!("ultra".parse::().is_err()); + assert!("ULTRA".parse::().is_err()); + assert!(serde_json::from_str::("\"ultra\"").is_err()); + assert_eq!(ReasoningEffort::Max.as_str(), "max"); } /// The account id is decoded STATELESSLY from the bearer JWT payload's @@ -2122,7 +2098,7 @@ mod tests { ); let bad_type = as_map(serde_json::json!({"reasoningEffort": 3})); assert_eq!(parse_reasoning_effort_meta(Some(&bad_type)), None); - // `ultra` is a real codex tier; a genuinely-unknown token still None. + // A genuinely-unknown token is dropped, not guessed at. let unknown = as_map(serde_json::json!({"reasoningEffort": "MEGA"})); assert_eq!(parse_reasoning_effort_meta(Some(&unknown)), None); } diff --git a/crates/codegen/kigi-shell/src/agent/models_fetch.rs b/crates/codegen/kigi-shell/src/agent/models_fetch.rs index b54406e..2c6c638 100644 --- a/crates/codegen/kigi-shell/src/agent/models_fetch.rs +++ b/crates/codegen/kigi-shell/src/agent/models_fetch.rs @@ -1475,7 +1475,7 @@ mod tests { /// short-circuits BEFORE any HTTP — there is NO mock `/models` server, yet /// the fetch returns exactly the 4 compiled-in models keyed /// `openai-codex/` on the Responses backend, ctx 272000, each exposing - /// its exact reasoning efforts (incl. the codex-only `xhigh`/`max`/`ultra`). + /// its exact reasoning efforts (incl. the codex-only `xhigh`/`max`). /// A BOGUS base URL confirms no live `/models` request is attempted (it would /// otherwise fail against an unroutable host). #[tokio::test(flavor = "multi_thread")] @@ -1556,10 +1556,10 @@ mod tests { .iter() .map(|o| o.id.as_str()) .collect::>(), - vec!["low", "medium", "high", "xhigh", "max", "ultra"], - "sol exposes the full codex effort menu incl. ultra" + vec!["low", "medium", "high", "xhigh", "max"], + "sol exposes the full codex effort menu" ); - // gpt-5.5 tops out at xhigh (no max/ultra). + // gpt-5.5 tops out at xhigh (no max). let five_five = result .models .iter() diff --git a/crates/codegen/kigi-shell/src/agent/session_config.rs b/crates/codegen/kigi-shell/src/agent/session_config.rs index eb19d52..e363de9 100644 --- a/crates/codegen/kigi-shell/src/agent/session_config.rs +++ b/crates/codegen/kigi-shell/src/agent/session_config.rs @@ -60,7 +60,6 @@ fn effort_label(effort: ReasoningEffort) -> String { ReasoningEffort::High => "High", ReasoningEffort::Xhigh => "X-High", ReasoningEffort::Max => "Max", - ReasoningEffort::Ultra => "Ultra", } .to_string() } diff --git a/crates/codegen/kigi-tui/src/slash/commands/effort_levels.rs b/crates/codegen/kigi-tui/src/slash/commands/effort_levels.rs index e90d918..bb8bd03 100644 --- a/crates/codegen/kigi-tui/src/slash/commands/effort_levels.rs +++ b/crates/codegen/kigi-tui/src/slash/commands/effort_levels.rs @@ -25,7 +25,6 @@ pub(crate) fn effort_description(level: ReasoningEffort) -> &'static str { ReasoningEffort::High => "Heavy reasoning", ReasoningEffort::Xhigh => "Extra-heavy reasoning", ReasoningEffort::Max => "Maximum reasoning", - ReasoningEffort::Ultra => "Ultra reasoning", } }