Trigger agents from GitHub, Stripe, Slack, or any custom webhook
Bind a reasoner to an external event source. The control plane verifies the signature, drops replays, and dispatches the event to your reasoner.
Bind a reasoner to an external event source and the control plane handles the rest — webhook URL provisioning, signature verification, replay protection, and dispatch. Same pattern works for cron schedules and any custom HMAC- or Bearer-secured webhook.
from agentfield import Agent, EventTrigger, TriggerContext, on_event, on_schedule
app = Agent(node_id="ops-agent")
# GitHub: fire on pull_request events
@app.reasoner()
@on_event(
source="github",
types=["pull_request"],
secret_env="GITHUB_WEBHOOK_SECRET", # secret lives on the control plane
)
async def on_pr(event: dict, trigger: TriggerContext | None = None):
pr = event["pull_request"]
return {
"action": event["action"],
"title": pr["title"],
"delivery_id": trigger.idempotency_key if trigger else None,
}
# Stripe: fire on successful payments, with a transform that flattens the envelope
def _flatten(evt: dict) -> dict:
obj = evt.get("data", {}).get("object", {})
return {"id": obj.get("id"), "amount": obj.get("amount"), "customer": obj.get("customer")}
@app.reasoner(triggers=[
EventTrigger(
source="stripe",
types=["payment_intent.succeeded"],
secret_env="STRIPE_WEBHOOK_SECRET",
transform=_flatten,
),
])
async def on_payment(payment: dict, trigger: TriggerContext | None = None):
return {"stripe_id": payment["id"], "amount": payment["amount"]}
# Custom webhook with HMAC signing
@app.reasoner()
@on_event(source="generic_hmac", secret_env="MY_WEBHOOK_SECRET")
async def on_custom(payload: dict, trigger: TriggerContext | None = None):
return {"event_type": trigger.event_type, "payload": payload}
# Cron: fire every five minutes
@app.reasoner()
@on_schedule("*/5 * * * *")
async def heartbeat(_input, trigger: TriggerContext | None = None):
return {"fired_at": trigger.received_at.isoformat()}
app.run()When the agent registers, the control plane provisions one public webhook URL per trigger and prints them. Paste them into the provider dashboard.
The triggers are visible in the control plane UI under Triggers → Active, with their source, target reasoner, event filter, and last-fired time:
The full integration catalog lives under Triggers → Integrations:
Built-in sources
stripe, github, slack, linear, sentry, hubspot, calendly, pagerduty, generic_hmac, generic_bearer, plus cron for schedules. Each verifies signatures and rejects replays before your reasoner runs.
What this gives you
- One decorator binds an agent to any provider — no glue code, no signature plumbing.
- Replay protection and idempotency keys come from the source plugin, not from you.
- Same dispatch path as direct calls, so triggered runs show up in the workflow DAG.
Next
Multi-step human approval that survives restarts
Pause execution mid-run for a human decision. State persists in PostgreSQL, so a crashed server resumes exactly where it left off.
Orchestrate Claude Code, Codex, and Gemini alongside your agents
Dispatch a task to a coding agent — Claude Code, Codex, Gemini CLI, or OpenCode — and get back schema-validated output with cost and turn caps.