mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
auto-picker
This commit is contained in:
@@ -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((
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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)");
|
||||
|
||||
@@ -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()
|
||||
});
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user