Tools
Advent of AI - Day 10: Understanding Arguments in Goose Recipes
2025-12-14
0 views
admin
Advent of AI 2025 - Day 7: Goose Recipes ## Nick Taylor ・ Dec 10 ## block / goose ## an open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM ## Quick Links ## Need Help? ## The Problem I Was Solving ## How Recipe Parameters Work ## Required vs Optional ## Conditional Logic with Jinja ## What This Actually Does ## Useful Jinja Patterns ## Variable Interpolation ## Conditional Blocks ## String Manipulation ## Combining Conditions ## Why This Matters ## Beyond Posters ## Things I Learned ## Start Simple ## Use Select Types When You Can ## Provide Defaults for Optional Stuff ## Test All the Paths ## Check the Docs ## Reference Docs ## Wrapping Up I've edited this post, but AI helped. These are meant to be quick posts related to the Advent of AI. I don't have time if I'm doing one of these each day to spend a couple hours on a post. For Advent of AI Day 10, I built a festival poster generator using Goose recipes. But this post isn't really about making posters. It's about understanding how recipe arguments and conditional logic turn static prompts into reusable AI workflows. Up until now in the Advent of AI challenges, I'd been using recipes pretty simply. Pass in some parameters, get output. But Day 10 made me dig deeper into what's actually happening under the hood with arguments and Jinja templating. The advent of AI series leverages Goose, an open source AI agent. If you've never heard of it, check it out! a local, extensible, open source AI agent that automates engineering tasks goose is your on-machine AI agent, capable of automating complex development tasks from start to finish. More than just code suggestions, goose can build entire projects from scratch, write and execute code, debug failures, orchestrate workflows, and interact with external APIs - autonomously. Whether you're prototyping an idea, refining existing code, or managing intricate engineering pipelines, goose adapts to your workflow and executes tasks with precision. Designed for maximum flexibility, goose works with any LLM and supports multi-model configuration to optimize performance and cost, seamlessly integrates with MCP servers, and is available as both a desktop app as well as CLI - making it the ultimate AI assistant for developers who want to move faster and focus on innovation. The Day 10 challenge asks you to generate festival posters. Not just one poster, but posters for different event types. Food events need warm, cozy vibes. Kids events need bright, playful energy. Performance events need elegant styling. Without parameters, you're writing separate prompts for each type. That's tedious and doesn't scale. With parameters and conditional logic, you write one recipe that handles all of them. Goose recipes let you define inputs just like function parameters. You specify what can change, and users provide those values when they run the recipe. Here's the basic setup: Required parameters are non-negotiable. You can't generate a poster without knowing the event name, date, location, and type. The recipe won't run if these are missing. Optional parameters add flexibility. A tagline is nice to have, but if you don't provide one, the recipe still works. Setting default: "" means optional parameters become empty strings when not provided, which is perfect for conditional logic later. This is where it gets really good. The instructions section of a recipe supports Jinja2 templating. That means you can write logic that changes what the AI actually sees based on the parameters you pass in. For the poster generator, the entire styling instructions change based on event_type: Same recipe, completely different instructions sent to the AI depending on what event_type you provide. That's the power of this approach. When you run the recipe with event_type: food, the AI gets instructions about warm colors and cozy vibes. Run it with event_type: kids, and it gets instructions about bright colors and playful energy. The AI doesn't see both sets of instructions. It only sees the one that matches your event type. That's way better than trying to cram all the logic into a single prompt and hoping the AI picks the right path. The basic {{ variable_name }} syntax injects parameter values: {% if condition %} lets you include or skip entire sections: I used this a lot for optional parameters. If someone provides a tagline, include it. If not, skip that section entirely. Jinja filters let you transform values on the fly: This converts "Hot Cocoa Tasting" to "hot_cocoa_tasting" automatically. Super useful for file names. You can get fancy with multiple conditions: With parameters and conditional logic, you write once and reuse forever. For the Day 10 challenge, I can generate posters for all the different festival events just by changing the parameters: Want a kids event? Same recipe, different parameters: In Goose Desktop, you get a form UI with dropdowns for the event type and text inputs for everything else. Way nicer than typing command-line args. The real win is consistency. All the posters follow the same structure and quality standards because they're coming from the same recipe. The only thing that changes is the data and the conditional styling. The Day 10 challenge is about posters, but these patterns work for any repetitive AI task. I've been using Goose recipes for all sorts of stuff during Advent of AI: Each one follows the same pattern. Define what varies (parameters), write conditional logic for different paths (Jinja), run it as many times as you need. For work at Pomerium, I could see this being useful for generating security policies or MCP server configurations with different auth providers and policy levels. Same recipe, different security postures based on parameters. Don't try to make everything configurable on day one. Figure out the 3-5 things that actually need to vary, make those parameters, and ship it. You can always add more later. For the event type, I used input_type: select instead of a freeform string. This prevents typos and makes the conditional logic reliable. If someone can only pick from "food", "kids", "performance", etc., you don't have to worry about handling "Food" vs "food" vs "FOOD". For optional parameters, think about what makes sense when nothing is provided: Most people probably want HTML, so default to that. With conditional logic, you're creating multiple execution paths. I made sure to test: The Recipe Parameters docs list all the input types and validation options. Reference these when you're setting up parameters instead of guessing. Everything here is documented officially: I referenced these docs a lot while building the poster recipe. Parameters and conditional logic turn recipes from one-off tools into reusable workflows. Instead of "make me a poster", it becomes "here's a poster recipe that adapts based on what you need". Run it once, run it a hundred times, same quality every time. The Day 10 challenge is a good intro to these concepts. You get to see how the same recipe generates five completely different poster themes just by changing one parameter. But the real learning is recognizing when you could apply this pattern to your own work. What repetitive tasks are you doing with AI right now? What parts change each time? Those changing parts are your parameters. The logic that decides what to do with those parameters? That's your Jinja conditionals. Check out the Day 10 challenge if you want to try building one yourself. If you want to stay in touch, all my socials are on nickyt.online. Photo by Sven Mieke on Unsplash Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
version: 1.0.0
title: Festival Poster Generator
description: Generate themed HTML posters with conditional styling parameters: - key: event_name input_type: string requirement: required description: Name of the festival event - key: event_type input_type: select requirement: required description: Type of event - determines theme and styling options: - food - kids - performance - competition - workshop - key: tagline input_type: string requirement: optional description: Optional tagline or subtitle default: "" Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
version: 1.0.0
title: Festival Poster Generator
description: Generate themed HTML posters with conditional styling parameters: - key: event_name input_type: string requirement: required description: Name of the festival event - key: event_type input_type: select requirement: required description: Type of event - determines theme and styling options: - food - kids - performance - competition - workshop - key: tagline input_type: string requirement: optional description: Optional tagline or subtitle default: "" CODE_BLOCK:
version: 1.0.0
title: Festival Poster Generator
description: Generate themed HTML posters with conditional styling parameters: - key: event_name input_type: string requirement: required description: Name of the festival event - key: event_type input_type: select requirement: required description: Type of event - determines theme and styling options: - food - kids - performance - competition - workshop - key: tagline input_type: string requirement: optional description: Optional tagline or subtitle default: "" COMMAND_BLOCK:
instructions: | You are a festival poster generator. **Event Details:** - Event Name: {{ event_name }} - Date & Time: {{ event_datetime }} - Location: {{ location }} - Event Type: {{ event_type }} {% if tagline %}- Tagline: {{ tagline }}{% endif %} {% if description %}- Description: {{ description }}{% endif %} {% if event_type == "food" %} ## Food Event Theme - Use warm, inviting colors (burgundy, warm orange, cream) - Typography: Friendly, rounded fonts - Mood: Cozy, appetizing, welcoming {% endif %} {% if event_type == "kids" %} ## Kids Event Theme - Use bright, playful colors (rainbow palette, pastels) - Typography: Playful, bold, easy-to-read fonts - Mood: Fun, energetic, joyful {% endif %} Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
instructions: | You are a festival poster generator. **Event Details:** - Event Name: {{ event_name }} - Date & Time: {{ event_datetime }} - Location: {{ location }} - Event Type: {{ event_type }} {% if tagline %}- Tagline: {{ tagline }}{% endif %} {% if description %}- Description: {{ description }}{% endif %} {% if event_type == "food" %} ## Food Event Theme - Use warm, inviting colors (burgundy, warm orange, cream) - Typography: Friendly, rounded fonts - Mood: Cozy, appetizing, welcoming {% endif %} {% if event_type == "kids" %} ## Kids Event Theme - Use bright, playful colors (rainbow palette, pastels) - Typography: Playful, bold, easy-to-read fonts - Mood: Fun, energetic, joyful {% endif %} COMMAND_BLOCK:
instructions: | You are a festival poster generator. **Event Details:** - Event Name: {{ event_name }} - Date & Time: {{ event_datetime }} - Location: {{ location }} - Event Type: {{ event_type }} {% if tagline %}- Tagline: {{ tagline }}{% endif %} {% if description %}- Description: {{ description }}{% endif %} {% if event_type == "food" %} ## Food Event Theme - Use warm, inviting colors (burgundy, warm orange, cream) - Typography: Friendly, rounded fonts - Mood: Cozy, appetizing, welcoming {% endif %} {% if event_type == "kids" %} ## Kids Event Theme - Use bright, playful colors (rainbow palette, pastels) - Typography: Playful, bold, easy-to-read fonts - Mood: Fun, energetic, joyful {% endif %} CODE_BLOCK:
instructions: | Create a poster for {{ event_name }} on {{ event_datetime }}. Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
instructions: | Create a poster for {{ event_name }} on {{ event_datetime }}. CODE_BLOCK:
instructions: | Create a poster for {{ event_name }} on {{ event_datetime }}. CODE_BLOCK:
{% if tagline %}
Make the tagline prominent: {{ tagline }}
{% endif %} {% if not description %}
Since no description was provided, create a brief one.
{% endif %} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{% if tagline %}
Make the tagline prominent: {{ tagline }}
{% endif %} {% if not description %}
Since no description was provided, create a brief one.
{% endif %} CODE_BLOCK:
{% if tagline %}
Make the tagline prominent: {{ tagline }}
{% endif %} {% if not description %}
Since no description was provided, create a brief one.
{% endif %} CODE_BLOCK:
Save to: poster_{{ event_type }}_{{ event_name | lower | replace(" ", "_") }}.html Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
Save to: poster_{{ event_type }}_{{ event_name | lower | replace(" ", "_") }}.html CODE_BLOCK:
Save to: poster_{{ event_type }}_{{ event_name | lower | replace(" ", "_") }}.html CODE_BLOCK:
{% if event_type == "performance" and ticket_info %}
Display ticket info with elegant styling: {{ ticket_info }}
{% elif event_type == "kids" and not ticket_info %}
Add "Free admission - all families welcome!"
{% endif %} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{% if event_type == "performance" and ticket_info %}
Display ticket info with elegant styling: {{ ticket_info }}
{% elif event_type == "kids" and not ticket_info %}
Add "Free admission - all families welcome!"
{% endif %} CODE_BLOCK:
{% if event_type == "performance" and ticket_info %}
Display ticket info with elegant styling: {{ ticket_info }}
{% elif event_type == "kids" and not ticket_info %}
Add "Free admission - all families welcome!"
{% endif %} COMMAND_BLOCK:
# CLI
goose run festival-poster-generator \ --event_name "Hot Cocoa Tasting" \ --event_datetime "December 15, 2pm–4pm" \ --location "Main Plaza" \ --event_type food Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
# CLI
goose run festival-poster-generator \ --event_name "Hot Cocoa Tasting" \ --event_datetime "December 15, 2pm–4pm" \ --location "Main Plaza" \ --event_type food COMMAND_BLOCK:
# CLI
goose run festival-poster-generator \ --event_name "Hot Cocoa Tasting" \ --event_datetime "December 15, 2pm–4pm" \ --location "Main Plaza" \ --event_type food CODE_BLOCK:
goose run festival-poster-generator \ --event_name "Storytelling Hour" \ --event_datetime "December 17, 3pm–4pm" \ --location "Story Tent" \ --event_type kids Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
goose run festival-poster-generator \ --event_name "Storytelling Hour" \ --event_datetime "December 17, 3pm–4pm" \ --location "Story Tent" \ --event_type kids CODE_BLOCK:
goose run festival-poster-generator \ --event_name "Storytelling Hour" \ --event_datetime "December 17, 3pm–4pm" \ --location "Story Tent" \ --event_type kids CODE_BLOCK:
- key: output_format input_type: select requirement: optional default: html options: - html - markdown Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
- key: output_format input_type: select requirement: optional default: html options: - html - markdown CODE_BLOCK:
- key: output_format input_type: select requirement: optional default: html options: - html - markdown - Installation
- Documentation
- Responsible AI-Assisted Coding Guide - Diagnostics & Reporting
- Known Issues - Data transformation (Day 8: messy vendor data to structured JSON)
- GitHub automation (Day 6: issue triage and labeling)
- UI generation (Day 4: festival website with theme switching) - All five event types to confirm each conditional branch works
- Optional parameters both provided and omitted
- Edge cases like really long event names - Recipe Guide - Overview of how recipes work
- Recipe Reference - Complete spec
- Recipe Parameters - All parameter types
- Jinja2 Docs - Full templating syntax - Advent of AI - Day 10 Challenge
- Goose Recipe Guide
- Recipe Parameters Documentation
- Jinja2 Templating
how-totutorialguidedev.toaimlllmserverswitchsslgitgithub