Agent Orchestrator’s flexibility comes from its plugin architecture . Every major component — from where sessions run to how notifications are delivered — is swappable via plugins.
Plugin System Overview
A plugin is a TypeScript module that implements one of the 8 plugin interfaces defined in packages/core/src/types.ts. Each plugin:
Exports a manifest object describing itself
Exports a create() function that returns the plugin implementation
Uses satisfies PluginModule<T> for compile-time type safety
Plugin Structure
Every plugin follows this pattern:
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 > ;
The satisfies PluginModule<T> syntax ensures compile-time checking that your plugin correctly implements all required interface methods.
The 8 Plugin Slots
1. Runtime Plugin
Slot: runtime
Interface: Runtime
Purpose: Determines WHERE and HOW agent sessions execute
Available Plugins:
tmux (default)
process
docker
k8s
Local tmux sessions Pros:
Native terminal access
Persist across disconnects
Easy to attach and monitor
Minimal overhead
Cons:
Local machine only
Requires tmux installed
Configuration: Direct child processes Pros:
No dependencies
Simplest implementation
Works everywhere
Cons:
Dies if orchestrator stops
No persistence
Limited monitoring
Configuration: defaults :
runtime : process
Docker containers Pros:
Complete isolation
Reproducible environments
Resource limits
Works on any Docker host
Cons:
Requires Docker
Higher overhead
More complex setup
Configuration: defaults :
runtime : docker
Kubernetes pods Pros:
Cloud-scale orchestration
High availability
Resource management
Multi-node distribution
Cons:
Requires K8s cluster
Most complex setup
Higher latency
Configuration:
Interface Methods:
interface Runtime {
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 >;
}
2. Agent Plugin
Slot: agent
Interface: Agent
Purpose: Adapter for specific AI coding tools
Available Plugins:
claude-code (default)
codex
aider
opencode
Anthropic’s Claude Code Features:
Session resume support
JSONL-based activity detection
Auto-generated summaries
Cost tracking
Workspace hooks for metadata updates
Configuration: defaults :
agent : claude-code
projects :
my-app :
agentConfig :
permissions : skip # or "default"
model : claude-sonnet-4-20250514
OpenAI Codex Features:
Fast iteration speed
Strong code completion
Multi-language support
Configuration: defaults :
agent : codex
projects :
my-app :
agent : codex
agentConfig :
model : gpt-4
Aider AI pair programmer Features:
Git-aware editing
Interactive mode
Multiple model support
Configuration: defaults :
agent : aider
projects :
my-app :
agent : aider
agentConfig :
model : gpt-4-turbo
OpenCode agent Features:
Open source
Extensible
Multi-modal support
Configuration: defaults :
agent : opencode
Interface Methods:
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 >;
}
Critical for Dashboard: The setupWorkspaceHooks() method configures agents to automatically update session metadata when they run git/gh commands. Without this, PRs created by agents never show up in the dashboard.
3. Workspace Plugin
Slot: workspace
Interface: Workspace
Purpose: Code isolation mechanism
Available Plugins:
Git worktrees Pros:
Shares git history (fast)
Minimal disk usage
Instant branch switching
Multiple sessions see each other’s commits
Cons:
Requires Git 2.25+
All worktrees share hooks
Can’t delete parent repo while worktrees exist
Configuration: defaults :
workspace : worktree
projects :
my-app :
workspace : worktree
symlinks :
- node_modules
- .env
postCreate :
- pnpm install
Full repository clones Pros:
Complete isolation
Independent git state
No shared hooks
Works with any Git version
Cons:
Higher disk usage
Slower to create
Must push/pull to share changes
Configuration: defaults :
workspace : clone
projects :
my-app :
workspace : clone
postCreate :
- npm install
Interface Methods:
interface Workspace {
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 >;
}
4. Tracker Plugin
Slot: tracker
Interface: Tracker
Purpose: Issue/task tracking integration
Available Plugins:
GitHub Issues Features:
Fetch issue details
Generate branch names
Create prompts from issues
Check completion status
Extract labels
Configuration: projects :
my-app :
repo : owner/my-app
tracker :
plugin : github
Usage: ao spawn my-app 42 # GitHub issue #42
ao spawn my-app "#42" # Also works
Linear issue tracker Features:
Fetch Linear issues
Team-aware queries
Status tracking
Priority handling
Configuration: projects :
my-app :
tracker :
plugin : linear
teamId : TEAM-ID
apiKey : ${LINEAR_API_KEY}
Usage: ao spawn my-app INT-100 # Linear issue INT-100
Interface Methods:
interface Tracker {
getIssue ( identifier : string , project : ProjectConfig ) : Promise < Issue >;
isCompleted ( identifier : string , project : ProjectConfig ) : Promise < boolean >;
issueUrl ( identifier : string , project : ProjectConfig ) : string ;
issueLabel ? ( url : string , project : ProjectConfig ) : string ;
branchName ( identifier : string , project : ProjectConfig ) : string ;
generatePrompt ( identifier : string , project : ProjectConfig ) : Promise < string >;
listIssues ? ( filters : IssueFilters , project : ProjectConfig ) : Promise < Issue []>;
updateIssue ? ( identifier : string , update : IssueUpdate , project : ProjectConfig ) : Promise < void >;
createIssue ? ( input : CreateIssueInput , project : ProjectConfig ) : Promise < Issue >;
}
5. SCM Plugin
Slot: scm
Interface: SCM
Purpose: Source control + PR/CI/review management
Available Plugins:
GitHub Features:
Auto-detect PRs by branch
Track PR state (open/merged/closed)
Monitor CI checks
Fetch code reviews
Get review comments
Check merge readiness
Merge PRs
Configuration: projects :
my-app :
repo : owner/my-app
scm :
plugin : github
Automatic PR Detection:
The github-scm plugin automatically detects PRs created by agents, even if the agent doesn’t write the PR URL to metadata.
Interface Methods:
interface SCM {
detectPR ( session : Session , project : ProjectConfig ) : Promise < PRInfo | null >;
getPRState ( pr : PRInfo ) : Promise < PRState >;
getPRSummary ? ( pr : PRInfo ) : Promise <{ state : PRState ; title : string ; additions : number ; deletions : number }>;
mergePR ( pr : PRInfo , method ?: MergeMethod ) : Promise < void >;
closePR ( pr : PRInfo ) : Promise < void >;
getCIChecks ( pr : PRInfo ) : Promise < CICheck []>;
getCISummary ( pr : PRInfo ) : Promise < CIStatus >;
getReviews ( pr : PRInfo ) : Promise < Review []>;
getReviewDecision ( pr : PRInfo ) : Promise < ReviewDecision >;
getPendingComments ( pr : PRInfo ) : Promise < ReviewComment []>;
getAutomatedComments ( pr : PRInfo ) : Promise < AutomatedComment []>;
getMergeability ( pr : PRInfo ) : Promise < MergeReadiness >;
}
6. Notifier Plugin
Slot: notifier
Interface: Notifier
Purpose: Push notifications to humans
Primary Human Interface: The Notifier is how the orchestrator communicates with you. The dashboard is for monitoring; notifications are for action.
Available Plugins:
desktop (default)
slack
webhook
composio
Native OS notifications Features:
System notification center
Works on macOS/Linux/Windows
No external dependencies
Immediate delivery
Configuration: notifiers :
desktop :
plugin : desktop
notificationRouting :
urgent : [ desktop ]
action : [ desktop ]
warning : [ desktop ]
info : []
Slack messages Features:
Team-visible notifications
Rich formatting
Actionable buttons
Thread support
Configuration: notifiers :
slack :
plugin : slack
token : ${SLACK_BOT_TOKEN}
channel : "#agent-updates"
notificationRouting :
urgent : [ desktop , slack ]
action : [ slack ]
warning : [ slack ]
info : []
Custom HTTP webhooks Features:
Send to any HTTP endpoint
Custom payloads
Integration with any service
Configuration: notifiers :
webhook :
plugin : webhook
url : https://your-service.com/webhook
headers :
Authorization : Bearer ${WEBHOOK_TOKEN}
notificationRouting :
urgent : [ desktop , webhook ]
action : [ webhook ]
Composio platform Features:
Integrated with Composio ecosystem
Multi-channel routing
Analytics and tracking
Configuration: notifiers :
composio :
plugin : composio
apiKey : ${COMPOSIO_API_KEY}
Interface Methods:
interface Notifier {
notify ( event : OrchestratorEvent ) : Promise < void >;
notifyWithActions ? ( event : OrchestratorEvent , actions : NotifyAction []) : Promise < void >;
post ? ( message : string , context ?: NotifyContext ) : Promise < string | null >;
}
7. Terminal Plugin
Slot: terminal
Interface: Terminal
Purpose: Human interaction with running sessions
Available Plugins:
iTerm2 integration (macOS) Features:
Open sessions in new tabs
Native terminal experience
Keyboard shortcuts
Split panes
Configuration: defaults :
terminal : iterm2
Usage: ao attach session-1 # Opens in iTerm2 tab
ao open my-app # Opens all sessions
Browser-based terminal Features:
Works anywhere
No native terminal required
Copy/paste friendly
Mobile-compatible
Configuration: defaults :
terminal : web
terminalPort : 3001 # WebSocket port
directTerminalPort : 3003 # Direct terminal port
Usage:
Open dashboard, click session to view terminal.
Interface Methods:
interface Terminal {
openSession ( session : Session ) : Promise < void >;
openAll ( sessions : Session []) : Promise < void >;
isSessionOpen ? ( session : Session ) : Promise < boolean >;
}
8. Lifecycle Manager
Not a plugin slot — this is core functionality built into the orchestrator.
Responsibilities:
Poll all sessions periodically (default: every 30 seconds)
Detect state transitions (working → pr_open → ci_failed → etc.)
Emit events on transitions
Trigger automatic reactions
Track reaction attempts and escalation
Notify humans when auto-handling fails
State Machine Logic:
Is the session’s runtime environment alive?
What is the agent currently doing? (active/ready/idle/waiting/exited)
If no PR in metadata, query SCM by branch name.
If PR exists: Is it open, merged, or closed?
Are CI checks passing or failing?
What’s the review decision? (approved/changes_requested/pending)
Is the PR mergeable? (approved + green CI + no conflicts)
Compute new session status from all checks.
If status changed, emit event and trigger reactions.
Configuration:
readyThresholdMs : 300000 # 5 minutes before ready → idle
Plugin Configuration
Global Defaults
Set defaults for all projects:
defaults :
runtime : tmux
agent : claude-code
workspace : worktree
notifiers : [ desktop ]
Per-Project Overrides
Override defaults for specific projects:
projects :
my-app :
repo : owner/my-app
path : ~/my-app
defaultBranch : main
# Override runtime
runtime : docker
# Override agent
agent : codex
# Override workspace
workspace : clone
# Agent-specific config
agentConfig :
permissions : skip
model : gpt-4-turbo
Per-Session Overrides
Specify agent at spawn time:
ao spawn my-app 123 --agent aider
The agent name is persisted in metadata so the same agent is used throughout the session lifecycle (including restores).
Plugin Discovery
Plugins are discovered in this order:
Built-in plugins — Shipped with Agent Orchestrator
npm packages — Installed via pnpm install
Local paths — Custom plugins in your project
Using Custom Plugins
Create a plugin in your project:
// plugins/my-runtime.ts
import type { PluginModule , Runtime } from "@composio/ao-core" ;
export const manifest = {
name: "my-runtime" ,
slot: "runtime" as const ,
description: "My custom runtime" ,
version: "1.0.0" ,
};
export function create () : Runtime {
return {
// Implement interface
};
}
export default { manifest , create } satisfies PluginModule < Runtime > ;
Register in config:
plugins :
- path : ./plugins/my-runtime.ts
defaults :
runtime : my-runtime
Best Practices
Choosing Plugins
Runtime: Use tmux for local work, docker for isolation, k8s for scale
Agent: Start with claude-code, try others for specific needs
Workspace: Use worktree unless you need complete isolation
Tracker: Match your existing issue tracker
Notifier: Use desktop for personal work, slack for team visibility
Plugin Configuration
Set sensible defaults in global config
Override per-project for special cases
Use environment variables for secrets: ${SLACK_TOKEN}
Test plugin changes with a single session first
Notification Routing
Route notifications by priority:
notificationRouting :
urgent : [ desktop , slack ] # Agent stuck/errored
action : [ desktop ] # Human decision needed
warning : [ slack ] # Auto-fixable issues
info : [] # Don't notify for FYI events
Next Steps
Architecture See how plugins interact in the overall architecture
Workflows Learn how plugins work together in end-to-end workflows
Plugin Development Build your own custom plugins