Triggers
Configure AGH automation triggers that react to runtime events, filters, and prompt templates.
- Audience
- Operators running durable agent work
- Focus
- Automation guidance shaped for scanability, day-two clarity, and operator context.
Triggers run agents in response to events. They are useful when the next agent run should depend on something that happened inside AGH, such as a session stopping, a memory consolidation completing, or a webhook delivery arriving.
Triggers do not bind to jobs by ID. A trigger is its own automation definition with an event, filters, agent, prompt template, retry policy, and fire limit. When a matching event arrives, AGH uses the same dispatcher and run history model that scheduled jobs use.
Trigger fields
| Field | Required | Meaning |
|---|---|---|
name | Yes | Human-readable trigger name. |
scope | Yes | global or workspace. |
workspace / workspace_id | Workspace triggers only | TOML uses workspace; API payloads and stored triggers use workspace_id. |
event | Yes | Event name to match. Built-in events are documented below, and extension events use ext.*. |
agent / agent_name | Yes | Agent to run when the trigger matches. |
prompt | Yes | Go text/template rendered against the activation envelope. |
filter | No | Exact-match conditions on envelope fields. |
enabled | No | Defaults to true for parsed config definitions. |
retry | No | Same retry policy as jobs. Defaults to none. |
fire_limit | No | Same rolling fire limit as jobs. Defaults to 12/1h unless changed. |
endpoint_slug | Webhook triggers | Human-readable webhook endpoint segment. |
webhook_secret_ref | Webhook triggers | env:NAME or vault:automation/... ref for the webhook signing secret. |
Event types
AGH stores trigger events as strings. The current runtime emits these built-in event names:
| Event | Source | Typical use |
|---|---|---|
session.created | Session lifecycle observer | Start a helper agent when a workspace session begins. |
session.stopped | Session lifecycle observer | Summarize work, collect failures, or schedule follow-up review. |
memory.consolidated | Memory consolidation runtime | Review durable memory changes after consolidation. |
hook.<hook_name>.completed | Hook runtime | Continue a workflow after a named hook completes. |
webhook | Signed HTTP webhook ingress | React to CI, deploy, incident, or repository events from external systems. |
ext.* | Extension trigger API | Let an extension publish its own automation event family. |
The event name must be non-empty. AGH does not restrict custom extension event names beyond the extension ingress contract.
Matching and filters
A trigger fires only when all of these match:
- the trigger is enabled
- the trigger event equals the activation event
- the trigger scope equals the activation scope
- workspace triggers match the same workspace ID
- every filter entry matches exactly
Filters support these paths:
| Filter path | Matches |
|---|---|
kind | Activation event name such as session.stopped, webhook, or ext.release. |
scope | global or workspace. |
workspace_id | Workspace ID carried by the activation envelope. |
source | Activation source such as observer, hook, webhook, or extension. |
data.<path> | String value inside the activation data object. |
Filter values must be non-empty strings.
filter = { "data.stop_reason" = "error", "data.agent_name" = "codex" }Prompt templates
Trigger prompts are rendered with Go text/template. The template data is the activation envelope:
| Template value | Meaning |
|---|---|
.Kind | Activation event name. |
.Scope | global or workspace. |
.WorkspaceID | Workspace ID for workspace-scoped activations. |
.Source | Activation source such as observer, hook, webhook, or extension. |
.Data | Event-specific data map. |
Use index for dynamic data keys:
prompt = "Summarize session {{ index .Data \"session_id\" }}. Stop reason: {{ index .Data \"stop_reason\" }}."Invalid templates fail validation when the trigger is created or loaded from config.
Worked example: summarize failed sessions
This trigger runs after a workspace session stops with an error. The prompt template receives the event data and turns it into a targeted summarization request.
[[automation.triggers]]
scope = "workspace"
workspace = "/Users/you/src/checkout-api"
name = "summarize-failed-sessions"
event = "session.stopped"
agent = "summarizer"
prompt = "Summarize session {{ index .Data \"session_id\" }}. Stop reason: {{ index .Data \"stop_reason\" }}."
filter = { "data.stop_reason" = "error" }
retry = { strategy = "backoff", max_retries = 2, base_delay = "5s" }
fire_limit = { max = 4, window = "1h" }Create the same dynamic trigger from the CLI:
agh automation triggers create \
--name summarize-failed-sessions \
--scope workspace \
--workspace /Users/you/src/checkout-api \
--event session.stopped \
--agent summarizer \
--prompt 'Summarize session {{ index .Data "session_id" }}. Stop reason: {{ index .Data "stop_reason" }}.' \
--filter data.stop_reason=error \
--retry backoff:2:5sAPI example
Create a dynamic trigger over HTTP:
curl -sS -X POST http://localhost:2123/api/automation/triggers \
-H "Content-Type: application/json" \
--data '{
"name": "memory-review",
"scope": "workspace",
"workspace_id": "ws_123",
"event": "memory.consolidated",
"agent_name": "reviewer",
"prompt": "Review memory consolidation {{ index .Data \"consolidation_id\" }}.",
"filter": {
"data.scope": "workspace"
},
"retry": {
"strategy": "none"
},
"fire_limit": {
"max": 3,
"window": "1h"
},
"enabled": true
}'The response is wrapped as:
{
"trigger": {
"id": "trg_...",
"name": "memory-review",
"event": "memory.consolidated",
"enabled": true
}
}Conditional execution
Filters handle exact-match conditions. For richer policy, use lifecycle hooks around automation runs:
- job or trigger pre-fire hooks can rewrite the prompt
- pre-fire hooks can cancel the run, which records the run as
canceled - run-failed hooks receive retry metadata, including whether AGH will retry
Hooks are part of the same runtime flow, so cancellation and prompt changes are visible in run history.
Monitoring trigger runs
Read trigger-specific history:
agh automation triggers history <trigger-id> --last 20Read all recent automation runs for a status:
agh automation runs --status failed --last 20Query the API:
curl -sS "http://localhost:2123/api/automation/triggers/<trigger-id>/runs?limit=20"Run statuses are the same statuses documented for jobs: scheduled, running, delegated,
completed, failed, and canceled.