diff --git a/codex-rs/app-server/src/codex_message_processor.rs b/codex-rs/app-server/src/codex_message_processor.rs index 0439068db9a..06e52839c08 100644 --- a/codex-rs/app-server/src/codex_message_processor.rs +++ b/codex-rs/app-server/src/codex_message_processor.rs @@ -599,11 +599,10 @@ impl CodexMessageProcessor { ClientRequest::ModelList { request_id, params } => { let outgoing = self.outgoing.clone(); let thread_manager = self.thread_manager.clone(); - let config = self.config.clone(); let request_id = to_connection_request_id(request_id); tokio::spawn(async move { - Self::list_models(outgoing, thread_manager, config, request_id, params).await; + Self::list_models(outgoing, thread_manager, request_id, params).await; }); } ClientRequest::ExperimentalFeatureList { request_id, params } => { @@ -3599,7 +3598,6 @@ impl CodexMessageProcessor { async fn list_models( outgoing: Arc, thread_manager: Arc, - config: Arc, request_id: ConnectionRequestId, params: ModelListParams, ) { @@ -3608,10 +3606,7 @@ impl CodexMessageProcessor { cursor, include_hidden, } = params; - let mut config = (*config).clone(); - config.features.enable(Feature::RemoteModels); - let models = - supported_models(thread_manager, &config, include_hidden.unwrap_or(false)).await; + let models = supported_models(thread_manager, include_hidden.unwrap_or(false)).await; let total = models.len(); if total == 0 { diff --git a/codex-rs/app-server/src/models.rs b/codex-rs/app-server/src/models.rs index d31e005210e..1594c66229f 100644 --- a/codex-rs/app-server/src/models.rs +++ b/codex-rs/app-server/src/models.rs @@ -3,18 +3,16 @@ use std::sync::Arc; use codex_app_server_protocol::Model; use codex_app_server_protocol::ReasoningEffortOption; use codex_core::ThreadManager; -use codex_core::config::Config; use codex_core::models_manager::manager::RefreshStrategy; use codex_protocol::openai_models::ModelPreset; use codex_protocol::openai_models::ReasoningEffortPreset; pub async fn supported_models( thread_manager: Arc, - config: &Config, include_hidden: bool, ) -> Vec { thread_manager - .list_models(config, RefreshStrategy::OnlineIfUncached) + .list_models(RefreshStrategy::OnlineIfUncached) .await .into_iter() .filter(|preset| include_hidden || preset.show_in_picker) diff --git a/codex-rs/app-server/tests/common/config.rs b/codex-rs/app-server/tests/common/config.rs index 09471b4a695..bffb35aa025 100644 --- a/codex-rs/app-server/tests/common/config.rs +++ b/codex-rs/app-server/tests/common/config.rs @@ -13,7 +13,7 @@ pub fn write_mock_responses_config_toml( compact_prompt: &str, ) -> std::io::Result<()> { // Phase 1: build the features block for config.toml. - let mut features = BTreeMap::from([(Feature::RemoteModels, false)]); + let mut features = BTreeMap::new(); for (feature, enabled) in feature_flags { features.insert(*feature, *enabled); } diff --git a/codex-rs/app-server/tests/suite/v2/plan_item.rs b/codex-rs/app-server/tests/suite/v2/plan_item.rs index d138954ac4b..881bbb54c8a 100644 --- a/codex-rs/app-server/tests/suite/v2/plan_item.rs +++ b/codex-rs/app-server/tests/suite/v2/plan_item.rs @@ -215,10 +215,7 @@ async fn collect_turn_notifications( } fn create_config_toml(codex_home: &Path, server_uri: &str) -> std::io::Result<()> { - let features = BTreeMap::from([ - (Feature::RemoteModels, false), - (Feature::CollaborationModes, true), - ]); + let features = BTreeMap::from([(Feature::CollaborationModes, true)]); let feature_entries = features .into_iter() .map(|(feature, enabled)| { diff --git a/codex-rs/app-server/tests/suite/v2/review.rs b/codex-rs/app-server/tests/suite/v2/review.rs index 05397d485d3..219812d6b19 100644 --- a/codex-rs/app-server/tests/suite/v2/review.rs +++ b/codex-rs/app-server/tests/suite/v2/review.rs @@ -437,7 +437,6 @@ sandbox_mode = "read-only" model_provider = "mock_provider" [features] -remote_models = false shell_snapshot = false [model_providers.mock_provider] diff --git a/codex-rs/app-server/tests/suite/v2/thread_resume.rs b/codex-rs/app-server/tests/suite/v2/thread_resume.rs index e001d4a7fd6..3976d3eea6b 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_resume.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_resume.rs @@ -1008,7 +1008,6 @@ sandbox_mode = "read-only" model_provider = "mock_provider" [features] -remote_models = false personality = true [model_providers.mock_provider] @@ -1038,7 +1037,6 @@ sandbox_mode = "read-only" model_provider = "mock_provider" [features] -remote_models = false personality = true [model_providers.mock_provider] diff --git a/codex-rs/app-server/tests/suite/v2/turn_start.rs b/codex-rs/app-server/tests/suite/v2/turn_start.rs index 97cb14f445d..2eecfc55905 100644 --- a/codex-rs/app-server/tests/suite/v2/turn_start.rs +++ b/codex-rs/app-server/tests/suite/v2/turn_start.rs @@ -1871,7 +1871,7 @@ fn create_config_toml_with_sandbox( feature_flags: &BTreeMap, sandbox_mode: &str, ) -> std::io::Result<()> { - let mut features = BTreeMap::from([(Feature::RemoteModels, false)]); + let mut features = BTreeMap::new(); for (feature, enabled) in feature_flags { features.insert(*feature, *enabled); } diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 34f0d9f873c..80f90e26760 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -327,15 +327,11 @@ impl Codex { let config = Arc::new(config); let _ = models_manager - .list_models( - &config, - crate::models_manager::manager::RefreshStrategy::OnlineIfUncached, - ) + .list_models(crate::models_manager::manager::RefreshStrategy::OnlineIfUncached) .await; let model = models_manager .get_default_model( &config.model, - &config, crate::models_manager::manager::RefreshStrategy::OnlineIfUncached, ) .await; @@ -5545,11 +5541,7 @@ async fn try_run_sampling_request( } ResponseEvent::ModelsEtag(etag) => { // Update internal state with latest models etag - let config = sess.get_config().await; - sess.services - .models_manager - .refresh_if_new_etag(etag, &config) - .await; + sess.services.models_manager.refresh_if_new_etag(etag).await; } ResponseEvent::Completed { response_id: _, diff --git a/codex-rs/core/src/config/service.rs b/codex-rs/core/src/config/service.rs index db6963a2f8c..02a9da23fd0 100644 --- a/codex-rs/core/src/config/service.rs +++ b/codex-rs/core/src/config/service.rs @@ -777,7 +777,7 @@ unified_exec = true service .write_value(ConfigValueWriteParams { file_path: Some(tmp.path().join(CONFIG_TOML_FILE).display().to_string()), - key_path: "features.remote_models".to_string(), + key_path: "features.personality".to_string(), value: serde_json::json!(true), merge_strategy: MergeStrategy::Replace, expected_version: None, @@ -797,7 +797,7 @@ hide_full_access_warning = true [features] unified_exec = true -remote_models = true +personality = true "#; assert_eq!(updated, expected); Ok(()) diff --git a/codex-rs/core/src/features.rs b/codex-rs/core/src/features.rs index 3cab14d1fa9..8b8519af7c3 100644 --- a/codex-rs/core/src/features.rs +++ b/codex-rs/core/src/features.rs @@ -101,7 +101,7 @@ pub enum Feature { WindowsSandbox, /// Use the elevated Windows sandbox pipeline (setup + runner). WindowsSandboxElevated, - /// Refresh remote models and emit AppReady once the list is available. + /// Legacy remote models flag kept for backward compatibility. RemoteModels, /// Experimental shell snapshotting. ShellSnapshot, @@ -529,8 +529,8 @@ pub const FEATURES: &[FeatureSpec] = &[ FeatureSpec { id: Feature::RemoteModels, key: "remote_models", - stage: Stage::Stable, - default_enabled: true, + stage: Stage::Removed, + default_enabled: false, }, FeatureSpec { id: Feature::PowershellUtf8, diff --git a/codex-rs/core/src/models_manager/manager.rs b/codex-rs/core/src/models_manager/manager.rs index dd769da2e89..457351995f8 100644 --- a/codex-rs/core/src/models_manager/manager.rs +++ b/codex-rs/core/src/models_manager/manager.rs @@ -7,7 +7,6 @@ use crate::config::Config; use crate::default_client::build_reqwest_client; use crate::error::CodexErr; use crate::error::Result as CoreResult; -use crate::features::Feature; use crate::model_provider_info::ModelProviderInfo; use crate::models_manager::collaboration_mode_presets::builtin_collaboration_mode_presets; use crate::models_manager::model_info; @@ -74,18 +73,11 @@ impl ModelsManager { /// List all available models, refreshing according to the specified strategy. /// /// Returns model presets sorted by priority and filtered by auth mode and visibility. - pub async fn list_models( - &self, - config: &Config, - refresh_strategy: RefreshStrategy, - ) -> Vec { - if let Err(err) = self - .refresh_available_models(config, refresh_strategy) - .await - { + pub async fn list_models(&self, refresh_strategy: RefreshStrategy) -> Vec { + if let Err(err) = self.refresh_available_models(refresh_strategy).await { error!("failed to refresh available models: {err}"); } - let remote_models = self.get_remote_models(config).await; + let remote_models = self.get_remote_models().await; self.build_available_models(remote_models) } @@ -99,8 +91,8 @@ impl ModelsManager { /// Attempt to list models without blocking, using the current cached state. /// /// Returns an error if the internal lock cannot be acquired. - pub fn try_list_models(&self, config: &Config) -> Result, TryLockError> { - let remote_models = self.try_get_remote_models(config)?; + pub fn try_list_models(&self) -> Result, TryLockError> { + let remote_models = self.try_get_remote_models()?; Ok(self.build_available_models(remote_models)) } @@ -112,19 +104,15 @@ impl ModelsManager { pub async fn get_default_model( &self, model: &Option, - config: &Config, refresh_strategy: RefreshStrategy, ) -> String { if let Some(model) = model.as_ref() { return model.to_string(); } - if let Err(err) = self - .refresh_available_models(config, refresh_strategy) - .await - { + if let Err(err) = self.refresh_available_models(refresh_strategy).await { error!("failed to refresh available models: {err}"); } - let remote_models = self.get_remote_models(config).await; + let remote_models = self.get_remote_models().await; let available = self.build_available_models(remote_models); available .iter() @@ -137,9 +125,7 @@ impl ModelsManager { // todo(aibrahim): look if we can tighten it to pub(crate) /// Look up model metadata, applying remote overrides and config adjustments. pub async fn get_model_info(&self, model: &str, config: &Config) -> ModelInfo { - let remote = self - .find_remote_model_by_longest_prefix(model, config) - .await; + let remote = self.find_remote_model_by_longest_prefix(model).await; let model_info = if let Some(remote) = remote { ModelInfo { slug: model.to_string(), @@ -152,13 +138,9 @@ impl ModelsManager { model_info::with_config_overrides(model_info, config) } - async fn find_remote_model_by_longest_prefix( - &self, - model: &str, - config: &Config, - ) -> Option { + async fn find_remote_model_by_longest_prefix(&self, model: &str) -> Option { let mut best: Option = None; - for candidate in self.get_remote_models(config).await { + for candidate in self.get_remote_models().await { if !model.starts_with(&candidate.slug) { continue; } @@ -177,7 +159,7 @@ impl ModelsManager { /// Refresh models if the provided ETag differs from the cached ETag. /// /// Uses `Online` strategy to fetch latest models when ETags differ. - pub(crate) async fn refresh_if_new_etag(&self, etag: String, config: &Config) { + pub(crate) async fn refresh_if_new_etag(&self, etag: String) { let current_etag = self.get_etag().await; if current_etag.clone().is_some() && current_etag.as_deref() == Some(etag.as_str()) { if let Err(err) = self.cache_manager.renew_cache_ttl().await { @@ -185,23 +167,13 @@ impl ModelsManager { } return; } - if let Err(err) = self - .refresh_available_models(config, RefreshStrategy::Online) - .await - { + if let Err(err) = self.refresh_available_models(RefreshStrategy::Online).await { error!("failed to refresh available models: {err}"); } } /// Refresh available models according to the specified strategy. - async fn refresh_available_models( - &self, - config: &Config, - refresh_strategy: RefreshStrategy, - ) -> CoreResult<()> { - if !config.features.enabled(Feature::RemoteModels) { - return Ok(()); - } + async fn refresh_available_models(&self, refresh_strategy: RefreshStrategy) -> CoreResult<()> { if self.auth_manager.auth_mode() != Some(AuthMode::Chatgpt) { if matches!( refresh_strategy, @@ -336,20 +308,12 @@ impl ModelsManager { merged_presets } - async fn get_remote_models(&self, config: &Config) -> Vec { - if config.features.enabled(Feature::RemoteModels) { - self.remote_models.read().await.clone() - } else { - Vec::new() - } + async fn get_remote_models(&self) -> Vec { + self.remote_models.read().await.clone() } - fn try_get_remote_models(&self, config: &Config) -> Result, TryLockError> { - if config.features.enabled(Feature::RemoteModels) { - Ok(self.remote_models.try_read()?.clone()) - } else { - Ok(Vec::new()) - } + fn try_get_remote_models(&self) -> Result, TryLockError> { + Ok(self.remote_models.try_read()?.clone()) } /// Construct a manager with a specific provider for testing. @@ -399,7 +363,6 @@ mod tests { use crate::CodexAuth; use crate::auth::AuthCredentialsStoreMode; use crate::config::ConfigBuilder; - use crate::features::Feature; use crate::model_provider_info::WireApi; use chrono::Utc; use codex_protocol::openai_models::ModelsResponse; @@ -476,17 +439,16 @@ mod tests { #[tokio::test] async fn get_model_info_tracks_fallback_usage() { let codex_home = tempdir().expect("temp dir"); - let mut config = ConfigBuilder::default() + let config = ConfigBuilder::default() .codex_home(codex_home.path().to_path_buf()) .build() .await .expect("load default test config"); - config.features.enable(Feature::RemoteModels); let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::from_api_key("Test API Key")); let manager = ModelsManager::new(codex_home.path().to_path_buf(), auth_manager); let known_slug = manager - .get_remote_models(&config) + .get_remote_models() .await .first() .expect("bundled models should include at least one model") @@ -520,12 +482,6 @@ mod tests { .await; let codex_home = tempdir().expect("temp dir"); - let mut config = ConfigBuilder::default() - .codex_home(codex_home.path().to_path_buf()) - .build() - .await - .expect("load default test config"); - config.features.enable(Feature::RemoteModels); let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing()); let provider = provider_for(server.uri()); @@ -536,15 +492,13 @@ mod tests { ); manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("refresh succeeds"); - let cached_remote = manager.get_remote_models(&config).await; + let cached_remote = manager.get_remote_models().await; assert_models_contain(&cached_remote, &remote_models); - let available = manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) - .await; + let available = manager.list_models(RefreshStrategy::OnlineIfUncached).await; let high_idx = available .iter() .position(|model| model.model == "priority-high") @@ -577,12 +531,6 @@ mod tests { .await; let codex_home = tempdir().expect("temp dir"); - let mut config = ConfigBuilder::default() - .codex_home(codex_home.path().to_path_buf()) - .build() - .await - .expect("load default test config"); - config.features.enable(Feature::RemoteModels); let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing()); let provider = provider_for(server.uri()); @@ -593,17 +541,17 @@ mod tests { ); manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("first refresh succeeds"); - assert_models_contain(&manager.get_remote_models(&config).await, &remote_models); + assert_models_contain(&manager.get_remote_models().await, &remote_models); // Second call should read from cache and avoid the network. manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("cached refresh succeeds"); - assert_models_contain(&manager.get_remote_models(&config).await, &remote_models); + assert_models_contain(&manager.get_remote_models().await, &remote_models); assert_eq!( models_mock.requests().len(), 1, @@ -624,12 +572,6 @@ mod tests { .await; let codex_home = tempdir().expect("temp dir"); - let mut config = ConfigBuilder::default() - .codex_home(codex_home.path().to_path_buf()) - .build() - .await - .expect("load default test config"); - config.features.enable(Feature::RemoteModels); let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing()); let provider = provider_for(server.uri()); @@ -640,7 +582,7 @@ mod tests { ); manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("initial refresh succeeds"); @@ -664,10 +606,10 @@ mod tests { .await; manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("second refresh succeeds"); - assert_models_contain(&manager.get_remote_models(&config).await, &updated_models); + assert_models_contain(&manager.get_remote_models().await, &updated_models); assert_eq!( initial_mock.requests().len(), 1, @@ -693,12 +635,6 @@ mod tests { .await; let codex_home = tempdir().expect("temp dir"); - let mut config = ConfigBuilder::default() - .codex_home(codex_home.path().to_path_buf()) - .build() - .await - .expect("load default test config"); - config.features.enable(Feature::RemoteModels); let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing()); let provider = provider_for(server.uri()); @@ -709,7 +645,7 @@ mod tests { ); manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("initial refresh succeeds"); @@ -733,10 +669,10 @@ mod tests { .await; manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("second refresh succeeds"); - assert_models_contain(&manager.get_remote_models(&config).await, &updated_models); + assert_models_contain(&manager.get_remote_models().await, &updated_models); assert_eq!( initial_mock.requests().len(), 1, @@ -762,12 +698,6 @@ mod tests { .await; let codex_home = tempdir().expect("temp dir"); - let mut config = ConfigBuilder::default() - .codex_home(codex_home.path().to_path_buf()) - .build() - .await - .expect("load default test config"); - config.features.enable(Feature::RemoteModels); let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing()); let provider = provider_for(server.uri()); @@ -779,7 +709,7 @@ mod tests { manager.cache_manager.set_ttl(Duration::ZERO); manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("initial refresh succeeds"); @@ -794,12 +724,12 @@ mod tests { .await; manager - .refresh_available_models(&config, RefreshStrategy::OnlineIfUncached) + .refresh_available_models(RefreshStrategy::OnlineIfUncached) .await .expect("second refresh succeeds"); let available = manager - .try_list_models(&config) + .try_list_models() .expect("models should be available"); assert!( available.iter().any(|preset| preset.model == "remote-new"), @@ -834,12 +764,6 @@ mod tests { .await; let codex_home = tempdir().expect("temp dir"); - let mut config = ConfigBuilder::default() - .codex_home(codex_home.path().to_path_buf()) - .build() - .await - .expect("load default test config"); - config.features.enable(Feature::RemoteModels); let auth_manager = Arc::new(AuthManager::new( codex_home.path().to_path_buf(), false, @@ -853,10 +777,10 @@ mod tests { ); manager - .refresh_available_models(&config, RefreshStrategy::Online) + .refresh_available_models(RefreshStrategy::Online) .await .expect("refresh should no-op without chatgpt auth"); - let cached_remote = manager.get_remote_models(&config).await; + let cached_remote = manager.get_remote_models().await; assert!( !cached_remote .iter() diff --git a/codex-rs/core/src/thread_manager.rs b/codex-rs/core/src/thread_manager.rs index b13ef8c61a8..c16a8838525 100644 --- a/codex-rs/core/src/thread_manager.rs +++ b/codex-rs/core/src/thread_manager.rs @@ -230,12 +230,11 @@ impl ThreadManager { pub async fn list_models( &self, - config: &Config, refresh_strategy: crate::models_manager::manager::RefreshStrategy, ) -> Vec { self.state .models_manager - .list_models(config, refresh_strategy) + .list_models(refresh_strategy) .await } diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index 25278073ec1..22a6c720760 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -5,7 +5,6 @@ use codex_core::built_in_model_providers; use codex_core::compact::SUMMARIZATION_PROMPT; use codex_core::compact::SUMMARY_PREFIX; use codex_core::config::Config; -use codex_core::features::Feature; use codex_core::protocol::AskForApproval; use codex_core::protocol::EventMsg; use codex_core::protocol::ItemCompletedEvent; @@ -1708,7 +1707,6 @@ async fn pre_sampling_compact_runs_on_switch_to_smaller_context_model() { .with_config(move |config| { config.model_provider = model_provider; set_test_compact_prompt(config); - config.features.enable(Feature::RemoteModels); }); let test = builder.build(&server).await.expect("build test codex"); @@ -1831,7 +1829,6 @@ async fn pre_sampling_compact_runs_after_resume_and_switch_to_smaller_model() { .with_config(move |config| { config.model_provider = model_provider; set_test_compact_prompt(config); - config.features.enable(Feature::RemoteModels); }); let initial = initial_builder .build(&server) @@ -1885,7 +1882,6 @@ async fn pre_sampling_compact_runs_after_resume_and_switch_to_smaller_model() { .with_config(move |config| { config.model_provider = model_provider; set_test_compact_prompt(config); - config.features.enable(Feature::RemoteModels); }); let resumed = resumed_builder .resume(&server, home, rollout_path) diff --git a/codex-rs/core/tests/suite/model_info_overrides.rs b/codex-rs/core/tests/suite/model_info_overrides.rs index a9e18f9605b..2b085a004fc 100644 --- a/codex-rs/core/tests/suite/model_info_overrides.rs +++ b/codex-rs/core/tests/suite/model_info_overrides.rs @@ -1,5 +1,4 @@ use codex_core::CodexAuth; -use codex_core::features::Feature; use codex_core::models_manager::manager::ModelsManager; use codex_protocol::openai_models::TruncationPolicyConfig; use core_test_support::load_default_config_for_test; @@ -9,8 +8,7 @@ use tempfile::TempDir; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn offline_model_info_without_tool_output_override() { let codex_home = TempDir::new().expect("create temp dir"); - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); + let config = load_default_config_for_test(&codex_home).await; let auth_manager = codex_core::test_support::auth_manager_from_auth( CodexAuth::create_dummy_chatgpt_auth_for_testing(), ); @@ -28,7 +26,6 @@ async fn offline_model_info_without_tool_output_override() { async fn offline_model_info_with_tool_output_override() { let codex_home = TempDir::new().expect("create temp dir"); let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); config.tool_output_token_limit = Some(123); let auth_manager = codex_core::test_support::auth_manager_from_auth( CodexAuth::create_dummy_chatgpt_auth_for_testing(), diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index 44d0d8a2fc7..4d4abafeb6e 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -266,13 +266,12 @@ async fn model_change_from_image_to_text_strips_prior_image_content() -> Result< let mut builder = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(move |config| { - config.features.enable(Feature::RemoteModels); config.model = Some(image_model_slug.to_string()); }); let test = builder.build(&server).await?; let models_manager = test.thread_manager.get_models_manager(); let _ = models_manager - .list_models(&test.config, RefreshStrategy::OnlineIfUncached) + .list_models(RefreshStrategy::OnlineIfUncached) .await; let image_url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=" .to_string(); @@ -434,15 +433,12 @@ async fn model_switch_to_smaller_model_updates_token_context_window() -> Result< let mut builder = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some(large_model_slug.to_string()); }); let test = builder.build(&server).await?; let models_manager = test.thread_manager.get_models_manager(); - let available_models = models_manager - .list_models(&test.config, RefreshStrategy::Online) - .await; + let available_models = models_manager.list_models(RefreshStrategy::Online).await; assert!( available_models .iter() diff --git a/codex-rs/core/tests/suite/model_tools.rs b/codex-rs/core/tests/suite/model_tools.rs index 836807881b8..026be98dab8 100644 --- a/codex-rs/core/tests/suite/model_tools.rs +++ b/codex-rs/core/tests/suite/model_tools.rs @@ -36,7 +36,6 @@ async fn collect_tool_identifiers_for_model(model: &str) -> Vec { .with_model(model) // Keep tool expectations stable when the default web_search mode changes. .with_config(|config| { - config.features.enable(Feature::RemoteModels); config .web_search_mode .set(WebSearchMode::Cached) diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index 780937c111c..e9f0a73f98c 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -6,7 +6,6 @@ use chrono::DateTime; use chrono::TimeZone; use chrono::Utc; use codex_core::CodexAuth; -use codex_core::features::Feature; use codex_core::models_manager::manager::RefreshStrategy; use codex_core::protocol::EventMsg; use codex_core::protocol::Op; @@ -57,7 +56,6 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { let mut builder = test_codex().with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()); builder = builder.with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some("gpt-5".to_string()); config.model_provider.request_max_retries = Some(0); config.model_provider.stream_max_retries = Some(1); @@ -70,7 +68,7 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { // Populate cache via initial refresh. let models_manager = test.thread_manager.get_models_manager(); let _ = models_manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) + .list_models(RefreshStrategy::OnlineIfUncached) .await; let cache_path = config.codex_home.join(CACHE_FILE); @@ -123,7 +121,7 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { // Cached models remain usable offline. let offline_models = test .thread_manager - .list_models(&config, RefreshStrategy::Offline) + .list_models(RefreshStrategy::Offline) .await; assert!( offline_models @@ -160,14 +158,13 @@ async fn uses_cache_when_version_matches() -> Result<()> { write_cache_sync(&cache_path, &cache).expect("write cache"); }) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model_provider.request_max_retries = Some(0); }); let test = builder.build(&server).await?; let models_manager = test.thread_manager.get_models_manager(); let models = models_manager - .list_models(&test.config, RefreshStrategy::OnlineIfUncached) + .list_models(RefreshStrategy::OnlineIfUncached) .await; assert!( @@ -208,14 +205,13 @@ async fn refreshes_when_cache_version_missing() -> Result<()> { write_cache_sync(&cache_path, &cache).expect("write cache"); }) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model_provider.request_max_retries = Some(0); }); let test = builder.build(&server).await?; let models_manager = test.thread_manager.get_models_manager(); let models = models_manager - .list_models(&test.config, RefreshStrategy::OnlineIfUncached) + .list_models(RefreshStrategy::OnlineIfUncached) .await; assert!( @@ -257,14 +253,13 @@ async fn refreshes_when_cache_version_differs() -> Result<()> { write_cache_sync(&cache_path, &cache).expect("write cache"); }) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model_provider.request_max_retries = Some(0); }); let test = builder.build(&server).await?; let models_manager = test.thread_manager.get_models_manager(); let models = models_manager - .list_models(&test.config, RefreshStrategy::OnlineIfUncached) + .list_models(RefreshStrategy::OnlineIfUncached) .await; assert!( diff --git a/codex-rs/core/tests/suite/models_etag_responses.rs b/codex-rs/core/tests/suite/models_etag_responses.rs index 413616b9dc7..13c31cd7f92 100644 --- a/codex-rs/core/tests/suite/models_etag_responses.rs +++ b/codex-rs/core/tests/suite/models_etag_responses.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use anyhow::Result; use codex_core::CodexAuth; -use codex_core::features::Feature; use codex_core::protocol::AskForApproval; use codex_core::protocol::EventMsg; use codex_core::protocol::Op; @@ -48,7 +47,6 @@ async fn refresh_models_on_models_etag_mismatch_and_avoid_duplicate_models_fetch .with_auth(auth) .with_model("gpt-5") .with_config(|config| { - config.features.enable(Feature::RemoteModels); // Keep this test deterministic: no request retries, and a small stream retry budget. config.model_provider.request_max_retries = Some(0); config.model_provider.stream_max_retries = Some(1); diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index 51f99720aa3..d15147ed367 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -81,7 +81,6 @@ async fn user_turn_personality_none_does_not_add_update_message() -> anyhow::Res let mut builder = test_codex() .with_model("gpt-5.2-codex") .with_config(|config| { - config.features.disable(Feature::RemoteModels); config.features.enable(Feature::Personality); }); let test = builder.build(&server).await?; @@ -127,7 +126,6 @@ async fn config_personality_some_sets_instructions_template() -> anyhow::Result< let mut builder = test_codex() .with_model("gpt-5.2-codex") .with_config(|config| { - config.features.disable(Feature::RemoteModels); config.features.enable(Feature::Personality); config.personality = Some(Personality::Friendly); }); @@ -181,7 +179,6 @@ async fn config_personality_none_sends_no_personality() -> anyhow::Result<()> { let mut builder = test_codex() .with_model("gpt-5.2-codex") .with_config(|config| { - config.features.disable(Feature::RemoteModels); config.features.enable(Feature::Personality); config.personality = Some(Personality::None); }); @@ -242,7 +239,6 @@ async fn default_personality_is_pragmatic_without_config_toml() -> anyhow::Resul let mut builder = test_codex() .with_model("gpt-5.2-codex") .with_config(|config| { - config.features.disable(Feature::RemoteModels); config.features.enable(Feature::Personality); }); let test = builder.build(&server).await?; @@ -290,7 +286,6 @@ async fn user_turn_personality_some_adds_update_message() -> anyhow::Result<()> let mut builder = test_codex() .with_model("exp-codex-personality") .with_config(|config| { - config.features.disable(Feature::RemoteModels); config.features.enable(Feature::Personality); }); let test = builder.build(&server).await?; @@ -386,7 +381,6 @@ async fn user_turn_personality_same_value_does_not_add_update_message() -> anyho let mut builder = test_codex() .with_model("exp-codex-personality") .with_config(|config| { - config.features.disable(Feature::RemoteModels); config.features.enable(Feature::Personality); config.personality = Some(Personality::Pragmatic); }); @@ -494,7 +488,6 @@ async fn user_turn_personality_skips_if_feature_disabled() -> anyhow::Result<()> let mut builder = test_codex() .with_model("exp-codex-personality") .with_config(|config| { - config.features.disable(Feature::RemoteModels); config.features.disable(Feature::Personality); }); let test = builder.build(&server).await?; @@ -570,123 +563,6 @@ async fn user_turn_personality_skips_if_feature_disabled() -> anyhow::Result<()> Ok(()) } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn ignores_remote_personality_if_remote_models_disabled() -> anyhow::Result<()> { - skip_if_no_network!(Ok(())); - - let server = MockServer::builder() - .body_print_limit(BodyPrintLimit::Limited(80_000)) - .start() - .await; - - let remote_slug = "gpt-5.2-codex"; - let remote_personality_message = "Friendly from remote template"; - let remote_model = ModelInfo { - slug: remote_slug.to_string(), - display_name: "Remote personality test".to_string(), - description: Some("Remote model with personality template".to_string()), - default_reasoning_level: Some(ReasoningEffort::Medium), - supported_reasoning_levels: vec![ReasoningEffortPreset { - effort: ReasoningEffort::Medium, - description: ReasoningEffort::Medium.to_string(), - }], - shell_type: ConfigShellToolType::UnifiedExec, - visibility: ModelVisibility::List, - supported_in_api: true, - priority: 1, - upgrade: None, - base_instructions: "base instructions".to_string(), - model_messages: Some(ModelMessages { - instructions_template: Some("Base instructions\n{{ personality }}\n".to_string()), - instructions_variables: Some(ModelInstructionsVariables { - personality_default: None, - personality_friendly: Some(remote_personality_message.to_string()), - personality_pragmatic: None, - }), - }), - supports_reasoning_summaries: false, - support_verbosity: false, - default_verbosity: None, - apply_patch_tool_type: None, - truncation_policy: TruncationPolicyConfig::bytes(10_000), - supports_parallel_tool_calls: false, - context_window: Some(128_000), - auto_compact_token_limit: None, - effective_context_window_percent: 95, - experimental_supported_tools: Vec::new(), - input_modalities: default_input_modalities(), - prefer_websockets: false, - used_fallback_model_metadata: false, - }; - - let _models_mock = mount_models_once( - &server, - ModelsResponse { - models: vec![remote_model], - }, - ) - .await; - - let resp_mock = mount_sse_once(&server, sse_completed("resp-1")).await; - - let mut builder = test_codex() - .with_auth(codex_core::CodexAuth::create_dummy_chatgpt_auth_for_testing()) - .with_config(|config| { - config.features.disable(Feature::RemoteModels); - config.features.enable(Feature::Personality); - config.model = Some(remote_slug.to_string()); - config.personality = Some(Personality::Friendly); - }); - let test = builder.build(&server).await?; - - wait_for_model_available( - &test.thread_manager.get_models_manager(), - remote_slug, - &test.config, - ) - .await; - - test.codex - .submit(Op::UserTurn { - items: vec![UserInput::Text { - text: "hello".into(), - text_elements: Vec::new(), - }], - final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: AskForApproval::Never, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - model: remote_slug.to_string(), - effort: test.config.model_reasoning_effort, - summary: ReasoningSummary::Auto, - collaboration_mode: None, - personality: None, - }) - .await?; - - wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; - - let request = resp_mock.single_request(); - let instructions_text = request.instructions_text(); - - assert!( - instructions_text.contains("You are Codex, a coding agent based on GPT-5. You and the user share the same workspace and collaborate to achieve the user's goals."), - "expected instructions to use the template instructions, got: {instructions_text:?}" - ); - assert!( - instructions_text.contains( - "You optimize for team morale and being a supportive teammate as much as code quality." - ), - "expected instructions to include the local friendly personality template, got: {instructions_text:?}" - ); - assert!( - !instructions_text.contains("{{ personality }}"), - "expected legacy personality placeholder to be replaced, got: {instructions_text:?}" - ); - - Ok(()) -} - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn remote_model_friendly_personality_instructions_with_feature() -> anyhow::Result<()> { skip_if_no_network!(Ok(())); @@ -750,19 +626,13 @@ async fn remote_model_friendly_personality_instructions_with_feature() -> anyhow let mut builder = test_codex() .with_auth(codex_core::CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.features.enable(Feature::Personality); config.model = Some(remote_slug.to_string()); config.personality = Some(Personality::Friendly); }); let test = builder.build(&server).await?; - wait_for_model_available( - &test.thread_manager.get_models_manager(), - remote_slug, - &test.config, - ) - .await; + wait_for_model_available(&test.thread_manager.get_models_manager(), remote_slug).await; test.codex .submit(Op::UserTurn { @@ -867,18 +737,12 @@ async fn user_turn_personality_remote_model_template_includes_update_message() - let mut builder = test_codex() .with_auth(codex_core::CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.features.enable(Feature::Personality); config.model = Some("gpt-5.2-codex".to_string()); }); let test = builder.build(&server).await?; - wait_for_model_available( - &test.thread_manager.get_models_manager(), - remote_slug, - &test.config, - ) - .await; + wait_for_model_available(&test.thread_manager.get_models_manager(), remote_slug).await; test.codex .submit(Op::UserTurn { @@ -957,16 +821,10 @@ async fn user_turn_personality_remote_model_template_includes_update_message() - Ok(()) } -async fn wait_for_model_available( - manager: &Arc, - slug: &str, - config: &codex_core::config::Config, -) { +async fn wait_for_model_available(manager: &Arc, slug: &str) { let deadline = Instant::now() + Duration::from_secs(2); loop { - let models = manager - .list_models(config, RefreshStrategy::OnlineIfUncached) - .await; + let models = manager.list_models(RefreshStrategy::OnlineIfUncached).await; if models.iter().any(|model| model.model == slug) { return; } diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 71a565540b7..cd3b4272a07 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -194,7 +194,6 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an let TestCodex { codex, .. } = test_codex() .with_config(|config| { config.user_instructions = Some("be consistent and helpful".to_string()); - config.features.enable(Feature::RemoteModels); config.features.disable(Feature::ApplyPatchFreeform); config.features.enable(Feature::CollaborationModes); config.model = Some("gpt-5".to_string()); diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index 29ba047d019..110150d4475 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -7,8 +7,6 @@ use anyhow::Result; use codex_core::CodexAuth; use codex_core::ModelProviderInfo; use codex_core::built_in_model_providers; -use codex_core::config::Config; -use codex_core::features::Feature; use codex_core::models_manager::manager::ModelsManager; use codex_core::models_manager::manager::RefreshStrategy; use codex_core::protocol::AskForApproval; @@ -92,8 +90,7 @@ async fn remote_models_get_model_info_uses_longest_matching_prefix() -> Result<( .await; let codex_home = TempDir::new()?; - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); + let config = load_default_config_for_test(&codex_home).await; let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); let provider = ModelProviderInfo { @@ -106,9 +103,7 @@ async fn remote_models_get_model_info_uses_longest_matching_prefix() -> Result<( provider, ); - manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) - .await; + manager.list_models(RefreshStrategy::OnlineIfUncached).await; let model_info = manager.get_model_info("gpt-5.3-codex-test", &config).await; @@ -163,7 +158,6 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some(requested_model.to_string()); }) .build(&server) @@ -253,7 +247,6 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { let mut builder = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some("gpt-5.1".to_string()); }); let TestCodex { @@ -265,8 +258,7 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { } = builder.build(&server).await?; let models_manager = thread_manager.get_models_manager(); - let available_model = - wait_for_model_available(&models_manager, REMOTE_MODEL_SLUG, &config).await; + let available_model = wait_for_model_available(&models_manager, REMOTE_MODEL_SLUG).await; assert_eq!(available_model.model, REMOTE_MODEL_SLUG); @@ -375,13 +367,12 @@ async fn remote_models_truncation_policy_without_override_preserves_remote() -> let mut builder = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some("gpt-5.1".to_string()); }); let test = builder.build(&server).await?; let models_manager = test.thread_manager.get_models_manager(); - wait_for_model_available(&models_manager, slug, &test.config).await; + wait_for_model_available(&models_manager, slug).await; let model_info = models_manager.get_model_info(slug, &test.config).await; assert_eq!( @@ -420,14 +411,13 @@ async fn remote_models_truncation_policy_with_tool_output_override() -> Result<( let mut builder = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some("gpt-5.1".to_string()); config.tool_output_token_limit = Some(50); }); let test = builder.build(&server).await?; let models_manager = test.thread_manager.get_models_manager(); - wait_for_model_available(&models_manager, slug, &test.config).await; + wait_for_model_available(&models_manager, slug).await; let model_info = models_manager.get_model_info(slug, &test.config).await; assert_eq!( @@ -502,7 +492,6 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { let mut builder = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some("gpt-5.1".to_string()); }); let TestCodex { @@ -514,7 +503,7 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { } = builder.build(&server).await?; let models_manager = thread_manager.get_models_manager(); - wait_for_model_available(&models_manager, model, &config).await; + wait_for_model_available(&models_manager, model).await; codex .submit(Op::OverrideTurnContext { @@ -574,8 +563,6 @@ async fn remote_models_preserve_builtin_presets() -> Result<()> { .await; let codex_home = TempDir::new()?; - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); let provider = ModelProviderInfo { @@ -588,9 +575,7 @@ async fn remote_models_preserve_builtin_presets() -> Result<()> { provider, ); - let available = manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) - .await; + let available = manager.list_models(RefreshStrategy::OnlineIfUncached).await; let remote = available .iter() .find(|model| model.model == "remote-alpha") @@ -639,8 +624,6 @@ async fn remote_models_merge_adds_new_high_priority_first() -> Result<()> { .await; let codex_home = TempDir::new()?; - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); let provider = ModelProviderInfo { @@ -653,9 +636,7 @@ async fn remote_models_merge_adds_new_high_priority_first() -> Result<()> { provider, ); - let available = manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) - .await; + let available = manager.list_models(RefreshStrategy::OnlineIfUncached).await; assert_eq!( available.first().map(|model| model.model.as_str()), Some("remote-top") @@ -690,8 +671,6 @@ async fn remote_models_merge_replaces_overlapping_model() -> Result<()> { .await; let codex_home = TempDir::new()?; - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); let provider = ModelProviderInfo { @@ -704,9 +683,7 @@ async fn remote_models_merge_replaces_overlapping_model() -> Result<()> { provider, ); - let available = manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) - .await; + let available = manager.list_models(RefreshStrategy::OnlineIfUncached).await; let overridden = available .iter() .find(|model| model.model == slug) @@ -738,8 +715,6 @@ async fn remote_models_merge_preserves_bundled_models_on_empty_response() -> Res let _models_mock = mount_models_once(&server, ModelsResponse { models: Vec::new() }).await; let codex_home = TempDir::new()?; - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); let provider = ModelProviderInfo { @@ -752,9 +727,7 @@ async fn remote_models_merge_preserves_bundled_models_on_empty_response() -> Res provider, ); - let available = manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) - .await; + let available = manager.list_models(RefreshStrategy::OnlineIfUncached).await; let bundled_slug = bundled_model_slug(); assert!( available.iter().any(|model| model.model == bundled_slug), @@ -783,8 +756,6 @@ async fn remote_models_request_times_out_after_5s() -> Result<()> { .await; let codex_home = TempDir::new()?; - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); let provider = ModelProviderInfo { @@ -800,7 +771,7 @@ async fn remote_models_request_times_out_after_5s() -> Result<()> { let start = Instant::now(); let model = timeout( Duration::from_secs(7), - manager.get_default_model(&None, &config, RefreshStrategy::OnlineIfUncached), + manager.get_default_model(&None, RefreshStrategy::OnlineIfUncached), ) .await; let elapsed = start.elapsed(); @@ -850,8 +821,6 @@ async fn remote_models_hide_picker_only_models() -> Result<()> { .await; let codex_home = TempDir::new()?; - let mut config = load_default_config_for_test(&codex_home).await; - config.features.enable(Feature::RemoteModels); let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); let provider = ModelProviderInfo { @@ -865,13 +834,11 @@ async fn remote_models_hide_picker_only_models() -> Result<()> { ); let selected = manager - .get_default_model(&None, &config, RefreshStrategy::OnlineIfUncached) + .get_default_model(&None, RefreshStrategy::OnlineIfUncached) .await; assert_eq!(selected, "gpt-5.2-codex"); - let available = manager - .list_models(&config, RefreshStrategy::OnlineIfUncached) - .await; + let available = manager.list_models(RefreshStrategy::OnlineIfUncached).await; let hidden = available .iter() .find(|model| model.model == "codex-auto-balanced") @@ -888,17 +855,11 @@ async fn remote_models_hide_picker_only_models() -> Result<()> { Ok(()) } -async fn wait_for_model_available( - manager: &Arc, - slug: &str, - config: &Config, -) -> ModelPreset { +async fn wait_for_model_available(manager: &Arc, slug: &str) -> ModelPreset { let deadline = Instant::now() + Duration::from_secs(2); loop { if let Some(model) = { - let guard = manager - .list_models(config, RefreshStrategy::OnlineIfUncached) - .await; + let guard = manager.list_models(RefreshStrategy::OnlineIfUncached).await; guard.iter().find(|model| model.model == slug).cloned() } { return model; diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index 467f4e354d6..d1394f7a74d 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -11,7 +11,6 @@ use std::time::UNIX_EPOCH; use codex_core::CodexAuth; use codex_core::config::types::McpServerConfig; use codex_core::config::types::McpServerTransportConfig; -use codex_core::features::Feature; use codex_core::models_manager::manager::RefreshStrategy; use codex_core::protocol::AskForApproval; @@ -441,8 +440,6 @@ async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Re let fixture = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(move |config| { - config.features.enable(Feature::RemoteModels); - let mut servers = config.mcp_servers.get().clone(); servers.insert( server_name.to_string(), @@ -478,7 +475,7 @@ async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Re fixture .thread_manager .get_models_manager() - .list_models(&fixture.config, RefreshStrategy::Online) + .list_models(RefreshStrategy::Online) .await; assert_eq!(models_mock.requests().len(), 1); diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index bd5bd6a0371..bad9efa2d00 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -698,7 +698,6 @@ async fn view_image_tool_returns_unsupported_message_for_text_only_model() -> an let TestCodex { codex, cwd, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { - config.features.enable(Feature::RemoteModels); config.model = Some(model_slug.to_string()); }) .build(&server) diff --git a/codex-rs/exec/src/lib.rs b/codex-rs/exec/src/lib.rs index 68c88f00001..49163c900b8 100644 --- a/codex-rs/exec/src/lib.rs +++ b/codex-rs/exec/src/lib.rs @@ -374,7 +374,7 @@ pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option) -> any )); let default_model = thread_manager .get_models_manager() - .get_default_model(&config.model, &config, RefreshStrategy::OnlineIfUncached) + .get_default_model(&config.model, RefreshStrategy::OnlineIfUncached) .await; // Handle resume subcommand by resolving a rollout path and using explicit resume API. diff --git a/codex-rs/mcp-server/tests/suite/codex_tool.rs b/codex-rs/mcp-server/tests/suite/codex_tool.rs index c898b8f0d72..de8a9306d4b 100644 --- a/codex-rs/mcp-server/tests/suite/codex_tool.rs +++ b/codex-rs/mcp-server/tests/suite/codex_tool.rs @@ -507,7 +507,6 @@ request_max_retries = 0 stream_max_retries = 0 [features] -remote_models = false "# ), ) diff --git a/codex-rs/tui/src/app.rs b/codex-rs/tui/src/app.rs index b23b5f1a13b..108f85ff8a4 100644 --- a/codex-rs/tui/src/app.rs +++ b/codex-rs/tui/src/app.rs @@ -1029,11 +1029,11 @@ impl App { )); let mut model = thread_manager .get_models_manager() - .get_default_model(&config.model, &config, RefreshStrategy::Offline) + .get_default_model(&config.model, RefreshStrategy::Offline) .await; let available_models = thread_manager .get_models_manager() - .list_models(&config, RefreshStrategy::Offline) + .list_models(RefreshStrategy::Offline) .await; let exit_info = handle_model_migration_prompt_if_needed( tui, diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index dcbee999bc8..c4a20b567ff 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -4698,7 +4698,7 @@ impl ChatWidget { } fn lower_cost_preset(&self) -> Option { - let models = self.models_manager.try_list_models(&self.config).ok()?; + let models = self.models_manager.try_list_models().ok()?; models .iter() .find(|preset| preset.show_in_picker && preset.model == NUDGE_MODEL_SLUG) @@ -4815,7 +4815,7 @@ impl ChatWidget { return; } - let presets: Vec = match self.models_manager.try_list_models(&self.config) { + let presets: Vec = match self.models_manager.try_list_models() { Ok(models) => models, Err(_) => { self.add_info_message( @@ -6137,7 +6137,7 @@ impl ChatWidget { fn current_model_supports_personality(&self) -> bool { let model = self.current_model(); self.models_manager - .try_list_models(&self.config) + .try_list_models() .ok() .and_then(|models| { models @@ -6155,7 +6155,7 @@ impl ChatWidget { fn current_model_supports_images(&self) -> bool { let model = self.current_model(); self.models_manager - .try_list_models(&self.config) + .try_list_models() .ok() .and_then(|models| { models diff --git a/codex-rs/tui/src/chatwidget/tests.rs b/codex-rs/tui/src/chatwidget/tests.rs index f069db91608..f49d3182744 100644 --- a/codex-rs/tui/src/chatwidget/tests.rs +++ b/codex-rs/tui/src/chatwidget/tests.rs @@ -2749,7 +2749,7 @@ fn active_blob(chat: &ChatWidget) -> String { fn get_available_model(chat: &ChatWidget, model: &str) -> ModelPreset { let models = chat .models_manager - .try_list_models(&chat.config) + .try_list_models() .expect("models lock available"); models .iter()