diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_fast_mode_footer.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_fast_mode_footer.snap index c558ac4726..5848dac563 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_fast_mode_footer.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_fast_mode_footer.snap @@ -6,4 +6,4 @@ expression: normalized_backend_snapshot(terminal.backend()) " " "› Ask Codex to do anything " " " -" Fast on " +" gpt-5.2 high " diff --git a/codex-rs/tui/src/chatwidget/status_surfaces.rs b/codex-rs/tui/src/chatwidget/status_surfaces.rs index 66c7b26d8a..8f37252bf3 100644 --- a/codex-rs/tui/src/chatwidget/status_surfaces.rs +++ b/codex-rs/tui/src/chatwidget/status_surfaces.rs @@ -760,13 +760,23 @@ impl ChatWidget { .and_then(|usage| usage.estimated_usage_usd_micros) .and_then(format_estimated_usd_micros), StatusLineItem::SessionId => self.thread_id.map(|id| id.to_string()), - StatusLineItem::FastMode => Some( - if self.current_service_tier() == Some(ServiceTier::Fast.request_value()) { - "Fast on".to_string() - } else { - "Fast off".to_string() - }, - ), + StatusLineItem::FastMode => self + .model_catalog + .try_list_models() + .ok() + .and_then(|models| { + models + .into_iter() + .find(|preset| preset.model == self.current_model()) + }) + .is_none_or(|preset| preset.supports_fast_mode()) + .then(|| { + if self.current_service_tier() == Some(ServiceTier::Fast.request_value()) { + "Fast on".to_string() + } else { + "Fast off".to_string() + } + }), StatusLineItem::RawOutput => self.raw_output_mode().then(|| "raw output".to_string()), StatusLineItem::ThreadTitle => self.thread_name.as_ref().map_or_else( || self.thread_id.map(|id| id.to_string()), diff --git a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs index b80923dfd9..52a9e34972 100644 --- a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs +++ b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs @@ -3806,7 +3806,8 @@ async fn completed_turn_clears_visible_running_hook() { #[tokio::test] async fn status_line_fast_mode_renders_on_and_off() { - let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await; + let (mut chat, _rx, _op_rx) = make_chatwidget_manual(Some("gpt-5.4")).await; + set_fast_mode_test_catalog(&mut chat); chat.config.tui_status_line = Some(vec!["fast-mode".to_string()]); chat.refresh_status_line(); @@ -3817,15 +3818,40 @@ async fn status_line_fast_mode_renders_on_and_off() { assert_eq!(status_line_text(&chat), Some("Fast on".to_string())); } +#[tokio::test] +async fn status_line_fast_mode_updates_visibility_on_model_change() { + let (mut chat, _rx, _op_rx) = make_chatwidget_manual(Some("gpt-5.4")).await; + set_fast_mode_test_catalog(&mut chat); + chat.config.tui_status_line = Some(vec!["fast-mode".to_string()]); + + chat.refresh_status_line(); + assert_eq!(status_line_text(&chat), Some("Fast off".to_string())); + + chat.set_model("gpt-5.2"); + assert_eq!(status_line_text(&chat), None); + + chat.set_model("gpt-5.4"); + assert_eq!(status_line_text(&chat), Some("Fast off".to_string())); + + chat.set_model("uncatalogued-model"); + assert_eq!(status_line_text(&chat), Some("Fast off".to_string())); + chat.set_service_tier(Some(ServiceTier::Fast.request_value().to_string())); + assert_eq!(status_line_text(&chat), Some("Fast on".to_string())); +} + #[tokio::test] async fn status_line_fast_mode_footer_snapshot() { use ratatui::Terminal; use ratatui::backend::TestBackend; - let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await; + let (mut chat, _rx, _op_rx) = make_chatwidget_manual(Some("gpt-5.2")).await; + set_fast_mode_test_catalog(&mut chat); chat.show_welcome_banner = false; - chat.config.tui_status_line = Some(vec!["fast-mode".to_string()]); - chat.set_service_tier(Some(ServiceTier::Fast.request_value().to_string())); + chat.config.tui_status_line = Some(vec![ + "model-with-reasoning".to_string(), + "fast-mode".to_string(), + ]); + chat.set_reasoning_effort(Some(ReasoningEffortConfig::High)); chat.refresh_status_line(); let width = 80;