Skip to main content

Self-maintaining memory plugin for Hermes Agent — embedded YantrikDB engine, ~10 MB, no server, no token, no GPU. Canonicalizes duplicates, surfaces contradictions, ranks with recency awareness, and explains recall.

Project description

yantrikdb-hermes-plugin

CI Tests Python License YantrikDB Hermes Agent Ruff mypy

YantrikDB as a memory provider for Hermes Agent. Self-maintaining memory — canonicalizes duplicates, surfaces contradictions, explains recall — in a drop-in plugin. As of v0.2.0 the default backend is in-process (pip install and go, no separate server).

This repository tracks the plugin as a standalone artifact so users can install it immediately, without waiting on upstream review. Issue NousResearch/hermes-agent#9975 asks whether upstream would welcome it; a PR is in flight. Until that lands, install from here.

Install (default — embedded backend)

The v0.2.0 default backend is in-process: pip install and go, no separate server.

Step 1 — drop the plugin into your Hermes checkout:

cd path/to/hermes-agent/plugins/memory
git clone https://github.com/yantrikos/yantrikdb-hermes-plugin tmp
mv tmp/yantrikdb .
rm -rf tmp

Step 2 — install the engine:

pip install yantrikdb        # ~10 MB; pulls only uuid-utils + click

Step 3 — activate:

hermes config set memory.provider yantrikdb

Verify:

hermes memory status
# → Provider: yantrikdb  Plugin: installed ✓  Status: available ✓

That's it. No Docker, no token mint, no URL configuration. The bundled potion-base-2M static embedder (~8 MB, dim=64, R@5 ≈ 0.90 vs MiniLM's 0.95) loads on first call (~80 ms one-time warmup) and stays in-process.

Optional: tier up the embedder (downloads on first use, cached in user data dir):

echo "YANTRIKDB_EMBEDDER=potion-base-8M" >> ~/.hermes/.env   # 28 MB, dim=256, ~92% MiniLM
# or potion-base-32M for 121 MB, dim=512, ~95% MiniLM

Install (alternative — HTTP backend, for HA cluster setups)

If you run multiple Hermes instances that need to share one memory store, or you want HA via raft:

docker run -d -p 7438:7438 -v yantrikdb-data:/var/lib/yantrikdb \
  --name yantrikdb ghcr.io/yantrikos/yantrikdb:latest
docker exec yantrikdb yantrikdb token --data-dir /var/lib/yantrikdb \
  create --db default --label hermes
# → ydb_abc123...

cat >> ~/.hermes/.env <<EOF
YANTRIKDB_MODE=http
YANTRIKDB_URL=http://localhost:7438
YANTRIKDB_TOKEN=ydb_abc123...
EOF

Same plugin, same 8 tools, same hooks, same provider contract — just talks HTTP to a separately-managed server instead of running the engine in-process.

Full config, tool reference, troubleshooting: yantrikdb/README.md.

What it does

The differentiator versus other Hermes memory plugins is not the vector store — it's what happens after the write:

Feature Plain vector memory YantrikDB
Duplicate facts pile up canonicalized by think()
Contradictions silently overwrite surfaced via conflicts(), closed via resolve_conflict()
Stale facts outrank fresh ones recency-aware ranking without deletion
Why did a memory rank? ¯\(ツ) every recall() result carries a why_retrieved reason list
Cross-entity recall semantic-only graph edges from relate() boost related memories

Eight tools exposed to the agent by default: yantrikdb_remember, _recall, _forget, _think, _conflicts, _resolve_conflict, _relate, _stats. Three additional opt-in skill tools (v0.3.0+): _skill_search, _skill_define, _skill_outcome — see Skills below.

Three optional lifecycle hooks: on_session_end auto-consolidates, on_pre_compress preserves high-salience memories through context compression, on_memory_write mirrors built-in MEMORY.md / USER.md additions.

Skills (opt-in, v0.3.0+)

Skills are procedural memory: reusable patterns the agent distills from observed success and pulls back next session. They live in YantrikDB's shared skill_substrate namespace alongside skills authored by other consumers (Lane B SDK, server handlers, WisePick). Hermes-authored skills are tagged metadata.source=hermes so any downstream consumer can filter them in or out cleanly.

Disabled by default. Adding the plugin to an existing Hermes install doesn't change the tool schema the model sees. Enable explicitly when you want the agentic skill loop:

echo "YANTRIKDB_SKILLS_ENABLED=true" >> ~/.hermes/.env

When enabled, three new tools join the schema:

Tool Purpose
yantrikdb_skill_search Semantic search over agent-authored skills, namespace-isolated from regular memory recall.
yantrikdb_skill_define Distill a procedural pattern into a reusable skill (skill_id, body, skill_type, applies_to). Client-side validation reproduces yantrikdb-server's wrapper checks.
yantrikdb_skill_outcome Record success/failure for a skill after it's used. Append-only event log; rollup is the agent's call, not the substrate's.

The agentic loop closes: agent observes a successful sequence → distills it via define → next session pulls it via search → records outcome via outcome → over time, ranking reflects what actually works.

Lifecycle distinction worth understanding. Hermes' own filesystem skills ($HERMES_HOME/skills/*.md) are human-authored, durable, version-controlled. YantrikDB skills are agent-authored, runtime-evolving, semantic-search-queryable. Different kinds of canonical, not competing authorities. The model picks by lifecycle.

Explainability is a side effect, not a bolt-on

Every recall() result already carries the structured ranking-reason list — that's the engine's standard response shape. The model can read it without prompt engineering. From the live Hermes session captured in VERIFICATION.md, DeepSeek's natural-language summary of the recall:

"All 3 memories returned, ranked by relevance × recency × importance. The top result ranked highest (semantic match + keyword + high importance + recency), followed by [...] (keyword match), then [...] (high importance but no direct keyword overlap)."

DeepSeek wasn't told the reason codes existed; it parsed them from the tool response and reflected them in its explanation. That's the architectural shape we wanted: the explainability surface is the recall response itself, transport-agnostic, model-agnostic, and visible to anyone who looks at the JSON. No separate "explain" tool. No second LLM call. The cost of explainability is zero because it was never separate.

Verification

  • 96 unit tests covering request formation, error taxonomy, provider contract, hook semantics, circuit breaker, text truncation, mode-aware availability — all mocked, no network required.
  • 2 live integration tests (tests/integration/test_live.py) that exercise the full flow against a real yantrikdb-server. Skipped by default; run with YANTRIKDB_INTEGRATION_URL + YANTRIKDB_INTEGRATION_TOKEN set.
  • End-to-end Hermes demos against an unmodified Hermes 0.9.0 install for both backends, captured in VERIFICATION.md — DeepSeek-driven sessions calling all 8 tools, with why_retrieved reason codes flowing through the model's reasoning verbatim.

Performance (steady-state, post-warmup)

Op v0.1 HTTP (Apr 14) v0.2 Embedded (May 9)
record_text p50 13.8 ms 0.60 ms
recall_text p50 24.0 ms 2.58 ms
record_text p99 55.3 ms 10.66 ms
recall_text p99 67.2 ms 13.24 ms
Cold start n/a 77 ms (one-time)
Required infrastructure yantrikdb-server + token none
pip install footprint wheel + requests wheel + 2 small libs (~10 MB total)

Even embedded p99 tail latency is faster than HTTP p50 — bad-case embedded beats typical-case HTTP. Long-running soak validation is in progress upstream (yantrikos/yantrikdb saga task #2); these numbers are 100-iteration micro-benchmarks, not 24-hour production traces.

About the embedder quality claims

Tier 1 (with_default(), ~8 MB) uses potion-base-2M via model2vec-rs — a pure-Rust static embedding (lookup table + mean-pool + L2-normalize), no transformer forward pass. Tier 2 (potion-base-8M, 28 MB) and Tier 3 (potion-base-32M, 121 MB) trade larger model files for higher recall and live behind set_embedder_named() (downloaded on first use, cached under user data dir).

Quality numbers cited in this README are R@5 vs sentence-transformers/all-MiniLM-L6-v2 (dim=384) on the upstream evaluation corpus. The "~89% / ~92% / ~95% of MiniLM" approximations are from that specific eval; your mileage will vary on a different corpus or task. Semantic separation is also corpus-size dependent — at 3 records all vectors look similar (top score ~0.58); at 8+ with real diversity the score range opens up (top score ~0.84). If you're evaluating, run against your own data.

CI runs ruff + mypy + pytest on Python 3.11 / 3.12 / 3.13 on every push.

Running the tests

python -m pytest tests/                          # unit tests
YANTRIKDB_INTEGRATION_URL=http://localhost:7438 \
YANTRIKDB_INTEGRATION_TOKEN=ydb_... \
  python -m pytest tests/integration/ -v         # live integration

Status

v0.3.0 — skill substrate bridge with feature-flag opt-in (YANTRIKDB_SKILLS_ENABLED); embedded backend remains the default, 128 tests passing, ~10 MB install. v0.2.x users upgrade in place — the default tool surface is unchanged when skills are off. Upstream Hermes discussion still open at hermes-agent#9975 and PR #9989; the standalone install path doesn't depend on either.

See yantrikdb/CHANGELOG.md for the v0.3.0 changes and yantrikdb/ARCHITECTURE.md for the control flow, error taxonomy, and threading model (covering both backends).

License

This plugin is MIT (matching Hermes — the code is intended for upstream contribution). The YantrikDB server itself is AGPL-3.0; the plugin only talks to it over HTTP and does not embed or redistribute any server code, so the boundary is the same as any MIT client talking to an AGPL service. See yantrikdb/SECURITY.md for the full note.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yantrikdb_hermes_plugin-0.3.1.tar.gz (58.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

yantrikdb_hermes_plugin-0.3.1-py3-none-any.whl (50.2 kB view details)

Uploaded Python 3

File details

Details for the file yantrikdb_hermes_plugin-0.3.1.tar.gz.

File metadata

  • Download URL: yantrikdb_hermes_plugin-0.3.1.tar.gz
  • Upload date:
  • Size: 58.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yantrikdb_hermes_plugin-0.3.1.tar.gz
Algorithm Hash digest
SHA256 bbfbcf8885ea37c287a433b851f378676f1375139aecd2ac7923af3af2867fef
MD5 9f907758323598fecbce41ab0b9857e2
BLAKE2b-256 f8f6c08c23382147b9ce733597294d5f799e283e986c5aa27d953a370b127178

See more details on using hashes here.

Provenance

The following attestation bundles were made for yantrikdb_hermes_plugin-0.3.1.tar.gz:

Publisher: publish.yml on yantrikos/yantrikdb-hermes-plugin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yantrikdb_hermes_plugin-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for yantrikdb_hermes_plugin-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b4658068c3c37236b5856cc31ce4e43c4a7c7e9b75e8c6c75ce1876b5fdf1c0f
MD5 f1e5686079adf0671cf3a26670faf8ec
BLAKE2b-256 a3946e0b7ad6576bd90e9e060c683fe2246beffaf9786f7dcdeed6e6cc724a1f

See more details on using hashes here.

Provenance

The following attestation bundles were made for yantrikdb_hermes_plugin-0.3.1-py3-none-any.whl:

Publisher: publish.yml on yantrikos/yantrikdb-hermes-plugin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page