mirror of
https://github.com/openai/codex.git
synced 2026-09-15 12:08:01 +00:00
Support clearing map values via --config overrides
This commit is contained in:
@@ -5,6 +5,11 @@ pub fn merge_toml_values(base: &mut TomlValue, overlay: &TomlValue) {
|
||||
if let TomlValue::Table(overlay_table) = overlay
|
||||
&& let TomlValue::Table(base_table) = base
|
||||
{
|
||||
if overlay_table.is_empty() {
|
||||
base_table.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (key, value) in overlay_table {
|
||||
if let Some(existing) = base_table.get_mut(key) {
|
||||
merge_toml_values(existing, value);
|
||||
@@ -16,3 +21,75 @@ pub fn merge_toml_values(base: &mut TomlValue, overlay: &TomlValue) {
|
||||
*base = overlay.clone();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
use toml::toml;
|
||||
|
||||
#[test]
|
||||
fn empty_overlay_table_replaces_existing_table() {
|
||||
let mut base = TomlValue::Table(toml! {
|
||||
[mcp_servers.docs]
|
||||
command = "uvx"
|
||||
|
||||
[mcp_servers.logs]
|
||||
command = "tail"
|
||||
});
|
||||
let overlay = TomlValue::Table(toml! {
|
||||
mcp_servers = {}
|
||||
});
|
||||
|
||||
merge_toml_values(&mut base, &overlay);
|
||||
|
||||
assert_eq!(base, TomlValue::Table(toml! { mcp_servers = {} }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_overlay_table_only_clears_targeted_nested_table() {
|
||||
let mut base = TomlValue::Table(toml! {
|
||||
[model_providers.default]
|
||||
name = "provider-a"
|
||||
|
||||
[model_providers.default.extra]
|
||||
endpoint = "https://example-a"
|
||||
|
||||
[model_providers.other]
|
||||
name = "provider-b"
|
||||
});
|
||||
let overlay = TomlValue::Table(toml! {
|
||||
model_providers = { default = {} }
|
||||
});
|
||||
|
||||
merge_toml_values(&mut base, &overlay);
|
||||
|
||||
assert_eq!(
|
||||
base,
|
||||
TomlValue::Table(toml! {
|
||||
model_providers = { default = {}, other = { name = "provider-b" } }
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_empty_overlay_table_keeps_recursive_merge_behavior() {
|
||||
let mut base = TomlValue::Table(toml! {
|
||||
[mcp_servers.docs]
|
||||
command = "uvx"
|
||||
disabled = false
|
||||
});
|
||||
let overlay = TomlValue::Table(toml! {
|
||||
mcp_servers = { docs = { disabled = true } }
|
||||
});
|
||||
|
||||
merge_toml_values(&mut base, &overlay);
|
||||
|
||||
assert_eq!(
|
||||
base,
|
||||
TomlValue::Table(toml! {
|
||||
mcp_servers = { docs = { command = "uvx", disabled = true } }
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,3 +53,40 @@ fn apply_toml_override(root: &mut TomlValue, path: &str, value: TomlValue) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::merge::merge_toml_values;
|
||||
use pretty_assertions::assert_eq;
|
||||
use toml::toml;
|
||||
|
||||
#[test]
|
||||
fn build_cli_overrides_layer_preserves_empty_table_values() {
|
||||
let cli_overrides = vec![(
|
||||
"mcp_servers".to_string(),
|
||||
TomlValue::Table(toml::map::Map::new()),
|
||||
)];
|
||||
|
||||
let layer = build_cli_overrides_layer(&cli_overrides);
|
||||
|
||||
assert_eq!(layer, TomlValue::Table(toml! { mcp_servers = {} }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_table_cli_override_clears_existing_map() {
|
||||
let cli_overrides = vec![(
|
||||
"mcp_servers".to_string(),
|
||||
TomlValue::Table(toml::map::Map::new()),
|
||||
)];
|
||||
let cli_layer = build_cli_overrides_layer(&cli_overrides);
|
||||
let mut merged = TomlValue::Table(toml! {
|
||||
[mcp_servers.docs]
|
||||
command = "uvx"
|
||||
});
|
||||
|
||||
merge_toml_values(&mut merged, &cli_layer);
|
||||
|
||||
assert_eq!(merged, TomlValue::Table(toml! { mcp_servers = {} }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,18 @@ Codex can connect to MCP servers configured in `~/.codex/config.toml`. See the c
|
||||
|
||||
- https://developers.openai.com/codex/config-reference
|
||||
|
||||
### Clearing map-valued settings from the CLI
|
||||
|
||||
`--config` / `-c` overrides can clear map-valued settings by assigning an explicit empty table.
|
||||
|
||||
For example, to disable all configured MCP servers for a single run:
|
||||
|
||||
```bash
|
||||
codex --config 'mcp_servers={}'
|
||||
```
|
||||
|
||||
This replacement behavior is generic, so any map-valued config key can be reset the same way.
|
||||
|
||||
## Apps (Connectors)
|
||||
|
||||
Use `$` in the composer to insert a ChatGPT connector; the popover lists accessible
|
||||
|
||||
Reference in New Issue
Block a user