HY Memory provider plugin for Hermes Agent (native, 100% passive injection)
Project description
HY Memory Provider for Hermes
A native Memory Provider plugin for Hermes Agent — first-class, 100% passive injection.
How it works
Hermes calls prefetch(query) before every LLM turn. This provider:
- searches HY Memory with the query (chat path, three-channel recall),
- formats the hits by layer (
§ [profile]/§ [intent]/§), - lets Hermes inject that block into the system prompt.
Once installed, memory works automatically — no per-turn user action; recall and capture are passive.
At the end of each turn Hermes calls sync_turn(user, assistant). To save tokens and avoid duplicate extraction, the provider buffers turns and writes once every HY_MEMORY_WRITE_TURN_WINDOW turns (default 5) as a single batched, asynchronous write — so the main loop is never blocked. A partial tail (fewer than N turns, e.g. a session that ends after 3 turns) is always flushed on session end / pre-compress / shutdown, so no turns are lost.
Install
Two names, don't confuse them:
hermes-hy-memory— the PyPI package youpip install.hy-memory— the provider name Hermes activates it under (set inconfig.yaml).The SDK package
hy-memoryis on public PyPI — a plainpip installworks, no extra index or credentials needed.
The chroma backend needs
sqlite3 >= 3.35(defaultMEMORY_VECTOR_STORE=chroma). On systems with an older sqlite (some CentOS/Linux reportunsupported version of sqlite3):pip install pysqlite3-binaryand swap it in at process entry (import sys; sys.modules["sqlite3"] = __import__("pysqlite3")), or switch toMEMORY_VECTOR_STORE=qdrant/faiss.
⚠️ pip install alone is NOT enough. Hermes discovers memory providers by scanning a directory (
~/.hermes/plugins/<name>/), not via pip entry points. So you need two things: (a) the package importable by the Python that Hermes actually runs, and (b) a directory/symlink at~/.hermes/plugins/hy-memory/. Theinstallcommand below does both for you.
1. Install the package
pip install "hermes-hy-memory[init]" # plugin + hy-memory SDK + wizard deps
This gives you the hermes-hy-memory CLI. It does not yet activate the
provider inside Hermes (see the warning above).
2. Configure (the wizard)
hermes-hy-memory init
The 4-step wizard (LLM → embedding → vector store → userId):
- writes the SDK configuration to
~/.hermes/.env, - sets
memory.provider: hy-memoryin~/.hermes/config.yaml, and - runs the
installstep below automatically (links the plugin into Hermes).
Processing mode defaults to pro (the wizard doesn't ask) — set
HY_MEMORY_MODE in ~/.hermes/.env if you want ultra or lite.
3. Activate in Hermes (install)
If you skipped the wizard, or want to (re)link the plugin explicitly:
hermes-hy-memory install
This:
- auto-detects the Python that Hermes runs (follows the
hermeslauncher; Hermes usually lives in its own venv that does not see your normal site-packages), - ensures the
hy-memorySDK is importable there (installs it into that venv viauv/pipif missing), - symlinks
~/.hermes/plugins/hy-memory/→ the installed package dir (so a laterpip install -Ukeeps it current — no stale copies), - reminds you to restart Hermes.
If auto-detection fails, pass the interpreter explicitly:
hermes-hy-memory install --hermes-python /usr/local/lib/hermes-agent/venv/bin/python
# other flags: --copy (copy files instead of symlink), --no-sdk (skip SDK install)
Manual equivalent, if you'd rather not use
install:HPY=/usr/local/lib/hermes-agent/venv/bin/python # the Python Hermes runs uv pip install --python "$HPY" hermes-hy-memory # or: "$HPY" -m pip install PKG=$("$HPY" -c "import hy_memory_hermes,os;print(os.path.dirname(hy_memory_hermes.__file__))") mkdir -p ~/.hermes/plugins && ln -sfn "$PKG" ~/.hermes/plugins/hy-memory
4. Restart Hermes, then verify
The memory provider is loaded once at agent startup, so restart Hermes
(start a new hermes chat, or hermes gateway restart if you run the gateway
service) before checking.
hermes memory status # Hermes side — expect: Plugin: installed ✓ / available ✓
hermes-hy-memory doctor # SDK side — client builds, vector store reachable
hermes memory status vs hermes-hy-memory doctor
These answer two different questions — status is the decisive one for
"is memory actually turned on in Hermes?":
hermes memory status |
hermes-hy-memory doctor |
|
|---|---|---|
| Whose view | Hermes side — the source of truth for activation | SDK side — internal health probe |
| Answers | Will Hermes load & use this provider? | Does the memory engine itself work? |
| Checks | memory.provider in config.yaml; plugin directory discovered (~/.hermes/plugins/hy-memory/); is_available() (env present) |
HY_MEMORY_USER_ID set; HyMemoryClient constructs (LLM/embedder keys valid); list_memories runs (vector store reachable) |
| Healthy output | Plugin: installed ✓ / Status: available ✓ / hy-memory … ← active |
All checks passed. |
| If it fails | provider not active — likely the directory/symlink is missing (pip alone isn't enough — see step 3) or memory.provider not set |
the engine can't run — missing API key, unreachable vector store, etc. |
Rule of thumb: if hermes memory status doesn't say installed ✓ / available ✓, Hermes is not using HY Memory at all — fix that first (it's almost
always a missing ~/.hermes/plugins/hy-memory/ directory or an unset
memory.provider). Only once status is green does doctor tell you whether
the backend itself is healthy. doctor passing while status fails means the
engine works but Hermes isn't wired to it.
Update
The plugin Hermes runs lives in Hermes' own venv (the symlink points there),
which is usually not the env your pip install touches. So upgrading your
shell's copy alone does not update Hermes. The reliable one-liner:
hermes-hy-memory install # detects the version in Hermes' venv; upgrades it if stale, re-links
install compares the plugin version already in Hermes' venv against the
latest and upgrades in place when they differ (use -U/--upgrade to force a
reinstall regardless). Then it refreshes the ~/.hermes/plugins/hy-memory
symlink.
Manual equivalent, if you prefer:
uv pip install --python /usr/local/lib/hermes-agent/venv/bin/python -U hermes-hy-memory
# (or: <hermes-python> -m pip install -U hermes-hy-memory)
Your settings in ~/.hermes/.env and ~/.hermes/config.yaml survive upgrades —
no need to re-run init. After upgrading, check the version and restart
Hermes:
hermes-hy-memory --version
hermes memory status # confirm Plugin: installed ✓ still holds
Uninstall
# 1. Deactivate the provider — remove (or change) memory.provider in ~/.hermes/config.yaml:
# memory:
# provider: hy-memory ← delete this line (or set another provider)
#
# 2. Remove the plugin directory/symlink Hermes scans
rm -rf ~/.hermes/plugins/hy-memory
# 3. Uninstall the package (from whichever env you installed it in)
pip uninstall hermes-hy-memory
# if you installed into Hermes' venv:
# uv pip uninstall --python /usr/local/lib/hermes-agent/venv/bin/python hermes-hy-memory
# 4. (optional) drop the SDK too, if nothing else uses it
pip uninstall hy-memory
# 5. (optional) remove saved settings
# edit ~/.hermes/.env and delete the HY_MEMORY_* / MEMORY_* lines the wizard added
Removing the package without first clearing
memory.provider: hy-memory(step
- and the plugin dir (step 2) leaves Hermes pointing at a provider it can no longer load. Your stored memories (the vector store / DB) are not deleted by uninstall — remove that data directory manually if you want a clean slate.
Configuration
Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
HY_MEMORY_USER_ID |
✅ | — | First-level isolation key (your memory namespace) |
HY_MEMORY_AGENT_ID |
❌ | hermes |
Second-level isolation key |
HY_MEMORY_MODE |
❌ | pro |
Processing mode: lite / pro / ultra |
HY_MEMORY_WRITE_TURN_WINDOW |
❌ | 5 |
Write throttle: buffer turns and persist once every N turns (one batched extraction → saves tokens, avoids per-turn dup writes). 1 = write every turn. Tail (< N turns) is flushed on session end / pre-compress / shutdown. |
HY_MEMORY_PREFETCH_MAX_CHARS |
❌ | 2000 |
Max chars of injected prefetch text |
HY_MEMORY_SYNC_WORKERS |
❌ | 2 |
sync_turn background thread-pool size |
HY_MEMORY_SHUTDOWN_GRACE_SEC |
❌ | 10 |
Max seconds to wait for in-flight writes on shutdown |
HY_MEMORY_LOG_LEVEL |
❌ | (unset) | Set INFO/DEBUG to attach a console handler (logger hermes-hy-memory) and see search/write activity. Unset → inherit Hermes' root logging (usually WARNING, i.e. quiet). |
MEMORY_LOG_PROPAGATE |
❌ | true (set by the plugin) |
Routes the SDK's own hy_memory.* logs into Hermes' root logger, so they appear in hermes logs and follow its --level. The plugin sets this automatically; set false to keep SDK logs in their own file only. |
OPENAI_API_KEY (or matching LLM/embedder key) |
✅* | — | Required for pro/ultra; lite only needs the embedder |
*The HY Memory SDK's own LLM/Embedder configuration (see the hy-memory docs).
Environment variables take precedence and can be persisted in ~/.hermes/.env (written automatically by the init wizard).
Processing modes (HY_MEMORY_MODE)
| Mode | Write pipeline | Speed | Recall quality |
|---|---|---|---|
lite |
pure embedding (no LLM) | fastest | vector similarity only |
pro (default) |
LLM fact/identity extraction + reconcile/evolution | medium | profile + fact layers |
ultra |
pro + System2 async cognition (Schema/Intention) | fullest | + cross-domain induction + proactive intent |
⚠️
litemode is not suitable for Hermes passive injection / recall. lite only embeds and skips LLM extraction, so memories stay at theL1_RAWlayer; the SDK'slist/searchfilter outL1_RAW, meaning lite-written memories cannot be recalled byprefetch(writes succeed but search is always empty). Usepro(default) orultrafor Hermes;liteonly fits write-only / no-semantic-recall scenarios.
CLI
After pip install, the hermes-hy-memory subcommands let you run diagnostics and manual operations (outside the Hermes main process):
# activate the plugin in Hermes (symlink + ensure SDK in Hermes' venv)
hermes-hy-memory install
# health check: env present / client constructs / list works (read-only)
hermes-hy-memory doctor
# manual write
hermes-hy-memory add "I like K-Pop but prefer Jazz"
# manual search
hermes-hy-memory search "music taste" --limit 5
# list recent 20
hermes-hy-memory list
# cross-user test (override env)
hermes-hy-memory search "x" --user-id other_user --agent-id test
# reset: delete this user's memories (DESTRUCTIVE — prompts for confirmation)
hermes-hy-memory reset # only the current agent (HY_MEMORY_AGENT_ID)
hermes-hy-memory reset --all-agents # every agent under this user
hermes-hy-memory reset --all-agents -y # skip the confirmation prompt
resetcalls the SDK'sdelete_allfor the resolveduser_id. Default scope is the current agent only;--all-agentswipes every agent for that user. It asks for confirmation unless you pass-y/--yes. This deletes the stored memories themselves (not your.env/config.yaml).
When loaded by the Hermes main CLI:
hermes hy-memory doctor
Hooks
| Hook | When | Behavior |
|---|---|---|
prefetch(query) |
before each LLM call | search memory → inject into system prompt |
sync_turn(user, ast) |
end of each turn | buffer the turn; flush a batched async write every HY_MEMORY_WRITE_TURN_WINDOW turns (default 5) |
on_session_end(msgs) |
session end | flush the partial (< window) tail buffer + wait for in-flight |
on_pre_compress(msgs) |
before context compression | same as on_session_end, preserves about-to-be-trimmed content |
on_memory_write(action, target, content) |
Hermes built-in memory commands | add syncs to HY Memory; delete is skipped (target IDs are not interchangeable) |
Tools (LLM-invoked, optional)
| Tool | Purpose |
|---|---|
memory_search(query, limit) |
search memories |
memory_add(content) |
write a memory |
memory_delete(memory_id) |
delete a memory |
memory_list(limit) |
list memories for the current user/agent |
Even with tools disabled, the passive prefetch injection guarantees relevant memories reach every LLM call.
Troubleshooting
hermes memory status shows Plugin: NOT installed ✗
The single most common issue: you pip install-ed but never created the
directory Hermes scans. pip alone does not activate a Hermes memory
provider. Fix:
hermes-hy-memory install # symlinks ~/.hermes/plugins/hy-memory + ensures SDK in Hermes' venv
then restart Hermes and re-check hermes memory status. If detection of
Hermes' Python failed, pass it explicitly with --hermes-python. See
Install → step 3.
Also check memory.provider: hy-memory is set in ~/.hermes/config.yaml.
hermes memory status shows Status: not available ✗
The plugin is discovered but is_available() is false — usually
HY_MEMORY_USER_ID isn't set in the env Hermes loads (~/.hermes/.env). The
status output lists the missing env vars. Re-run hermes-hy-memory init.
provider not initialized or all hooks silently no-op
Run the SDK-side health check:
hermes-hy-memory doctor
Common causes:
HY_MEMORY_USER_IDnot set- embed/LLM key not set (
OPENAI_API_KEY, etc.) →HyMemoryClient(mode="pro")fails to construct - SDK not installed in Hermes' venv:
hermes-hy-memory install(or pip into that venv)
I see no logs for search / write
By default the hermes-hy-memory logger inherits Hermes' root level (usually
WARNING), so INFO activity is hidden. Set HY_MEMORY_LOG_LEVEL=INFO (or
DEBUG) in ~/.hermes/.env to attach a console handler and see
prefetch/search and sync_turn lines.
prefetch injects nothing
- There really is no relevant memory — confirm with
hermes-hy-memory list - Query too short (< 3 chars) or in the skip list (
ok/thanks, etc.) — by design - Using
litemode? lite memories stay atL1_RAWand are never recalled — usepro/ultra
sync_turn doesn't seem to write
- Writes are throttled: by default they flush every 5 turns (
HY_MEMORY_WRITE_TURN_WINDOW). A short session flushes its tail on session end. SetHY_MEMORY_WRITE_TURN_WINDOW=1to write every turn while debugging - Default daemon threads are killed when the main process exits. Use Hermes daemon mode in production
- Raise
HY_MEMORY_SHUTDOWN_GRACE_SECto let shutdown wait a few more seconds - Set
HY_MEMORY_LOG_LEVEL=INFOand check for[hermes] sync_turn failed: ...
cross-loop errors (multi-client deployments)
If your Hermes deployment runs multiple HyMemoryClient instances (e.g. a multi-tenant server), use SharedRuntime:
from hy_memory import HyMemoryClient, SharedRuntime
runtime = await SharedRuntime.create(base_config)
client = HyMemoryClient(cfg, runtime=runtime)
A single-process Hermes deployment uses a solo-mode client by default and does not need this.
Comparison with Mem0-style integrations
Mem0's Hermes integration relies on a TypeScript SDK; this plugin uses the Python SDK. HY Memory offers three processing depths — lite/pro/ultra (lite skips the LLM, pro does standard extraction, ultra adds System2 cognition) — whereas Mem0 is single-tier LLM extraction.
Development
cd plugins/native/hermes
python -m pytest tests/ -v
Tests mock HyMemoryClient and need no external dependencies (no OPENAI_API_KEY, no running Qdrant).
Versions
| Plugin | SDK dependency | Notes |
|---|---|---|
| 0.2.4 | hy-memory>=1.2.18 |
install now upgrades the SDK too: it ran -U hermes-hy-memory only, which left an already-satisfying hy-memory SDK at the old version (Hermes kept running stale SDK code). Now upgrades both packages (-U hermes-hy-memory hy-memory) and prints honest before→after for each; removed the misleading version-direction message. |
| 0.2.3 | hy-memory>=1.2.18 |
SDK logs now flow into hermes logs and follow its --level: the plugin sets MEMORY_LOG_PROPAGATE=true so the SDK's hy_memory.* loggers propagate to Hermes' root logger (instead of writing only to their own file). Requires SDK 1.2.18 (adds the host-managed logging mode). |
| 0.2.2 | hy-memory>=1.2.17 |
install now actually upgrades: previously it only checked "is the SDK importable?" and skipped — so an old plugin already in Hermes' venv was never updated (Hermes kept running stale code). Now compares the plugin version in Hermes' venv and reinstalls when stale; -U/--upgrade to force. plugin_version reads via python -I so a stray *.egg-info in CWD can't report the wrong version. |
| 0.2.1 | hy-memory>=1.2.17 |
Fix: handle_tool_call now returns a JSON string (was a dict) — a dict in the tool-result content caused HTTP 400: content should be a string or a list from OpenAI-compatible APIs (DeepSeek) right after a successful memory_add. Matches bundled providers' -> str contract. |
| 0.2.0 | hy-memory>=1.2.17 |
Install fix: new install subcommand (auto-detect Hermes venv → ensure SDK there → symlink ~/.hermes/plugins/hy-memory/); init now runs it automatically. Corrects the install story — pip entry points do not activate Hermes memory providers; the directory scan does. Also: HY_MEMORY_LOG_LEVEL for opt-in console logging; logger key renamed to hermes-hy-memory; INFO logs for search/write. |
| 0.1.10 | hy-memory>=1.2.17 |
New reset subcommand — delete a user's memories (delete_all), per-agent by default or --all-agents, confirmation unless -y |
| 0.1.9 | hy-memory>=1.2.17 |
README: Update / Uninstall sections; hermes-hy-memory --version flag |
| 0.1.8 | hy-memory>=1.2.17 |
Turn-window write throttle (HY_MEMORY_WRITE_TURN_WINDOW, default 5) — batch writes every N turns, flush partial tail on session end; wizard no longer asks for mode (defaults to pro) |
| 0.1.7 | hy-memory>=1.2.17 |
Standalone CLI (doctor/add/search/list) now loads ~/.hermes/.env, so wizard-written settings are visible outside the Hermes daemon |
| 0.1.6 | hy-memory>=1.2.17 |
init auto-activates memory.provider in config.yaml; docs steer to standalone hermes-hy-memory init (avoids pre-activation invalid choice error) |
| 0.1.5 | hy-memory>=1.2.17 |
Single-level standalone CLI; corrected install docs (real pip + config.yaml flow) |
| 0.1.4 | hy-memory>=1.2.17 |
English README; init wizard (questionary) |
| 0.1.3 | hy-memory>=1.2.17 |
init interactive setup wizard |
| 0.1.2 | hy-memory>=1.2.17 |
Published to public PyPI; channel-dict flatten fix |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermes_hy_memory-0.2.4.tar.gz.
File metadata
- Download URL: hermes_hy_memory-0.2.4.tar.gz
- Upload date:
- Size: 52.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9ef3c78cee1206498f31330a12f9664bcd762dda51c6f6a931cd5b6bcab6626
|
|
| MD5 |
5922674b31b205878bd3850247da3b97
|
|
| BLAKE2b-256 |
5de44fb4671403b3387112bdbbdb1b62f5326cb99f166adbb58c13498b7acfc7
|
File details
Details for the file hermes_hy_memory-0.2.4-py3-none-any.whl.
File metadata
- Download URL: hermes_hy_memory-0.2.4-py3-none-any.whl
- Upload date:
- Size: 35.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62c0809fe5d1a1658e8798ea904e707ea408b74090510fb52e71b3c8ab0744b2
|
|
| MD5 |
7e64f68a029ee8110cf3940c168d1252
|
|
| BLAKE2b-256 |
1cc9fa912155935a16beb14a96a20ec48dd09d69a4d75dfd3efe60f7a82b3eea
|