Skip to content

Writing templates

A template is a small document that declares when a workflow starts and what it does. Templates are versioned; runs always execute the exact version they were created with.

You author templates as text and create them through the API — there is no other authoring path, which means every template is validated at creation (unknown step names, bad conditions, and malformed clauses are rejected with line-anchored errors).

POST /api/v1/projects/{project_uuid}/workflows/templates
{"name": "reviewed_publish", "dsl": "<template text>"}

Document structure

A template names itself and version, then declares optional start gates and an ordered list of actions:

new workflow "reviewed_publish" v1
  then call "webhook_call" (url="https://writer.example/draft") as "draft"
       work_unit (minimum_reviews=2, minimum_confidence=0.8,
                 maximum_reviews=5,
                 reviewer_competency_names=["editorial"],
                 producer_competency_names=["writing"])
       until state result_ready == true
  • # starts a comment (to end of line).
  • Keywords are case-insensitive; names and values are case-sensitive.
  • Newlines are just whitespace — actions in the then list are separated by commas.
  • Strings are double-quoted. Numbers may be signed decimals. Lists look like ["editorial", "writing"].

Conditions

Conditions appear everywhere — start gates, per-step gates, loop stops, branch arms. They are AND-joined with and (OR-joined with or in loop stops).

Condition Syntax True when
message message not_empty · message not_too_long max 100000 The run's input message exists / is short enough.
step done step_done steps["draft"] · step_done steps["draft"] as exception The referenced step finished with that status (done, exception, skipped).
step result result steps["draft"] round_outcome == "finish" A field of the step's result matches a value.
run state state result_ready == true A key of the run's state bag matches.
budget budget tokens <= 10000 Spend is within budget (checked at every step).
iteration iteration < 5 The loop round counter satisfies the bound.

Actions

  • call "step_name" (key=value, …) — invoke a step function. A bare quoted string (then "solo") is shorthand for a call.
  • loop(call "a", call "b", stop_when=…, max_iterations=N) — repeat an ordered sub-chain of calls; stop_when is checked after each round, max_iterations defaults to 50.
  • parallel(call …, call …) — run calls concurrently; join waits for all (default), parallel(budget 30, …) proceeds after 30 seconds with whatever finished.
  • branch(when … => …, when … => …, else => …) — first matching arm wins; an unmatched branch with no else skips entirely.
  • emit "event" (key=value, …) — push a live event payload.
  • workflow "other_template" — start (or advance) another template's run as a child.

Any action can be labeled — call "webhook_call" as "draft" — and steps["draft"] refers to it from conditions. Labels are template-wide and may reference steps inside loops and branches.

The three call clauses

Every call can carry up to three trailing clauses, in any order:

  • when <condition> — a pre-execution gate. Unmet at execution time, the run waits and retries later.
  • until <condition> — a post-execution gate: do the work, then wait for the world to satisfy a condition (typically state result_ready == true, set when your agent calls back). Unmet, the run parks with no deadline and no cost until your agent's callback arrives.
  • work_unit (…) — the review configuration, required on every call even when the step is not reviewed. The ungated form is work_unit (minimum_reviews=0, minimum_confidence=0.0) — the run is recorded and proceeds. See review workflows for the full clause.

The step catalog

Steps available to call (unknown names are rejected at template creation):

Step Purpose
webhook_call POST a request to your service and wait for its callback. The workhorse for external agents.
create_work_unit Create a review unit for produced work.
answer_work_unit Submit a reviewer's yes/no answer to the decision engine.
tool_loop_iteration One agentic knowledge-tool round (used by system templates).
tool_flush Commit a tool loop's writes (used by system templates).

System templates

Two ready-made templates ship with every project and are read-only:

  • webhook_call v1 — POST a request to your agent and wait for its callback:

    new workflow "webhook_call" v1
      then call "webhook_call" as "request"
           work_unit (minimum_reviews=0, minimum_confidence=0.0)
           until state result_ready == true
    
  • knowledge_tool_loop v1 — the internal knowledge-update loop; useful as a reference for loop composition.

Next

  • Start a run from a template: runs.
  • Connect your agents to webhook_call and reviews: review workflows.