Deterministic scripts.
AI-powered steps.

Ash is a scripting language where the control flow is rigid and the steps are intelligent. Sequencing, branching, retry limits — defined in code. Each step executes autonomously by an AI agent.
Designed to be readable enough that non-programmers can automate their daily routines.

Why a language for agent workflows?

AI agents are powerful, but letting them drive the entire workflow — deciding what to do next, how many times to retry, when to stop — burns tokens on decisions that should be deterministic.

Workflows as Code

Any multi-step process — review content, generate a report, audit compliance, publish an update — should live in a file you commit, version, share, and rerun. Not buried in a chat thread.

Guaranteed Sequencing

"Research, then draft, then review, publish only if quality passes" — this is control flow, not intelligence. The agent executes the step, not the sequence.

Bounded Autonomy

The agent decides how to do its step. The script decides whether the step happens, how many times, and what comes next.

Execution Efficiency

Every agent decision — even "what next?" — burns tokens and adds latency. Pre-determined control flow runs at CPU speed. AI time is spent only where it adds value.

Repeatability

A weekly report, a recurring audit, a batch processing job — these need to run the same way every time, even if the content of each step varies.

Bidirectional Calling

Scripts invoke agents. Agents invoke scripts. The boundary dissolves — deterministic and intelligent execution woven into a single runtime, not stacked in layers.

Why not just use a shell script?

Bash and Python have no concept of an "agent" — no built-in retry, no evaluation, no stdout/stderr per step. You end up hand-rolling infrastructure that has nothing to do with your workflow.
Same task — loop over items, process each with an agent, retry on failure:

Bash

~35 lines · no agent abstraction, error handling repeated for every interaction
#!/bin/bash
# monitor support inbox — manual retry per ticket
TICKETS=("password reset request" "refund inquiry" "account locked")
for TICKET in "${TICKETS[@]}"; do
  for TRY in 1 2; do
    RESULT=$(opencode -p "Classify and reply to: $TICKET" 2>/dev/null)
    if [ -n "$RESULT" ]; then
      echo "handled: $TICKET"
      break
    fi
    sleep 2
  done
done

# check PRs — another nearly identical block
for TRY in 1 2; do
  opencode -p "Summarize open PRs" 2>/dev/null && break
  sleep 2
done

# verify deployment — branching on result
for TRY in 1 2; do
  RESULT=$(opencode -p "Verify deployment health" 2>/dev/null)
  if echo "$RESULT" | grep -qi "healthy"; then
    echo "all good"
  else
    opencode -p "Investigate and alert" 2>/dev/null
  fi
  break
done

Ash

~16 lines · agents as first-class citizens, built-in retry, focus on the workflow
#!opencode:0.1.0

# monitor support inbox — each ticket processed with a prompt file
TICKETS = ["password reset request", "refund inquiry", "account locked"]
for TICKET in TICKETS {
  do @classify-and-reply.md
  print "handled: ${TICKET}"
}

# one-shot review using a spec file
do @review-prs.md

# verify deployment — branch on result
do @verify-deploy.md
if $? != 0 {
  do @investigate-and-alert.md
}

Bash makes you build agent infrastructure. Ash gives you agents as a first-class language feature — so you write the workflow, not the plumbing.
Plain enough that non-technical team members can read (and write) their daily routines.

Language at a Glance

Variables & Strings

MSG = "hello"
COUNT = 3
ITEMS = ["a", "b", "c"]
FIRST = ITEMS[0]
print "count: ${len(ITEMS)}"
exec RUSTFLAGS="-D warnings" cargo build 2>&1
working_dir = $(pwd)

Control Flow

for ITEM in ITEMS {
  do "Process ${ITEM}" with js-echo
  if $? != 0 {
    print "failed on ${ITEM}"
    exit 1
  } else if len(stdout) < 5 {
    print "too short, retrying"
    continue
  }
  print "${ITEM} done"
}

Agent Calls

within "/project" {
  try {
    do @refactor_auth.md with subagent fixer
  } evaluate with {
    exec python complexity_analysis.py
  } accept {
    print "approved"
  } partial {
    do "Revise: ${report}"
  } fail {
     print "rejected" 
  } upto 3
}

Retry

try {
  do "Refactor" with subagent refactor
  exec RUSTFLAGS="-D warnings" cargo build 2>&1
} fail {
  print "attempt failed: ${stderr}"
  do "Retry with context: ${stderr}"
} upto 3

Playground

Write and run Ash scripts in your browser. The built-in js-echo agent echoes your prompt back — useful for testing control flow and syntax. Use real agent engines with the Ash CLI locally.

Script.ash
Output Status: ready
Click "Run" to execute the script.
Powered by ash.wasm loading WASM...