Reference
Trigger schema
A trigger is a record in the agent's agent_triggers dataset: a program, a schedule or event that fires it, and a device pin that says which of your devices runs it. The dataset is the source of truth — every running device converges its in-memory registry on these records every tick, so creating a trigger is one write, and editing one is another.
agent_trigger fields
| Field | Type | Meaning |
|---|---|---|
name |
string | display name |
kind |
cron | event | once |
what fires it |
spec |
per kind (below) | |
program |
string | program spec, e.g. agent:rollup@v1 |
args |
object | passed to main |
owner |
string | device pin — the peer id of the device that runs this trigger; empty = floating (the election winner runs it) |
enabled |
bool | |
logRuns |
bool | keep trigger_runs records |
limits |
{fuelPerRun?, timeoutS?, maxCostPerRun?} |
per-run budgets, enforced by the executor and the llm effect |
maxConsecutiveFailures |
number (default 3) | circuit breaker threshold |
lastRunAt / lastDurationMs / lastStatus / runCount / lastRunRef |
rollup | observability, written by the owning device |
lastFuel / lastCostUsd / lastMemPages / avgDurationMs / failureRate |
rollup | aggregated resource stats computed from the retained runs window |
spec by kind
| Kind | Spec | Fires when |
|---|---|---|
cron |
a cron expression string | the next occurrence, armed strictly forward — a missed occurrence does not exist |
once |
{"at": <epoch seconds>} |
now >= at and it has never run (lastRunAt empty); a past at fires late on the next tick, then the trigger auto-disables |
event |
{"dataset": "chat_messages", "objectId": "<chat>", "filter"?} |
a new message lands in that chat; the program receives args ∪ {"event": {space, objectId, messageId, text, agent?}}. chat_messages is the one supported source; other datasets are stamped unsupported_source. filter is reserved |
Event triggers are live-only, like cron: a message that arrives while the owner is down does not fire later. Self-authored messages (the agent's own name) never fire.
# create a reminder — one record write
curl -X POST http://127.0.0.1:7001/v1/spaces/$BAO/modify -d '{
"objectId": "'$TRIGGER_ANCHOR'", "dataset": "agent_triggers",
"records": [{"id": "remind-standup", "upsert": true, "ops": [{"type": "$set", "path": "", "value": {
"name": "Standup reminder", "kind": "once", "spec": {"at": 1787000000},
"program": "agent:remind@v1", "args": {"text": "standup in 5"}, "enabled": true, "logRuns": true }}]}]}'
Lifecycle rules
- Adopt — a record pinned to this device, or (on the election-active device) an unowned record, which gets this device's peer id stamped and persisted.
- Refresh — an edit to the definition core (
kind,spec,program,args,name,limits,maxConsecutiveFailures) rebuilds the entry: crons re-arm forward; aoncetakes the record'slastRunAtas its consumed state, so rewriting the definition re-arms the shot.enablededits apply in place; afalse → trueflip resets the breaker and re-arms forward. - Evict — a record repinned to another device, or deleted, leaves the registry within a tick. Deleted ids stay tombstoned; recreating a trigger means a new id.
- Repin — write
owner; the old device evicts, the new one adopts on its next tick. An offline pinned device simply does not fire. Clearingownerfloats the trigger back to the election winner. - Circuit breaker — after
maxConsecutiveFailuresconsecutive failures the trigger auto-disables withlastStatus: "auto_disabled"; re-enable is manual. - Health markers — an enabled trigger that can never fire gets
lastStatusstampedinvalid_spec(cron with no next occurrence,oncewithout a numericat) orunsupported_source; markers self-clear when fixed and are overwritten by the first real run. - Chat responder — boot seeds one reserved record
chat-watch(kind: eventon the general chat,program: internal:chat-watch, floating). Disabling it stops the agent answering chat everywhere; pinning it moves where it answers. Dispatch is native, not a program run.
trigger_runs
One record per fire, on the trigger object, keep-last-N:
| Field | Meaning |
|---|---|
ts |
start time |
durationMs |
|
status |
ok | failed | … |
error |
present on failure |
traceRef |
the run id; inline for small traces, a file attachment for large ones |
fuel / costUsd / tokens / memPages |
metrics extracted from the trace at write time |
Read them through POST /v1/spaces/:id/query with dataset: "agent_trigger_runs", filter: {"triggerId": "<id>"}, sort: ["-ts"].
Control-plane routes
The anyrt serve control API (127.0.0.1:7010 by default) exposes the registry as a monitoring surface. Mutating routes write through to the dataset record.
| Method | Path | Body | Returns |
|---|---|---|---|
| GET | /triggers |
— | every entry: definition + owner + enabled + rollup + resource stats |
| GET | /triggers/:id |
— | one record |
| GET | /triggers/:id/runs |
— | last 20 runs, newest first |
| PATCH | /triggers/:id |
{spec?, enabled?} |
updated record; a new spec re-arms forward |
| POST | /triggers/:id/enable |
— | record; resets the breaker |
| POST | /triggers/:id/disable |
— | record |
curl -s http://127.0.0.1:7010/triggers | jq '.[] | {id, kind, owner, enabled, lastStatus}'
curl -X POST http://127.0.0.1:7010/triggers/remind-standup/disable
Note. The trigger type is a plain user-created type; the invariants above are enforced by the runtime, not by a server handler. Guides: Cron, Once, Event triggers, Device pins, Runs and monitoring.