AO

Per-role agents

Run a reasoning-heavy agent for orchestration and a fast agent for workers — globally or per-project.

Why split roles

AO runs two distinct types of sessions: an orchestrator and one or more workers. The orchestrator is a supervisor — it reads session state, spawns workers with ao spawn, nudges stuck sessions with ao send, and never owns a PR or writes code. Workers actually implement features, fix CI failures, and push branches. Because these workloads are so different, they benefit from different models: orchestrators need broad reasoning over many sessions (reach for a large model like Opus); workers need fast, focused execution on a single task (a smaller or specialised model like Sonnet or Codex).

Global default (whole config)

Set default agent and model for both roles under defaults: in your agent-orchestrator.yaml. These apply to every project unless overridden.

defaults:
  orchestrator:
    agent: claude-code
  worker:
    agent: codex

defaults.orchestrator and defaults.worker accept only the agent key at the global defaults level. To set agentConfig (model, permissions, etc.), use the per-project orchestrator and worker blocks described below.

Per-project override

The per-project orchestrator and worker blocks accept both agent and agentConfig, giving you full control including model selection:

projects:
  myapp:
    repo: org/myapp
    path: ~/code/myapp
    orchestrator:
      agent: claude-code
      agentConfig:
        model: claude-opus-4
    worker:
      agent: codex
      agentConfig:
        model: gpt-5-codex

Per-project values take precedence over defaults. Any project that does not define orchestrator or worker inherits from defaults.

Recipe 1: Opus orchestrator, Sonnet workers

Use a large reasoning model to supervise and a fast model for execution:

defaults:
  orchestrator:
    agent: claude-code
  worker:
    agent: claude-code

projects:
  myapp:
    repo: org/myapp
    path: ~/code/myapp
    orchestrator:
      agent: claude-code
      agentConfig:
        model: claude-opus-4
    worker:
      agent: claude-code
      agentConfig:
        model: claude-sonnet-4

Recipe 2: Claude Code orchestrator, Codex workers

Keep the orchestrator on Claude Code (good for tool-heavy coordination) and use Codex for cost-effective worker sessions:

defaults:
  orchestrator:
    agent: claude-code
  worker:
    agent: codex

projects:
  myapp:
    repo: org/myapp
    path: ~/code/myapp
    orchestrator:
      agent: claude-code
      agentConfig:
        model: claude-opus-4
    worker:
      agent: codex
      agentConfig:
        model: gpt-5-codex

Recipe 3: Same agent, different models

Keep agent: claude-code for both roles but override the model per role. Useful when you want identical tooling but different cost/latency profiles:

projects:
  myapp:
    repo: org/myapp
    path: ~/code/myapp
    orchestrator:
      agent: claude-code
      agentConfig:
        model: claude-opus-4
    worker:
      agent: claude-code
      agentConfig:
        model: claude-haiku-4

What the orchestrator actually does

The orchestrator prompt, injected by ao start, enforces the following rules:

  • Read-only by design. The orchestrator may inspect session status, logs, PR state, and CI output — but it must never edit repository files, run implementation code, or create its own PR. All code changes are delegated to worker sessions.
  • Spawns workers via ao spawn. Pass an issue ID (GitHub: #123, Linear: INT-1234) or --claim-pr to attach an existing PR to a new worker.
  • Nudges stuck workers via ao send. Sends instructions or clarification directly to a worker's terminal. Always uses ao send — never raw tmux send-keys.
  • Monitors with ao status. Gets a live view of every session's PR, CI, and review state across all projects.
  • Cleans up via ao session kill and ao session cleanup. Removes dead or merged sessions.

The orchestrator is itself a long-running agent session (<prefix>-orchestrator) launched with ao start. It has access to all ao CLI commands and your project configuration but is explicitly prohibited from owning a branch or PR.

Role metadata

AO records a role field in each session's metadata file with the value orchestrator or worker. The lifecycle manager and dashboard use this field to display sessions differently (orchestrator sessions get a distinct label and are excluded from PR-tracking flows). You never need to set role manually — AO assigns it automatically: ao start creates the orchestrator session; ao spawn (called from the orchestrator) creates worker sessions tagged as worker.

Gotchas

  • Missing agent binary. If you set defaults.worker.agent: codex but Codex is not installed, ao spawn will fail when a worker session starts. Run ao doctor to verify all configured agents are available before starting a run.
  • Inheritance order. Workers inherit the top-level defaults unless overridden at the project level. A project-level worker block fully replaces the default — it is not merged field-by-field, so specify every field you need.
  • Separate rule sets. orchestratorRules and agentRules in the project config apply independently to orchestrator and worker sessions respectively. See the Projects configuration reference for details.

Next steps