Wire up cloud reqs in exec, app-server (#10241)

We're fetching cloud requirements in TUI in
https://github.com/openai/codex/pull/10167.

This adds the same fetching in exec and app-server binaries also.
This commit is contained in:
gt-oai
2026-01-30 23:53:41 +00:00
committed by GitHub
parent 10ea117ee1
commit a046481ad9
16 changed files with 235 additions and 101 deletions

View File

@@ -366,7 +366,7 @@ pub struct ConfigBuilder {
cli_overrides: Option<Vec<(String, TomlValue)>>,
harness_overrides: Option<ConfigOverrides>,
loader_overrides: Option<LoaderOverrides>,
cloud_requirements: Option<CloudRequirementsLoader>,
cloud_requirements: CloudRequirementsLoader,
fallback_cwd: Option<PathBuf>,
}
@@ -392,7 +392,7 @@ impl ConfigBuilder {
}
pub fn cloud_requirements(mut self, cloud_requirements: CloudRequirementsLoader) -> Self {
self.cloud_requirements = Some(cloud_requirements);
self.cloud_requirements = cloud_requirements;
self
}
@@ -523,7 +523,7 @@ pub async fn load_config_as_toml_with_cli_overrides(
Some(cwd.clone()),
&cli_overrides,
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -627,7 +627,7 @@ pub async fn load_global_mcp_servers(
cwd,
&cli_overrides,
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
let merged_toml = config_layer_stack.effective_config();
@@ -2627,9 +2627,14 @@ profile = "project"
};
let cwd = AbsolutePathBuf::try_from(codex_home.path())?;
let config_layer_stack =
load_config_layers_state(codex_home.path(), Some(cwd), &Vec::new(), overrides, None)
.await?;
let config_layer_stack = load_config_layers_state(
codex_home.path(),
Some(cwd),
&Vec::new(),
overrides,
CloudRequirementsLoader::default(),
)
.await?;
let cfg = deserialize_config_toml_with_base(
config_layer_stack.effective_config(),
codex_home.path(),
@@ -2756,7 +2761,7 @@ profile = "project"
Some(cwd),
&[("model".to_string(), TomlValue::String("cli".to_string()))],
overrides,
None,
CloudRequirementsLoader::default(),
)
.await?;

View File

@@ -2,6 +2,7 @@ use super::CONFIG_TOML_FILE;
use super::ConfigToml;
use crate::config::edit::ConfigEdit;
use crate::config::edit::ConfigEditsBuilder;
use crate::config_loader::CloudRequirementsLoader;
use crate::config_loader::ConfigLayerEntry;
use crate::config_loader::ConfigLayerStack;
use crate::config_loader::ConfigLayerStackOrdering;
@@ -109,6 +110,7 @@ pub struct ConfigService {
codex_home: PathBuf,
cli_overrides: Vec<(String, TomlValue)>,
loader_overrides: LoaderOverrides,
cloud_requirements: CloudRequirementsLoader,
}
impl ConfigService {
@@ -116,11 +118,13 @@ impl ConfigService {
codex_home: PathBuf,
cli_overrides: Vec<(String, TomlValue)>,
loader_overrides: LoaderOverrides,
cloud_requirements: CloudRequirementsLoader,
) -> Self {
Self {
codex_home,
cli_overrides,
loader_overrides,
cloud_requirements,
}
}
@@ -129,6 +133,7 @@ impl ConfigService {
codex_home,
cli_overrides: Vec::new(),
loader_overrides: LoaderOverrides::default(),
cloud_requirements: CloudRequirementsLoader::default(),
}
}
@@ -146,6 +151,7 @@ impl ConfigService {
.cli_overrides(self.cli_overrides.clone())
.loader_overrides(self.loader_overrides.clone())
.fallback_cwd(Some(cwd.to_path_buf()))
.cloud_requirements(self.cloud_requirements.clone())
.build()
.await
.map_err(|err| {
@@ -376,7 +382,7 @@ impl ConfigService {
cwd,
&self.cli_overrides,
self.loader_overrides.clone(),
None,
self.cloud_requirements.clone(),
)
.await
}
@@ -814,6 +820,7 @@ remote_compaction = true
managed_preferences_base64: None,
macos_managed_config_requirements_base64: None,
},
CloudRequirementsLoader::default(),
);
let response = service
@@ -896,6 +903,7 @@ remote_compaction = true
managed_preferences_base64: None,
macos_managed_config_requirements_base64: None,
},
CloudRequirementsLoader::default(),
);
let result = service
@@ -1000,6 +1008,7 @@ remote_compaction = true
managed_preferences_base64: None,
macos_managed_config_requirements_base64: None,
},
CloudRequirementsLoader::default(),
);
let error = service
@@ -1048,6 +1057,7 @@ remote_compaction = true
managed_preferences_base64: None,
macos_managed_config_requirements_base64: None,
},
CloudRequirementsLoader::default(),
);
let response = service
@@ -1095,6 +1105,7 @@ remote_compaction = true
managed_preferences_base64: None,
macos_managed_config_requirements_base64: None,
},
CloudRequirementsLoader::default(),
);
let result = service

View File

@@ -32,6 +32,12 @@ impl fmt::Debug for CloudRequirementsLoader {
}
}
impl Default for CloudRequirementsLoader {
fn default() -> Self {
Self::new(async { None })
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -101,7 +101,7 @@ pub async fn load_config_layers_state(
cwd: Option<AbsolutePathBuf>,
cli_overrides: &[(String, TomlValue)],
overrides: LoaderOverrides,
cloud_requirements: Option<CloudRequirementsLoader>, // TODO(gt): Once exec and app-server are wired up, we can remove the option.
cloud_requirements: CloudRequirementsLoader,
) -> io::Result<ConfigLayerStack> {
let mut config_requirements_toml = ConfigRequirementsWithSources::default();
@@ -114,9 +114,7 @@ pub async fn load_config_layers_state(
)
.await?;
if let Some(loader) = cloud_requirements
&& let Some(requirements) = loader.get().await
{
if let Some(requirements) = cloud_requirements.get().await {
config_requirements_toml
.merge_unset_fields(RequirementSource::CloudRequirements, requirements);
}

View File

@@ -69,7 +69,7 @@ async fn returns_config_error_for_invalid_user_config_toml() {
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await
.expect_err("expected error");
@@ -99,7 +99,7 @@ async fn returns_config_error_for_invalid_managed_config_toml() {
Some(cwd),
&[] as &[(String, TomlValue)],
overrides,
None,
CloudRequirementsLoader::default(),
)
.await
.expect_err("expected error");
@@ -188,7 +188,7 @@ extra = true
Some(cwd),
&[] as &[(String, TomlValue)],
overrides,
None,
CloudRequirementsLoader::default(),
)
.await
.expect("load config");
@@ -225,7 +225,7 @@ async fn returns_empty_when_all_layers_missing() {
Some(cwd),
&[] as &[(String, TomlValue)],
overrides,
None,
CloudRequirementsLoader::default(),
)
.await
.expect("load layers");
@@ -323,7 +323,7 @@ flag = false
Some(cwd),
&[] as &[(String, TomlValue)],
overrides,
None,
CloudRequirementsLoader::default(),
)
.await
.expect("load config");
@@ -363,7 +363,7 @@ allowed_sandbox_modes = ["read-only"]
),
),
},
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -424,7 +424,7 @@ allowed_approval_policies = ["never"]
),
),
},
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -546,7 +546,7 @@ async fn load_config_layers_includes_cloud_requirements() -> anyhow::Result<()>
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
Some(cloud_requirements),
cloud_requirements,
)
.await?;
@@ -599,7 +599,7 @@ async fn project_layers_prefer_closest_cwd() -> std::io::Result<()> {
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -731,7 +731,7 @@ async fn project_layer_is_added_when_dot_codex_exists_without_config_toml() -> s
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -769,7 +769,7 @@ async fn codex_home_is_not_loaded_as_project_layer_from_home_dir() -> std::io::R
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -819,7 +819,7 @@ async fn codex_home_within_project_tree_is_not_double_loaded() -> std::io::Resul
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -888,7 +888,7 @@ async fn project_layers_disabled_when_untrusted_or_unknown() -> std::io::Result<
Some(cwd.clone()),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
let project_layers_untrusted: Vec<_> = layers_untrusted
@@ -926,7 +926,7 @@ async fn project_layers_disabled_when_untrusted_or_unknown() -> std::io::Result<
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
let project_layers_unknown: Vec<_> = layers_unknown
@@ -987,7 +987,7 @@ async fn invalid_project_config_ignored_when_untrusted_or_unknown() -> std::io::
Some(cwd.clone()),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
let project_layers: Vec<_> = layers
@@ -1043,7 +1043,7 @@ async fn cli_overrides_with_relative_paths_do_not_break_trust_check() -> std::io
Some(cwd),
&cli_overrides,
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;
@@ -1085,7 +1085,7 @@ async fn project_root_markers_supports_alternate_markers() -> std::io::Result<()
Some(cwd),
&[] as &[(String, TomlValue)],
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await?;

View File

@@ -10,6 +10,7 @@ use tracing::warn;
use crate::config::Config;
use crate::config::types::SkillsConfig;
use crate::config_loader::CloudRequirementsLoader;
use crate::config_loader::LoaderOverrides;
use crate::config_loader::load_config_layers_state;
use crate::skills::SkillLoadOutcome;
@@ -88,7 +89,7 @@ impl SkillsManager {
Some(cwd_abs),
&cli_overrides,
LoaderOverrides::default(),
None,
CloudRequirementsLoader::default(),
)
.await
{