diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index 8744b756bf..8a29d49cbd 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -1355,16 +1355,16 @@ impl Config { || cfg.sandbox_mode.is_some(); let mut model_providers = built_in_model_providers(); + // Merge user-defined providers into the built-in list. + for (key, provider) in cfg.model_providers.into_iter() { + model_providers.insert(key, provider); + } if features.enabled(Feature::ResponsesWebsockets) && let Some(provider) = model_providers.get_mut("openai") && provider.is_openai() { provider.wire_api = crate::model_provider_info::WireApi::ResponsesWebsocket; } - // Merge user-defined providers into the built-in list. - for (key, provider) in cfg.model_providers.into_iter() { - model_providers.entry(key).or_insert(provider); - } let model_provider_id = model_provider .or(config_profile.model_provider) @@ -2530,6 +2530,33 @@ profile = "project" Ok(()) } + #[test] + fn config_overrides_openai_base_url() -> std::io::Result<()> { + let codex_home = TempDir::new()?; + let mut provider = built_in_model_providers() + .get("openai") + .expect("openai provider should exist") + .clone(); + provider.base_url = Some("https://us.api.openai.com/v1".to_string()); + let cfg = ConfigToml { + model_providers: HashMap::from([("openai".to_string(), provider)]), + ..Default::default() + }; + + let config = Config::load_from_base_config_with_overrides( + cfg, + ConfigOverrides::default(), + codex_home.path().to_path_buf(), + )?; + + assert_eq!( + config.model_provider.base_url.as_deref(), + Some("https://us.api.openai.com/v1") + ); + + Ok(()) + } + #[test] fn config_honors_explicit_file_oauth_store_mode() -> std::io::Result<()> { let codex_home = TempDir::new()?;