mirror of
https://github.com/openai/codex.git
synced 2026-05-29 15:30:22 +00:00
Split silent and warning lenient unwraps
Keep Lenient::into_valid as the silent projection helper and add into_valid_with_warning for runtime config consumption that should emit startup warnings. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -512,25 +512,25 @@ impl From<ConfigToml> 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,
|
||||
|
||||
@@ -28,15 +28,24 @@ impl<T> Lenient<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_valid(self, field_path: &str, warnings: Option<&mut Vec<String>>) -> Option<T> {
|
||||
pub fn into_valid(self) -> Option<T> {
|
||||
match self {
|
||||
Self::Valid(value) => Some(value),
|
||||
Self::Invalid(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_valid_with_warning(
|
||||
self,
|
||||
field_path: &str,
|
||||
warnings: &mut Vec<String>,
|
||||
) -> Option<T> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,16 +81,16 @@ impl From<ConfigProfile> 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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<TomlValue>(
|
||||
r#"
|
||||
model = "gpt-5-codex"
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
|
||||
@@ -1678,7 +1678,7 @@ fn valid_lenient<T>(
|
||||
field_path: &str,
|
||||
warnings: &mut Vec<String>,
|
||||
) -> Option<T> {
|
||||
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<T: Clone>(
|
||||
@@ -1688,7 +1688,7 @@ fn valid_lenient_ref<T: Clone>(
|
||||
) -> Option<T> {
|
||||
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<T: Clone>(value: &Option<Lenient<T>>) -> Option<T> {
|
||||
|
||||
@@ -17,7 +17,7 @@ use tokio::io::AsyncWriteExt;
|
||||
const TEST_TIMESTAMP: &str = "2025-01-01T00-00-00";
|
||||
|
||||
fn valid_lenient<T>(value: Option<Lenient<T>>) -> Option<T> {
|
||||
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<ConfigToml> {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -23,7 +23,7 @@ use tokio::io::AsyncWriteExt;
|
||||
const TEST_TIMESTAMP: &str = "2025-01-01T00-00-00";
|
||||
|
||||
fn valid_lenient<T>(value: Option<Lenient<T>>) -> Option<T> {
|
||||
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<ConfigToml> {
|
||||
|
||||
Reference in New Issue
Block a user