Don't show the model for apikey (#3607)

This commit is contained in:
Ahmed Ibrahim
2025-09-14 21:32:18 -04:00
committed by GitHub
parent e5dd7f0934
commit 2ad6a37192
5 changed files with 87 additions and 58 deletions

View File

@@ -1,4 +1,6 @@
use codex_core::config::SWIFTFOX_MEDIUM_MODEL;
use codex_core::protocol_config_types::ReasoningEffort;
use codex_protocol::mcp_protocol::AuthMode;
/// A simple preset pairing a model slug with a reasoning effort.
#[derive(Debug, Clone, Copy)]
@@ -15,61 +17,65 @@ pub struct ModelPreset {
pub effort: Option<ReasoningEffort>,
}
/// Built-in list of model presets that pair a model with a reasoning effort.
///
/// Keep this UI-agnostic so it can be reused by both TUI and MCP server.
pub fn builtin_model_presets() -> &'static [ModelPreset] {
// Order groups swiftfox variants before gpt-5 presets, each from minimal to high.
const PRESETS: &[ModelPreset] = &[
ModelPreset {
id: "swiftfox-low",
label: "swiftfox low",
description: "",
model: "swiftfox",
effort: Some(ReasoningEffort::Low),
},
ModelPreset {
id: "swiftfox-medium",
label: "swiftfox medium",
description: "",
model: "swiftfox",
effort: None,
},
ModelPreset {
id: "swiftfox-high",
label: "swiftfox high",
description: "",
model: "swiftfox",
effort: Some(ReasoningEffort::High),
},
ModelPreset {
id: "gpt-5-minimal",
label: "gpt-5 minimal",
description: "— fastest responses with limited reasoning; ideal for coding, instructions, or lightweight tasks",
model: "gpt-5",
effort: Some(ReasoningEffort::Minimal),
},
ModelPreset {
id: "gpt-5-low",
label: "gpt-5 low",
description: "— balances speed with some reasoning; useful for straightforward queries and short explanations",
model: "gpt-5",
effort: Some(ReasoningEffort::Low),
},
ModelPreset {
id: "gpt-5-medium",
label: "gpt-5 medium",
description: "— default setting; provides a solid balance of reasoning depth and latency for general-purpose tasks",
model: "gpt-5",
effort: Some(ReasoningEffort::Medium),
},
ModelPreset {
id: "gpt-5-high",
label: "gpt-5 high",
description: "— maximizes reasoning depth for complex or ambiguous problems",
model: "gpt-5",
effort: Some(ReasoningEffort::High),
},
];
PRESETS
const PRESETS: &[ModelPreset] = &[
ModelPreset {
id: "swiftfox-low",
label: "swiftfox low",
description: "",
model: "swiftfox",
effort: Some(ReasoningEffort::Low),
},
ModelPreset {
id: "swiftfox-medium",
label: "swiftfox medium",
description: "",
model: "swiftfox",
effort: None,
},
ModelPreset {
id: "swiftfox-high",
label: "swiftfox high",
description: "",
model: "swiftfox",
effort: Some(ReasoningEffort::High),
},
ModelPreset {
id: "gpt-5-minimal",
label: "gpt-5 minimal",
description: "— fastest responses with limited reasoning; ideal for coding, instructions, or lightweight tasks",
model: "gpt-5",
effort: Some(ReasoningEffort::Minimal),
},
ModelPreset {
id: "gpt-5-low",
label: "gpt-5 low",
description: "— balances speed with some reasoning; useful for straightforward queries and short explanations",
model: "gpt-5",
effort: Some(ReasoningEffort::Low),
},
ModelPreset {
id: "gpt-5-medium",
label: "gpt-5 medium",
description: "— default setting; provides a solid balance of reasoning depth and latency for general-purpose tasks",
model: "gpt-5",
effort: Some(ReasoningEffort::Medium),
},
ModelPreset {
id: "gpt-5-high",
label: "gpt-5 high",
description: "— maximizes reasoning depth for complex or ambiguous problems",
model: "gpt-5",
effort: Some(ReasoningEffort::High),
},
];
pub fn builtin_model_presets(auth_mode: Option<AuthMode>) -> Vec<ModelPreset> {
match auth_mode {
Some(AuthMode::ApiKey) => PRESETS
.iter()
.copied()
.filter(|p| !p.model.contains(SWIFTFOX_MEDIUM_MODEL))
.collect(),
_ => PRESETS.to_vec(),
}
}

View File

@@ -38,6 +38,7 @@ pub(crate) struct App {
pub(crate) server: Arc<ConversationManager>,
pub(crate) app_event_tx: AppEventSender,
pub(crate) chat_widget: ChatWidget,
pub(crate) auth_manager: Arc<AuthManager>,
/// Config is stored here so we can recreate ChatWidgets as needed.
pub(crate) config: Config,
@@ -88,6 +89,7 @@ impl App {
initial_prompt: initial_prompt.clone(),
initial_images: initial_images.clone(),
enhanced_keys_supported,
auth_manager: auth_manager.clone(),
};
ChatWidget::new(init, conversation_manager.clone())
}
@@ -109,6 +111,7 @@ impl App {
initial_prompt: initial_prompt.clone(),
initial_images: initial_images.clone(),
enhanced_keys_supported,
auth_manager: auth_manager.clone(),
};
ChatWidget::new_from_existing(
init,
@@ -124,6 +127,7 @@ impl App {
server: conversation_manager,
app_event_tx,
chat_widget,
auth_manager: auth_manager.clone(),
config,
active_profile,
file_search,
@@ -205,6 +209,7 @@ impl App {
initial_prompt: None,
initial_images: Vec::new(),
enhanced_keys_supported: self.enhanced_keys_supported,
auth_manager: self.auth_manager.clone(),
};
self.chat_widget = ChatWidget::new(init, self.server.clone());
tui.frame_requester().schedule_frame();
@@ -418,6 +423,7 @@ mod tests {
use crate::app_backtrack::BacktrackState;
use crate::chatwidget::tests::make_chatwidget_manual_with_sender;
use crate::file_search::FileSearchManager;
use codex_core::AuthManager;
use codex_core::CodexAuth;
use codex_core::ConversationManager;
use std::sync::Arc;
@@ -430,12 +436,15 @@ mod tests {
let server = Arc::new(ConversationManager::with_auth(CodexAuth::from_api_key(
"Test API Key",
)));
let auth_manager =
AuthManager::from_auth_for_testing(CodexAuth::from_api_key("Test API Key"));
let file_search = FileSearchManager::new(config.cwd.clone(), app_event_tx.clone());
App {
server,
app_event_tx,
chat_widget,
auth_manager,
config,
active_profile: None,
file_search,

View File

@@ -335,6 +335,7 @@ impl App {
initial_prompt: None,
initial_images: Vec::new(),
enhanced_keys_supported: self.enhanced_keys_supported,
auth_manager: self.auth_manager.clone(),
};
self.chat_widget =
crate::chatwidget::ChatWidget::new_from_existing(init, conv, session_configured);

View File

@@ -82,6 +82,7 @@ use codex_common::approval_presets::ApprovalPreset;
use codex_common::approval_presets::builtin_approval_presets;
use codex_common::model_presets::ModelPreset;
use codex_common::model_presets::builtin_model_presets;
use codex_core::AuthManager;
use codex_core::ConversationManager;
use codex_core::protocol::AskForApproval;
use codex_core::protocol::SandboxPolicy;
@@ -103,6 +104,7 @@ pub(crate) struct ChatWidgetInit {
pub(crate) initial_prompt: Option<String>,
pub(crate) initial_images: Vec<PathBuf>,
pub(crate) enhanced_keys_supported: bool,
pub(crate) auth_manager: Arc<AuthManager>,
}
pub(crate) struct ChatWidget {
@@ -111,6 +113,7 @@ pub(crate) struct ChatWidget {
bottom_pane: BottomPane,
active_exec_cell: Option<ExecCell>,
config: Config,
auth_manager: Arc<AuthManager>,
session_header: SessionHeader,
initial_user_message: Option<UserMessage>,
token_info: Option<TokenUsageInfo>,
@@ -646,6 +649,7 @@ impl ChatWidget {
initial_prompt,
initial_images,
enhanced_keys_supported,
auth_manager,
} = common;
let mut rng = rand::rng();
let placeholder = EXAMPLE_PROMPTS[rng.random_range(0..EXAMPLE_PROMPTS.len())].to_string();
@@ -665,6 +669,7 @@ impl ChatWidget {
}),
active_exec_cell: None,
config: config.clone(),
auth_manager,
session_header: SessionHeader::new(config.model.clone()),
initial_user_message: create_initial_user_message(
initial_prompt.unwrap_or_default(),
@@ -697,6 +702,7 @@ impl ChatWidget {
initial_prompt,
initial_images,
enhanced_keys_supported,
auth_manager,
} = common;
let mut rng = rand::rng();
let placeholder = EXAMPLE_PROMPTS[rng.random_range(0..EXAMPLE_PROMPTS.len())].to_string();
@@ -718,6 +724,7 @@ impl ChatWidget {
}),
active_exec_cell: None,
config: config.clone(),
auth_manager,
session_header: SessionHeader::new(config.model.clone()),
initial_user_message: create_initial_user_message(
initial_prompt.unwrap_or_default(),
@@ -1188,7 +1195,8 @@ impl ChatWidget {
pub(crate) fn open_model_popup(&mut self) {
let current_model = self.config.model.clone();
let current_effort = self.config.model_reasoning_effort;
let presets: &[ModelPreset] = builtin_model_presets();
let auth_mode = self.auth_manager.auth().map(|auth| auth.mode);
let presets: Vec<ModelPreset> = builtin_model_presets(auth_mode);
let mut items: Vec<SelectionItem> = Vec::new();
for preset in presets.iter() {

View File

@@ -1,6 +1,7 @@
use super::*;
use crate::app_event::AppEvent;
use crate::app_event_sender::AppEventSender;
use codex_core::AuthManager;
use codex_core::CodexAuth;
use codex_core::config::Config;
use codex_core::config::ConfigOverrides;
@@ -195,6 +196,7 @@ async fn helpers_are_available_and_do_not_panic() {
let conversation_manager = Arc::new(ConversationManager::with_auth(CodexAuth::from_api_key(
"test",
)));
let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::from_api_key("test"));
let init = ChatWidgetInit {
config: cfg,
frame_requester: FrameRequester::test_dummy(),
@@ -202,6 +204,7 @@ async fn helpers_are_available_and_do_not_panic() {
initial_prompt: None,
initial_images: Vec::new(),
enhanced_keys_supported: false,
auth_manager,
};
let mut w = ChatWidget::new(init, conversation_manager);
// Basic construction sanity.
@@ -226,12 +229,14 @@ fn make_chatwidget_manual() -> (
placeholder_text: "Ask Codex to do anything".to_string(),
disable_paste_burst: false,
});
let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::from_api_key("test"));
let widget = ChatWidget {
app_event_tx,
codex_op_tx: op_tx,
bottom_pane: bottom,
active_exec_cell: None,
config: cfg.clone(),
auth_manager,
session_header: SessionHeader::new(cfg.model.clone()),
initial_user_message: None,
token_info: None,