Skip to main content
Agent Orchestrator is built on a flexible plugin architecture with 8 distinct plugin slots. Every abstraction is swappable, allowing you to adapt the system to your specific needs.

Core Principle

Push, not pull. Spawn agents, walk away, get notified when your judgment is needed. The orchestrator operates as a stateless system with no database — using flat metadata files and JSONL event logs for persistence. This design ensures backwards compatibility and simplicity.

The 8 Plugin Slots

Agent Orchestrator’s architecture is defined by 8 plugin slots. Each slot represents a specific responsibility, and every plugin must implement the interface defined in packages/core/src/types.ts.
All plugin interfaces are defined in a single source of truth: packages/core/src/types.ts
SlotInterfacePurposeDefault Plugin
RuntimeRuntimeWhere sessions execute (environment)tmux
AgentAgentAI coding tool adapterclaude-code
WorkspaceWorkspaceCode isolation mechanismworktree
TrackerTrackerIssue/task trackinggithub
SCMSCMSource control + PR/CI/reviewsgithub
NotifierNotifierPush notifications to humansdesktop
TerminalTerminalHuman interaction UIiterm2
Lifecycle(core)State machine + reaction engine(not pluggable)

Runtime Plugin

Determines WHERE and HOW agent sessions execute. Examples include:
  • tmux (default) — Local terminal sessions
  • docker — Containerized environments
  • process — Direct child processes
  • k8s — Kubernetes pods for cloud-scale orchestration
Key responsibilities:
  • Create and destroy session environments
  • Send messages to running agents
  • Capture session output
  • Check if sessions are alive
  • Provide attachment info for Terminal plugin

Agent Plugin

Adapter for specific AI coding tools. The plugin knows how to:
  • Launch the agent with proper configuration
  • Detect agent activity (active, ready, idle, blocked)
  • Extract session information (summary, cost, session ID)
  • Resume previous sessions
  • Set up workspace hooks for automatic metadata updates
Supported agents:
  • claude-code — Anthropic’s Claude Code
  • codex — OpenAI Codex
  • aider — Aider AI pair programmer
  • opencode — OpenCode agent

Workspace Plugin

Manages code isolation — how each session gets its own copy of the repository.
  • worktree (default) — Git worktrees for shared history
  • clone — Full repository clones for complete isolation
Features:
  • Create isolated workspaces per session
  • Automatic branch management
  • Post-creation hooks (symlinks, dependency installation)
  • Workspace restoration for crashed sessions

Tracker Plugin

Integrates with issue tracking systems to:
  • Fetch issue details and descriptions
  • Generate branch names from issue IDs
  • Create prompts for agents based on issue context
  • Check issue completion status
  • Update issue state (optional)
Supported trackers:
  • github — GitHub Issues
  • linear — Linear issue tracker

SCM Plugin

Manages the entire PR lifecycle:
  • Detect PRs created by agents
  • Track PR state (open, merged, closed)
  • Monitor CI check results
  • Fetch code reviews and review comments
  • Determine merge readiness
  • Execute merge operations
Supported platforms:
  • github — GitHub pull requests

Notifier Plugin

The primary interface between orchestrator and human. Delivers push notifications when:
  • Agent needs input or gets stuck
  • PR is approved and ready to merge
  • CI failures can’t be auto-fixed
  • Review comments require human judgment
Supported notifiers:
  • desktop — Native OS notifications
  • slack — Slack messages
  • composio — Composio platform integration
  • webhook — Custom HTTP webhooks

Terminal Plugin

Manages how humans view and interact with running sessions:
  • Open sessions in IDE tabs
  • Launch browser windows to web terminals
  • Attach to tmux/docker sessions
  • Open all sessions for a project at once
Supported terminals:
  • iterm2 — iTerm2 integration (macOS)
  • web — Browser-based terminal

Lifecycle Manager

Not pluggable. The core state machine that:
  • Polls all sessions periodically
  • Detects state transitions (working → pr_open → ci_failed → etc.)
  • Emits events on transitions
  • Triggers automatic reactions
  • Escalates to human notification when auto-handling fails

Component Interaction Flow

1
Session Spawn
2
When you run ao spawn my-project 123:
3
  • Tracker fetches issue details and generates a prompt
  • Workspace creates an isolated git worktree with feature branch
  • Agent generates the launch command with issue context
  • Runtime creates the execution environment (tmux session)
  • Agent launches inside the runtime with the prompt
  • Session metadata is written to ~/.agent-orchestrator/{hash}-{project}/sessions/{session-id}
  • 4
    Active Work
    5
    While the agent works:
    6
  • Agent writes code, runs tests, commits changes
  • Lifecycle Manager polls session status every N seconds
  • Agent plugin detects activity state (active/ready/idle/blocked/exited)
  • When agent creates PR, SCM detects it and updates session status
  • Session transitions through states: workingpr_open
  • 7
    Automatic Reactions
    8
    When events occur:
    9
  • SCM detects CI failure on PR
  • Lifecycle Manager emits ci.failing event
  • Reaction engine checks configured reactions
  • If ci-failed.auto: true, Runtime sends CI logs to agent via message
  • Agent reads logs, fixes issue, pushes new commit
  • If retries exhausted, Notifier escalates to human
  • 10
    Human Notification
    11
    When human judgment needed:
    12
  • Lifecycle Manager determines notification priority
  • Notifier delivers push notification with context
  • Human reviews PR, makes decision
  • Human can send instructions: ao send session-1 "Please add more tests"
  • Runtime delivers message to agent
  • Event-Driven Architecture

    The system is driven by events rather than continuous polling:

    Event Types

    Session Lifecycle:
    • session.spawned — New session created
    • session.working — Agent is actively working
    • session.stuck — Agent inactive for threshold period
    • session.needs_input — Agent waiting for user response
    • session.killed — Session terminated
    PR Lifecycle:
    • pr.created — Agent opened a pull request
    • pr.updated — PR was updated with new commits
    • pr.merged — PR was merged
    • pr.closed — PR was closed without merging
    CI Events:
    • ci.passing — All CI checks passed
    • ci.failing — One or more CI checks failed
    • ci.fix_sent — Auto-fix sent to agent
    • ci.fix_failed — Auto-fix attempts exhausted
    Review Events:
    • review.pending — PR awaiting review
    • review.approved — PR approved by reviewer
    • review.changes_requested — Reviewer requested changes
    • review.comments_sent — Review comments forwarded to agent
    Merge Events:
    • merge.ready — PR approved with passing CI
    • merge.conflicts — Merge conflicts detected
    • merge.completed — PR successfully merged

    Event Priority Levels

    Events are classified by priority for notification routing:
    • urgent — Agent stuck, needs input, or errored (immediate attention)
    • action — PR approved and ready, or merge completed (human decision needed)
    • warning — CI failure, changes requested, merge conflicts (may auto-resolve)
    • info — Progress updates, summaries (FYI only)

    Lifecycle State Machine

    Sessions progress through defined states:
    spawning → working → pr_open → ci_failed → working → pr_open
    
                        review_pending → changes_requested → working → pr_open
    
                           approved → mergeable → merged
    
    Terminal states (session ended):
    • killed — Session terminated
    • merged — PR merged successfully
    • done — Work completed
    • terminated — Force-stopped
    • cleanup — Being cleaned up
    • errored — Fatal error occurred
    Intervention states (needs human):
    • needs_input — Agent waiting for response
    • stuck — Agent inactive beyond threshold

    Directory Structure

    The architecture enforces convention over configuration:
    Repo (versioned):
    ~/path/to/agent-orchestrator/
      agent-orchestrator.yaml              # Config file (single source of truth)
      packages/
        core/                              # Type definitions, services
        cli/                               # Command-line interface
        web/                               # Next.js dashboard
        plugins/                           # All plugins
    
    Runtime Data (not versioned):
    ~/.agent-orchestrator/                 # Single parent directory
      {hash}-{projectId}/                  # Hash from config location
        sessions/
          {session-id}                     # Flat key=value metadata
        worktrees/
          {session-id}/                    # Git worktrees
        archive/
          {session-id}_{timestamp}         # Archived sessions
        .origin                            # Config path reference
    
    The hash is derived from the config file location, ensuring multiple orchestrator instances never collide.

    Design Principles

    1. Convention Over Configuration

    All paths are auto-derived. No need to configure:
    • Data directories
    • Worktree locations
    • Session namespaces
    The config file location determines everything.

    2. Single Source of Truth

    • Config: agent-orchestrator.yaml in repo
    • Runtime data: ~/.agent-orchestrator/ on disk
    • Plugin interfaces: packages/core/src/types.ts

    3. Zero Path Configuration

    Paths are computed from:
    • Config file location (for hash)
    • Project path (from config)
    • Session ID (auto-generated)
    No manual path management needed.

    4. Global Uniqueness

    Hash-based namespacing prevents collisions:
    • Multiple config checkouts don’t conflict
    • Projects from same config share hash prefix
    • Tmux session names are globally unique

    5. Stateless Orchestrator

    No database required:
    • Flat metadata files (key=value format)
    • JSONL event log for history
    • Plugins determine live state on demand

    6. Plugin Interfaces

    Every plugin is a pure implementation:
    • Imports interface from @composio/ao-core
    • Exports PluginModule<T> with satisfies
    • No framework lock-in

    7. Security First

    • Always use execFile, never exec (prevent shell injection)
    • Validate all external input (API, CLI, files)
    • No interpolation of user input into shell commands
    • Timeouts on all external commands
    Security Critical: All plugins must use execFile or spawn for shell commands. Never use exec or interpolate user input into command strings.

    Plugin Development Pattern

    Every plugin follows this structure:
    import type { PluginModule, Runtime } from "@composio/ao-core";
    
    export const manifest = {
      name: "tmux",
      slot: "runtime" as const,
      description: "Runtime plugin: tmux sessions",
      version: "0.1.0",
    };
    
    export function create(): Runtime {
      return {
        name: "tmux",
        async create(config) {
          // Implement interface method
        },
        async destroy(handle) {
          // Implement interface method
        },
        // ... other interface methods
      };
    }
    
    export default { manifest, create } satisfies PluginModule<Runtime>;
    
    Always use inline satisfies PluginModule<T> — this provides compile-time type checking and prevents interface mismatches.

    Next Steps

    Sessions

    Learn about session lifecycle and state management

    Plugins

    Explore the plugin system in detail

    Workflows

    See how typical workflows operate end-to-end

    Build docs developers (and LLMs) love