Reactions
Configure what AO does when CI fails, reviews arrive, agents get stuck, or PRs become ready.
Reactions are AO's automatic responses to session events. They decide whether AO should message an agent, notify a human, or mark a PR as ready for a merge action.
You do not need to configure reactions to start. AO ships with defaults for CI failures, review comments, merge conflicts, stuck agents, input prompts, and completed sessions.
Common Recipes
Watch Without Auto-Recovery
Use this while onboarding AO to a sensitive repo. You still see notifications, but AO stops sending recovery prompts to agents automatically.
reactions:
ci-failed:
auto: false
changes-requested:
auto: false
bugbot-comments:
auto: false
merge-conflicts:
auto: falseGive CI Recovery More Attempts
reactions:
ci-failed:
retries: 3
message: |
CI is failing. Read the failing check logs, reproduce locally when possible,
fix the smallest cause, and push the correction.Escalate Stuck Agents Faster
reactions:
agent-stuck:
priority: urgent
threshold: "7m"Notify On Merge-Ready PRs
approved-and-green does not merge by default. It notifies you that the PR is ready.
reactions:
approved-and-green:
auto: false
action: notify
priority: actionauto-merge is currently an intent flag, not a bypass. AO does not ignore branch protection, reviews, or failing checks.
Default Reactions
| Key | When it fires | Default action | Notes |
|---|---|---|---|
ci-failed | CI check fails | send-to-agent | Sends the agent a recovery prompt |
changes-requested | Human requests changes | send-to-agent | Sends review feedback to the agent |
bugbot-comments | Known automation leaves actionable feedback | send-to-agent | Keeps bot feedback separate from human reviews |
merge-conflicts | PR has conflicts | send-to-agent | Asks the agent to resolve conflicts |
approved-and-green | PR is approved and checks pass | notify | Does not merge unless future SCM support enables it |
agent-stuck | Agent has been inactive past threshold | notify | Urgent by default |
agent-needs-input | Agent is waiting for human input | notify | Urgent by default |
agent-exited | Session exits unexpectedly or is killed | notify | Urgent by default |
all-complete | Session finishes cleanly | notify | Includes summary by default |
agent-idle | Reserved | send-to-agent | Defined for future idle handling |
Action Types
| Action | Meaning |
|---|---|
send-to-agent | Sends message into the running agent session |
notify | Routes an event to configured notifiers |
auto-merge | Reserved merge intent; currently routes like a notification |
send-to-agent is the autonomous recovery path. notify is the human awareness path.
Config Fields
Each reaction accepts:
| Field | Type | Purpose |
|---|---|---|
auto | boolean | Whether AO should perform the automated action |
action | send-to-agent | notify | auto-merge | What AO does when the reaction fires |
message | string | Message sent to the agent or included in notification text |
priority | urgent | action | warning | info | Notification routing priority |
retries | number | Max repeated agent messages before escalation |
escalateAfter | number or duration string | Escalate after attempts or time, whichever applies |
threshold | duration string | Used by stuck/idle style reactions |
includeSummary | boolean | Include session summary in the notification |
Example:
reactions:
changes-requested:
action: send-to-agent
retries: 2
escalateAfter: "30m"
message: |
Reviewers requested changes. Read the unresolved comments,
make the requested fixes, and push an update.Notification Routing
Reaction priority maps to notificationRouting in the global config:
notificationRouting:
urgent: [desktop, composio]
action: [desktop]
warning: [composio]
info: [composio]Named notifier instances are configured separately:
notifiers:
desktop:
plugin: desktop
slack:
plugin: slack
webhookUrl: ${SLACK_WEBHOOK_URL}Per-Project Overrides
Put reaction overrides in a local project config to affect only that project:
reactions:
ci-failed:
retries: 4
approved-and-green:
priority: infoProject values override global values for the same reaction key.
CI Failure Flow
CI failure handling happens in two passes:
- AO sends the configured
ci-failed.messagewhen the session first enters a failed-CI state. - On the next poll, AO sends a structured follow-up with the failing check names, statuses, and URLs.
The second message does not consume the ci-failed retry budget. It exists so the agent gets both the instruction and the specific failing checks.
Review Backlog Throttle
AO throttles review-comment lookups to avoid hammering GitHub or GitLab. Pending human comments and known automation comments are fetched at most once every two minutes per session.
Force a check when you need one immediately:
ao review-check <session-id>Event Reference
| Event | Reaction |
|---|---|
ci.failing | ci-failed |
review.changes_requested | changes-requested |
automated_review.found | bugbot-comments |
merge.conflicts | merge-conflicts |
merge.ready | approved-and-green |
session.stuck | agent-stuck |
session.needs_input | agent-needs-input |
session.killed | agent-exited |
summary.all_complete | all-complete |