Skip to content

Commit 1e8eb6a

Browse files
committed
fix: correctly handle yaml templating
1 parent e2792a5 commit 1e8eb6a

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

agent-control/src/agent_type/runtime_config/on_host/filesystem.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,18 @@ impl Templateable for TemplateableValue<DirEntriesMap> {
236236
let value: HashMap<SafePath, String> = if templated_string.is_empty() {
237237
HashMap::new()
238238
} else {
239-
serde_yaml::from_str(&templated_string).map_err(|e| {
240-
AgentTypeError::ValueNotParseableFromString(format!(
241-
"Could not parse templated directory items as YAML mapping: {e}"
242-
))
243-
})?
239+
let map_string_value: HashMap<SafePath, serde_yaml::Value> =
240+
serde_yaml::from_str(&templated_string).map_err(|e| {
241+
AgentTypeError::ValueNotParseableFromString(format!(
242+
"Could not parse templated directory items as YAML: {e}"
243+
))
244+
})?;
245+
// Convert the serde_yaml::Value (i.e. the file contents) to String
246+
247+
map_string_value
248+
.into_iter()
249+
.map(|(k, v)| Ok((k, output_string(v)?)))
250+
.collect::<Result<HashMap<_, _>, serde_yaml::Error>>()?
244251
};
245252

246253
Ok(Self {
@@ -250,6 +257,18 @@ impl Templateable for TemplateableValue<DirEntriesMap> {
250257
}
251258
}
252259

260+
/// Converts a serde_yaml::Value to a String.
261+
/// If the value is already a String, it is returned as-is.
262+
/// Otherwise, it is serialized to a YAML string using serde_yaml.
263+
fn output_string(value: serde_yaml::Value) -> Result<String, serde_yaml::Error> {
264+
match value {
265+
// Pass the string directly (serde_yaml inserts literal syntax for multi-line strings)
266+
serde_yaml::Value::String(s) => Ok(s),
267+
// Else serialize the value to a YAML string using the default methods
268+
v => serde_yaml::to_string(&v),
269+
}
270+
}
271+
253272
/// Validates that a file entry path is relative and does not escape its base directory.
254273
/// Returns a comma-separated list of error messages, if any.
255274
fn validate_file_entry_path(path: &Path) -> Result<(), String> {

agent-control/tests/on_host/scenarios/filesystem_ops.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ fn complete_render_and_and_write_files_and_dirs() {
128128
"file4.txt",
129129
format!("File 4 contents with a variable: {string_var_content}\n"),
130130
);
131+
let expected_dir_file5 = ("file5.yaml", "my_key: my_value\nmy_seq:\n- item1\n- item2\nmy_string: |-\n This is a multi-line\n string in YAML\n".to_string());
131132

132133
// Create agent type definition
133134
create_file(
@@ -192,6 +193,14 @@ some_mapstringyaml:
192193
file3.txt: "File 3 contents"
193194
file4.txt: |
194195
File 4 contents with a variable: {string_var_content}
196+
file5.yaml:
197+
my_key: my_value
198+
my_seq:
199+
- item1
200+
- item2
201+
my_string: |-
202+
This is a multi-line
203+
string in YAML
195204
"#
196205
),
197206
local_dir.to_path_buf(),
@@ -248,6 +257,10 @@ some_mapstringyaml:
248257
fully_templated_dir_search_path.join(expected_dir_file4.0),
249258
expected_dir_file4.1,
250259
),
260+
(
261+
fully_templated_dir_search_path.join(expected_dir_file5.0),
262+
expected_dir_file5.1,
263+
),
251264
];
252265

253266
retry(30, Duration::from_secs(1), || {

0 commit comments

Comments
 (0)