Replies: 1 comment
-
|
Opened a PR implementing this proposal: #8934 The PR adds
All CI checks passing. Happy to iterate based on maintainer feedback. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Problem
Recipe parameters today are flat scalars (
string,number,boolean,date,file,select). This works well for interactive and desktop use cases where a human fills in a form. However, when an orchestrator invokes a recipe programmatically — for example, an enterprise platform passing structured incident context to a recipe — the orchestrator must flatten all structured data into individual string parameters.For a real-world example: an incident response orchestrator needs to pass signal context, enrichment data, and findings from prior pipeline phases to a recipe. Today, this requires 25+ flat string parameters:
And the recipe author cannot use conditionals or loops over structured data:
Observation
Goose already uses MiniJinja for recipe template rendering (
prompt_template.rs). MiniJinja natively supports:{{ signal.namespace }}{% if enrichment.owner_chain %}{% for item in findings %}{{ data | tojson }}These capabilities are already compiled into Goose. The test suite in
validate_recipe.rseven validates{% if %}conditionals in recipes today. The gap is not the template engine — it's that recipe parameters are passed asHashMap<String, String>, which discards structure before reaching MiniJinja.Proposal
Add
objectandarrayas parameter input types, and pass structured values into the MiniJinja rendering context.Recipe author experience:
Orchestrator passes structured values:
{ "signal": { "name": "OOMKilled", "namespace": "production", "severity": "critical", "resource_kind": "Pod", "resource_name": "api-server-abc123" }, "enrichment": { "owner_chain": "Pod/api-server-abc123 → ReplicaSet/api-server → Deployment/api-server" }, "prior_findings": [ { "name": "change-freeze-check", "phase": "pre-investigation", "output": "No active change freeze for namespace production" } ] }Scope of Change
Based on code review, the changes are localized to the recipe module:
recipe/mod.rs: AddObjectandArrayvariants toRecipeParameterInputTyperecipe/template_recipe.rs: Changerender_recipe_content_with_paramssignature fromparams: &HashMap<String, String>toparams: &HashMap<String, serde_json::Value>(orminijinja::Value). MiniJinja'sValue::from_serialize()already handles the conversion.recipe/validate_recipe.rs: Updatevalidate_parameters_in_templateto recognize dot-notation variables (e.g.,signal.namespace→ verifysignalis a declared parameter).undeclared_variables(true)already returnssignalas the top-level name.recipe_utils.rsingoose-server): Acceptserde_json::Valuefor object/array params instead of forcing string conversion.Use Cases
values)Backward Compatibility
string/number/boolean/date/file/selectparameters are unaffectedserde_json::Valueand auto-convert scalar values to strings for backward compatibilityobject/arrayparameters: optionality rules apply to the top-level value; nested field validation is left to the template's runtime behavior (consistent with how MiniJinja handles missing attributes)Prior Art
context!(users => vec![...])with{% for user in users %}render_string<T: Serialize>()inprompt_template.rsalready accepts arbitrary serializable types — the recipe path is the only one that narrows toHashMap<String, String>Posted as a Discussion per CONTRIBUTING.md guidance for architectural changes. Happy to follow up with a focused issue and PR if this direction aligns with Goose's goals.
Beta Was this translation helpful? Give feedback.
All reactions