Skip to content

Pipelines

Pipelines wire multiple agents together for complex workflows. Define them as YAML files in your local workspace (~/.muaz/plugins/local/pipelines/).

From the REPL:

/run <name> [input] run a pipeline
/pipelines list available pipelines

From the shell (scriptable, no REPL):

Terminal window
muaz pipeline run research-write "analyse recent AI papers"
echo "my topic" | muaz pipeline run research-write
muaz pipeline list

A pipeline is a single ordered list of steps. Each step runs an agent (or a parallel: group), builds its input from a template over shared variables, and can gate itself with when:, retry on failure, cap its budget, and expose structured output as variables for later steps. There is no pattern field — sequential, parallel, and router flows are all expressed with steps.

A step’s input: is a template. These placeholders are substituted (an unknown placeholder is a hard error, so typos surface immediately):

PlaceholderValue
${input}the pipeline’s initial input
${vars.<name>}a top-level output field promoted from a step’s output_schema
${steps.<name>.output}a named step’s full text output
${steps.<name>.<field>}a structured field from that step’s output_schema

Chain steps by feeding one step’s output into the next. Reference steps by their name:

~/.muaz/plugins/local/pipelines/research-write.yaml
name: research-write
description: "Research a topic, then write from the sourced notes"
steps:
- name: research
agent: researcher # resolved across namespaces; use @plugin/name to disambiguate
input: "Research this topic and produce structured notes:\n\n${input}"
retry: { max: 1, backoff_secs: 2 }
- name: write
agent: writer
input: |
Write the piece requested below, working only from the research notes.
Request:
${input}
Research notes:
${steps.research.output}

A step may be a parallel: group whose members run concurrently. Later steps read each member’s output by name.

steps:
- name: reviews
parallel:
- name: security
agent: security-reviewer
input: "${input}"
- name: style
agent: style-reviewer
input: "${input}"
- name: summary
agent: editor
input: |
Security review:
${steps.security.output}
Style review:
${steps.style.output}

A router is just a step with an output_schema containing a route field; the downstream specialists gate on it with when:. No free-text parsing — the route is a typed, structured-output field. Bind the router to a cheap model and the specialists to a strong one.

name: triage
steps:
- name: route
agent: triage-router
output_schema:
type: object
properties:
route: { type: string, enum: [write, analyze, general] }
message: { type: string, description: The request, forwarded to the specialist. }
required: [route, message]
additionalProperties: false
budget: { max_tokens: 6000 }
- name: write
agent: writer
when: { value: "${steps.route.route}", equals: write }
input: "${steps.route.message}"
- name: analyze
agent: analyst
when: { value: "${steps.route.route}", equals: analyze }
input: "${steps.route.message}"
  • when: — run the step only if a condition holds. The form is { value, equals | not_equals | contains } (no loops, no free-form expressions): when: { value: "${steps.route.route}", equals: write }.
  • output_schema: — a JSON schema; the step returns structured output, and top-level fields become ${steps.<name>.<field>} (and, at the pipeline’s top level, ${vars.<field>}).
  • retry:{ max, backoff_secs } retries a failing step.
  • on_error:fail (default, abort the pipeline), continue (skip and move on), or fallback (use the step’s fallback path).
  • budget:{ max_cost_usd, max_tokens, max_seconds }, allowed per step and at the pipeline top level. Token/cost limits are checked at step boundaries; a max_seconds limit hard-times-out an in-flight step.

Pipelines resolve across namespaces (local → plugins → built-ins) just like agents, so a plugin’s pipeline is referenced by its qualified @plugin/name. The shipped built-ins triage, research-write, and parallel-review are working examples you can run or duplicate.