config requirements: improve requirement error messages (#8843)

**Before:**
```
Error loading configuration: value `Never` is not in the allowed set [OnRequest]
```

**After:**
```
Error loading configuration: invalid value for `approval_policy`: `Never` is not in the
allowed set [OnRequest] (set by MDM com.openai.codex:requirements_toml_base64)
```

Done by introducing a new struct `ConfigRequirementsWithSources` onto
which we `merge_unset_fields` now. Also introduces a pair of requirement
value and its `RequirementSource` (inspired by `ConfigLayerSource`):

```rust
pub struct Sourced<T> {
    pub value: T,
    pub source: RequirementSource,
}
```
This commit is contained in:
gt-oai
2026-01-08 16:11:14 +00:00
committed by GitHub
parent 484f6f4c26
commit 932a5a446f
6 changed files with 378 additions and 140 deletions

View File

@@ -11,6 +11,7 @@ use codex_core::config::Config;
use codex_core::config::ConfigBuilder;
use codex_core::config::Constrained;
use codex_core::config::ConstraintError;
use codex_core::config_loader::RequirementSource;
use codex_core::features::Feature;
use codex_core::models_manager::manager::ModelsManager;
use codex_core::protocol::AgentMessageDeltaEvent;
@@ -85,6 +86,15 @@ async fn test_config() -> Config {
.expect("config")
}
fn invalid_value(candidate: impl Into<String>, allowed: impl Into<String>) -> ConstraintError {
ConstraintError::InvalidValue {
field_name: "<unknown>",
candidate: candidate.into(),
allowed: allowed.into(),
requirement_source: RequirementSource::Unknown,
}
}
fn snapshot(percent: f64) -> RateLimitSnapshot {
RateLimitSnapshot {
primary: Some(RateLimitWindow {
@@ -2303,7 +2313,7 @@ async fn approvals_popup_shows_disabled_presets() {
chat.config.approval_policy =
Constrained::new(AskForApproval::OnRequest, |candidate| match candidate {
AskForApproval::OnRequest => Ok(()),
_ => Err(ConstraintError::invalid_value(
_ => Err(invalid_value(
candidate.to_string(),
"this message should be printed in the description",
)),
@@ -2339,10 +2349,7 @@ async fn approvals_popup_navigation_skips_disabled() {
chat.config.approval_policy =
Constrained::new(AskForApproval::OnRequest, |candidate| match candidate {
AskForApproval::OnRequest => Ok(()),
_ => Err(ConstraintError::invalid_value(
candidate.to_string(),
"[on-request]",
)),
_ => Err(invalid_value(candidate.to_string(), "[on-request]")),
})
.expect("construct constrained approval policy");
chat.open_approvals_popup();