Flows Specification
Complete YAML schema reference for ayo flow definitions. Flows are stored in
~/.config/ayo/flows/ as .yaml files.
Full Schema
name: string # Required. Flow identifier
description: string # Optional. Human-readable description
version: string # Optional. Semver (default: "1.0.0")
inputs: # Optional. Declare expected inputs
- name: string # Input name (referenced as {{.input.name}})
type: string # Type: string, number, boolean, object, array
required: boolean # Whether input must be provided (default: true)
default: any # Default value if not provided
outputs: # Optional. Declare flow outputs
- name: string # Output name
from: string # Step name to get output from
field: string # Optional. Specific field from step output
steps: # Required. List of workflow steps
- name: string # Required. Unique step identifier
agent: string # Required. Agent reference (@name)
prompt: string # Required. Instructions for the agent
depends_on: [string] # Optional. Steps that must complete first
parallel: boolean # Optional. Force parallel execution (default: false)
timeout: string # Optional. Step timeout (e.g., "5m", "1h")
retries: integer # Optional. Retry count on failure (default: 0)
retry_delay: string # Optional. Delay between retries (e.g., "10s")
condition: string # Optional. Expression to evaluate before running
on_error: string # Optional. Error handling: "fail", "continue", "retry"
skills: [string] # Optional. Additional skills to grant agent
context: # Optional. Additional context for the agent
files: [string] # Files to include
memory: [string] # Memory namespaces to access
on_complete: # Optional. Actions when flow completes
notify: [string] # Notification channels
webhook: string # Webhook URL to call
run: string # Command to execute
on_error: # Optional. Actions when flow fails
notify: [string]
webhook: string
run: string
Top-Level Fields
name
Required. The flow identifier, used in commands like ayo flow run.
name: document-pipeline
description
Optional. Human-readable description shown in ayo flow list.
description: Process and file incoming documents
version
Optional. Semantic version for tracking flow changes.
version: "2.1.0"
Inputs
Declare expected input parameters with types and defaults.
inputs:
- name: file
type: string
required: true
- name: options
type: object
required: false
default:
verbose: false
format: "json"
Input Types
| Type | Description | Example |
|---|---|---|
string | Text value | "invoice.pdf" |
number | Integer or float | 42, 3.14 |
boolean | True or false | true |
object | Key-value pairs | {"key": "value"} |
array | List of values | ["a", "b", "c"] |
Outputs
Define which step results become flow outputs.
outputs:
- name: result
from: final-step
- name: classification
from: classify
field: type
Steps
The core of every flow. Each step runs an agent with a prompt.
Required Step Fields
| Field | Type | Description |
|---|---|---|
name | string | Unique identifier for the step |
agent | string | Agent to execute (@name format) |
prompt | string | Instructions for the agent |
Optional Step Fields
| Field | Type | Default | Description |
|---|---|---|---|
depends_on | [string] | [] | Steps that must complete first |
parallel | boolean | false | Force parallel execution |
timeout | string | none | Maximum step duration |
retries | integer | 0 | Retry count on failure |
retry_delay | string | "0s" | Delay between retries |
condition | string | none | Skip step if evaluates false |
on_error | string | "fail" | Error handling strategy |
skills | [string] | [] | Additional skills for this step |
Step Example
steps:
- name: extract
agent: "@extractor"
prompt: "Extract key data from {{.input.file}}"
timeout: "2m"
retries: 2
retry_delay: "5s"
on_error: retry
skills:
- pdf-reader
- ocr
Template Variables
Use Go template syntax to reference inputs and outputs in prompts. Variables are evaluated at runtime.
Input Variables
{{.input}} # Entire input object
{{.input.file}} # Specific input field
{{.input.options.verbose}} # Nested field
Step Output Variables
{{.steps.classify.output}} # Entire output from "classify" step
{{.steps.classify.output.type}} # Specific field from output
{{.steps.classify.status}} # Step status: success, failed, skipped
Flow Variables
{{.flow.name}} # Current flow name
{{.flow.run_id}} # Unique run identifier
{{.flow.started_at}} # Start timestamp
Dependencies
The depends_on field creates execution order. Steps wait for
all dependencies to complete before starting.
steps:
- name: a
agent: "@agent"
prompt: "First step"
- name: b
agent: "@agent"
prompt: "Second step"
depends_on: [a] # Waits for a
- name: c
agent: "@agent"
prompt: "Third step"
depends_on: [a, b] # Waits for both a and b
Parallel Execution
Steps without dependencies run in parallel by default.
steps:
- name: review-grammar
agent: "@editor"
prompt: "Check grammar"
- name: review-facts
agent: "@researcher"
prompt: "Verify facts"
- name: review-legal
agent: "@compliance"
prompt: "Legal review"
# All three run simultaneously, then:
- name: compile
agent: "@reviewer"
depends_on: [review-grammar, review-facts, review-legal]
prompt: "Compile reviews"
Conditions
Skip steps conditionally using expressions. The step runs only if the condition evaluates to true.
steps:
- name: classify
agent: "@classifier"
prompt: "Classify document"
- name: legal-review
agent: "@compliance"
depends_on: [classify]
condition: "{{.steps.classify.output.type}} == 'contract'"
prompt: "Review contract for legal issues"
- name: invoice-process
agent: "@accounting"
depends_on: [classify]
condition: "{{.steps.classify.output.type}} == 'invoice'"
prompt: "Process invoice"
Error Handling
on_error Options
| Value | Behavior |
|---|---|
fail | Stop flow immediately (default) |
continue | Mark step failed, continue with other steps |
retry | Retry step up to retries times |
Error Handling Example
steps:
- name: fetch
agent: "@fetcher"
prompt: "Fetch data from API"
timeout: "30s"
retries: 3
retry_delay: "10s"
on_error: retry
- name: process
agent: "@processor"
depends_on: [fetch]
on_error: continue # Don't fail entire flow
prompt: "Process fetched data"
- name: fallback
agent: "@fallback"
depends_on: [process]
condition: "{{.steps.process.status}} == 'failed'"
prompt: "Use fallback processing"
Timeouts
Duration strings use Go format: 30s, 5m, 1h, 2h30m.
steps:
- name: quick-task
agent: "@agent"
timeout: "30s"
prompt: "Do something fast"
- name: long-task
agent: "@agent"
timeout: "1h"
prompt: "Do something that takes a while"
Context
Provide additional context to steps.
steps:
- name: analyze
agent: "@analyst"
prompt: "Analyze the codebase"
context:
files:
- "src/**/*.go"
- "README.md"
memory:
- project-history
- team-decisions
Hooks
Execute actions when the flow completes or fails.
on_complete
on_complete:
notify:
- slack:#deployments
- email:[email protected]
webhook: "https://api.example.com/flow-complete"
run: "echo 'Flow completed at $(date)' >> /var/log/flows.log"
on_error
on_error:
notify:
- slack:#alerts
- pagerduty:oncall
webhook: "https://api.example.com/flow-failed"
run: "echo 'Flow failed: {{.flow.error}}' >> /var/log/flows.log"
Complete Example
name: customer-support-triage
description: Automatically triage and respond to support tickets
version: "1.2.0"
inputs:
- name: ticket_id
type: string
required: true
- name: customer_email
type: string
required: true
- name: message
type: string
required: true
outputs:
- name: classification
from: classify
field: category
- name: response
from: respond
steps:
- name: classify
agent: "@classifier"
prompt: |
Classify this support ticket:
From: {{.input.customer_email}}
Message: {{.input.message}}
Categories: billing, technical, general, urgent
- name: lookup-history
agent: "@researcher"
prompt: "Find previous tickets from {{.input.customer_email}}"
parallel: true
- name: lookup-account
agent: "@researcher"
prompt: "Get account details for {{.input.customer_email}}"
parallel: true
- name: respond
agent: "@support"
depends_on: [classify, lookup-history, lookup-account]
timeout: "5m"
prompt: |
Draft a response to this {{.steps.classify.output.category}} ticket.
Customer: {{.input.customer_email}}
Message: {{.input.message}}
History: {{.steps.lookup-history.output}}
Account: {{.steps.lookup-account.output}}
- name: escalate
agent: "@escalation"
depends_on: [classify]
condition: "{{.steps.classify.output.category}} == 'urgent'"
prompt: "Create urgent escalation for ticket {{.input.ticket_id}}"
on_complete:
webhook: "https://support.example.com/api/ticket/{{.input.ticket_id}}/processed"
on_error:
notify:
- slack:#support-errors
Validation
Validate flow syntax before running:
ayo flow validate customer-support-triage
Output on success:
✓ Flow "customer-support-triage" is valid
5 steps
3 inputs
2 outputs
Related
- Flows Guide — Tutorial and examples
- Triggers — Schedule and automate flows
- Agents Reference — Agent configuration