Skip to content

fix(webhook): filter route actions before agent dispatch - #21744

Closed
nettee wants to merge 1 commit into
NousResearch:mainfrom
nettee:fix-webhook-action-filter
Closed

fix(webhook): filter route actions before agent dispatch#21744
nettee wants to merge 1 commit into
NousResearch:mainfrom
nettee:fix-webhook-action-filter

Conversation

@nettee

@nettee nettee commented May 8, 2026

Copy link
Copy Markdown

What does this PR do?

Adds route-level actions filtering for webhook routes so providers such as GitHub can be filtered by payload action before the agent runs.

This fixes cases where a route accepts a broad event type such as pull_request, then still dispatches agents for non-actionable sub-actions like synchronize, closed, or labeled. With this change, routes can opt into action filtering:

events: [pull_request]
actions: [opened]

A non-matching action now returns an ignored response and skips agent dispatch:

{"status":"ignored","event":"pull_request","action":"synchronize"}

Related Issue

No linked issue.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • gateway/platforms/webhook.py
    • Adds optional route config key actions.
    • Checks payload["action"] after event filtering and before prompt rendering / agent dispatch.
    • Returns status=ignored with the event and action when the action does not match.
  • tests/gateway/test_webhook_adapter.py
    • Adds coverage for rejected non-matching actions.
    • Adds coverage for accepted matching actions.
  • website/docs/guides/webhook-github-pr-review.md
    • Documents the new actions route field.
    • Updates the action-filtering section to explain ignore-before-agent behavior.

How to Test

  1. Configure a webhook route with:
    events: [pull_request]
    actions: [opened]
  2. Send a pull_request payload with action: synchronize.
  3. Verify Hermes returns:
    {"status":"ignored","event":"pull_request","action":"synchronize"}
  4. Send a pull_request payload with action: opened.
  5. Verify Hermes accepts the delivery and dispatches the agent.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS (Darwin arm64)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

Targeted test run:

$ /Users/william/.hermes/hermes-agent/venv/bin/python -m pytest tests/gateway/test_webhook_adapter.py -q
bringing up nodes...
bringing up nodes...

........................................................                 [100%]
56 passed in 1.93s

Manual verification from a local Hermes gateway:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"status":"ignored","event":"pull_request","action":"synchronize"}

A real GitHub pull_request/synchronize delivery returned 200 after this change, where the same route previously returned 202 and dispatched the agent.

@alt-glitch alt-glitch added type/feature New feature or request platform/webhook Webhook / API server comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have labels May 8, 2026
@cwest

cwest commented Jun 19, 2026

Copy link
Copy Markdown

Works for what I needed. One edge case though: if allowed_actions and payload_action not in allowed_actions also drops a delivery whose payload has no action field, since None not in [...] is true. pull_request always carries an action, but actions is a generic route key, so a route that mixes pull_request with an action-less event like push or ping would silently drop those once an allow-list is set. A truthiness check fails open:

if allowed_actions and payload_action and payload_action not in allowed_actions:

Might be worth a test that posts an action-less payload to an actions-filtered route, to pin whichever behavior you intend.

@teknium1

teknium1 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for this PR — webhook payload filtering has now landed on main via #60944 (salvage of @evelynburger's #57544), which generalizes this: route-level payload filters (equals/not_equals/contains/exists/... on payload fields, event type, and headers) plus optional route scripts for transform/narrow logic, wired through hermes webhook subscribe --filter/--script and config.yaml. Your use case should be covered by the generic filter syntax; if something specific is missing, please open a fresh issue against the new mechanism. Closing as superseded — appreciate the earlier push in this direction.

@teknium1 teknium1 closed this Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have platform/webhook Webhook / API server type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants