Hermes Agent

Hermes gives plugins ownership, events and streaming hooks

Hermes proposes a profile-isolated plugin ownership ledger, a declared inter-plugin event bus and streaming-output observer hooks. Together the records turn plugins from loose callbacks into supervised components with named resources, lifecycle boundaries and observable message flow.

← Back to homeOriginal source ↗

NousResearch/hermes-agent PR #84923 is the inspected primary source: “feat(plugins): ownership ledger, on_unload, supervised tasks — profile-isolated.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- NousResearch/hermes-agent PR #84923 was created 2026-08-13T00:51:18Z and was open at inspection; its title is “feat(plugins): ownership ledger, on_unload, supervised tasks — profile-isolated.” - NousResearch/hermes-agent PR #84932 was created 2026-08-13T01:00:20Z and was open at inspection; its title is “feat(plugins): inter-plugin event bus with declared emits/listens.” - NousResearch/hermes-agent PR #84924 was created 2026-08-13T00:52:54Z and was open at inspection; its title is “feat(plugins): streaming output observer hooks — deltas, interim messages, lifecycle.” - The repository reported 229581 stars, 31523 open issues, default branch main, and last push 2026-08-13T01:03:02Z. - The latest tagged-release baseline checked was v2026.8.3 published 2026-08-03T16:57:52Z.

What changed

NousResearch/hermes-agent PR #84923 reports: Summary Every plugin registration is now recorded in a per-plugin, profile-isolated ownership ledger, with on_unload teardown and supervised background tasks — the Phase-0 structural prerequisite for #64178's symmetric force-reload (sub-issue #64229, tracker #64182). Salvages PR #76490 (@doncazper) with authorship preserved. Changes Ownership ledger in hermes_cli/plugins.py: every ctx.register_* records plugin id → handle across 18 registration surfaces (tools, platforms, hooks, middleware, CLI/slash commands, context engine, image/video/web-search/browser/TTS/transcription providers, dashboard auth, secret sources, auxiliary tasks, skills, slack actions, tool override policy — plus the new prompt sections and approval transports, widened in salvage) on_unload lifecycle callback + ctx.spawn_task supervised background tasks, cancelled on unload Profile isolation: scope-keyed registries (tools/platform overlays, profile-scoped secret sources) so one profile's unload never clears another's — the #65593 constraint, implemented not just documented (includes @terry197913's keyed plugin-manager cache fix, cherry-picked with credit) Validation | | Result | |---|---| | Tests | PR suite + tests/hermes_cli/test_plugins*.py green in fresh venv | | Widening | prompt sections + approval transports (this wave's new registries) ledgered with dedicated tests | | Lint | ruff clean |

NousResearch/hermes-agent PR #84932 reports: Summary Plugins can now react to each other: an inter-plugin event bus with manifest-declared emits/listens contracts, bounded delivery, and owner-tagged subscriptions (sub-issue #64164, tracker #64182 — blockcipher's reactivity ask). Salvages PR #66085 (@hansai-art) with authorship preserved. Changes hermes_cli/plugins.py: emits/listens manifest declarations; ctx.emit_event() / subscription registration; event names validated against declarations All three round-2 corrections implemented: Bounded delivery — 64-event queue cap, per-worker chain depth cap 8, over-cap emits dropped with warning Payload copy semantics — copy.deepcopy per dispatch envelope; emitters cannot mutate listeners' view Unload cleanup — owner-tagged _EventSubscription entries + _remove_plugin_subscriptions() wired into failed-load cleanup and generation reset, with a TODO(#64229) seam for ledger routing once #84923 lands plugins_cmd/subcommands: PR's show subcommand kept alongside main's doctor Validation | | Result | |---|---| | Tests | 146 passed (test_plugin_event_bus.py + test_plugins*.py) | | Lint | ruff clean | Infographic inter-plugin event bus

NousResearch/hermes-agent PR #84924 reports: Summary Plugins can now watch streamed model output live — on_stream_start / on_stream_delta / on_stream_end / on_interim_message observer hooks, delivered through a host-owned bounded queue so plugin callbacks never run inline on the token path (sub-issue #64161, tracker #64182). Salvages PR #64317 (@deaneeth) with authorship preserved. Changes run_agent.py: stream lifecycle emitters (_stream_hook_base_payload / _emit_stream_start / _emit_stream_end), interim-message observation integrated with main's Codex interim-commentary extraction (#65919) and single-writer stream fencing (#65991) hermes_cli/plugins.py: 4 new VALID_HOOKS entries + iter_hook_callbacks, coexisting with the prompt-sections registry Bounded delivery contract per the round-2 correction: host-owned queue, one worker per callback, full-drain semantics; reasoning deltas opt-in via plugins.stream_reasoning_deltas Docs: hooks.md catalog rows in the shipped 5-column format Validation | | Result | |---|---| | PR + plugin suites | 129 passed (test_plugin_stream_hooks.py + test_plugins*.py) | | Adjacent streaming suites | all pass (streaming, single-writer #65991, drop logging, interrupt retry, stale-breaker, multimodal interim #66267) | | Lint | ruff clean | Hyper's TTS-pipe ask from the original thread; observer-only v1 per ground rule 3. Infographic streaming observer hooks

Why it matters

Extensibility becomes an operations problem when plugins spawn tasks, subscribe to events or inspect streaming output. Without ownership and unload semantics, one profile can leak work or state into another. The operator test is whether visible output, retained state and authority still describe the same event after retries, background work or restart.

Current

The primary record was open when captured on 2026-08-13. The tagged-release baseline was v2026.8.3 published 2026-08-03T16:57:52Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/NousResearch/hermes-agent/pull/84923. Supporting records are https://github.com/NousResearch/hermes-agent/pull/84932 and https://github.com/NousResearch/hermes-agent/pull/84924. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Require declared event contracts, cancel supervised tasks on unload, and expose which plugin owns every hook, background task and emitted event. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.