chore: rm remote models fflag (#11699)

rm `remote_models` feature flag.

We see issues like #11527 when a user has `remote_models` disabled, as
we always use the default fallback `ModelInfo`. This causes issues with
model performance.

Builds on #11690, which helps by warning the user when they are using
the default fallback. This PR will make that happen much less frequently
as an accidental consequence of disabling `remote_models`.
This commit is contained in:
sayan-oai
2026-02-17 11:43:16 -08:00
committed by GitHub
Unverified
parent 314029ffa3
commit 41800fc876
28 changed files with 87 additions and 391 deletions
@@ -621,11 +621,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 } => {
@@ -3621,7 +3620,6 @@ impl CodexMessageProcessor {
async fn list_models(
outgoing: Arc<OutgoingMessageSender>,
thread_manager: Arc<ThreadManager>,
config: Arc<Config>,
request_id: ConnectionRequestId,
params: ModelListParams,
) {
@@ -3630,10 +3628,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 {
+1 -3
View File
@@ -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<ThreadManager>,
config: &Config,
include_hidden: bool,
) -> Vec<Model> {
thread_manager
.list_models(config, RefreshStrategy::OnlineIfUncached)
.list_models(RefreshStrategy::OnlineIfUncached)
.await
.into_iter()
.filter(|preset| include_hidden || preset.show_in_picker)
+1 -1
View File
@@ -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);
}
@@ -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)| {
@@ -437,7 +437,6 @@ sandbox_mode = "read-only"
model_provider = "mock_provider"
[features]
remote_models = false
shell_snapshot = false
[model_providers.mock_provider]
@@ -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]
@@ -1871,7 +1871,7 @@ fn create_config_toml_with_sandbox(
feature_flags: &BTreeMap<Feature, bool>,
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);
}
+2 -10
View File
@@ -329,15 +329,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;
@@ -5583,11 +5579,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: _,
+2 -2
View File
@@ -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(())
+3 -3
View File
@@ -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,
@@ -530,8 +530,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,
+37 -113
View File
@@ -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<ModelPreset> {
if let Err(err) = self
.refresh_available_models(config, refresh_strategy)
.await
{
pub async fn list_models(&self, refresh_strategy: RefreshStrategy) -> Vec<ModelPreset> {
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<Vec<ModelPreset>, TryLockError> {
let remote_models = self.try_get_remote_models(config)?;
pub fn try_list_models(&self) -> Result<Vec<ModelPreset>, 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<String>,
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<ModelInfo> {
async fn find_remote_model_by_longest_prefix(&self, model: &str) -> Option<ModelInfo> {
let mut best: Option<ModelInfo> = 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<ModelInfo> {
if config.features.enabled(Feature::RemoteModels) {
self.remote_models.read().await.clone()
} else {
Vec::new()
}
async fn get_remote_models(&self) -> Vec<ModelInfo> {
self.remote_models.read().await.clone()
}
fn try_get_remote_models(&self, config: &Config) -> Result<Vec<ModelInfo>, 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<Vec<ModelInfo>, 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()
+1 -2
View File
@@ -230,12 +230,11 @@ impl ThreadManager {
pub async fn list_models(
&self,
config: &Config,
refresh_strategy: crate::models_manager::manager::RefreshStrategy,
) -> Vec<ModelPreset> {
self.state
.models_manager
.list_models(config, refresh_strategy)
.list_models(refresh_strategy)
.await
}
-4
View File
@@ -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)
@@ -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(),
+2 -6
View File
@@ -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()
-1
View File
@@ -36,7 +36,6 @@ async fn collect_tool_identifiers_for_model(model: &str) -> Vec<String> {
.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)
+5 -10
View File
@@ -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!(
@@ -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);
+4 -146
View File
@@ -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<ModelsManager>,
slug: &str,
config: &codex_core::config::Config,
) {
async fn wait_for_model_available(manager: &Arc<ModelsManager>, 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;
}
@@ -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());
+15 -54
View File
@@ -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<ModelsManager>,
slug: &str,
config: &Config,
) -> ModelPreset {
async fn wait_for_model_available(manager: &Arc<ModelsManager>, 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;
+1 -4
View File
@@ -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);
-1
View File
@@ -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)
+1 -1
View File
@@ -374,7 +374,7 @@ pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> 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.
@@ -507,7 +507,6 @@ request_max_retries = 0
stream_max_retries = 0
[features]
remote_models = false
"#
),
)
+2 -2
View File
@@ -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,
+4 -4
View File
@@ -4699,7 +4699,7 @@ impl ChatWidget {
}
fn lower_cost_preset(&self) -> Option<ModelPreset> {
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)
@@ -4816,7 +4816,7 @@ impl ChatWidget {
return;
}
let presets: Vec<ModelPreset> = match self.models_manager.try_list_models(&self.config) {
let presets: Vec<ModelPreset> = match self.models_manager.try_list_models() {
Ok(models) => models,
Err(_) => {
self.add_info_message(
@@ -6138,7 +6138,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
@@ -6156,7 +6156,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
+1 -1
View File
@@ -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()