Skip to content

feat(plugins): add pre_gateway_dispatch hook - #15050

Merged
teknium1 merged 3 commits into
mainfrom
hermes/hermes-d72add2b
Apr 24, 2026
Merged

feat(plugins): add pre_gateway_dispatch hook#15050
teknium1 merged 3 commits into
mainfrom
hermes/hermes-d72add2b

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvage of #13445 onto current main.

Adds pre_gateway_dispatch plugin hook fired in GatewayRunner._handle_message after the internal-event guard, before auth/pairing. Plugins return a dict to influence flow:

  • {"action": "skip", "reason": ...} — drop (no reply, plugin handled)
  • {"action": "rewrite", "text": ...} — replace event.text, continue normally
  • {"action": "allow"} / None — normal dispatch

Consumer plugin exists out-of-tree: https://github.com/pebble-tech/hermes-plugin-gateway-policy (listen-only windows, human handover).

Changes

  • hermes_cli/plugins.py — add pre_gateway_dispatch to VALID_HOOKS + inline doc
  • gateway/run.py — invoke hook in _handle_message (before auth, skips internal events), dispatch skip/rewrite/allow actions
  • tests/gateway/test_pre_gateway_dispatch.py — 5 tests (skip, rewrite, allow, exception safety, internal-event bypass)
  • tests/hermes_cli/test_plugins.py — 2 tests (registration, action-dict collection)
  • website/docs/user-guide/features/{hooks,plugins}.md — docs
  • scripts/release.py — AUTHOR_MAP entry for @keiravoss94

Validation

scripts/run_tests.sh tests/gateway/test_pre_gateway_dispatch.py tests/hermes_cli/test_plugins.py: 63/63 passed. E2E verified hook is in VALID_HOOKS + dataclasses.replace(event, text=...) preserves source fields.

Original PR #13445 by @keiravoss94, commits cherry-picked with authorship preserved.

keiravoss94 and others added 3 commits April 24, 2026 03:01
Introduces a new plugin hook `pre_gateway_dispatch` fired once per
incoming MessageEvent in `_handle_message`, after the internal-event
guard but before the auth / pairing chain. Plugins may return a dict
to influence flow:

    {"action": "skip",    "reason": "..."}  -> drop (no reply)
    {"action": "rewrite", "text":   "..."}  -> replace event.text
    {"action": "allow"}  /  None             -> normal dispatch

Motivation: gateway-level message-flow patterns that don't fit cleanly
into any single adapter — e.g. listen-only group-chat windows (buffer
ambient messages, collapse on @mention), or human-handover silent
ingest (record messages while an owner handles the chat manually).
Today these require forking core; with this hook they can live in a
single profile-agnostic plugin.

Hook runs BEFORE auth so plugins can handle unauthorized senders
(e.g. customer-service handover ingest) without triggering the
pairing-code flow. Exceptions in plugin callbacks are caught and
logged; the first non-None action dict wins, remaining results are
ignored.

Includes:
- `VALID_HOOKS` entry + inline doc in `hermes_cli/plugins.py`
- Invocation block in `gateway/run.py::_handle_message`
- 5 new tests in `tests/gateway/test_pre_gateway_dispatch.py`
  (skip, rewrite, allow, exception safety, internal-event bypass)
- 2 additional tests in `tests/hermes_cli/test_plugins.py`
- Table entry in `website/docs/user-guide/features/plugins.md`

Made-with: Cursor
… section

Follow-up to aeff6dfe:

- Fix semantic error in VALID_HOOKS inline comment ("after core auth" ->
  "before auth"). Hook intentionally runs BEFORE auth so plugins can
  handle unauthorized senders without triggering the pairing flow.
- Fix wrong class name in the same comment (HermesGateway ->
  GatewayRunner, matching gateway/run.py).
- Add a full ### pre_gateway_dispatch section in
  website/docs/user-guide/features/hooks.md (matches the pattern of
  every other plugin hook: signature, params table, fires-where,
  return-value table, use cases, two worked examples) plus a row in
  the quick-reference table.
- Add the anchor link on the plugins.md table row so it matches the
  other hook entries.

No code behavior change.
@teknium1
teknium1 merged commit 5fdba79 into main Apr 24, 2026
9 of 11 checks passed
@teknium1
teknium1 deleted the hermes/hermes-d72add2b branch April 24, 2026 10:02
@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/plugins Plugin system and bundled plugins comp/gateway Gateway runner, session dispatch, delivery labels Apr 24, 2026
github-actions Bot pushed a commit to pebble-tech/hermes-agent that referenced this pull request Apr 27, 2026
This is the sole commit on ops-overlay. It carries:

  - .github/workflows/sync-upstream.yml: daily rebase + rebuild of main
    on top of upstream/main + ops-overlay + each feature branch.
  - FORK.md: branch layout, sync model, recovery procedure.

Steady state (2026-04-26 onward): both feature branches we used to
carry have merged upstream (PRs NousResearch#13445 and NousResearch#14904 via NousResearch#15050 and
NousResearch#15191). FEATURE_BRANCHES is now empty; main collapses to
upstream/main + ops-overlay. The fork stays alive so customer VPSes
have a stable deploy target rebuilt on our schedule.
github-actions Bot pushed a commit to pebble-tech/hermes-agent that referenced this pull request Apr 30, 2026
This is the sole commit on ops-overlay. It carries:

  - .github/workflows/sync-upstream.yml: daily rebase + rebuild of main
    on top of upstream/main + ops-overlay + each feature branch.
  - FORK.md: branch layout, sync model, recovery procedure.

Steady state (2026-04-26 onward): both feature branches we used to
carry have merged upstream (PRs NousResearch#13445 and NousResearch#14904 via NousResearch#15050 and
NousResearch#15191). FEATURE_BRANCHES is now empty; main collapses to
upstream/main + ops-overlay. The fork stays alive so customer VPSes
have a stable deploy target rebuilt on our schedule.
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 comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants