Flow specification#
A flow file is the Flow resource in YAML (or JSON). astra anemoi flows
apply -f and the console's YAML tab read it; the API takes {metadata,
spec}. Every version is immutable once written.
apiVersion: anemoi.astralyx/v1
kind: Flow
metadata:
name: pr-triage
spec:
description: Review a pull request twice, ask, then merge or comment.
drive: flow-files
inputs:
- {name: pr, description: The pull request's URL, required: true}
steps:
- id: review
kind: agent
agent: pr-reviewer
input: "Review ${{ inputs.pr }}. Write verdict=approve or verdict=changes to $ASTRAEUS_OUTPUTS."
- id: security
kind: agent
agent: security-reviewer
input: "Look for security problems in ${{ inputs.pr }}"
- id: ok
kind: approval
needs: [review, security]
target: "Merge ${{ inputs.pr }}? The review says ${{ steps.review.outputs.verdict }}."
approvers: ["role:editor"]
wait_seconds: 86400
- id: merge
kind: run
needs: [ok]
when: steps.review.outputs.verdict == 'approve'
retry: {max: 3, backoff_seconds: 30}
template:
image: ghcr.io/acme/merge-bot:1.4
command: merge
args: ["${{ inputs.pr }}"]
requested_resources: {cpu_cores: 1, memory_bytes: 536870912}
- id: comment
kind: agent
needs: [ok]
when: steps.review.outputs.verdict != 'approve'
agent: pr-commenter
input: "Summarise /flow/review/answer.md as a comment on ${{ inputs.pr }}"
outputs:
verdict: "${{ steps.review.outputs.verdict }}"
merged: "${{ steps.merge.state }}"
The document#
| Field | Description |
|---|---|
apiVersion |
anemoi.astralyx/v1 (may be left out). |
kind |
Flow (may be left out). |
metadata.name |
Required: the flow's name in the workspace. |
metadata.labels |
Optional labels. |
spec |
Below. |
spec#
| Field | Type | Default | Description |
|---|---|---|---|
description |
string | — | For people; at most 4 096 bytes. |
inputs |
list | — | [{name, description, required, default}]. name: [a-z0-9_], at most 64; default at most 64 KiB. Inputs are text: ${{ inputs.<name> }}. |
steps |
list | required | 1 to 64 steps; their needs make a graph without cycles. |
outputs |
map | — | name → template, computed when the execution ends. Names [a-z0-9_], at most 64. |
timeout_seconds |
integer | — | The whole execution's limit: 60 to 2 592 000 (30 days). |
on_failure |
string | stop |
stop: a step failing for good fails the execution and cancels steps under way. continue: steps that do not depend on it go on; the execution fails at the end. |
drive |
string | — | A drive of the workspace (a shared one, for steps on several machines): each execution mounts its own folder of it at /flow. Without one, each execution gets a drive of its own, a copy per machine, deleted with it. |
Every step#
| Field | Type | Default | Description |
|---|---|---|---|
id |
string | required | [a-z][a-z0-9_-]*, at most 40, unique. |
kind |
string | required | agent, run, approval, wait_event, sleep, flow. |
description |
string | — | For people; at most 4 096 bytes. |
needs |
ids | — | Steps that must be done first. Without it, the step starts at once. |
when |
expression | — | Run only when it holds; otherwise the step is Skipped. |
retry |
object | {max: 2} |
max: attempts after the first, at most 10; backoff_seconds: wait before the next, at most 86 400. Agents, runs and child flows are retried; an approval or an event is asked again only when a person retries the step. |
repeat |
object | — | until (an expression, which may read the step itself) and max (1 to 20): run the step again, as new attempts, until it holds. |
timeout_seconds |
integer | — | One attempt's limit: 1 to 2 592 000. For wait_event, the wait's. |
Each kind#
| Kind | Fields | Done when |
|---|---|---|
agent |
agent (required), version (from 1; the current one when absent), input (template, required) |
The agent's run ends. Budgets, guardrails, approvals of its tool calls and receipts apply. Its answer is written to /flow/<step>/answer.md; the agent may read and write /flow. |
run |
template: one worker (image, command, args, env, requested_resources, datavolume_refs…, as in the run specification); command, args and env values are templates |
The run ends. Its restart policy is Never: retry retries. It may not mount anything at /flow. |
approval |
target (template: what approvers read), approvers (role:admin, role:editor, role:viewer, user:<id>; editors when empty), wait_seconds (60 to 604 800; 86 400 by default) |
Someone approves. Denied or not decided in time, it fails. |
wait_event |
name ([a-z0-9_-], at most 63) |
The event arrives (POST …/flow-executions/{e}/events/{name}); one sent before the step waits counts. Its data are the step's outputs. |
sleep |
seconds (1 to 604 800) |
The time has passed. |
flow |
flow (required, not itself), version, inputs (name → template) |
The child execution ends; its outputs are the step's. At most three flows deep. |
Outputs of a step#
A step's run writes its outputs to the file named by $ASTRAEUS_OUTPUTS,
one key=value per line:
Keys are lowercase letters, digits and _; all of a step's outputs
together at most 4 KiB. They are reported when the run ends. A
wait_event step's outputs are the event's data; a flow step's, the
child's outputs.
Expressions and templates#
A template is text with ${{ expression }} in it, each replaced by the
expression's value as text. when and repeat.until are expressions,
written bare or inside ${{ }}. At most 16 KiB each.
| Element | Forms |
|---|---|
| Names | inputs.<name>, steps.<id>.outputs.<key>, steps.<id>.state (Succeeded, Failed, Skipped, …), execution.name |
| Literals | 'text' or "text", numbers, true, false, null |
| Operators | ==, !=, <, <=, >, >=, &&, \|\|, !, parentheses |
| Functions | contains(a, b): whether text a contains b |
- A comparison is numeric when both sides read as numbers, textual otherwise.
false,null,"","false",0and"0"are false.- An output a step did not write is
null. - A step may name only steps it depends on (through
needs, directly or not);repeat.untilmay also name the step itself; the flow'soutputsmay name any step. Names that cannot exist are refused when the flow is written.
Nothing is evaluated as code.
The execution#
GET $WS/flow-executions/{name}:
| Field | Description |
|---|---|
metadata.name |
<flow>-<6 hex>. |
spec |
flow, version, inputs (defaults filled in), started_by, flow_spec (the version as it was), drive, drive_path, parent (a child's), depth. |
status |
state: Pending, Running, Waiting (only on people or events), Succeeded, Failed, Cancelled; reason; times. |
steps |
<id>: {state, reason, attempts: [{n, name, state, reason, node, started_at, finished_at, outputs}], outputs}. A step is Pending, Running, Waiting, Succeeded, Failed, Skipped or Cancelled. An attempt's name is the run, approval, child execution or event it made. |
outputs |
The execution's outputs, once it succeeded. |
events |
[{name, data, sent_by, at}]. |
receipts |
[{step, attempt, agent, run}]: its agent runs' receipts. |
Listings (GET $WS/flow-executions?flow=&state=) give {metadata, flow,
version, started_by, status, step_counts}.