auto-picker

This commit is contained in:
Ahmed Ibrahim
2025-11-18 15:37:25 -08:00
parent e7227ffec8
commit c7e6666337
5 changed files with 47 additions and 5 deletions

View File

@@ -1,6 +1,7 @@
use codex_core::WireApi;
use codex_core::config::Config;
use crate::model_presets::reasoning_effort_label_for_model;
use crate::sandbox_summary::summarize_sandbox_policy;
/// Build a list of key/value pairs summarizing the effective configuration.
@@ -19,7 +20,7 @@ pub fn create_config_summary_entries(config: &Config) -> Vec<(&'static str, Stri
"reasoning effort",
config
.model_reasoning_effort
.map(|effort| effort.to_string())
.map(|effort| reasoning_effort_label_for_model(&config.model, effort))
.unwrap_or_else(|| "none".to_string()),
));
entries.push((

View File

@@ -271,6 +271,16 @@ impl ModelPreset {
.unwrap_or_else(|| effort.to_string())
}
}
/// Return the display label for a reasoning effort on a given model, falling back to the effort
/// name when no label is provided.
pub fn reasoning_effort_label_for_model(model: &str, effort: ReasoningEffort) -> String {
all_model_presets()
.iter()
.find(|preset| preset.model == model)
.map(|preset| preset.reasoning_effort_label(effort))
.unwrap_or_else(|| effort.to_string())
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -19,6 +19,7 @@ use crate::update_action::UpdateAction;
use codex_ansi_escape::ansi_escape_line;
use codex_common::model_presets::ModelUpgrade;
use codex_common::model_presets::all_model_presets;
use codex_common::model_presets::reasoning_effort_label_for_model;
use codex_core::AuthManager;
use codex_core::ConversationManager;
use codex_core::config::Config;
@@ -99,7 +100,8 @@ fn should_show_model_migration_prompt(
fn format_model_change_target(model: &str, effort: Option<ReasoningEffortConfig>) -> String {
if let Some(effort) = effort {
format!("{model} ({effort})")
let effort_label = reasoning_effort_label_for_model(model, effort);
format!("{model} ({effort_label})")
} else {
format!("{model} with default reasoning")
}
@@ -1128,11 +1130,11 @@ mod tests {
fn format_model_change_target_prefers_featured_label() {
let formatted =
super::format_model_change_target("codex-auto", Some(ReasoningEffortConfig::Low));
assert_eq!(formatted, "codex-auto (low)");
assert_eq!(formatted, "codex-auto (Fast)");
}
#[test]
fn format_model_change_target_uses_effort_label() {
fn format_model_change_target_falls_back_to_effort_name_when_no_label() {
let formatted =
super::format_model_change_target("gpt-5.1-codex", Some(ReasoningEffortConfig::High));
assert_eq!(formatted, "gpt-5.1-codex (high)");

View File

@@ -1996,7 +1996,7 @@ impl ChatWidget {
actions: vec![Box::new(|tx| {
tx.send(AppEvent::OpenAllModelsPopup);
})],
dismiss_on_select: true,
dismiss_on_select: false,
..Default::default()
});

View File

@@ -1464,6 +1464,9 @@ fn model_selection_popup_chatgpt_auth_snapshot() {
fn featured_model_popup_hides_default_label_when_option_is_current() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();
chat.auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
let preset = builtin_model_presets(None)
.into_iter()
.find(|preset| preset.is_default)
@@ -1483,6 +1486,32 @@ fn featured_model_popup_hides_default_label_when_option_is_current() {
);
}
#[test]
fn esc_on_all_models_returns_to_featured_picker() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();
chat.auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
chat.open_model_popup();
// Select "All models" from the featured picker (option 4) and open the full list.
chat.handle_key_event(KeyEvent::new(KeyCode::Char('4'), KeyModifiers::NONE));
chat.open_all_models_popup();
assert!(
!chat.bottom_pane.is_normal_backtrack_mode(),
"all models popup should be stacked on top of the featured picker"
);
// Esc should close the all-models list but leave the featured picker visible.
chat.handle_key_event(KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE));
assert!(
!chat.bottom_pane.is_normal_backtrack_mode(),
"esc should return to the featured picker instead of dismissing the model picker"
);
}
#[test]
fn approvals_selection_popup_snapshot() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();