diff --git a/crates/goose-cli/src/recipes/recipe.rs b/crates/goose-cli/src/recipes/recipe.rs index 6d0fa2f47..a25d3335d 100644 --- a/crates/goose-cli/src/recipes/recipe.rs +++ b/crates/goose-cli/src/recipes/recipe.rs @@ -7,7 +7,7 @@ use crate::recipes::secret_discovery::{discover_recipe_secrets, SecretRequiremen use anyhow::Result; use goose::config::Config; use goose::recipe::build_recipe::{ - apply_values_to_parameters, build_recipe_from_template, RecipeError, + apply_values_to_parameters_without_file_expansion, build_recipe_from_template, RecipeError, }; use goose::recipe::validate_recipe::parse_and_validate_parameters; use goose::recipe::Recipe; @@ -140,7 +140,7 @@ pub fn explain_recipe(recipe_name: &str, params: Vec<(String, String)>) -> Resul parse_and_validate_parameters(recipe_file_content, Some(recipe_dir_str.clone()))?; let recipe_parameters = recipe_template.parameters.clone(); - let (params_for_template, missing_params) = apply_values_to_parameters( + let (params_for_template, missing_params) = apply_values_to_parameters_without_file_expansion( ¶ms, recipe_parameters, &recipe_dir_str, @@ -154,6 +154,7 @@ pub fn explain_recipe(recipe_name: &str, params: Vec<(String, String)>) -> Resul #[cfg(test)] mod tests { + use goose::recipe::build_recipe::apply_values_to_parameters_without_file_expansion; use goose::recipe::{RecipeParameterInputType, RecipeParameterRequirement}; use crate::recipes::recipe::load_recipe; @@ -198,4 +199,32 @@ mod tests { assert_eq!(param.description, "A test parameter"); } } + + #[test] + fn explanation_preserves_file_parameter_path_without_reading_contents() { + let temp_dir = tempfile::tempdir().unwrap(); + let file_path = temp_dir.path().join("does-not-exist.txt"); + let parameters = vec![goose::recipe::RecipeParameter { + key: "input_file".to_string(), + input_type: RecipeParameterInputType::File, + requirement: RecipeParameterRequirement::Required, + description: "Input file".to_string(), + default: None, + options: None, + }]; + + let (values, missing) = apply_values_to_parameters_without_file_expansion( + &[("input_file".to_string(), file_path.display().to_string())], + Some(parameters), + temp_dir.path().to_str().unwrap(), + None:: anyhow::Result>, + ) + .unwrap(); + + assert!(missing.is_empty()); + assert_eq!( + values.get("input_file"), + Some(&file_path.display().to_string()) + ); + } } diff --git a/crates/goose/src/recipe/build_recipe/mod.rs b/crates/goose/src/recipe/build_recipe/mod.rs index a08d3fc27..5a8da37ff 100644 --- a/crates/goose/src/recipe/build_recipe/mod.rs +++ b/crates/goose/src/recipe/build_recipe/mod.rs @@ -83,6 +83,44 @@ pub fn apply_values_to_parameters( ) -> Result<(HashMap, Vec)> where F: Fn(&str, &str) -> Result, +{ + apply_values_to_parameters_with_file_handler( + user_params, + recipe_parameters, + recipe_dir, + user_prompt_fn, + |path| read_parameter_file_content(path), + ) +} + +pub fn apply_values_to_parameters_without_file_expansion( + user_params: &[(String, String)], + recipe_parameters: Option>, + recipe_dir: &str, + user_prompt_fn: Option, +) -> Result<(HashMap, Vec)> +where + F: Fn(&str, &str) -> Result, +{ + apply_values_to_parameters_with_file_handler( + user_params, + recipe_parameters, + recipe_dir, + user_prompt_fn, + |path| Ok(path.to_string()), + ) +} + +fn apply_values_to_parameters_with_file_handler( + user_params: &[(String, String)], + recipe_parameters: Option>, + recipe_dir: &str, + user_prompt_fn: Option, + file_handler: H, +) -> Result<(HashMap, Vec)> +where + F: Fn(&str, &str) -> Result, + H: Fn(&str) -> Result, { let mut param_map: HashMap = user_params.iter().cloned().collect(); param_map.insert( @@ -106,7 +144,7 @@ where match raw_value { Some(value) => { let final_value = if matches!(param.input_type, RecipeParameterInputType::File) { - read_parameter_file_content(&value)? + file_handler(&value)? } else { value };