Web automation that learns the site,
then runs it deterministically.

A3 is a stage-based automation framework. You define the workflow and any agents; A3 learns and writes typed stage modules plus a durable playbook, and the runner replays them with no LLM in the loop.

— What it is

Three runtimes, one mental model.

A3 separates the parts of automation that benefit from intelligence from the parts that don't. You define the workflow and agents once. Stages are then learned and captured as code. A runner replays them — fast, typed, and free of model spend.

01 · WORKFLOW

Define the workflow.

Set the objective, write mission.md, and wire tools, schemas, and agents in defineWorkflow() — the contract the agent learns against.

mission.md · defineWorkflow()
02 · LEARNING

Agent learns each target site.

The agent visits sites, writes per-page stages as Playwright scripts, and captures findings in playbook.md for drift and edge cases.

stages · playbook.md
03 · RUNNER

Run at scale, deterministically.

Stages and playbooks live as git-friendly files. The runner replays them with no LLM at runtime — locally or on Automation Cloud.

a3 run · cloud
— Works for any use case

Same 3 steps, different automation goals.

Select a use case to preview how A3 applies the same three-step model in practice. Then look below to see fully worked Workflow → Learning → Runner examples update instantly for that scenario.

Hotel rates scraping

— Step 1 · Workflow

Define the workflow.

  • Write mission.md with the objective and success criteria.
  • Configure tools, schemas, and agents in defineWorkflow().
Workflow · mission Configuration
objectives/mission.md
# Mission — scrape rates

Given a hotel id, stay dates, and guest count, drive the property’s booking flow on the live site.
Prefer the public consumer path unless `playbook.md` already documents otherwise.

## What to capture

- Every bookable room with nightly rates (fees/taxes when the UI shows them).
- Normalise to the workflow’s `Rate` schema — don’t invent inventory the page never offered.
Workflow · config Configuration
scrape-rates.workflow.ts
import { defineWorkflow } from '@athree/runner';
import { ScrapeRatesInputSchema } from './schema/ScrapeRatesInput.js';
import { ScrapeRatesOutputSchema } from './schema/ScrapeRatesOutput.js';
import { TestAgent } from './TestAgent.js';

export default defineWorkflow({
  title: 'Scrape Rates',
  description: 'Scrape rates from a website',
  inputsSchema: ScrapeRatesInputSchema,
  outputsSchema: ScrapeRatesOutputSchema,
  rootDir: 'src',
  sitesDir: import.meta.dirname + '/sites',
  agents: [TestAgent],
  projectLocations: [
    { dir: import.meta.dirname + '/objectives',
      writable: true, patterns: ['*.md'] },
    { dir: import.meta.dirname + '/schema',
      writable: false },
  ],
});
— Step 2 · Learning

Agent learns sites and documents findings.

  • Visit each target site and generate readable stage files under sites/<hostname>/.
  • Write findings into playbook.md, including drift and edge-case notes.
Learning · stage Learning output
sites/be-synxis-com/extract-rates.stage.ts
import { defineStage } from '@athree/runner';

export default defineStage({
  title: 'Extract Rooms and Rates',
  description: 'Pulls rooms+rates from API or DOM',
  success: true,
  match: async (ctx) => {
    const url = new URL(ctx.page.url());
    return url.pathname.startsWith('/');
  },
  run: async (ctx) => {
    const resp = ctx.networkResources.find(
      r => r.request.url.includes('getProductAvailability')
    );
    const data = JSON.parse(resp.response.responseBody);
    ctx.outputs.hotelId = ctx.inputs.search.hotelId;
    ctx.outputs.results = [{ search: ctx.inputs.search,
                             rooms: extract(data) }];
  },
});
Learning · playbook Learning output
sites/be-synxis-com/playbook.md
# Synxis property — public rates

## Objective
Scrape nightly room rates from the consumer booking path.

## Entry points
- Deep link with property id + stay dates, or hotel home → check availability.

## Flow states
1. `cookie-banner` (dismiss)
2. `rate-shopping` (rates visible)

## Known risks
- Inventory JSON from `getProductAvailability`; vendor changes the shape occasionally.

## Changelog

### 2026-04-12
- Rates list moved to `[data-test="room-list"]`; `extract-rates` `match()` updated. Mobile lazy-loads guest row — `main.stage.ts` waits on `networkidle`.

### 2026-01-28
- Currency toggle removed; property currency only. “Member rate” badge ignored for the public `Rate` schema.
— Step 3 · Runner

Run deterministically at scale.

  • Stages, playbooks, and config live as editable files in git.
  • The runner replays them at scale with no LLM required during runtime.
Runner · project files Configuration
my-automation-project/
├── package.json
└── src/
    └── workflows/scrape-rates/
        ├── scrape-rates.workflow.ts
        ├── TestAgent.ts
        ├── objectives/
        │   └── mission.md
        ├── schema/
        │   ├── ScrapeRatesInput.ts
        │   ├── ScrapeRatesOutput.ts
        │   └── Rate.ts
        ├── skills/
        │   └── create-site/SKILL.md
        └── sites/
            ├── default/
            │   └── main.stage.ts          # global fallback
            ├── be-synxis-com/
            │   ├── main.stage.ts
            │   ├── extract-rates.stage.ts
            │   ├── inputs.yaml
            │   └── playbook.md
            └── asp-hotel-story-ne-jp/
                ├── main.stage.ts
                ├── inputs.yaml
                └── playbook.md
Runner · runtime config Infrastructure
infra/ubio-runner.yaml
version: '1'
workflow: src/workflows/scrape-rates/scrape-rates.workflow.ts
runtime:
  provider: ubio-automation-cloud
  mode: deterministic
  llmInLoop: false
  concurrency: 60
  retries:
    maxAttempts: 2
    backoffMs: 1500
targets:
  - site: be-synxis-com
    inputs: src/workflows/scrape-rates/sites/be-synxis-com/inputs.yaml
  - site: asp-hotel-story-ne-jp
    inputs: src/workflows/scrape-rates/sites/asp-hotel-story-ne-jp/inputs.yaml
outputs:
  artifactDir: ./.runs/scrape-rates
  uploadPlaybooks: true
— Get started

Start building your first workflow in minutes.

Begin with the quickstart in Docs, learn the architecture in Concepts, and use the Product tour while implementing workflows and stages.