Repository navigation
fix(hermes): port two post-handoff fixes and floor the deps at 0.10.1 - #4655
Merged
Merged
Conversation
Closes #4640. Two fixes landed on hermes-agent's bundled copy after the 2026-09-17 handoff and never reached this tree. Users moved onto our copy by the catalog migration would have regressed on both. - Bounded append-mode turn buffer (hermes-agent 6e1de4850e6, their #62950). sync_turn now clears _session_turns after an append retain instead of moving the watermark to its length. The retain job snapshots its own content and append retains only ever read the un-retained tail, so keeping the turns pinned the whole session in memory on long-running gateway sessions. Overwrite mode is untouched — it resends the full session each retain and must keep every turn. This also removes a duplicate write: on_session_switch flushes the WHOLE buffer under the old document id, so after an append retain it re-shipped turns that had already been stored. test_session_switch_starts_a_new_document was pinning that second retain; it now expects one per session. - Gated root warning (hermes-agent cd3de040ab9). initialize() records warning_callback/platform and _start_embedded_daemon routes the "cannot run as root" notice through the host's sink, falling back to gateway.warning_notifications.render_notification, instead of an unconditional stderr print. That is what lets users opt out of user-channel warnings on messaging platforms. Also drops the `hooks:` key from plugin.yaml. Hermes reads `provides_hooks`, and the bundled copy dropped the declaration in 72ee40fa680 because memory providers get their lifecycle calls through the provider interface, not registered hooks. Separately, floors the declared deps at >=0.10.1. hindsight-embed 0.10.0 (on PyPI 2026-09-14 to 2026-09-21) shipped a probe that ran asyncio.run on the caller's thread, clearing its event loop, so the next client call hit an aiohttp session bound to a dead loop and local_embedded failed outright. Anyone who installed in that window is pinned to the broken release until a floor moves them off it; _MIN_CLIENT_VERSION moves with it so _maybe_upgrade_client() pulls the client forward on session start rather than waiting for a `hermes update`. Both behaviour fixes have a regression test, each verified to fail on the pre-fix code.
teknium authored the real entry in NousResearch/hermes-agent#119767, so plugin-catalog-entry.yaml is a second copy of a file we do not own and would silently drift from the one that actually ships. The README now points at theirs and states the consequence that matters: changes here reach nobody until that pin moves.
__init__ now guarantees _warning_callback/_platform, so the getattr fallbacks carried over from the upstream port were dead defensiveness. Reading the attributes directly makes the __init__ defaults load-bearing, so a test pins them: availability probes construct a provider without ever calling initialize(), and _start_embedded_daemon reads both.
nicoloboschi
added a commit
that referenced
this pull request
Sep 23, 2026
The catalog entry carries a `version` label alongside its pinned sha, and the pin is about to move to the post-handoff fixes (#4655). Bump the manifest so that label is truthful rather than advertising 1.0.1 against a plugin that still calls itself 1.0.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4640.
The two fixes teknium flagged
Both landed on hermes-agent's bundled
plugins/memory/hindsightafter the 2026-09-17 handoff and never reached this tree. Users moved onto our copy by the catalog migration would have regressed on them.1. Bounded append-mode turn buffer (hermes-agent
6e1de4850e6, their #62950)sync_turnnow clears_session_turnsafter an append retain instead of advancing the watermark to its length. The retain job snapshots its own content and append retains only ever read the un-retained tail, so keeping every turn pinned the whole session in memory on long-running gateway sessions. Overwrite mode is untouched — it resends the full session each retain and must keep every turn.This also removes a duplicate write I hit while testing:
on_session_switchflushes the whole buffer under the old document id, so after an append retain it re-shipped turns that were already stored.test_session_switch_starts_a_new_documentwas pinning that second retain (["session-1", "session-1", "session-2"]); it now expects one retain per session.2. Gated root warning (hermes-agent
cd3de040ab9)initialize()recordswarning_callback/platform, and_start_embedded_daemonroutes the "cannot run as root" notice through the host's sink, falling back togateway.warning_notifications.render_notification, instead of an unconditional stderr print. That's what lets users opt out of user-channel warnings on messaging platforms.Nit: dropped the
hooks:key fromplugin.yaml— Hermes readsprovides_hooks, and the bundled copy dropped the declaration in72ee40fa680because memory providers get lifecycle calls through the provider interface, not registered hooks.Dependency floor → 0.10.1
hindsight-embed0.10.0 (on PyPI 2026-09-14 → 2026-09-21) shipped a probe that ranasyncio.runon the caller's thread, clearing its event loop, so the next client call hit an aiohttp session bound to a dead loop andlocal_embeddedfailed outright withTimeout context manager should be used inside a task. Fixed in 0.10.1.I confirmed this against the published wheels, not just the source:
probe_getget_running_loop()/asyncio.run(probe())fast pathAnyone who installed in that window is pinned to the broken release, because
>=0.6.1,<1is satisfied by 0.10.0 and nothing moves them. Floors inpyproject.tomlandplugin.yamlnow sit at>=0.10.1, and_MIN_CLIENT_VERSIONmoves with them so_maybe_upgrade_client()pulls the client forward on session start rather than waiting for ahermes update.Tests
Two regression tests, each verified to fail on the pre-fix code (I reverted each fix and watched the test go red):
test_append_mode_drops_retained_turns_from_the_buffer— buffer empty, watermark 0, each retain carries only its own deltatest_overwrite_mode_keeps_every_turn— the other half of the branch, so nobody "simplifies" the clear into both pathstest_root_warning_goes_through_the_hosts_warning_callback— callback receives it, stderr does not24 pass, lint clean.
After merge
This needs a SHA bump in
plugin-catalog/hindsight.yaml(sha+versiontogether) for any of it to reach users — the catalog currently pinsdc75038.