Skip to main content

Macros

Note: Macros depend on the flow executor, which is not yet implemented. This is a design document for a future version. See Flows for details.

Macros are reusable flow snippets. Define them once, invoke them anywhere in your flow with different parameters.

Defining a Macro

macros:
- name: read_and_summarize
description: "Read a file and produce a summary"
params:
path:
type: string
required: true
max_lines:
type: integer
default: 200
body:
- id: read_file
action: filesystem.read_file
params:
path: "{{macro.path}}"
- id: summarize
agent: default
input: |
Summarize this file (first {{macro.max_lines}} lines):
{{result.read_file}}

Using a Macro

Invoke a macro in a flow with the use: keyword and pass parameters with with::

flow:
- id: summarize_config
use: read_and_summarize
with:
path: "{{workspace}}/config.json"
max_lines: 100

- id: summarize_readme
use: read_and_summarize
with:
path: "{{workspace}}/README.md"

Macro Parameters

Parameter Types

TypeAliasesDescription
stringText value
intintegerInteger number
floatnumberDecimal number
boolbooleanTrue/false
objectJSON object
arraylistJSON array

Required vs Optional

macros:
- name: run_test
params:
command:
type: string
required: true # Must be provided
working_dir:
type: string
required: false
default: "{{workspace}}" # Default value if not provided

Shorthand Syntax

For simple defaults, use shorthand:

macros:
- name: greet
params:
name: "World" # Inferred as string, required=false, default="World"
loud: false # Inferred as bool, required=false, default=false

Accessing Parameters

Inside a macro body, access parameters with {{macro.param_name}}:

macros:
- name: run_command
params:
command:
type: string
required: true
dir:
type: string
default: "."
body:
- id: exec
action: os_exec.run_command
params:
command: "{{macro.command}}"
working_directory: "{{macro.dir}}"

Macro Body

The body is a list of flow steps — exactly the same as the top-level flow: block. All 18 step types are supported inside macros.

Action Steps

body:
- id: step1
action: filesystem.read_file
params:
path: "{{macro.path}}"

Agent Steps

body:
- id: analyze
agent: reviewer
input: "Analyze: {{result.step1}}"

Branching

body:
- id: check
branch:
"on": "{{result.exec.exit_code}}"
cases:
"0":
- agent: default
input: "Success!"
default:
- agent: default
input: "Failed: {{result.exec.stderr}}"

Nested Macros

Macros can invoke other macros:

macros:
- name: ensure_dir
params:
dir: { type: string, required: true }
body:
- action: os_exec.run_command
params: { command: "mkdir -p {{macro.dir}}" }

- name: save_report
params:
dir: { type: string, required: true }
content: { type: string, required: true }
body:
- id: mkdir
use: ensure_dir
with: { dir: "{{macro.dir}}" }
- action: filesystem.write_file
params:
path: "{{macro.dir}}/report.md"
content: "{{macro.content}}"

Result Scoping

Step results inside a macro are scoped to the macro invocation. The macro's overall result is the result of its last step.

flow:
- id: review
use: read_and_summarize
with:
path: "config.json"

# {{result.review}} contains the output of the macro's last step
- id: use_summary
agent: default
input: "Based on the summary: {{result.review}}"

Validation

The compiler validates macro references at compile time:

  • Macro names must be unique
  • use: must reference a defined macro name
  • Unknown macro references produce a CompilationError

Real-World Examples

Git Diff Macro

macros:
- name: git_diff
description: "Get git diff for analysis"
params:
range:
type: string
default: "HEAD~1..HEAD"
body:
- id: get_diff
action: os_exec.run_command
params:
command: "git diff {{macro.range}} --stat && echo '---' && git diff {{macro.range}}"
working_directory: "{{workspace}}"

Parallel Analysis Macro

macros:
- name: parallel_lint
description: "Run multiple linters in parallel"
params:
targets:
type: string
default: "."
body:
- parallel:
max_concurrent: 3
fail_fast: false
steps:
- id: ruff
action: os_exec.run_command
params: { command: "ruff check {{macro.targets}}" }
- id: mypy
action: os_exec.run_command
params: { command: "mypy {{macro.targets}}" }
- id: bandit
action: os_exec.run_command
params: { command: "bandit -r {{macro.targets}}" }

Search and Summarize Macro

macros:
- name: search_and_summarize
description: "Search the web and summarize findings"
params:
query: { type: string, required: true }
context: { type: string, default: "" }
body:
- id: search
action: web_search.search_web
params:
query: "{{macro.query}}"
- id: summarize
agent: researcher
input: |
Summarize results for: "{{macro.query}}"
Context: {{macro.context}}
Results: {{result.search}}