Hide Fast mode status for unsupported models (#39999)

## Why

The `fast-mode` status item showed `Fast off` even when the selected model did not support Fast mode.

## What changed

- Hide the Fast mode status value when the current model is known not to support Fast mode.
- Continue showing the value for supported and uncatalogued models.

## Testing

- Cover visibility updates when switching among supported, unsupported, and uncatalogued models.
- Update the footer snapshot to verify that an unsupported model omits the Fast mode value.

GitOrigin-RevId: c297655189efc719b2097c2aa415029b01d6873e
This commit is contained in:
Benjamin Carlsson
2026-08-21 19:47:49 +00:00
committed by copyberry
parent df6a54ee85
commit 9cdc66904f
3 changed files with 48 additions and 12 deletions
@@ -6,4 +6,4 @@ expression: normalized_backend_snapshot(terminal.backend())
" "
"› Ask Codex to do anything "
" "
" Fast on "
" gpt-5.2 high "
+17 -7
View File
@@ -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()),
@@ -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;