Garudust's agent core exposes a single base primitive: agent.run(task). Every entry point — a chat message, a cron job, a webhook call — eventually resolves to that same call. This means any external system that can send an HTTP POST can act as an event trigger.
This article covers how that works today, the patterns that hold up in production, and concrete use cases.
How the Webhook Adapter Works
When Garudust is configured with the webhook platform, it starts an Axum HTTP server and registers a POST endpoint at a path you configure. An inbound request looks like this:
{
"text": "A new billing invoice has arrived from Acme Corp for $4,200.",
"callback_url": "https://your-system.example.com/garudust/reply",
"user_id": "billing-watcher",
"session_key": "billing-acme-corp"
}
| Field | Required | Notes |
|---|---|---|
text |
✅ | The task prompt the agent will run |
callback_url |
✅ | Where Garudust POSTs the agent's reply |
user_id |
optional | Used for role-based access control |
session_key |
optional | Pins conversation history; defaults to webhook:{callback_url}
|
Garudust wraps this into an InboundMessage, passes it through GatewayHandler, spawns agent.run(), and when the agent finishes it POSTs the reply back to callback_url:
{
"text": "Invoice from Acme Corp for $4,200 — categorised as SaaS/Infrastructure. Flagged for approval above $3,000 threshold. Draft approval request sent to #finance."
}
The HTTP response to your POST is 202 Accepted immediately — the agent runs asynchronously.
Security
Garudust verifies an HMAC-SHA256 signature on every inbound request. Set a shared secret in your config, and sign every outbound POST with:
X-Hub-Signature-256: sha256=<hex(HMAC-SHA256(secret, raw_body))>
Requests without a valid signature are rejected with 401. Private IP callback URLs (192.168.x.x, 10.x.x.x, localhost) are also blocked by the network guard — the agent cannot be made to call back to internal infrastructure.
The Core Pattern
The separation of concerns is explicit:
External system Garudust
───────────────── ──────────────────────────
Event source (email, → Webhook adapter
calendar, DB, queue)
Filter / match logic → Your code (pre-POST)
Task description → agent.run(task)
Result handling → Your callback_url handler
Your system owns the filter. Garudust owns the agent execution. Neither needs to know the other's internal structure.
Use Cases
1. Billing Email Monitor
An email processing service watches your inbox for messages from known billing senders. When one matches, it extracts the subject, sender, and amount, then triggers Garudust:
{
"text": "New invoice received: Stripe — $1,840 for May 2026. Attach to this month's expense report and notify the finance channel if it exceeds the $1,500 alert threshold.",
"callback_url": "https://your-ops.example.com/hooks/garudust",
"session_key": "finance-inbox"
}
The agent uses its tools to read the expense report file, append the line item, and post to Slack. Your email service only had to match sender and fire — it did not need to know anything about expense reports or Slack.
2. GitHub PR Review Gate
A GitHub Actions workflow calls Garudust after a PR is opened against main. The workflow builds the payload from the GitHub context:
{
"text": "PR #214 opened by @alice: 'feat: add OAuth2 PKCE flow'. Changed files: src/auth/oauth.rs, src/auth/pkce.rs, tests/auth_integration.rs. Diff summary attached. Review for security issues in the auth flow and post a summary comment.",
"callback_url": "https://your-ci.example.com/garudust/pr-review",
"session_key": "pr-214"
}
GitHub's webhook fires the workflow; the workflow builds the task text; Garudust runs the review. The session_key is tied to the PR number so follow-up triggers (new commits, re-review requests) continue the same conversation thread.
3. Database Anomaly Alert
A monitoring job queries your database on a schedule and checks aggregate metrics. When a metric crosses a threshold, it fires Garudust instead of just sending a static alert:
{
"text": "Anomaly detected: orders table insert rate dropped 94% in the last 10 minutes (baseline 340/min, current 19/min). Last successful insert: 09:42 UTC. Investigate root cause and summarise for on-call.",
"callback_url": "https://ops.example.com/garudust/incidents",
"session_key": "incident-2026-05-23-orders"
}
The agent can use its terminal or database tools to run follow-up queries, check recent deploys, and produce a structured incident summary — the monitoring job only needed to detect the threshold breach.
4. Calendar External-Attendee Watch
An integration layer polls Google Calendar (or receives push notifications) and fires Garudust when an event is created with an attendee whose domain does not match your organisation:
{
"text": "New calendar event: 'Q3 partnership discussion' on 2026-06-04 14:00 UTC. External attendees: jane@partner.com, bob@partner.com. Prepare a one-page briefing on Partner Corp using the CRM notes and recent email thread.",
"callback_url": "https://your-system.example.com/garudust/calendar",
"session_key": "meeting-prep-2026-06-04"
}
The calendar integration owns the "external attendee" filter logic. Garudust owns the briefing generation.
5. Queue Worker Trigger
A background worker drains a task queue (SQS, Redis, RabbitMQ) and dispatches each item to Garudust. This is useful for workloads where volume is variable and you want the agent to handle each item at its own pace:
{
"text": "Customer support ticket #8821 (priority: high): User reports that export to CSV silently truncates rows above 10,000. Reproduce the scenario, identify the code path responsible, and draft a fix description for the engineering team.",
"callback_url": "https://support.example.com/garudust/tickets",
"session_key": "ticket-8821"
}
The queue worker dequeues, formats the task text, fires the webhook. Multiple tickets run as concurrent agent sessions.
Session Keys and Continuity
session_key is what makes event triggers useful beyond one-shot tasks. When you pin a key, all webhook calls with that key share the same conversation history. This means:
- A PR review trigger on commit 1 and a re-review trigger on commit 2 are the same conversation — the agent remembers what it said before.
- An incident trigger and a follow-up "what's the status?" call from your on-call engineer share context.
- A billing session can accumulate all invoices for the month across multiple triggers before generating the monthly summary.
If you want complete isolation (each event is independent), omit session_key — Garudust will key the session to the callback_url, giving you a fresh context per unique callback target.
What This Pattern Does Not Cover
The webhook adapter is a push target — your external system must initiate the call. If you need Garudust to pull from a source (check an inbox, poll an API, watch a file) on its own without a scheduler, that requires either a cron job that polls, or a future watch/filter primitive that does not exist yet.
For use cases that are genuinely push-based (GitHub webhooks, queue workers, calendar push notifications, email routing services), the current architecture is sufficient and the separation of concerns is clean.
Top comments (0)