Agent Orchestrator uses a push notification model—agents notify humans only when judgment is required. Configure notifiers and routing to control where notifications go based on priority.
Notifier System Overview
The notification system has two parts:
Notifier Plugins
Define notification channels (Slack, Discord, webhooks, etc.)
Notification Routing
Route notifications to channels based on priority level
When an event occurs, the orchestrator:
Determines event priority (urgent, action, warning, info)
Looks up which notifiers should receive that priority
Sends the notification to all configured channels
Source: packages/core/src/lifecycle-manager.ts:422-431
Built-in Notifiers
Agent Orchestrator includes 4 built-in notifiers:
Notifier Description Use Case desktop Native OS notifications Local development, immediate alerts composio Composio integration Team visibility, workflow automation slack Slack webhooks Team channels, async updates webhook Custom HTTP webhooks Custom integrations, logging
Source: packages/core/src/plugin-registry.ts:43-46
Desktop Notifier
Native OS notifications for local development.
defaults :
notifiers : [ desktop ]
Desktop notifier is enabled by default. No additional configuration needed.
Supports:
macOS (Notification Center)
Linux (libnotify)
Windows (Toast notifications)
Composio Notifier
Integration with Composio platform for team visibility.
defaults :
notifiers : [ composio , desktop ]
Composio notifier is included in default notifiers. Remove it if you don’t use Composio: defaults :
notifiers : [ desktop ] # Desktop only
Slack Notifier
Send notifications to Slack channels via incoming webhooks.
Setup
Set Environment Variable
export SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
Add to your shell profile (~/.zshrc, ~/.bashrc): echo 'export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."' >> ~/.zshrc
source ~/.zshrc
Configure Notifier
notifiers :
slack :
plugin : slack
webhook : ${SLACK_WEBHOOK_URL}
channel : "#agent-updates"
Add to Routing
notificationRouting :
urgent : [ desktop , slack ]
action : [ desktop , slack ]
warning : [ slack ]
info : [ slack ]
Configuration
Slack notifier configuration
Slack incoming webhook URL. Use ${SLACK_WEBHOOK_URL} to reference environment variable.
Default channel for notifications (e.g., #agent-updates). Can be overridden per-notification.
notifiers.slack.username
string
default: "Agent Orchestrator"
Bot username displayed in Slack
Example
notifiers :
slack :
plugin : slack
webhook : ${SLACK_WEBHOOK_URL}
channel : "#agent-updates"
username : "Agent Orchestrator"
notificationRouting :
urgent : [ desktop , slack ] # Critical alerts to both
action : [ desktop , slack ] # Action items to both
warning : [ slack ] # Warnings to Slack only
info : [ slack ] # Info to Slack only
Source: packages/plugins/notifier-slack/src/index.ts, examples/multi-project.yaml:45-57
Webhook Notifier
Send notifications to custom HTTP endpoints.
Configuration
Webhook notifier configuration
HTTP endpoint URL. Use ${WEBHOOK_URL} to reference environment variable.
HTTP method: POST, PUT, PATCH
Custom HTTP headers (e.g., authentication)
Example
notifiers :
webhook :
plugin : webhook
url : https://your-service.com/agent-events
method : POST
headers :
Authorization : "Bearer ${WEBHOOK_TOKEN}"
Content-Type : "application/json"
notificationRouting :
urgent : [ desktop , webhook ]
action : [ webhook ]
warning : [ webhook ]
info : [ webhook ]
Webhook Payload
The webhook receives a JSON payload with event details:
{
"id" : "evt_abc123" ,
"type" : "ci.failing" ,
"priority" : "warning" ,
"sessionId" : "my-app-5" ,
"projectId" : "my-app" ,
"timestamp" : "2026-03-04T12:34:56.789Z" ,
"message" : "CI checks are failing" ,
"data" : {
"prUrl" : "https://github.com/org/repo/pull/123" ,
"ciStatus" : "failing" ,
"branch" : "feature/new-thing"
}
}
Source: packages/core/src/types.ts:747-757
Notification Routing
Route notifications to different channels based on priority level.
notificationRouting :
urgent : [ desktop , slack ] # Critical issues
action : [ desktop , slack ] # Action required
warning : [ slack ] # Something to be aware of
info : [ slack ] # Informational only
Priority Levels
notificationRouting.urgent
Urgent priority — Critical issues requiring immediate attention:
Agent stuck
Agent needs input (permission prompt, question)
Agent crashed/exited
Multiple failed escalations
Recommended routing: Desktop + Slack (immediate attention)
notificationRouting.action
Action priority — Action required but not urgent:
PR ready to merge (approved + CI green)
Manual intervention needed
Recommended routing: Desktop + Slack (check when convenient)
notificationRouting.warning
Warning priority — Something to be aware of:
Auto-fix failed (escalated after retries)
CI failing (after automatic retries exhausted)
Review comments (after automatic handling failed)
Recommended routing: Slack only (async, no immediate action)
Info priority — Informational only:
All agents complete
PR merged successfully
Session summary
Recommended routing: Slack only (FYI, no action needed)
Source: packages/core/src/types.ts:705-706
Default Routing
If you don’t specify notificationRouting, these defaults apply:
notificationRouting :
urgent : [ desktop , composio ]
action : [ desktop , composio ]
warning : [ composio ]
info : [ composio ]
Source: packages/core/src/config.ts:99-104
Routing Examples
Desktop-only (local development):
defaults :
notifiers : [ desktop ]
notificationRouting :
urgent : [ desktop ]
action : [ desktop ]
warning : [ desktop ]
info : [ desktop ]
Slack-only (team environment):
defaults :
notifiers : [ slack ]
notifiers :
slack :
plugin : slack
webhook : ${SLACK_WEBHOOK_URL}
channel : "#agent-updates"
notificationRouting :
urgent : [ slack ]
action : [ slack ]
warning : [ slack ]
info : [ slack ]
Hybrid (local + team):
defaults :
notifiers : [ desktop , slack ]
notifiers :
slack :
plugin : slack
webhook : ${SLACK_WEBHOOK_URL}
channel : "#agent-updates"
notificationRouting :
urgent : [ desktop , slack ] # Critical: both
action : [ desktop , slack ] # Action: both
warning : [ slack ] # Warning: team only
info : [ slack ] # Info: team only
Multiple channels:
notifiers :
slack-team :
plugin : slack
webhook : ${SLACK_WEBHOOK_TEAM}
channel : "#agent-updates"
slack-oncall :
plugin : slack
webhook : ${SLACK_WEBHOOK_ONCALL}
channel : "#oncall-alerts"
pagerduty :
plugin : webhook
url : ${PAGERDUTY_WEBHOOK}
notificationRouting :
urgent : [ desktop , slack-oncall , pagerduty ] # Critical: all channels
action : [ desktop , slack-team ] # Action: desktop + team
warning : [ slack-team ] # Warning: team only
info : [ slack-team ] # Info: team only
Custom Notification Rules
Adjust notification behavior per reaction:
reactions :
ci-failed :
auto : true
action : send-to-agent
retries : 3
escalateAfter : 3
priority : warning # Override: warning instead of urgent on escalation
agent-stuck :
auto : true
action : notify
priority : urgent # Send as urgent
threshold : 10m
approved-and-green :
auto : false
action : notify
priority : action # Send as action priority
When reactions escalate or trigger notifications, they use the configured priority to determine routing.
Source: packages/core/src/types.ts:774-775
Channel Configuration
Some notifiers support per-notification channel overrides.
Slack Channels
Override the default channel:
notifiers :
slack :
plugin : slack
webhook : ${SLACK_WEBHOOK_URL}
channel : "#agent-updates" # Default channel
When posting via the API, you can override:
await notifier . post ( "Custom message" , {
channel: "#different-channel"
});
Source: packages/plugins/notifier-slack/src/index.ts:171-184
Complete Example
A production-ready notification configuration:
# Default notifiers
defaults :
runtime : tmux
agent : claude-code
workspace : worktree
notifiers : [ desktop , slack , webhook ]
# Configure notification channels
notifiers :
slack :
plugin : slack
webhook : ${SLACK_WEBHOOK_URL}
channel : "#agent-updates"
username : "Agent Orchestrator"
webhook :
plugin : webhook
url : https://your-service.com/agent-events
method : POST
headers :
Authorization : "Bearer ${WEBHOOK_TOKEN}"
# Route by priority
notificationRouting :
urgent : [ desktop , slack ] # Agent stuck, needs input, crashed
action : [ desktop , slack ] # PR ready to merge
warning : [ slack , webhook ] # Auto-fix failed, escalated
info : [ slack , webhook ] # Summary, all done
# Configure reactions with priorities
reactions :
ci-failed :
auto : true
action : send-to-agent
retries : 3
escalateAfter : 3
priority : warning # Routed to: slack, webhook
changes-requested :
auto : true
action : send-to-agent
escalateAfter : 30m
priority : warning # Routed to: slack, webhook
approved-and-green :
auto : false
action : notify
priority : action # Routed to: desktop, slack
agent-stuck :
auto : true
action : notify
priority : urgent # Routed to: desktop, slack
threshold : 10m
agent-needs-input :
auto : true
action : notify
priority : urgent # Routed to: desktop, slack
all-complete :
auto : true
action : notify
priority : info # Routed to: slack, webhook
includeSummary : true
Testing Notifications
Test your notification setup:
# Spawn a test agent
ao spawn my-app TEST-123
# Trigger events to test notifications:
# 1. Push a failing commit → triggers ci-failed → warning priority
# 2. Request changes → triggers changes-requested → warning priority
# 3. Approve PR → triggers approved-and-green → action priority
# 4. Let agent sit idle → triggers agent-stuck → urgent priority
Verify:
Desktop notifications appear (for urgent/action)
Slack messages arrive in correct channel
Webhooks receive POST requests with correct payload
Troubleshooting
No Desktop Notifications
macOS: Grant notification permissions:
System Settings → Notifications
Find Terminal or your terminal app
Enable “Allow Notifications”
Linux: Install libnotify-bin:
sudo apt install libnotify-bin
Slack Webhook Fails
Check webhook URL:
echo $SLACK_WEBHOOK_URL
# Should print: https://hooks.slack.com/services/...
Test webhook manually:
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Test from Agent Orchestrator"}' \
$SLACK_WEBHOOK_URL
Common issues:
Webhook URL expired (recreate in Slack)
Channel doesn’t exist (check spelling)
Workspace permissions (ensure app is installed)
Webhook Timeout
Increase timeout (future feature):
notifiers :
webhook :
plugin : webhook
url : https://slow-service.com/webhook
timeout : 10000 # 10 seconds
Use async webhooks: Configure your endpoint to return 200 immediately and process async.
Missing Notifications
Check routing:
# This won't send notifications if desktop notifier isn't configured!
notificationRouting :
urgent : [ desktop ] # But desktop isn't in defaults.notifiers!
Solution: Ensure notifiers are in defaults.notifiers or explicitly configured:
defaults :
notifiers : [ desktop , slack ] # Include all notifiers used in routing
Next Steps
Reactions Configure what events trigger notifications
Projects Set up projects with custom notification rules