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

TypeDescriptionExample
stringText value"invoice.pdf"
numberInteger or float42, 3.14
booleanTrue or falsetrue
objectKey-value pairs{"key": "value"}
arrayList 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

FieldTypeDescription
namestringUnique identifier for the step
agentstringAgent to execute (@name format)
promptstringInstructions for the agent

Optional Step Fields

FieldTypeDefaultDescription
depends_on[string][]Steps that must complete first
parallelbooleanfalseForce parallel execution
timeoutstringnoneMaximum step duration
retriesinteger0Retry count on failure
retry_delaystring"0s"Delay between retries
conditionstringnoneSkip step if evaluates false
on_errorstring"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

ValueBehavior
failStop flow immediately (default)
continueMark step failed, continue with other steps
retryRetry 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