Preserve requirement path layer bases

This commit is contained in:
Abhinav Vedmala
2026-06-17 03:29:19 +00:00
parent e7efba1fc3
commit 21d891f7b8
2 changed files with 71 additions and 0 deletions
@@ -71,6 +71,7 @@ impl ComposableRequirementsLayer {
};
requirements.apply_remote_sandbox_config(hostname);
materialize_resolved_path_requirements(&mut regular_toml, &requirements)?;
materialize_remote_sandbox_config(&mut regular_toml, &requirements)?;
strip_special_fields(&mut regular_toml);
@@ -134,6 +135,30 @@ fn parse_layer_requirements(
}
}
fn materialize_resolved_path_requirements(
layer_toml: &mut TomlValue,
requirements: &ConfigRequirementsToml,
) -> Result<(), RequirementsCompositionError> {
let Some(table) = layer_toml.as_table_mut() else {
return Ok(());
};
for (key, value) in [
("sqlite_home", requirements.sqlite_home.as_ref()),
("log_dir", requirements.log_dir.as_ref()),
(
"model_catalog_json",
requirements.model_catalog_json.as_ref(),
),
] {
if let Some(value) = value {
table.insert(key.to_string(), toml_value_from_serializable(value)?);
}
}
Ok(())
}
fn materialize_remote_sandbox_config(
layer_toml: &mut TomlValue,
requirements: &ConfigRequirementsToml,
@@ -11,6 +11,7 @@ use codex_protocol::protocol::AskForApproval;
use codex_utils_absolute_path::AbsolutePathBuf;
use pretty_assertions::assert_eq;
use std::collections::BTreeMap;
use tempfile::tempdir;
fn layer(id: &str, name: &str, contents: &str) -> RequirementsLayerEntry {
RequirementsLayerEntry::from_toml(
@@ -106,6 +107,51 @@ allow_remote_control = false
);
}
#[test]
fn relative_paths_resolve_against_their_own_layer_base() {
let low_dir = tempdir().expect("low-priority requirements directory");
let high_dir = tempdir().expect("high-priority requirements directory");
let low_base = AbsolutePathBuf::from_absolute_path(low_dir.path()).expect("absolute low base");
let high_base =
AbsolutePathBuf::from_absolute_path(high_dir.path()).expect("absolute high base");
let composed = compose(vec![
layer(
"req_low",
"Low",
r#"
sqlite_home = "state"
log_dir = "low-logs"
"#,
)
.with_base_dir(low_base),
layer(
"req_high",
"High",
r#"
log_dir = "high-logs"
model_catalog_json = "models.json"
"#,
)
.with_base_dir(high_base),
])
.expect("compose requirements")
.expect("requirements present");
assert_eq!(
composed.sqlite_home.as_deref(),
Some(low_dir.path().join("state").as_path())
);
assert_eq!(
composed.log_dir.as_deref(),
Some(high_dir.path().join("high-logs").as_path())
);
assert_eq!(
composed.model_catalog_json.as_deref(),
Some(high_dir.path().join("models.json").as_path())
);
}
#[test]
fn composition_strategy_applies_to_non_cloud_layers() {
let mdm_source = RequirementSource::MdmManagedPreferences {