Documentation

Flow Control

Filters, routers, foreach loops and parallel branches to govern a pipeline's execution paths, with best practices.

Beyond agents and operators, betool provides control nodes to structure the logic of a pipeline.

Filter

A filter node is a deterministic gate: execution continues to downstream nodes if its conditions are satisfied, otherwise the branch stops there.

Configuration:

  • Conditions — each of the form {field, operator, value}. The field is a selector into the flow (exchange.intent, webhook.payload.type…); the value is a string, templatable.
  • Combinator — AND (default) or OR across conditions.
  • Operators — equals / not_equals, contains / not_contains, starts_with, ends_with, regex, is_empty / is_not_empty, numeric comparisons gt / gte / lt / lte, list membership in / not_in (comma-separated values). An unknown operator is refused on save.

Typical use: eliminating noise before incurring downstream LLM costs — ignoring emails whose from field is on a blocklist, or webhooks where type != "order.created".

Router

A router node sends execution to one of its named routes. The decision is made by an LLM from a routing prompt and the context you compose — to route by intent, category, or tone.

Configuration:

  • Prompt — the classification instruction.
  • Routes — for each route name, the subgraph to execute. Each declared route must be wired, otherwise publication is refused.
  • Model — you can dedicate a lightweight LLM to routing (tiering) to control cost and latency.

For strictly deterministic routing (exact field value, HTTP status), prefer filter nodes laid out in parallel: the predicate is then mechanical, not interpreted.

Loop (foreach)

A foreach node iterates over a collection. Configuration:

  • items — the selector of the list to iterate over.
  • as — the local name for the current element.
  • max — iteration cap (default 10): beyond it, the list is truncated and the event is logged.
  • collect — (optional) the key where the results of each iteration are accumulated.
  • max_per_minute — (optional) maximum pace, to space out iterations when the loop body calls a rate-limited API. 0 (default) = no limit.

On each iteration, the internal subgraph executes against the current element.

The max cap is your cost guardrail: an unexpected list of 10,000 items will never trigger 10,000 executions.

Parallel

A parallel node runs several subgraphs concurrently and waits for all of them to finish before continuing. Useful for querying independent sources (a CRM search + a calendar read) without adding up latencies.

Best practices

  • Filter early. Every exchange that goes through an agent costs tokens; an upstream filter costs nothing.
  • Keep routing readable. A router with 12 routes is a signal that you need two classification stages rather than condensed logic.
  • Limit nested loops. A loop inside a loop multiplies costs. Prefer transforming the collection upstream instead.