Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Graph Memory

A temporal knowledge-graph long-term memory for Hermes Agent, packaged as a signed AXP v0.3 extension (mintbot.ai/graph-memory).

Graph Memory remembers more than isolated sentences. It extracts entities such as people, projects, decisions, topics, and artifacts; stores the relationships between them; tracks when facts become valid or are superseded; and recalls relevant subgraphs by meaning rather than exact wording.

Architecture

Hermes turn / explicit memory write
                 │
                 ▼
     user's active Hermes model
  (proxy, Codex, Claude, BYOK, ...)
      entity + relationship extraction
                 │
                 ▼
       Graphiti temporal graph
          ┌──────┴──────┐
          ▼             ▼
 embedded Ladybug  local FastEmbed
   graph store      semantic vectors
  • Extraction follows the model/provider currently selected in Hermes. The extension creates a tool-free nested agent with skip_memory=True, avoiding recursion and avoiding a second credential configuration.
  • Embeddings and reranking run locally with BAAI/bge-small-en-v1.5 through FastEmbed/ONNX. There is no embeddings API cost or data egress.
  • LadybugDB, the actively maintained continuation of Kuzu, runs in-process and stores one profile-scoped database at $HERMES_HOME/graph-memory/graph.lbug. An existing graph.kuzu store is migrated automatically through Kuzu EXPORT DATABASE → Ladybug IMPORT DATABASE; the legacy store is retained as a backup. The archived Kuzu wheel is not a runtime dependency; if it is unavailable during migration, the helper fetches kuzu==0.11.3 into an ephemeral uv environment used only for the export process. There is no Docker container, port, database daemon, or password to operate. Ladybug's FTS extension is downloaded once from extension.ladybugdb.com and loaded locally on each startup.

What it provides

  • Automatic extraction after each primary conversation turn (configurable).
  • Automatic relevant-memory injection before model calls.
  • memory_query: explicit semantic/relationship/history search.
  • memory_write: confirmed durable graph write.
  • Mirroring of Hermes built-in memory add/replace/remove operations with temporal supersession/removal events.
  • Pre-compression and delegation-result ingestion.
  • Clean shutdown that serializes and drains pending writes.

Install

AXP-aware host

Graph Memory is a signed AXP v0.3 package with the extension id mintbot.ai/graph-memory. Point your host at the manifest (agent-extension.json — served from the publisher's site or attached to every GitHub release) and it will show the consent card, verify the artifact digest and the ed25519 signature, run the Hermes lifecycle hooks in its sandbox, and keep the extension updated from GitHub releases.

Automated hooks support first installs, inactive-provider replacement, and active upgrades through Hermes' public plugin installer. Activation is verified, not inferred from exit status. Failed activation attempts retain recovery snapshots and restore the prior plugin/selection where feasible; this is not an atomic runtime rollback.

What the consent card shows, and why:

declared why
network_egress PyPI, Hugging Face, extension.ladybugdb.com Hermes PM stages the pinned dependencies before publishing an active replacement; the FastEmbed model and the LadybugDB extension are fetched on first use
filesystem config:rw, hermes:plugins:rw, cache:rw the Hermes home (config.yaml, the venv, the graph database under HERMES_HOME/graph-memory), the provider package, the pip cache
root: false not needed — the install prefix comes from the host (AXP_PREFIX)
signed by mintbot.ai-graph-memory-2026 ed25519:m5vaq2/BLL372gVnVljTkdS+TeYjkpyduQ7/zk/gHbk= — pinned on first install; later releases must be signed by this key or a properly announced rotation

Entity extraction calls whatever model Hermes already has selected, through Hermes itself: the extension holds no credentials and no API key of its own.

Standalone fallback (no AXP support)

Run ./install.sh or ./upgrade.sh from the verified artifact. The hook stages those exact bytes as a pinned local Git source and snapshots the previous plugin, config, memory provider, and disabled-plugin list before calling native hermes plugins install file://... --ref <sha> --force --yes-deps. It adds --enable for first/inactive installs and --no-enable for active upgrades. Do not run the hook with sudo to change profiles.

The hook checks installed source bytes, reads back memory.provider and plugins.disabled, and runs hermes memory status through its health hook. Exit zero alone is not success. On failure it attempts to reinstall the old plugin through the same native installer and restore selection with hermes config set, then reads back the result. Recovery files remain in the printed cache directory, including the prior config for manual inspection. A failed first activation can leave an installed, unselected tree; no old tree exists to restore. Interrupted commands require inspecting the retained files.

Hermes owns dependency preparation and publication. The hook never runs pip, patches Hermes, or restores code by copying it over a changed runtime. Native recovery can fail; neither dependency-runtime identity, graph data, nor changes to already-running sessions can be rolled back atomically. New sessions use the selected provider. Git and a Hermes CLI exposing --yes-deps are required.

The local source is ephemeral and the recorded commit is pinned: use AXP hooks for later upgrades, not hermes plugins update on that source. Lifecycle scripts are copied to the prefix only after verification; a filesystem failure then retains recovery inputs but does not undo native publication. Serialize lifecycle operations and configuration changes for a profile. See lifecycle safety for the reviewed upstream contract, test boundaries, and release-qualification requirements.

A non-root install also works; lifecycle scripts are stored under $HERMES_HOME/extensions/graph-memory instead of /opt/graph-memory. The scripts honour the AXP host contract (AXP_PREFIX, AXP_CACHE_DIR, AXP_PURGE, AXP_FROM_VERSION) and fall back to these defaults when the variables are absent.

To remove: uninstall.sh (keeps the graph database; AXP_PURGE=1 uninstall.sh deletes it too). Uninstall reads hermes config get memory.provider --json on Hermes' runtime and verifies a native config set before deleting an active provider. System Python needs only its standard JSON module, not PyYAML. Missing Hermes, malformed responses, read failures, or stderr warnings (including last-known-good fallbacks) stop removal, even with purge. An unrelated provider is not changed.

Configuration

Run:

hermes memory setup graph-memory

The defaults are:

memory:
  provider: graph-memory
  graph-memory:
    embedding_model: BAAI/bge-small-en-v1.5
    ingest_turns: all          # or explicit-only
    recall_limit: 8

No second LLM key is requested. Extraction resolves the active Hermes runtime on every call, so a later model/provider switch is picked up automatically.

Operations

./healthcheck.sh                         # provider installed + active + deps import
./upgrade.sh                             # idempotent reinstall; sees AXP_FROM_VERSION
./uninstall.sh                           # keeps the graph database
AXP_PURGE=1 ./uninstall.sh               # also deletes long-term memory

hermes backup already includes the graph because it lives under HERMES_HOME.

LadybugDB storage

LadybugDB is the active continuation of the archived Kuzu project. The extension pins the tested pair graphiti-core==0.29.3 and ladybug==0.18.3. Local embeddings use fastembed>=0.9.0,<0.10, qualified with Hermes' Python 3.14 runtime and Pillow 12.3.0 (required by browser-harness). An isolated compatibility adapter binds Graphiti's Kuzu-named operation layer to Ladybug's maintained Python API; the archived kuzu wheel is not installed. The adapter boundary can be replaced by a future native Graphiti Ladybug driver without changing the Hermes provider contract or on-disk graph.

Ladybug also allows one process to own a database at a time. Do not run a CLI and gateway concurrently against the same Hermes profile while this provider is active. Different Hermes profiles have separate databases and are isolated.

Development

python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements-dev.txt
pytest -q

The integration test exercises the real Ladybug/FastEmbed stack. A live extraction test additionally uses whichever Hermes model/provider is currently selected. tests/test_axp_manifest.py validates the manifest against the AXP schema and reference implementation from a sibling ../agent-extension checkout (or $AXP_SPEC_DIR).

Publishing a release

Releases are cut with the axp CLI from the agent-extension repo (pip install -e ../agent-extension). The publisher key never enters this repository; it lives on the release machine only.

AXP_SIGNING_KEY=/path/to/mintbot.ai-graph-memory.key scripts/release.sh 0.2.0

First add a ## v<version> heading and release notes to CHANGELOG.md. The script validates that heading, stamps plugin.yaml and the manifest's changelog URL before building the deterministic artifact (which includes CHANGELOG.md), then lets axp release write the version, digests, dates and signature and verifies it. A failed release may leave local stamped metadata; review/revert it before retrying. No release is published automatically. Then:

git commit -am "release v0.2.0" && git tag v0.2.0 && git push --tags
gh release create v0.2.0 dist/graph-memory-0.2.0.tar.gz agent-extension.json --notes-file CHANGELOG.md

Both assets matter: hosts on the github update source read the signed agent-extension.json release asset, and the tarball must be byte-identical to the digest inside it (the build is deterministic, so a rebuild from the tag reproduces it). Key rotation follows AXP section 8.3: publish one release with signing.next_key, then one dual-signed release under the new key.

Publisher key directory

agent-extension-keys.json is the AXP section 8.5 key directory for mintbot.ai: the public keys the publisher currently signs with, one entry per key, optionally restricted to named extensions. It is served at https://mintbot.ai/.well-known/agent-extension-keys.json, so hosts can tell a legitimate rotation (the new key is listed) from a compromised manifest (it is not), and release.sh refuses to cut a release whose signing key is missing from it. Re-deploy the file whenever a key is added, rotated or revoked ("revoked": true keeps a retired key listed so hosts can tell "replaced" from "never ours").

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages