mirror of
https://github.com/openai/codex.git
synced 2026-10-20 08:19:50 +00:00
Clarify config layer iteration APIs (#36774)
## What changed - Replace the ordering enum and `include_disabled` boolean with named `ConfigLayerStack` iterators for each precedence direction. - Keep enabled-only iteration separate from `all_layers_*` iteration, which includes disabled layers. - Update config consumers to use the iterator matching their precedence and disabled-layer requirements without allocating an intermediate `Vec`. ## Testing - Add coverage that verifies ordering and disabled-layer filtering for all four iterators. GitOrigin-RevId: d14df3db4a2eae80ba97cdec246bff405e6c5f3d
This commit is contained in:
@@ -16,7 +16,6 @@ use codex_config::ConfigLayerEntry;
|
||||
use codex_config::ConfigLayerMetadata;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::ConfigRequirementsToml;
|
||||
use codex_config::ShellEnvironmentPolicyFilterRepresentation;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
@@ -160,11 +159,7 @@ impl ConfigManager {
|
||||
.collect(),
|
||||
layers: params.include_layers.then(|| {
|
||||
layers
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.iter()
|
||||
.all_layers_high_to_low()
|
||||
.map(|layer| config_layer_to_api(layer.as_layer()))
|
||||
.collect()
|
||||
}),
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use codex_arg0::Arg0DispatchPaths;
|
||||
use codex_code_mode::CodeModeSessionProvider;
|
||||
use codex_code_mode::WebSocketCodeModeSessionProvider;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::LoaderOverrides;
|
||||
use codex_config::NoopThreadConfigLoader;
|
||||
use codex_config::RemoteThreadConfigLoader;
|
||||
@@ -355,10 +354,7 @@ fn app_text_range(range: &CoreTextRange) -> AppTextRange {
|
||||
fn project_config_warning(config: &Config) -> Option<ConfigWarningNotification> {
|
||||
let mut disabled_folders = Vec::new();
|
||||
|
||||
for layer in config.config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
) {
|
||||
for layer in config.config_layer_stack.all_layers_low_to_high() {
|
||||
let ConfigLayerSource::Project { dot_codex_folder } = &layer.name else {
|
||||
continue;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,6 @@ pub(super) async fn set_user_model_provider_to_bedrock(
|
||||
};
|
||||
if let Some((overriding_layer, effective_provider)) = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.filter(|layer| layer.name.precedence() > user_precedence)
|
||||
.find_map(|layer| {
|
||||
layer
|
||||
|
||||
@@ -3,7 +3,6 @@ use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_core::config::Config;
|
||||
use codex_git_utils::get_git_repo_root;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
@@ -171,11 +170,7 @@ fn terminal_title_project_root(config: &Config, cwd: &Path) -> Option<ProjectTit
|
||||
|
||||
config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.iter()
|
||||
.all_layers_low_to_high()
|
||||
.find_map(|layer| match &layer.name {
|
||||
ConfigLayerSource::Project { dot_codex_folder } => dot_codex_folder
|
||||
.as_path()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use super::*;
|
||||
use crate::CONFIG_TOML_FILE;
|
||||
use crate::ConfigLayerStack;
|
||||
use crate::ConfigLayerStackOrdering;
|
||||
use crate::ConfigRequirements;
|
||||
use crate::ConfigRequirementsToml;
|
||||
use crate::config_toml::ConfigToml;
|
||||
@@ -121,11 +120,7 @@ review_model = "system-review"
|
||||
|
||||
assert_eq!(
|
||||
stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false
|
||||
)
|
||||
.iter()
|
||||
.layers_low_to_high()
|
||||
.map(|layer| layer.name.clone())
|
||||
.collect::<Vec<_>>(),
|
||||
vec![
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use crate::ConfigLayerEntry;
|
||||
use crate::ConfigLayerSource;
|
||||
use crate::ConfigLayerStack;
|
||||
use crate::ConfigLayerStackOrdering;
|
||||
use crate::format_config_layer_source;
|
||||
use codex_utils_absolute_path::AbsolutePathBufGuard;
|
||||
use serde::de::DeserializeOwned;
|
||||
@@ -175,14 +174,8 @@ pub async fn first_layer_config_error<T: DeserializeOwned>(
|
||||
// When the merged config fails schema validation, we surface the first concrete
|
||||
// per-file error to point users at a specific file and range rather than an
|
||||
// opaque merged-layer failure.
|
||||
first_layer_config_error_for_entries::<T, _>(
|
||||
layers.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
),
|
||||
config_toml_file,
|
||||
)
|
||||
.await
|
||||
first_layer_config_error_for_entries::<T, _>(layers.layers_low_to_high(), config_toml_file)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn first_layer_config_error_from_entries<T: DeserializeOwned>(
|
||||
|
||||
@@ -153,7 +153,6 @@ pub use skills_config::SkillConfig;
|
||||
pub use skills_config::SkillsConfig;
|
||||
pub use state::ConfigLayerEntry;
|
||||
pub use state::ConfigLayerStack;
|
||||
pub use state::ConfigLayerStackOrdering;
|
||||
pub use state::ConfigLoadOptions;
|
||||
pub use state::LoaderOverrides;
|
||||
pub use strict_config::config_error_from_ignored_toml_fields;
|
||||
|
||||
@@ -14,7 +14,7 @@ Exported from `codex_config::loader`:
|
||||
- `ConfigLayerStack`
|
||||
- `effective_config() -> toml::Value`
|
||||
- `origins() -> HashMap<String, ConfigLayerMetadata>`
|
||||
- `layers_high_to_low() -> Vec<ConfigLayer>`
|
||||
- `layers_high_to_low() -> impl Iterator<Item = &ConfigLayerEntry>`
|
||||
- `with_user_config(user_config) -> ConfigLayerStack`
|
||||
- `ConfigLayerEntry` (one layer’s `{name, config, version, disabled_reason}`; `name` carries source metadata)
|
||||
- `ConfigLoadOptions` (user-facing load behavior such as strict config validation)
|
||||
@@ -68,7 +68,7 @@ let layers = load_config_layers_state(
|
||||
|
||||
let effective = layers.effective_config();
|
||||
let origins = layers.origins();
|
||||
let layers_for_ui = layers.layers_high_to_low();
|
||||
let layers_for_ui = layers.layers_high_to_low().collect::<Vec<_>>();
|
||||
```
|
||||
|
||||
## Internal layout
|
||||
|
||||
@@ -233,12 +233,6 @@ impl ConfigLayerEntry {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ConfigLayerStackOrdering {
|
||||
LowestPrecedenceFirst,
|
||||
HighestPrecedenceFirst,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
pub struct ConfigLayerStack {
|
||||
/// Layers are listed from lowest precedence (base) to highest (top), so
|
||||
@@ -323,34 +317,16 @@ impl ConfigLayerStack {
|
||||
Some(file)
|
||||
}
|
||||
|
||||
/// Returns all user config layers in the requested precedence order.
|
||||
///
|
||||
/// With profile-v2 enabled, `LowestPrecedenceFirst` returns the base user
|
||||
/// config before the profile overlay, while `HighestPrecedenceFirst` returns
|
||||
/// the profile overlay before the base user config.
|
||||
pub fn get_user_layers(
|
||||
&self,
|
||||
ordering: ConfigLayerStackOrdering,
|
||||
include_disabled: bool,
|
||||
) -> Vec<&ConfigLayerEntry> {
|
||||
self.get_layers(ordering, include_disabled)
|
||||
.into_iter()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::User { .. }))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns the merged config from enabled user layers only.
|
||||
///
|
||||
/// When profile config is active, this includes the base user config followed
|
||||
/// by the profile override config.
|
||||
pub fn effective_user_config(&self) -> Option<TomlValue> {
|
||||
let user_layers = self.get_user_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
);
|
||||
if user_layers.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let mut user_layers = self
|
||||
.layers_low_to_high()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::User { .. }))
|
||||
.peekable();
|
||||
user_layers.peek()?;
|
||||
|
||||
let mut merged = TomlValue::Table(toml::map::Map::new());
|
||||
for layer in user_layers {
|
||||
@@ -468,10 +444,7 @@ impl ConfigLayerStack {
|
||||
/// tracked separately.
|
||||
pub fn effective_config(&self) -> TomlValue {
|
||||
let mut merged = TomlValue::Table(toml::map::Map::new());
|
||||
for layer in self.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
) {
|
||||
for layer in self.layers_low_to_high() {
|
||||
merge_toml_values(&mut merged, &layer.config);
|
||||
}
|
||||
merged
|
||||
@@ -484,10 +457,7 @@ impl ConfigLayerStack {
|
||||
let mut origins = HashMap::new();
|
||||
let mut path = Vec::new();
|
||||
|
||||
for layer in self.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
) {
|
||||
for layer in self.layers_low_to_high() {
|
||||
let config = normalized_with_key_aliases(&layer.config, &[]);
|
||||
record_origins(&config, &layer.metadata(), &mut path, &mut origins);
|
||||
}
|
||||
@@ -495,33 +465,35 @@ impl ConfigLayerStack {
|
||||
origins
|
||||
}
|
||||
|
||||
/// Returns config layers from highest precedence to lowest precedence.
|
||||
/// Returns enabled config layers from lowest precedence to highest.
|
||||
///
|
||||
/// Requirement sources are tracked separately and are not included here.
|
||||
pub fn layers_high_to_low(&self) -> Vec<&ConfigLayerEntry> {
|
||||
self.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
)
|
||||
pub fn layers_low_to_high(&self) -> impl DoubleEndedIterator<Item = &ConfigLayerEntry> {
|
||||
self.all_layers_low_to_high()
|
||||
.filter(|layer| !layer.is_disabled())
|
||||
}
|
||||
|
||||
/// Returns config layers in the requested precedence order.
|
||||
/// Returns enabled config layers from highest precedence to lowest.
|
||||
///
|
||||
/// Requirement sources are tracked separately and are not included here.
|
||||
pub fn get_layers(
|
||||
&self,
|
||||
ordering: ConfigLayerStackOrdering,
|
||||
include_disabled: bool,
|
||||
) -> Vec<&ConfigLayerEntry> {
|
||||
let mut layers: Vec<&ConfigLayerEntry> = self
|
||||
.layers
|
||||
.iter()
|
||||
.filter(|layer| include_disabled || !layer.is_disabled())
|
||||
.collect();
|
||||
if ordering == ConfigLayerStackOrdering::HighestPrecedenceFirst {
|
||||
layers.reverse();
|
||||
}
|
||||
layers
|
||||
pub fn layers_high_to_low(&self) -> impl DoubleEndedIterator<Item = &ConfigLayerEntry> {
|
||||
self.layers_low_to_high().rev()
|
||||
}
|
||||
|
||||
/// Returns all config layers, including disabled layers, from lowest
|
||||
/// precedence to highest.
|
||||
///
|
||||
/// Requirement sources are tracked separately and are not included here.
|
||||
pub fn all_layers_low_to_high(&self) -> impl DoubleEndedIterator<Item = &ConfigLayerEntry> {
|
||||
self.layers.iter()
|
||||
}
|
||||
|
||||
/// Returns all config layers, including disabled layers, from highest
|
||||
/// precedence to lowest.
|
||||
///
|
||||
/// Requirement sources are tracked separately and are not included here.
|
||||
pub fn all_layers_high_to_low(&self) -> impl DoubleEndedIterator<Item = &ConfigLayerEntry> {
|
||||
self.all_layers_low_to_high().rev()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -250,6 +250,63 @@ approval_policy = "on-request"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layer_iterators_preserve_precedence_and_disabled_layers() {
|
||||
let temp_dir = TempDir::new().expect("tempdir");
|
||||
let user_source = ConfigLayerSource::User {
|
||||
file: test_user_config_path(&temp_dir, "config.toml"),
|
||||
profile: None,
|
||||
};
|
||||
let project_source = ConfigLayerSource::Project {
|
||||
dot_codex_folder: test_user_config_path(&temp_dir, ".codex"),
|
||||
};
|
||||
let session_source = ConfigLayerSource::SessionFlags;
|
||||
let empty_config = TomlValue::Table(toml::map::Map::new());
|
||||
let stack = ConfigLayerStack::new(
|
||||
vec![
|
||||
ConfigLayerEntry::new(user_source.clone(), empty_config.clone()),
|
||||
ConfigLayerEntry::new_disabled(
|
||||
project_source.clone(),
|
||||
empty_config.clone(),
|
||||
"project is untrusted",
|
||||
),
|
||||
ConfigLayerEntry::new(session_source.clone(), empty_config),
|
||||
],
|
||||
ConfigRequirements::default(),
|
||||
ConfigRequirementsToml::default(),
|
||||
)
|
||||
.expect("layer stack should be valid");
|
||||
|
||||
assert_eq!(
|
||||
stack
|
||||
.layers_low_to_high()
|
||||
.map(|layer| &layer.name)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![&user_source, &session_source]
|
||||
);
|
||||
assert_eq!(
|
||||
stack
|
||||
.layers_high_to_low()
|
||||
.map(|layer| &layer.name)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![&session_source, &user_source]
|
||||
);
|
||||
assert_eq!(
|
||||
stack
|
||||
.all_layers_low_to_high()
|
||||
.map(|layer| &layer.name)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![&user_source, &project_source, &session_source]
|
||||
);
|
||||
assert_eq!(
|
||||
stack
|
||||
.all_layers_high_to_low()
|
||||
.map(|layer| &layer.name)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![&session_source, &project_source, &user_source]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_user_config_updates_matching_user_layer_without_replacing_active_profile() {
|
||||
let temp_dir = TempDir::new().expect("tempdir");
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::collections::HashSet;
|
||||
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::SkillConfig;
|
||||
use codex_config::SkillsConfig;
|
||||
pub use codex_skills::SkillConfigRule;
|
||||
@@ -15,10 +14,7 @@ use crate::SkillMetadata;
|
||||
|
||||
pub fn skill_config_rules_from_stack(config_layer_stack: &ConfigLayerStack) -> SkillConfigRules {
|
||||
let mut entries = Vec::new();
|
||||
for layer in config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
) {
|
||||
for layer in config_layer_stack.all_layers_low_to_high() {
|
||||
if !matches!(
|
||||
layer.name,
|
||||
ConfigLayerSource::User { .. } | ConfigLayerSource::SessionFlags
|
||||
|
||||
@@ -19,7 +19,6 @@ use crate::model::SkillToolDependency;
|
||||
use crate::system::system_cache_root_dir;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::default_project_root_markers;
|
||||
use codex_config::merge_toml_values;
|
||||
use codex_config::project_root_markers_from_config;
|
||||
@@ -296,10 +295,7 @@ fn skill_roots_from_layer_stack_inner(
|
||||
) -> Vec<SkillRoot> {
|
||||
let mut roots = Vec::new();
|
||||
|
||||
for layer in config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
) {
|
||||
for layer in config_layer_stack.all_layers_high_to_low() {
|
||||
let Some(config_folder) = layer.config_folder() else {
|
||||
continue;
|
||||
};
|
||||
@@ -429,10 +425,7 @@ async fn repo_agents_skill_roots(
|
||||
|
||||
fn project_root_markers_from_stack(config_layer_stack: &ConfigLayerStack) -> Vec<String> {
|
||||
let mut merged = TomlValue::Table(toml::map::Map::new());
|
||||
for layer in config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
) {
|
||||
for layer in config_layer_stack.layers_low_to_high() {
|
||||
if matches!(layer.name, ConfigLayerSource::Project { .. }) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ use anyhow::anyhow;
|
||||
use codex_config::ConfigLayerEntry;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
use codex_config::loader::resolve_relative_paths_in_config_toml;
|
||||
use codex_exec_server::LOCAL_FS;
|
||||
@@ -236,11 +235,7 @@ mod reload {
|
||||
fn existing_layers(config: &Config) -> Vec<ConfigLayerEntry> {
|
||||
config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ use super::*;
|
||||
use crate::SkillsService;
|
||||
use crate::config::ConfigBuilder;
|
||||
use crate::skills_load_input_from_config;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_protocol::config_types::ServiceTier;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
@@ -39,11 +38,7 @@ async fn write_role_config(home: &TempDir, name: &str, contents: &str) -> PathBu
|
||||
fn session_flags_layer_count(config: &Config) -> usize {
|
||||
config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.filter(|layer| layer.name == ConfigLayerSource::SessionFlags)
|
||||
.count()
|
||||
}
|
||||
@@ -302,11 +297,7 @@ writable_roots = ["./sandbox-root"]
|
||||
|
||||
let role_layer = config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.rfind(|layer| layer.name == ConfigLayerSource::SessionFlags)
|
||||
.expect("expected a session flags layer");
|
||||
let sandbox_workspace_write = role_layer
|
||||
|
||||
@@ -19,7 +19,6 @@ use crate::config::Config;
|
||||
use crate::context::UserInstructions as ContextUserInstructions;
|
||||
use crate::environment_selection::TurnEnvironmentSnapshot;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::default_project_root_markers;
|
||||
use codex_config::merge_toml_values;
|
||||
use codex_config::project_root_markers_from_config;
|
||||
@@ -160,10 +159,7 @@ async fn agents_md_paths(
|
||||
let dir = cwd.clone();
|
||||
|
||||
let mut merged = TomlValue::Table(toml::map::Map::new());
|
||||
for layer in config.config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
) {
|
||||
for layer in config.config_layer_stack.layers_low_to_high() {
|
||||
if matches!(layer.name, ConfigLayerSource::Project { .. }) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::AgentRoleConfig;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::config_toml::AgentRoleToml;
|
||||
use codex_config::config_toml::AgentsToml;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
@@ -22,11 +21,8 @@ pub(crate) async fn load_agent_roles(
|
||||
config_layer_stack: &ConfigLayerStack,
|
||||
startup_warnings: &mut Vec<String>,
|
||||
) -> std::io::Result<BTreeMap<String, AgentRoleConfig>> {
|
||||
let layers = config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
);
|
||||
if layers.is_empty() {
|
||||
let mut layers = config_layer_stack.layers_low_to_high().peekable();
|
||||
if layers.peek().is_none() {
|
||||
return load_agent_roles_without_layers(fs, cfg).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ use codex_config::CloudConfigBundleLoader;
|
||||
use codex_config::ConfigError;
|
||||
use codex_config::ConfigLayerEntry;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::ConfigLoadError;
|
||||
use codex_config::ConfigLoadOptions;
|
||||
use codex_config::ConfigRequirements;
|
||||
@@ -844,7 +843,6 @@ async fn returns_empty_when_all_layers_missing() {
|
||||
);
|
||||
let num_system_layers = layers
|
||||
.layers_high_to_low()
|
||||
.iter()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::System { .. }))
|
||||
.count();
|
||||
assert_eq!(
|
||||
@@ -896,10 +894,10 @@ approval_policy = "on-request"
|
||||
.await
|
||||
.expect("load layers");
|
||||
|
||||
let user_layers = layers.get_user_layers(
|
||||
super::ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
);
|
||||
let user_layers = layers
|
||||
.layers_low_to_high()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::User { .. }))
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(user_layers.len(), 2);
|
||||
assert_eq!(
|
||||
user_layers[0].name,
|
||||
@@ -962,7 +960,6 @@ async fn includes_thread_config_layers_in_stack() -> anyhow::Result<()> {
|
||||
|
||||
let layer_sources = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.map(|layer| layer.name.clone())
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(
|
||||
@@ -1048,7 +1045,6 @@ flag = false
|
||||
assert_eq!(nested.get("flag"), Some(&TomlValue::Boolean(false)));
|
||||
let mdm_layer = state
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.find(|layer| {
|
||||
matches!(
|
||||
layer.name,
|
||||
@@ -2292,11 +2288,7 @@ model_provider = "cloud-provider"
|
||||
);
|
||||
assert_eq!(
|
||||
layers
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
)
|
||||
.iter()
|
||||
.layers_low_to_high()
|
||||
.map(|layer| layer.name.clone())
|
||||
.collect::<Vec<_>>(),
|
||||
vec![
|
||||
@@ -2634,7 +2626,6 @@ async fn project_layers_prefer_closest_cwd() -> std::io::Result<()> {
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.filter_map(|layer| match &layer.name {
|
||||
ConfigLayerSource::Project { dot_codex_folder } => Some(dot_codex_folder),
|
||||
_ => None,
|
||||
@@ -2716,7 +2707,6 @@ async fn linked_worktree_project_layers_keep_worktree_config_but_use_root_repo_h
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(project_layers.len(), 2);
|
||||
@@ -2797,7 +2787,6 @@ async fn linked_worktree_project_layers_use_root_repo_hooks_without_worktree_con
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(project_layers.len(), 1);
|
||||
@@ -2867,7 +2856,6 @@ async fn nested_project_root_markers_do_not_redirect_regular_repo_hooks() -> std
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(project_layers.len(), 2);
|
||||
@@ -3054,7 +3042,6 @@ async fn project_layer_is_added_when_dot_codex_exists_without_config_toml() -> s
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
let expected_project_layer = ConfigLayerEntry::new(
|
||||
@@ -3093,11 +3080,7 @@ async fn codex_home_is_not_loaded_as_project_layer_from_home_dir() -> std::io::R
|
||||
.await?;
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_high_to_low()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
let expected: Vec<&ConfigLayerEntry> = Vec::new();
|
||||
@@ -3158,11 +3141,7 @@ async fn codex_home_within_project_tree_is_not_double_loaded() -> std::io::Resul
|
||||
.await?;
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_high_to_low()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
|
||||
@@ -3232,11 +3211,7 @@ profile = "ignored"
|
||||
)
|
||||
.await?;
|
||||
let project_layers_untrusted: Vec<_> = layers_untrusted
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_high_to_low()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(project_layers_untrusted.len(), 1);
|
||||
@@ -3278,11 +3253,7 @@ profile = "ignored"
|
||||
)
|
||||
.await?;
|
||||
let project_layers_unknown: Vec<_> = layers_unknown
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_high_to_low()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(project_layers_unknown.len(), 1);
|
||||
@@ -3371,7 +3342,6 @@ wire_api = "responses"
|
||||
|
||||
let project_layer = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.find(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.expect("expected project layer");
|
||||
|
||||
@@ -3472,11 +3442,7 @@ async fn project_trust_does_not_match_configured_alias_for_canonical_cwd() -> st
|
||||
.await?;
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_high_to_low()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(project_layers.len(), 1);
|
||||
@@ -3636,11 +3602,7 @@ async fn invalid_project_config_ignored_when_untrusted_or_unknown() -> std::io::
|
||||
)
|
||||
.await?;
|
||||
let project_layers: Vec<_> = layers
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_high_to_low()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(
|
||||
@@ -3704,11 +3666,7 @@ async fn project_layer_without_config_toml_is_disabled_when_untrusted_or_unknown
|
||||
)
|
||||
.await?;
|
||||
let project_layers: Vec<_> = layers
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_high_to_low()
|
||||
.filter(|layer| matches!(layer.name, ConfigLayerSource::Project { .. }))
|
||||
.collect();
|
||||
assert_eq!(
|
||||
@@ -3811,7 +3769,6 @@ async fn project_root_markers_supports_alternate_markers() -> std::io::Result<()
|
||||
|
||||
let project_layers: Vec<_> = layers
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.filter_map(|layer| match &layer.name {
|
||||
ConfigLayerSource::Project { dot_codex_folder } => Some(dot_codex_folder),
|
||||
_ => None,
|
||||
|
||||
@@ -2369,11 +2369,7 @@ async fn managed_unrestricted_permission_profile_still_enables_network_requireme
|
||||
|
||||
let layers = config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.cloned()
|
||||
.collect();
|
||||
let mut requirements = config.config_layer_stack.requirements().clone();
|
||||
|
||||
@@ -9,7 +9,6 @@ use crate::windows_sandbox::resolve_windows_sandbox_private_desktop;
|
||||
use codex_config::CloudConfigBundleLoader;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::ConfigRequirements;
|
||||
use codex_config::ConfigRequirementsToml;
|
||||
use codex_config::ConstrainedWithSource;
|
||||
@@ -1769,21 +1768,13 @@ impl Config {
|
||||
) -> std::io::Result<Self> {
|
||||
let mut layers = refreshed_config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.filter(|layer| !is_session_layer(&layer.name))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
layers.extend(
|
||||
self.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.filter(|layer| is_session_layer(&layer.name))
|
||||
.cloned(),
|
||||
);
|
||||
@@ -2368,11 +2359,8 @@ fn resolve_tool_suggest_config_from_config(
|
||||
}
|
||||
};
|
||||
|
||||
let layers = config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
);
|
||||
if layers.is_empty() {
|
||||
let mut layers = config_layer_stack.layers_low_to_high().peekable();
|
||||
if layers.peek().is_none() {
|
||||
for disabled_tool in tool_suggest
|
||||
.into_iter()
|
||||
.flat_map(|tool_suggest| tool_suggest.disabled_tools.iter().cloned())
|
||||
@@ -2467,11 +2455,7 @@ fn resolve_permission_config_syntax(
|
||||
}
|
||||
|
||||
let session_flags_select_profiles = config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::HighestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
)
|
||||
.into_iter()
|
||||
.layers_high_to_low()
|
||||
.find(|layer| matches!(layer.name, ConfigLayerSource::SessionFlags))
|
||||
.and_then(|layer| {
|
||||
layer
|
||||
@@ -2486,10 +2470,7 @@ fn resolve_permission_config_syntax(
|
||||
}
|
||||
|
||||
let mut selection = None;
|
||||
for layer in config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
) {
|
||||
for layer in config_layer_stack.layers_low_to_high() {
|
||||
let Ok(layer_selection) = layer.config.clone().try_into::<PermissionSelectionToml>() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@ use arc_swap::ArcSwap;
|
||||
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_execpolicy::AmendError;
|
||||
use codex_execpolicy::Decision;
|
||||
use codex_execpolicy::Error as ExecPolicyRuleError;
|
||||
@@ -181,11 +180,7 @@ pub(crate) fn child_uses_parent_exec_policy(parent_config: &Config, child_config
|
||||
fn exec_policy_config_folders(config: &Config) -> Vec<AbsolutePathBuf> {
|
||||
config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
)
|
||||
.into_iter()
|
||||
.layers_low_to_high()
|
||||
.filter_map(codex_config::ConfigLayerEntry::config_folder)
|
||||
.collect()
|
||||
}
|
||||
@@ -639,10 +634,7 @@ pub async fn load_exec_policy(config_stack: &ConfigLayerStack) -> Result<Policy,
|
||||
// from each layer, so that higher-precedence layers can override
|
||||
// rules defined in lower-precedence ones.
|
||||
let mut policy_paths = Vec::new();
|
||||
for layer in config_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
) {
|
||||
for layer in config_stack.layers_low_to_high() {
|
||||
if config_stack.ignore_user_and_project_exec_policy_rules()
|
||||
&& matches!(
|
||||
layer.name,
|
||||
|
||||
@@ -5,7 +5,6 @@ use codex_config::CONFIG_TOML_FILE;
|
||||
use codex_config::ConfigLayerEntry;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::ConfigRequirements;
|
||||
use codex_config::ConfigRequirementsToml;
|
||||
use codex_config::LoaderOverrides;
|
||||
@@ -130,11 +129,7 @@ async fn child_uses_parent_exec_policy_when_non_exec_policy_layers_differ() {
|
||||
let mut child_config = parent_config.clone();
|
||||
let mut layers: Vec<_> = child_config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.cloned()
|
||||
.collect();
|
||||
layers.push(ConfigLayerEntry::new(
|
||||
@@ -190,11 +185,7 @@ async fn child_does_not_use_parent_exec_policy_when_requirements_exec_policy_dif
|
||||
child_config.config_layer_stack = ConfigLayerStack::new(
|
||||
child_config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.cloned()
|
||||
.collect(),
|
||||
requirements,
|
||||
|
||||
@@ -2136,7 +2136,6 @@ fn project_mcp_tool_approval_config_folder(
|
||||
config
|
||||
.config_layer_stack
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.find_map(|layer| {
|
||||
if !matches!(layer.name, ConfigLayerSource::Project { .. }) {
|
||||
return None;
|
||||
|
||||
@@ -191,7 +191,6 @@ use crate::context_manager::ContextManager;
|
||||
use crate::thread_rollout_truncation::initial_history_has_prior_user_turns;
|
||||
use codex_config::CONFIG_TOML_FILE;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::types::McpServerConfig;
|
||||
use codex_model_provider_info::ModelProviderInfo;
|
||||
use codex_protocol::error::CodexErr;
|
||||
@@ -1740,11 +1739,7 @@ impl Session {
|
||||
let config = &state.session_configuration.original_config_do_not_use;
|
||||
let user_config_paths = config
|
||||
.config_layer_stack
|
||||
.get_user_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.filter_map(|layer| match &layer.name {
|
||||
ConfigLayerSource::User { file, .. } => Some(file.clone()),
|
||||
_ => None,
|
||||
|
||||
@@ -18,7 +18,6 @@ use crate::test_support::models_manager_with_provider;
|
||||
use crate::tools::format_exec_output_str;
|
||||
use crate::tools::registry::ToolRegistry;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID;
|
||||
use codex_config::LoaderOverrides;
|
||||
use codex_config::NetworkConstraints;
|
||||
@@ -1269,11 +1268,7 @@ async fn danger_full_access_tool_attempts_do_not_enforce_managed_network() -> an
|
||||
|
||||
let layers = config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.cloned()
|
||||
.collect();
|
||||
let mut requirements = config.config_layer_stack.requirements().clone();
|
||||
@@ -1899,11 +1894,7 @@ async fn refresh_mcp_config_replaces_managed_server_and_plugin_requirements() {
|
||||
requirements_toml.plugins = Some(plugin_requirements.clone());
|
||||
let layers = next_config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.cloned()
|
||||
.collect();
|
||||
next_config.config_layer_stack = ConfigLayerStack::new(layers, requirements, requirements_toml)
|
||||
@@ -8617,11 +8608,7 @@ async fn record_context_updates_emits_environment_item_for_network_changes() {
|
||||
));
|
||||
let layers = config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.into_iter()
|
||||
.all_layers_low_to_high()
|
||||
.cloned()
|
||||
.collect();
|
||||
config.config_layer_stack = ConfigLayerStack::new(
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::collections::HashMap;
|
||||
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::HookStateToml;
|
||||
use codex_config::TomlValue;
|
||||
|
||||
@@ -21,10 +20,7 @@ pub fn hook_states_from_stack(
|
||||
};
|
||||
|
||||
let mut states: HashMap<String, HookStateToml> = HashMap::new();
|
||||
for layer in config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
) {
|
||||
for layer in config_layer_stack.all_layers_low_to_high() {
|
||||
if !matches!(
|
||||
layer.name,
|
||||
ConfigLayerSource::User { .. } | ConfigLayerSource::SessionFlags
|
||||
|
||||
@@ -7,7 +7,6 @@ use codex_config::CONFIG_TOML_FILE;
|
||||
use codex_config::ConfigLayerEntry;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::HookEventsToml;
|
||||
use codex_config::HookHandlerConfig;
|
||||
use codex_config::HookStateToml;
|
||||
@@ -98,10 +97,7 @@ pub(crate) fn discover_handlers(
|
||||
policy,
|
||||
);
|
||||
|
||||
for layer in config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ false,
|
||||
) {
|
||||
for layer in config_layer_stack.layers_low_to_high() {
|
||||
let (hook_source, is_managed) = hook_metadata_for_config_layer_source(&layer.name);
|
||||
let policy_path = config_toml_source_path(layer);
|
||||
let policy_source = HookHandlerSource {
|
||||
|
||||
@@ -134,7 +134,6 @@ use codex_app_server_protocol::TurnError as AppServerTurnError;
|
||||
use codex_app_server_protocol::TurnStatus;
|
||||
use codex_app_server_protocol::WriteStatus;
|
||||
use codex_config::CloudConfigBundleLoader;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::LoaderOverrides;
|
||||
use codex_config::types::ApprovalsReviewer;
|
||||
use codex_config::types::MemoriesToml;
|
||||
|
||||
@@ -30,22 +30,18 @@ pub(super) fn resume_model_settings_for_overrides(
|
||||
config: &Config,
|
||||
harness_overrides: &ConfigOverrides,
|
||||
) -> crate::app_server_session::ResumeModelSettings {
|
||||
let has_layer_override = config
|
||||
.config_layer_stack
|
||||
.layers_high_to_low()
|
||||
.into_iter()
|
||||
.any(|layer| {
|
||||
matches!(
|
||||
&layer.name,
|
||||
ConfigLayerSource::SessionFlags
|
||||
| ConfigLayerSource::User {
|
||||
profile: Some(_),
|
||||
..
|
||||
}
|
||||
) && ["model", "model_provider", "model_reasoning_effort"]
|
||||
.iter()
|
||||
.any(|key| layer.config.get(*key).is_some())
|
||||
});
|
||||
let has_layer_override = config.config_layer_stack.layers_high_to_low().any(|layer| {
|
||||
matches!(
|
||||
&layer.name,
|
||||
ConfigLayerSource::SessionFlags
|
||||
| ConfigLayerSource::User {
|
||||
profile: Some(_),
|
||||
..
|
||||
}
|
||||
) && ["model", "model_provider", "model_reasoning_effort"]
|
||||
.iter()
|
||||
.any(|key| layer.config.get(*key).is_some())
|
||||
});
|
||||
if harness_overrides.model.is_some()
|
||||
|| harness_overrides.model_provider.is_some()
|
||||
|| has_layer_override
|
||||
|
||||
@@ -69,10 +69,7 @@ pub(super) fn emit_skill_load_warnings(app_event_tx: &AppEventSender, errors: &[
|
||||
pub(super) fn emit_project_config_warnings(app_event_tx: &AppEventSender, config: &Config) {
|
||||
let mut disabled_folders = Vec::new();
|
||||
|
||||
for layer in config.config_layer_stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
) {
|
||||
for layer in config.config_layer_stack.all_layers_low_to_high() {
|
||||
let ConfigLayerSource::Project { dot_codex_folder } = &layer.name else {
|
||||
continue;
|
||||
};
|
||||
|
||||
@@ -116,7 +116,6 @@ use codex_app_server_protocol::TurnCompletedNotification;
|
||||
use codex_app_server_protocol::TurnPlanStepStatus;
|
||||
use codex_app_server_protocol::TurnStatus;
|
||||
use codex_app_server_protocol::UserInput;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::Constrained;
|
||||
use codex_config::ConstraintResult;
|
||||
use codex_config::types::ApprovalsReviewer;
|
||||
|
||||
@@ -448,11 +448,7 @@ impl ChatWidget {
|
||||
|
||||
self.config
|
||||
.config_layer_stack
|
||||
.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
)
|
||||
.iter()
|
||||
.all_layers_low_to_high()
|
||||
.find_map(|layer| match &layer.name {
|
||||
ConfigLayerSource::Project { dot_codex_folder } => {
|
||||
dot_codex_folder.as_path().parent().map(Path::to_path_buf)
|
||||
|
||||
@@ -6,7 +6,6 @@ use codex_config::CONFIG_TOML_FILE;
|
||||
use codex_config::ConfigLayerEntry;
|
||||
use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStack;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::ManagedHooksRequirementsToml;
|
||||
use codex_config::NetworkConstraints;
|
||||
use codex_config::NetworkDomainPermissionToml;
|
||||
@@ -131,14 +130,11 @@ fn render_debug_config_lines(
|
||||
.bold()
|
||||
.into(),
|
||||
);
|
||||
let layers = stack.get_layers(
|
||||
ConfigLayerStackOrdering::LowestPrecedenceFirst,
|
||||
/*include_disabled*/ true,
|
||||
);
|
||||
if layers.is_empty() {
|
||||
let mut layers = stack.all_layers_low_to_high().peekable();
|
||||
if layers.peek().is_none() {
|
||||
lines.push(" <none>".dim().into());
|
||||
} else {
|
||||
for (index, layer) in layers.iter().enumerate() {
|
||||
for (index, layer) in layers.enumerate() {
|
||||
let source = format_config_layer_source(&layer.name, CONFIG_TOML_FILE);
|
||||
let status = if layer.is_disabled() {
|
||||
"disabled"
|
||||
|
||||
Reference in New Issue
Block a user