Branches and actions
Three branch types. One leaf type. That is the whole language.
A tick is one evaluation pass through the tree by the runtime: the cursor visits the current node, returns success or failure, and advances or retries.
Branches
Branches coordinate flow of control — which children run, in what order, what counts as success. They have children but do no work themselves.
Sequence
Run children in order. All must succeed. If any child fails, the sequence fails. Use it for linear workflows where each step depends on the previous.
type: sequence
name: Deploy_Service
children:
- type: action
name: Run_Tests
- type: action
name: Build_Image
- type: action
name: Push_To_RegistryIf Run_Tests fails, the sequence aborts. The build never happens. The push never happens.
Selector
Run children in order until one succeeds. If all fail, the selector fails.
A selector is the decision-making primitive — the equivalent of an if/else chain.
type: selector
name: Choose_Greeting
children:
- type: action
name: Morning_Greeting
steps:
- evaluate: $VAR.time_of_day is "morning"
- instruct: ...
- type: action
name: Afternoon_Greeting
steps:
- evaluate: $VAR.time_of_day is "afternoon"
- instruct: ...The selector tries Morning_Greeting's evaluate first. If it passes, the morning instruct runs and the selector finishes. Otherwise it falls through to Afternoon_Greeting.
Parallel
Run all children. All must succeed.
Use a parallel when steps are independent and can run in any order.
type: parallel
name: Gather_Context
children:
- type: action
name: Check_Weather
- type: action
name: Check_NewsThe agent receives both instruct requests and satisfies them in any order. If either fails, the parallel fails.
Actions
Actions are the leaves of the tree. Each is a small, focused unit of work made of two kinds of step:
type: action
name: Determine_Time
steps:
- evaluate: $VAR.now is set
- instruct: |
Get the current hour from the system clock.
Classify as "morning", "afternoon", or "evening".
Store at $VAR.time_of_day.evaluate
A precondition. A semantic boolean expression checked against $VAR and $CONST. The agent reads it, decides whether it is true, and submits the answer with eval(trace_output, true|false).
If false, the action fails immediately. The runtime advances by branch rules: a sequence aborts; a selector tries the next child.
instruct
The work. Free-form prose telling the agent what to do. The agent does it, writes results to $VAR, and calls submit(trace_output, "success") to advance.
An action can have multiple steps — alternating evaluates and instructs — to handle multi-stage logic in a single leaf.
Retries
Any node — composite or action — can carry a retries: N config. On failure the runtime wipes the node's internal bookkeeping (status, step index, descendants), bumps an internal retry counter, and re-ticks the node from a clean slate. After N retries are exhausted, the failure propagates normally. User state in $VAR persists across retries — that is the feedback channel between attempts.
type: sequence
name: Write_And_Review
retries: 2 # one initial attempt + 2 retries = 3 total attempts
children:
- { type: action, name: Write, steps: [...] }
- { type: action, name: Review, steps: [...] }The bundled hello-world tree — available from the Quick start panel at app.behaviors.sh — covers the first three primitives (sequence, selector, action) end-to-end.
Next
- State — the two scopes the primitives read and write.
- Writing trees — turn the primitives into a working tree.
- Inspecting executions — how the runtime walks the tree at tick time.