Don't show the model for apikey (#3607)
This commit is contained in:
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user