Skip to main content

What are Plugins?

Agent Orchestrator uses a plugin architecture where every abstraction is swappable. This means you can choose different implementations for how agents run (tmux vs Docker), which AI tool to use (Claude Code vs Codex), how to manage code isolation (git worktrees vs clones), and more. All plugins implement well-defined TypeScript interfaces from @composio/ao-core, ensuring consistency and interoperability across the system.

The 8 Plugin Slots

Agent Orchestrator has 8 plugin slots, each representing a different aspect of the orchestration system:
1

Runtime

WHERE and HOW agent sessions executeControls the execution environment for agents. Determines whether agents run in tmux sessions, Docker containers, Kubernetes pods, or simple child processes.
  • Interface: Runtime
  • Default: tmux
  • Alternatives: process, docker, k8s
2

Agent

WHICH AI coding tool to useAdapter for a specific AI coding assistant. Knows how to launch the tool, detect its activity state, and extract session information.
  • Interface: Agent
  • Default: claude-code
  • Alternatives: codex, aider, opencode
3

Workspace

HOW to isolate code for each sessionManages code isolation so each agent session gets its own copy of the repository to work in without conflicts.
  • Interface: Workspace
  • Default: worktree
  • Alternatives: clone
4

Tracker

WHERE to fetch issues and tasksIntegration with issue tracking systems. Fetches issue details, generates prompts, and creates branches.
  • Interface: Tracker
  • Default: github
  • Alternatives: linear
5

SCM

HOW to manage PRs, CI, and reviewsSource control management platform integration. Handles the full PR lifecycle including CI checks and code reviews.
  • Interface: SCM
  • Default: github
  • Alternatives: (gitlab, bitbucket - community contributions welcome)
6

Notifier

HOW to reach humansPush notifications to bring humans back when their judgment is needed. This is the primary human interface.
  • Interface: Notifier
  • Default: desktop
  • Alternatives: slack, composio, webhook
7

Terminal

HOW humans view and interact with sessionsOpens terminal sessions for human interaction. Launches IDE tabs, browser windows, or terminal sessions.
  • Interface: Terminal
  • Default: iterm2
  • Alternatives: web
8

Lifecycle Manager

State machine and reaction engineCore orchestration logic (not pluggable). Manages session state transitions and triggers automatic reactions.
  • Interface: Core service
  • Implementation: Built-in

Plugin Architecture

Core Interfaces

All plugin interfaces are defined in packages/core/src/types.ts. Each plugin slot has a corresponding TypeScript interface:
// Runtime determines where sessions execute
export interface Runtime {
  readonly name: string;
  create(config: RuntimeCreateConfig): Promise<RuntimeHandle>;
  destroy(handle: RuntimeHandle): Promise<void>;
  sendMessage(handle: RuntimeHandle, message: string): Promise<void>;
  getOutput(handle: RuntimeHandle, lines?: number): Promise<string>;
  isAlive(handle: RuntimeHandle): Promise<boolean>;
  getMetrics?(handle: RuntimeHandle): Promise<RuntimeMetrics>;
  getAttachInfo?(handle: RuntimeHandle): Promise<AttachInfo>;
}

// Agent adapter for AI coding tools
export interface Agent {
  readonly name: string;
  readonly processName: string;
  readonly promptDelivery?: "inline" | "post-launch";
  getLaunchCommand(config: AgentLaunchConfig): string;
  getEnvironment(config: AgentLaunchConfig): Record<string, string>;
  detectActivity(terminalOutput: string): ActivityState;
  getActivityState(session: Session, readyThresholdMs?: number): Promise<ActivityDetection | null>;
  isProcessRunning(handle: RuntimeHandle): Promise<boolean>;
  getSessionInfo(session: Session): Promise<AgentSessionInfo | null>;
  getRestoreCommand?(session: Session, project: ProjectConfig): Promise<string | null>;
  postLaunchSetup?(session: Session): Promise<void>;
  setupWorkspaceHooks?(workspacePath: string, config: WorkspaceHooksConfig): Promise<void>;
}

// Workspace manages code isolation
export interface Workspace {
  readonly name: string;
  create(config: WorkspaceCreateConfig): Promise<WorkspaceInfo>;
  destroy(workspacePath: string): Promise<void>;
  list(projectId: string): Promise<WorkspaceInfo[]>;
  postCreate?(info: WorkspaceInfo, project: ProjectConfig): Promise<void>;
  exists?(workspacePath: string): Promise<boolean>;
  restore?(config: WorkspaceCreateConfig, workspacePath: string): Promise<WorkspaceInfo>;
}
The full interface definitions include Tracker, SCM, Notifier, and Terminal. See packages/core/src/types.ts for complete details.

Plugin Module Pattern

Every plugin exports a PluginModule with two required properties:
  1. manifest - Plugin metadata (name, slot, description, version)
  2. create - Factory function that returns the plugin implementation
Plugins use TypeScript’s satisfies operator for compile-time type checking:
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) { /* ... */ },
    async destroy(handle) { /* ... */ },
    async sendMessage(handle, message) { /* ... */ },
    async getOutput(handle, lines) { /* ... */ },
    async isAlive(handle) { /* ... */ },
  };
}

export default { manifest, create } satisfies PluginModule<Runtime>;

How Plugins are Loaded

Plugins are loaded during system initialization:
  1. Built-in plugins - Core plugins shipped with Agent Orchestrator
  2. npm packages - Third-party plugins installed via npm (prefix: @ao-plugin/)
  3. Local paths - Custom plugins from local directories
Plugins are selected from configuration in agent-orchestrator.yaml:
defaults:
  runtime: tmux
  agent: claude-code
  workspace: worktree
  notifiers: [desktop]

projects:
  my-app:
    runtime: docker  # Override runtime for this project
    agent: codex     # Override agent for this project

Available Plugins by Slot

Runtime Plugins

Runs agents in tmux sessions. Provides session isolation, persistence, and easy human attachment.Features:
  • Detached execution
  • Session persistence across network disconnects
  • Easy attachment: tmux attach -t <session-id>
  • Supports long commands via buffer pasting
Location: @composio/ao-plugin-runtime-tmux
Runs agents as child processes. Simpler than tmux but less robust.Features:
  • Direct process control
  • Lower overhead
  • No external dependencies
Location: @composio/ao-plugin-runtime-process

Agent Plugins

Adapter for Anthropic’s Claude Code CLI.Features:
  • Activity detection via JSONL session files
  • Cost tracking from usage data
  • Session resumption support
  • Auto-summary extraction
  • PostToolUse hooks for metadata updates
Location: @composio/ao-plugin-agent-claude-code
Adapter for Composio’s Codex agent.Features:
  • Native orchestrator integration
  • Rich session metadata
  • Cost tracking
Location: @composio/ao-plugin-agent-codex
Adapter for Paul Gauthier’s Aider.Features:
  • Multi-model support
  • Git-aware code editing
  • Cost tracking
Location: @composio/ao-plugin-agent-aider
Adapter for OpenCode AI coding assistant.Location: @composio/ao-plugin-agent-opencode

Workspace Plugins

Uses git worktrees for code isolation. Each session gets its own working directory sharing the same .git folder.Features:
  • Fast workspace creation
  • Shared git history (space efficient)
  • Automatic symlink support
  • postCreate hooks
Location: @composio/ao-plugin-workspace-worktree
Creates full git clones for isolation. Slower but more independent.Features:
  • Complete repository independence
  • No worktree conflicts
Location: @composio/ao-plugin-workspace-clone

Tracker Plugins

GitHub Issues integration.Features:
  • Fetch issue details
  • Generate agent prompts from issues
  • Branch naming from issue numbers
  • List and filter issues
  • Update issue state
  • Create new issues
Location: @composio/ao-plugin-tracker-github
Linear issue tracking integration.Features:
  • Linear GraphQL API integration
  • Issue states (Todo, In Progress, Done)
  • Team-based issue organization
  • Priority and label support
Location: @composio/ao-plugin-tracker-linear

SCM Plugins

GitHub PR lifecycle management.Features:
  • PR detection and state tracking
  • CI check monitoring
  • Review collection and analysis
  • Merge readiness assessment
  • Automated comment detection (bots)
  • PR merge/close operations
Location: @composio/ao-plugin-scm-github

Notifier Plugins

OS-native desktop notifications.Features:
  • macOS (via osascript)
  • Linux (via notify-send)
  • Priority-based sound alerts
  • Urgent event highlighting
Location: @composio/ao-plugin-notifier-desktop
Slack channel notifications.Features:
  • Channel-based routing
  • Rich message formatting
  • Action buttons
  • Thread support
Location: @composio/ao-plugin-notifier-slack
Composio platform integration.Features:
  • Multi-channel routing
  • Action tracking
  • Unified notification history
Location: @composio/ao-plugin-notifier-composio
Generic webhook notifications.Features:
  • POST events to custom endpoints
  • Flexible payload formatting
  • Retry logic
Location: @composio/ao-plugin-notifier-webhook

Terminal Plugins

iTerm2 integration (macOS).Features:
  • Opens tmux sessions in new tabs
  • AppleScript automation
  • Multi-session tab management
Location: @composio/ao-plugin-terminal-iterm2
Web-based terminal viewer.Features:
  • Browser-based session viewing
  • WebSocket live updates
  • Cross-platform
Location: @composio/ao-plugin-terminal-web

Plugin Selection Priority

Plugins are selected in this order:
  1. Session-level override (e.g., ao spawn --agent codex)
  2. Project-level override (in agent-orchestrator.yaml)
  3. Global default (in defaults section)
  4. Hardcoded fallback (if not configured)
Notifiers are special - they can be plural. You can configure multiple notifiers that all receive events based on priority routing.

Plugin Discovery

The PluginRegistry service manages plugin loading and lookup:
interface PluginRegistry {
  register(plugin: PluginModule, config?: Record<string, unknown>): void;
  get<T>(slot: PluginSlot, name: string): T | null;
  list(slot: PluginSlot): PluginManifest[];
  loadBuiltins(config?: OrchestratorConfig): Promise<void>;
  loadFromConfig(config: OrchestratorConfig): Promise<void>;
}
Built-in plugins are automatically loaded. Custom plugins are loaded from:
  • npm packages: @ao-plugin/<slot>-<name>
  • Local paths: specified in config

Plugin Configuration

Some plugins accept configuration via the config file:
projects:
  my-app:
    tracker:
      plugin: linear
      teamId: "abc123"  # Linear-specific config
      apiKey: "$LINEAR_API_KEY"
    
    scm:
      plugin: github
      # github uses gh CLI, no additional config needed

notifiers:
  myslack:
    plugin: slack
    token: "$SLACK_BOT_TOKEN"
    channel: "#agent-alerts"
  
  mywebhook:
    plugin: webhook
    url: "https://example.com/hooks/ao"
    secret: "$WEBHOOK_SECRET"
Never commit API keys or secrets to version control. Use environment variable references (e.g., $SLACK_BOT_TOKEN) in your config file.

Next Steps

Create a Plugin

Learn how to build your own plugin

Core Types

View complete interface definitions

Build docs developers (and LLMs) love