Files
hermes-agent/website/docs/user-guide/messaging/webhooks.md
Teknium 3aeb1736c5 Port from RooCodeInc/Roomote#1478: per-route webhook event coalescing
Rapid distinct events on the same logical entity (five pushes to one PR,
a burst of ticket edits, a flapping alert) each carry a fresh delivery ID,
so the idempotency cache cannot suppress them and every event wakes a
separate agent run. Roomote solved this for PR review tasks by keeping one
durable review task per PR and superseding stale heads; this ports the
same debounce-and-supersede pattern to the generic webhook adapter.

New opt-in per-route 'coalesce' block: events group by a payload-derived
key, each new event replaces the pending one and re-arms a quiet-window
timer (window_seconds, default 30), bounded by max_wait_seconds (default
300) past the group's first event so a steady stream cannot starve
dispatch. The settled group dispatches ONE agent run on the latest
event's payload/prompt/delivery templates, with a note when earlier
events were superseded. Pending groups flush on disconnect. Startup
validation rejects missing keys, non-positive windows, and the
deliver_only+coalesce combination.

Rebase onto the decomposed webhook adapter (salvage, #92066):
- Coalescing lives in a topical sibling, gateway/platforms/webhook_coalesce.py
  (WebhookCoalescer + validate_coalesce_config); webhook.py only wires it in
  (__init__, _validate_route, disconnect, _handle_webhook) and splits main's
  _dispatch_agent_run into the HTTP-response wrapper plus _spawn_agent_run,
  shared by the immediate and coalesced paths.
- Review finding (unresolved key fields collapsed unrelated entities into one
  group): an event whose rendered key still contains a {placeholder} is now
  dispatched immediately instead of coalesced; documented.
- Review finding (flush-on-disconnect vs process exit): disconnect() awaits
  the handoff of flushed runs; the docs claim is scoped to adapter disconnect
  and states that a hard kill loses the current window's buffer.
- cron_job + coalesce is rejected like deliver_only + coalesce (cron_job
  landed on main after the PR branched).
- Tests trimmed from 17 to 4 (validation parametrized; debounce/supersede/
  independent groups/duplicate-first in one behavioural test; max-wait +
  unresolved-key; flush-on-disconnect).
2026-09-15 04:08:12 -07:00

33 KiB

sidebar_position, title, description
sidebar_position title description
13 Webhooks Receive events from GitHub, GitLab, and other services to trigger Hermes agent runs

Webhooks

Receive events from external services (GitHub, GitLab, JIRA, Stripe, etc.) and trigger Hermes agent runs automatically. The webhook adapter runs an HTTP server that accepts POST requests, validates HMAC signatures, transforms payloads into agent prompts, and routes responses back to the source or to another configured platform.

The agent processes the event and can respond by posting comments on PRs, sending messages to Telegram/Discord, or logging the result.

Video Tutorial