From ff5f74b6bf119af6d91c30911e1b9665afeb4cc7 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Mon, 5 Jan 2026 09:22:04 -0800 Subject: [PATCH] models --- codex-rs/core/src/models_manager/manager.rs | 4 +- codex-rs/tui/src/model_migration.rs | 144 ++++++++++---------- codex-rs/tui2/src/model_migration.rs | 144 ++++++++++---------- 3 files changed, 146 insertions(+), 146 deletions(-) diff --git a/codex-rs/core/src/models_manager/manager.rs b/codex-rs/core/src/models_manager/manager.rs index e3bbc8517e..85bb761ecd 100644 --- a/codex-rs/core/src/models_manager/manager.rs +++ b/codex-rs/core/src/models_manager/manager.rs @@ -82,6 +82,7 @@ impl ModelsManager { /// Fetch the latest remote models, using the on-disk cache when still fresh. pub async fn refresh_available_models_with_cache(&self, config: &Config) -> CoreResult<()> { + let _refresh_guard = self.refresh_lock.lock().await; if !config.features.enabled(Feature::RemoteModels) || self.auth_manager.get_auth_mode() == Some(AuthMode::ApiKey) { @@ -93,11 +94,10 @@ impl ModelsManager { self.refresh_available_models_no_cache().await } - pub(crate) async fn refresh_available_models_no_cache(&self) -> CoreResult<()> { + async fn refresh_available_models_no_cache(&self) -> CoreResult<()> { if self.auth_manager.get_auth_mode() == Some(AuthMode::ApiKey) { return Ok(()); } - let _refresh_guard = self.refresh_lock.lock().await; let auth = self.auth_manager.auth(); let api_provider = self.provider.to_api_provider(Some(AuthMode::ChatGPT))?; let api_auth = auth_provider_from_auth(auth.clone(), &self.provider).await?; diff --git a/codex-rs/tui/src/model_migration.rs b/codex-rs/tui/src/model_migration.rs index 0fd5e411cc..67ccf08dd1 100644 --- a/codex-rs/tui/src/model_migration.rs +++ b/codex-rs/tui/src/model_migration.rs @@ -8,8 +8,6 @@ use serde::Serialize; use std::io; use std::path::PathBuf; -const PENDING_MODEL_MIGRATION_NOTICE_FILENAME: &str = "pending_model_migration_notice.json"; - #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct PendingModelMigrationNotice { pub(crate) from_model: String, @@ -19,53 +17,6 @@ pub(crate) struct PendingModelMigrationNotice { pub(crate) migration_config_key: Option, } -fn pending_model_migration_notice_path(config: &Config) -> PathBuf { - config - .codex_home - .join(PENDING_MODEL_MIGRATION_NOTICE_FILENAME) -} - -fn migration_prompt_hidden(config: &Config, migration_config_key: &str) -> bool { - match migration_config_key { - HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG => config - .notices - .hide_gpt_5_1_codex_max_migration_prompt - .unwrap_or(false), - HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG => { - config.notices.hide_gpt5_1_migration_prompt.unwrap_or(false) - } - _ => false, - } -} - -fn should_show_model_migration_notice( - current_model: &str, - target_model: &str, - available_models: &[ModelPreset], - config: &Config, -) -> bool { - if target_model == current_model { - return false; - } - - if let Some(seen_target) = config.notices.model_migrations.get(current_model) - && seen_target == target_model - { - return false; - } - - if available_models - .iter() - .any(|preset| preset.model == current_model && preset.upgrade.is_some()) - { - return true; - } - - available_models - .iter() - .any(|preset| preset.upgrade.as_ref().map(|u| u.id.as_str()) == Some(target_model)) -} - /// Read and clear the one-shot migration notice file, returning the notice if it should be shown. /// /// If the notice is returned, this also updates `config.notices.model_migrations` to prevent @@ -195,6 +146,55 @@ pub(crate) fn maybe_schedule_model_migration_notice( } } +const PENDING_MODEL_MIGRATION_NOTICE_FILENAME: &str = "pending_model_migration_notice.json"; + +fn pending_model_migration_notice_path(config: &Config) -> PathBuf { + config + .codex_home + .join(PENDING_MODEL_MIGRATION_NOTICE_FILENAME) +} + +fn migration_prompt_hidden(config: &Config, migration_config_key: &str) -> bool { + match migration_config_key { + HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG => config + .notices + .hide_gpt_5_1_codex_max_migration_prompt + .unwrap_or(false), + HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG => { + config.notices.hide_gpt5_1_migration_prompt.unwrap_or(false) + } + _ => false, + } +} + +fn should_show_model_migration_notice( + current_model: &str, + target_model: &str, + available_models: &[ModelPreset], + config: &Config, +) -> bool { + if target_model == current_model { + return false; + } + + if let Some(seen_target) = config.notices.model_migrations.get(current_model) + && seen_target == target_model + { + return false; + } + + if available_models + .iter() + .any(|preset| preset.model == current_model && preset.upgrade.is_some()) + { + return true; + } + + available_models + .iter() + .any(|preset| preset.upgrade.as_ref().map(|u| u.id.as_str()) == Some(target_model)) +} + #[cfg(test)] mod prompt_ui { use crate::key_hint; @@ -232,23 +232,12 @@ mod prompt_ui { pub can_opt_out: bool, } - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - enum MigrationMenuOption { - TryNewModel, - UseExistingModel, - } - - impl MigrationMenuOption { - fn all() -> [Self; 2] { - [Self::TryNewModel, Self::UseExistingModel] - } - - fn label(self) -> &'static str { - match self { - Self::TryNewModel => "Try new model", - Self::UseExistingModel => "Use existing model", - } - } + pub(crate) struct ModelMigrationScreen { + request_frame: FrameRequester, + copy: ModelMigrationCopy, + done: bool, + outcome: ModelMigrationOutcome, + highlighted_option: MigrationMenuOption, } pub(crate) fn migration_copy_for_models( @@ -312,12 +301,23 @@ mod prompt_ui { } } - pub(crate) struct ModelMigrationScreen { - request_frame: FrameRequester, - copy: ModelMigrationCopy, - done: bool, - outcome: ModelMigrationOutcome, - highlighted_option: MigrationMenuOption, + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + enum MigrationMenuOption { + TryNewModel, + UseExistingModel, + } + + impl MigrationMenuOption { + fn all() -> [Self; 2] { + [Self::TryNewModel, Self::UseExistingModel] + } + + fn label(self) -> &'static str { + match self { + Self::TryNewModel => "Try new model", + Self::UseExistingModel => "Use existing model", + } + } } impl ModelMigrationScreen { diff --git a/codex-rs/tui2/src/model_migration.rs b/codex-rs/tui2/src/model_migration.rs index 90bee5ef4c..6f1914537c 100644 --- a/codex-rs/tui2/src/model_migration.rs +++ b/codex-rs/tui2/src/model_migration.rs @@ -8,8 +8,6 @@ use serde::Serialize; use std::io; use std::path::PathBuf; -const PENDING_MODEL_MIGRATION_NOTICE_FILENAME: &str = "pending_model_migration_notice.json"; - #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct PendingModelMigrationNotice { pub(crate) from_model: String, @@ -19,53 +17,6 @@ pub(crate) struct PendingModelMigrationNotice { pub(crate) migration_config_key: Option, } -fn pending_model_migration_notice_path(config: &Config) -> PathBuf { - config - .codex_home - .join(PENDING_MODEL_MIGRATION_NOTICE_FILENAME) -} - -fn migration_prompt_hidden(config: &Config, migration_config_key: &str) -> bool { - match migration_config_key { - HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG => config - .notices - .hide_gpt_5_1_codex_max_migration_prompt - .unwrap_or(false), - HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG => { - config.notices.hide_gpt5_1_migration_prompt.unwrap_or(false) - } - _ => false, - } -} - -fn should_show_model_migration_notice( - current_model: &str, - target_model: &str, - available_models: &[ModelPreset], - config: &Config, -) -> bool { - if target_model == current_model { - return false; - } - - if let Some(seen_target) = config.notices.model_migrations.get(current_model) - && seen_target == target_model - { - return false; - } - - if available_models - .iter() - .any(|preset| preset.model == current_model && preset.upgrade.is_some()) - { - return true; - } - - available_models - .iter() - .any(|preset| preset.upgrade.as_ref().map(|u| u.id.as_str()) == Some(target_model)) -} - /// Read and clear the one-shot migration notice file, returning the notice if it should be shown. /// /// If the notice is returned, this also updates `config.notices.model_migrations` to prevent @@ -195,6 +146,55 @@ pub(crate) fn maybe_schedule_model_migration_notice( } } +const PENDING_MODEL_MIGRATION_NOTICE_FILENAME: &str = "pending_model_migration_notice.json"; + +fn pending_model_migration_notice_path(config: &Config) -> PathBuf { + config + .codex_home + .join(PENDING_MODEL_MIGRATION_NOTICE_FILENAME) +} + +fn migration_prompt_hidden(config: &Config, migration_config_key: &str) -> bool { + match migration_config_key { + HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG => config + .notices + .hide_gpt_5_1_codex_max_migration_prompt + .unwrap_or(false), + HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG => { + config.notices.hide_gpt5_1_migration_prompt.unwrap_or(false) + } + _ => false, + } +} + +fn should_show_model_migration_notice( + current_model: &str, + target_model: &str, + available_models: &[ModelPreset], + config: &Config, +) -> bool { + if target_model == current_model { + return false; + } + + if let Some(seen_target) = config.notices.model_migrations.get(current_model) + && seen_target == target_model + { + return false; + } + + if available_models + .iter() + .any(|preset| preset.model == current_model && preset.upgrade.is_some()) + { + return true; + } + + available_models + .iter() + .any(|preset| preset.upgrade.as_ref().map(|u| u.id.as_str()) == Some(target_model)) +} + #[cfg(test)] mod prompt_ui { use crate::key_hint; @@ -232,23 +232,12 @@ mod prompt_ui { pub can_opt_out: bool, } - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - enum MigrationMenuOption { - TryNewModel, - UseExistingModel, - } - - impl MigrationMenuOption { - fn all() -> [Self; 2] { - [Self::TryNewModel, Self::UseExistingModel] - } - - fn label(self) -> &'static str { - match self { - Self::TryNewModel => "Try new model", - Self::UseExistingModel => "Use existing model", - } - } + pub(crate) struct ModelMigrationScreen { + request_frame: FrameRequester, + copy: ModelMigrationCopy, + done: bool, + outcome: ModelMigrationOutcome, + highlighted_option: MigrationMenuOption, } pub(crate) fn migration_copy_for_models( @@ -292,12 +281,23 @@ mod prompt_ui { } } - pub(crate) struct ModelMigrationScreen { - request_frame: FrameRequester, - copy: ModelMigrationCopy, - done: bool, - outcome: ModelMigrationOutcome, - highlighted_option: MigrationMenuOption, + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + enum MigrationMenuOption { + TryNewModel, + UseExistingModel, + } + + impl MigrationMenuOption { + fn all() -> [Self; 2] { + [Self::TryNewModel, Self::UseExistingModel] + } + + fn label(self) -> &'static str { + match self { + Self::TryNewModel => "Try new model", + Self::UseExistingModel => "Use existing model", + } + } } impl ModelMigrationScreen {