DEV Community

Cover image for Advent of AI - Day 10: Understanding Arguments in Goose Recipes
Nick Taylor
Nick Taylor Subscriber

Posted on • Originally published at nickyt.co

Advent of AI - Day 10: Understanding Arguments in Goose Recipes

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.

The advent of AI series leverages Goose, an open source AI agent. If you've never heard of it, check it out!

GitHub logo block / goose

an open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM

goose

a local, extensible, open source AI agent that automates engineering tasks

Discord CI

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.

Watch the video

Quick Links

Need Help?

For Advent of AI Day 10, I built a festival poster generator using Goose recipes. Here’s my submission. 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 I discovered you can leverage Jinja templating with recipe arguments (args).

The Problem I Was Solving

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.

How Recipe Parameters Work

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:

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

Required vs Optional

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.

Conditional Logic with Jinja

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:

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

Hot Cocoa Tasting poster

Same recipe, completely different instructions sent to the AI depending on what event_type you provide. That's the power of this approach.

Kids Storytelling poster

What This Actually Does

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.

Useful Jinja Patterns

Variable Interpolation

The basic {{ variable_name }} syntax injects parameter values:

instructions: |
  Create a poster for {{ event_name }} on {{ event_datetime }}.
Enter fullscreen mode Exit fullscreen mode

Conditional Blocks

{% if condition %} lets you include or skip entire sections:

{% 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

I used this a lot for optional parameters. If someone provides a tagline, include it. If not, skip that section entirely.

String Manipulation

Jinja filters let you transform values on the fly:

Save to: poster_{{ event_type }}_{{ event_name | lower | replace(" ", "_") }}.html
Enter fullscreen mode Exit fullscreen mode

This converts "Hot Cocoa Tasting" to "hot_cocoa_tasting" automatically. Super useful for file names.

Combining Conditions

You can get fancy with multiple conditions:

{% 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

Why This Matters

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:

# 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

Want a kids event? Same recipe, different parameters:

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

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.

Beyond Posters

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:

  • 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)

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.

Things I Learned

Start Simple

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.

Use Select Types When You Can

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".

Provide Defaults for Optional Stuff

For optional parameters, think about what makes sense when nothing is provided:

- key: output_format
  input_type: select
  requirement: optional
  default: html
  options:
    - html
    - markdown
Enter fullscreen mode Exit fullscreen mode

Most people probably want HTML, so default to that.

Test All the Paths

With conditional logic, you're creating multiple execution paths. I made sure to test:

  • All five event types to confirm each conditional branch works
  • Optional parameters both provided and omitted
  • Edge cases like really long event names

Check the Docs

The Recipe Parameters docs list all the input types and validation options. Reference these when you're setting up parameters instead of guessing.

Reference Docs

Everything here is documented officially:

I referenced these docs a lot while building the poster recipe.

Wrapping Up

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 Advent of AI 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? Recipes are probably a good candidate for those kinds of tasks/workflows.

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.

Until the next one!


Resources:

Photo by Sven Mieke on Unsplash

Top comments (0)