Skip to content

Iteration Nodes ​

Martha workflows support array processing through three iteration node types: for-each, filter, and reduce. These let you iterate over search results, filter matching items, and aggregate outputs — all within the visual workflow builder.


For-Each Node ​

Iterates over an array, executing a body node for each item. Items are processed in configurable concurrent batches.

Configuration ​

FieldRequiredDefaultDescription
source_arrayYes—The array to iterate over. Use a variable reference like {{steps.search.results}}.
item_variableNoitemName to access the current item in templates
concurrencyNo1Max items to process in parallel per batch (capped at 20)
error_modeNofail_fastfail_fast = stop on first error; any other value (e.g. collect) = gather all errors
output_keyNoresultsKey name for the output array

Template Variables ​

Inside the for-each body, you can reference:

VariableDescription
{{foreach.item}}The current array item
{{foreach.index}}The current index (0-based)
{{foreach.<item_variable>}}Same as {{foreach.item}} if item_variable is left as default

Example ​

Process a list of documents through an LLM summarization step:

json
{
  "type": "FOR_EACH",
  "config": {
    "source_array": "{{steps.search.documents}}",
    "concurrency": 3,
    "error_mode": "collect"
  }
}

Connect the for-each node to its body node using an edge with source_handle: "foreach-body". The body node receives each item and produces a result that is collected into the output array.

Error Handling ​

  • fail_fast mode (default): Processing stops at the first error. Already-completed items are preserved in the output.
  • collect mode: All items are processed. Failed items leave results and appear in errors with their index; the for-each node itself succeeds. Map results back to items through those indices.
  • Agent step body: each iteration is its own step, with the id <body>[<index>] — its own attempts and evidence.

Filter Node ​

Filters an array by evaluating conditions against each item. Items that match all (or any) conditions are kept.

Configuration ​

FieldRequiredDefaultDescription
source_arrayYes—The array to filter. Use a variable reference.
conditionsYes—Array of condition objects (see below)
match_modeNoallall = item must match every condition, any = item must match at least one
output_keyNofilteredKey name for the filtered output array

Conditions ​

Each condition has three fields:

FieldDescription
fieldPath to the value on each item (e.g., score, metadata.category)
operatorComparison operator (see table below)
valueValue to compare against (not needed for is_empty, is_not_empty, is_falsy, is_truthy)

Operators ​

OperatorDescription
equalsExact match
not_equalsNot equal
containsSubstring or element check
not_containsInverse of contains
greater_thanNumeric >
less_thanNumeric <
greater_or_equalNumeric >=
less_or_equalNumeric <=
is_emptyNone, "", [], {}
is_not_emptyInverse of is_empty
is_falsyEmpty/zero values: null, "", 0, false, [], {}
is_truthyInverse of is_falsy
matches_regexRegex pattern match
starts_withString prefix check

Example ​

Keep only high-scoring results:

json
{
  "type": "FILTER",
  "config": {
    "source_array": "{{steps.search.results}}",
    "conditions": [
      { "field": "score", "operator": "greater_than", "value": "80" },
      { "field": "status", "operator": "not_equals", "value": "archived" }
    ],
    "match_mode": "all"
  }
}

Reduce Node ​

Aggregates an array into a single value using one of nine operations.

Configuration ​

FieldRequiredDefaultDescription
source_arrayYes—The array to reduce. Use a variable reference.
operationYes—Aggregation operation (see table below)
fieldDepends—Field path on each item (required for sum, min, max, collect_field)
output_keyNoresultKey name for the reduced output

Operations ​

OperationDescriptionRequires field
countNumber of items in the arrayNo
sumSum of numeric field valuesYes
minMinimum numeric field valueYes
maxMaximum numeric field valueYes
firstFirst item in the arrayNo
lastLast item in the arrayNo
concatConcatenate string field valuesYes
collect_fieldExtract a single field from all items into a new arrayYes
flattenFlatten nested arrays into a single arrayNo

Example ​

Sum the scores of filtered results:

json
{
  "type": "REDUCE",
  "config": {
    "source_array": "{{steps.filter.filtered}}",
    "operation": "sum",
    "field": "score"
  }
}

Combining Iteration Nodes ​

These nodes compose naturally with each other and with other workflow nodes:

  • For-each → Filter → Reduce: Process items, keep matches, aggregate results
  • Filter → For-each: Narrow down items before expensive per-item processing
  • Choice → For-each: Only iterate when a condition is met
  • For-each body = Sub-workflow: Each iteration runs a full child workflow

Example Pipeline ​

Search → For-Each (summarize each) → Filter (score > 80) → Reduce (count)

This processes search results through an LLM, filters for quality, and counts the keepers.

Martha is built by aiaiai-pt.