Docs
Reference

Templating

Quick Answer

Use this reference for Breyta Handlebars templating syntax, helpers, and practical template composition patterns.

Breyta Flows templates use Handlebars ({{...}}) via the Java implementation (handlebars-java).

Basics

PatternSyntaxUse
Variables{{id}}, {{user.name}}Read scalar or nested fields from input data.
Conditionals{{#if condition}}...{{/if}}, {{#unless condition}}...{{/unless}}Branch rendered content based on truthy/falsey values.
Loops{{#each items}}...{{/each}}Render repeated blocks from arrays/lists.
Context switch{{#with obj}}...{{/with}}Temporarily scope lookup to a nested object.

Custom helpers available

These helpers are available in the Flows runtime:

HelperExampleBehavior
truncate{{truncate text length=100 suffix="..."}}Truncates text to a max length with optional suffix.
json{{json data}}, {{json data pretty=true}}Serializes values to compact or pretty JSON.
length{{length items}}Returns collection/string length.
join{{join items separator=", "}}Joins list values with a separator.
first{{first items}}Returns first element from a collection.
last{{last items}}Returns last element from a collection.
default{{default value fallback}}Returns fallback when value is missing/empty.

Practical examples

LLM prompt template

{:id :findings
 :type :llm-prompt
 :system "Today is {{current-date}}."
 :prompt "Analyze: {{text}}"}

Called as:

(flow/step :llm :findings {:connection :ai
                           :template :findings
                           :data {:current-date "2026-01-16"
                                  :text "..."}})

The same contract applies to an isolated CLI probe. Select the flow and source
so the server can resolve the flow-local template, put interpolation values in
data, and raise the client request bound when a provider call is slow:

{"connection":"ai","template":"findings","data":{"currentDate":"2026-01-16","text":"..."}}
breyta steps run --flow my-flow --source draft --type llm --id summarize \
  --profile-id <profile-id> --params-file ./tmp/summarize.params.json --timeout 10m

Use the profile context when ai is a connection slot; alternatively replace
ai with a direct connection ID that does not require profile bindings.

template is the ID from the selected flow's :templates vector, not an
approved catalog/template slug. data is the map used to render {{...}}
variables; passing only the template ID does not supply those values.

Choosing between templates

When conditional logic gets messy, prefer two templates and select one in code:

(let [tpl ^{:label "Template variant"
            :yes "Include timestamps"
            :no "No timestamps"}
          (if (:include-timestamps? ctx) :findings-with-ts :findings-no-ts)]
  (flow/step :llm :findings {:connection :ai :template tpl :data ctx}))

Related

As of Jul 21, 2026