diff --git a/codex-rs/config/src/config_toml.rs b/codex-rs/config/src/config_toml.rs index 9c3faf7b3e..acb7b34479 100644 --- a/codex-rs/config/src/config_toml.rs +++ b/codex-rs/config/src/config_toml.rs @@ -512,25 +512,25 @@ impl From for UserSavedConfig { Self { approval_policy: config_toml .approval_policy - .and_then(|value| value.into_valid("approval_policy", None)), + .and_then(|value| value.into_valid()), sandbox_mode: config_toml .sandbox_mode - .and_then(|value| value.into_valid("sandbox_mode", None)), + .and_then(|value| value.into_valid()), sandbox_settings: config_toml.sandbox_workspace_write.map(From::from), forced_chatgpt_workspace_id: config_toml.forced_chatgpt_workspace_id, forced_login_method: config_toml .forced_login_method - .and_then(|value| value.into_valid("forced_login_method", None)), + .and_then(|value| value.into_valid()), model: config_toml.model, model_reasoning_effort: config_toml .model_reasoning_effort - .and_then(|value| value.into_valid("model_reasoning_effort", None)), + .and_then(|value| value.into_valid()), model_reasoning_summary: config_toml .model_reasoning_summary - .and_then(|value| value.into_valid("model_reasoning_summary", None)), + .and_then(|value| value.into_valid()), model_verbosity: config_toml .model_verbosity - .and_then(|value| value.into_valid("model_verbosity", None)), + .and_then(|value| value.into_valid()), tools: config_toml.tools.map(From::from), profile: config_toml.profile, profiles, diff --git a/codex-rs/config/src/lenient.rs b/codex-rs/config/src/lenient.rs index 5a18972202..12159742ab 100644 --- a/codex-rs/config/src/lenient.rs +++ b/codex-rs/config/src/lenient.rs @@ -28,15 +28,24 @@ impl Lenient { } } - pub fn into_valid(self, field_path: &str, warnings: Option<&mut Vec>) -> Option { + pub fn into_valid(self) -> Option { + match self { + Self::Valid(value) => Some(value), + Self::Invalid(_) => None, + } + } + + pub fn into_valid_with_warning( + self, + field_path: &str, + warnings: &mut Vec, + ) -> Option { match self { Self::Valid(value) => Some(value), Self::Invalid(value) => { - if let Some(warnings) = warnings { - warnings.push(format!( - "Ignoring invalid config value at {field_path}: {value}" - )); - } + warnings.push(format!( + "Ignoring invalid config value at {field_path}: {value}" + )); None } } diff --git a/codex-rs/config/src/profile_toml.rs b/codex-rs/config/src/profile_toml.rs index 726024a115..e492fd4923 100644 --- a/codex-rs/config/src/profile_toml.rs +++ b/codex-rs/config/src/profile_toml.rs @@ -81,16 +81,16 @@ impl From for codex_app_server_protocol::Profile { model_provider: config_profile.model_provider, approval_policy: config_profile .approval_policy - .and_then(|value| value.into_valid("approval_policy", None)), + .and_then(|value| value.into_valid()), model_reasoning_effort: config_profile .model_reasoning_effort - .and_then(|value| value.into_valid("model_reasoning_effort", None)), + .and_then(|value| value.into_valid()), model_reasoning_summary: config_profile .model_reasoning_summary - .and_then(|value| value.into_valid("model_reasoning_summary", None)), + .and_then(|value| value.into_valid()), model_verbosity: config_profile .model_verbosity - .and_then(|value| value.into_valid("model_verbosity", None)), + .and_then(|value| value.into_valid()), chatgpt_base_url: config_profile.chatgpt_base_url, } } diff --git a/codex-rs/core/src/config/config_loader_tests.rs b/codex-rs/core/src/config/config_loader_tests.rs index 10b8dd941a..7392d29d16 100644 --- a/codex-rs/core/src/config/config_loader_tests.rs +++ b/codex-rs/core/src/config/config_loader_tests.rs @@ -148,7 +148,7 @@ sandbox_mode = "make-it-so" let mut enum_warnings = Vec::new(); let sandbox_mode = config_toml .sandbox_mode - .and_then(|value| value.into_valid("sandbox_mode", Some(&mut enum_warnings))); + .and_then(|value| value.into_valid_with_warning("sandbox_mode", &mut enum_warnings)); let expected_config = toml::from_str::( r#" model = "gpt-5-codex" diff --git a/codex-rs/core/src/config/config_tests.rs b/codex-rs/core/src/config/config_tests.rs index d169ec748d..bf265ded49 100644 --- a/codex-rs/core/src/config/config_tests.rs +++ b/codex-rs/core/src/config/config_tests.rs @@ -3443,7 +3443,7 @@ async fn managed_config_overrides_oauth_store_mode() -> anyhow::Result<()> { assert_eq!( cfg.mcp_oauth_credentials_store .clone() - .and_then(|value| value.into_valid("mcp_oauth_credentials_store", None)), + .and_then(|value| value.into_valid()), Some(OAuthCredentialsStoreMode::Keyring), ); @@ -4570,7 +4570,7 @@ async fn set_model_updates_defaults() -> anyhow::Result<()> { assert_eq!( parsed .model_reasoning_effort - .and_then(|value| value.into_valid("model_reasoning_effort", None)), + .and_then(|value| value.into_valid()), Some(ReasoningEffort::High) ); @@ -4606,7 +4606,7 @@ model = "gpt-4.1" assert_eq!( parsed .model_reasoning_effort - .and_then(|value| value.into_valid("model_reasoning_effort", None)), + .and_then(|value| value.into_valid()), Some(ReasoningEffort::High) ); assert_eq!( @@ -4642,7 +4642,7 @@ async fn set_model_updates_profile() -> anyhow::Result<()> { profile .model_reasoning_effort .clone() - .and_then(|value| value.into_valid("model_reasoning_effort", None)), + .and_then(|value| value.into_valid()), Some(ReasoningEffort::Medium) ); @@ -4685,7 +4685,7 @@ model = "gpt-5.4" dev_profile .model_reasoning_effort .clone() - .and_then(|value| value.into_valid("model_reasoning_effort", None)), + .and_then(|value| value.into_valid()), Some(ReasoningEffort::Medium) ); diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index 816fe2b76a..3ef2a903c4 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -1678,7 +1678,7 @@ fn valid_lenient( field_path: &str, warnings: &mut Vec, ) -> Option { - value.and_then(|value| value.into_valid(field_path, Some(warnings))) + value.and_then(|value| value.into_valid_with_warning(field_path, warnings)) } fn valid_lenient_ref( @@ -1688,7 +1688,7 @@ fn valid_lenient_ref( ) -> Option { value .clone() - .and_then(|value| value.into_valid(field_path, Some(warnings))) + .and_then(|value| value.into_valid_with_warning(field_path, warnings)) } fn valid_lenient_ref_silent(value: &Option>) -> Option { diff --git a/codex-rs/core/src/personality_migration_tests.rs b/codex-rs/core/src/personality_migration_tests.rs index 3d84ce2e44..a67ca6289b 100644 --- a/codex-rs/core/src/personality_migration_tests.rs +++ b/codex-rs/core/src/personality_migration_tests.rs @@ -17,7 +17,7 @@ use tokio::io::AsyncWriteExt; const TEST_TIMESTAMP: &str = "2025-01-01T00-00-00"; fn valid_lenient(value: Option>) -> Option { - value.and_then(|value| value.into_valid("personality", None)) + value.and_then(|value| value.into_valid()) } async fn read_config_toml(codex_home: &Path) -> io::Result { diff --git a/codex-rs/core/src/session/config_lock.rs b/codex-rs/core/src/session/config_lock.rs index 5ce1f47cae..eceaf9c0ed 100644 --- a/codex-rs/core/src/session/config_lock.rs +++ b/codex-rs/core/src/session/config_lock.rs @@ -149,7 +149,7 @@ mod tests { assert_eq!( lock.model_reasoning_effort .clone() - .and_then(|value| value.into_valid("model_reasoning_effort", None)), + .and_then(|value| value.into_valid()), sc.collaboration_mode.reasoning_effort() ); assert_eq!(lock.profile, None); diff --git a/codex-rs/core/tests/suite/personality_migration.rs b/codex-rs/core/tests/suite/personality_migration.rs index fbcb92500e..e4bc757f3c 100644 --- a/codex-rs/core/tests/suite/personality_migration.rs +++ b/codex-rs/core/tests/suite/personality_migration.rs @@ -23,7 +23,7 @@ use tokio::io::AsyncWriteExt; const TEST_TIMESTAMP: &str = "2025-01-01T00-00-00"; fn valid_lenient(value: Option>) -> Option { - value.and_then(|value| value.into_valid("personality", None)) + value.and_then(|value| value.into_valid()) } async fn read_config_toml(codex_home: &Path) -> io::Result {