A memory-tree based memory system — tiered recall, pluggable storage, and memory that migrates to OpenClaw / Hermes and beyond.
Highlights · Overview · Core Technology · Features · Quick Start · Contents
English · 中文
Harness Memory is a pluggable long-term memory system for LLM agents, built around the memory tree model — a hierarchy of root → branch → leaf nodes. It does not talk to an LLM itself; it is a storage-and-recall layer any agent can drop in. What makes it special is portability: the storage backend is abstracted behind a MemoryBackend Protocol, and first-class host adapters let the same memory travel to other agents such as OpenClaw and Hermes.
Harness Memory's design goal: memory is a portable asset, not a lock-in. Capture it once, recall it anywhere — including in a different agent framework.
✨ Highlights
| Feature | Description | |
|---|---|---|
| 🌳 | Memory tree | Hierarchical root → branch → leaf nodes for organized recall |
| 🧩 | Portable by design | MemoryBackend Protocol makes storage swappable |
| 🔄 | Agent-agnostic | Drop into any agent; OpenClaw & Hermes adapters ship in-box |
| 🚚 | Cross-agent migration | Pack to .hmpkg, adopt into OpenClaw / Hermes / another agent |
| 🔍 | Recall pipeline | M4 pipeline: parse → route → gather → rerank → diversify → suppress → budget → render |
| 💾 | Pluggable storage | SQLite + FTS5 by default; PostgreSQL / Chroma / Qdrant optional |
| 🪶 | Zero core deps | stdlib + sqlite3; extras add the rest |
| 🧠 | Tiered distillation | L0 raw → L1 candidate → L2 atom → L3 entity |
📌 Overview
A fact is recorded canonically as an AtomCard (L2) grouped under an Entity (L3). The memory tree is a lightweight index over those atoms: root and branch nodes hold directory-style labels, and each leaf points at an atom — its content is projected from the atom at read time, so there is never a second copy of the fact to drift out of sync. Recall walks the tree and surfaces the linked leaves most relevant to a query.
Because storage sits behind a Protocol, the same Memory object can run on a local SQLite file, a Postgres database, or a vector index — and because host adapters exist for OpenClaw and Hermes, the memory you build in one agent can be adopted by another.
🧠 Core Technology
| Layer | Technology |
|---|---|
| Language | Python 3.11+ |
| Core deps | None — stdlib + sqlite3 |
| Model | MemoryNode tree + AtomCard |
| Recall | M4 pipeline (pipeline/recall/) |
| Storage | MemoryBackend Protocol — SQLite/FTS5, Postgres, vector (Chroma/Qdrant) |
| Host adapters | adapters/bridge/ host bridge for OpenClaw & Hermes |
| LangGraph | Optional checkpointer (SQLite / Postgres) |
| Build / quality | hatchling · ruff · mypy · pytest |
🧰 Features
Memory tree
root → branch → leafhierarchy; leaves reference atoms, content is projected on read.- Tiered distillation: L0 raw event → L1 candidate → L2
AtomCard→ L3 entity page (plus an L2.5 episode/diary layer).
Recall
recall_for_prompt(memory, query)returnsresult.rendered+result.snippets.- M4 pipeline routes the query, gathers candidates, reranks, diversifies, suppresses noise, and budgets tokens before rendering.
Pluggable backends
- Default: SQLite + FTS5 (full-text search).
- Optional: PostgreSQL (
[postgres]), ChromaDB ([chroma]), Qdrant ([qdrant]), local embeddings ([embeddings]), and a LangGraph checkpointer ([langgraph]).
Portability — OpenClaw & Hermes
MemoryBackendProtocol keeps storage swappable, so the engine is agent-agnostic.adapters/bridge/is a shared JSON-RPC bridge reused by OpenClaw; in-process hosts call the sameapplication/runtime.pythroughMemoryService.plugins/openclaw/ships a TypeScript shell (harnessmemory);plugins/hermes/ships a Python plugin — both build on the same bridge.- CLI:
harness-memory openclaw ...manages the OpenClaw integration; the standaloneharness-memory-hermes install|doctorpackage manages Hermes.
Cross-agent migration
operations/migration/portable/ packs memory into a .hmpkg and adopts it into a target host:
harness-memory portable list-sources # discover migratable stores
harness-memory portable pack --from agent:my-agent --out my-agent.hmpkg
harness-memory portable adopt my-agent.hmpkg --as openclaw
harness-memory portable doctor --host openclaw --compare-with my-agent.hmpkg
adopt resolves the target store and namespace for OpenClaw, Hermes, another
agent, or a plain harnessmemory backend — for OpenClaw it defaults to the
namespace the installed plugin actually reads (from openclaw.json); override
with --as openclaw:<namespace>. Imports are idempotent, back up the target db
first, and can rewrite the host field (--host-rewrite target).
🚀 Quick Start
Prerequisites
- Python 3.11+
1. Install
pip install harness-memory # core (SQLite + FTS5)
pip install "harness-memory[postgres]" # PostgreSQL backend
pip install "harness-memory[chroma,embeddings]" # vector index + embeddings
pip install "harness-memory[langgraph]" # LangGraph checkpointer
pip install "harness-memory[cli]" # CLI (incl. openclaw / hermes)
2. Store & recall
from harness_memory import Memory
from harness_memory.pipeline.recall import recall_for_prompt
m = Memory(namespace="my-agent") # defaults to ~/.harness-memory/session.sqlite
m.store("User prefers Python over Java", topic="preferences")
# Recall is FTS-based (no stemming) — query with words that appear in the memory.
result = recall_for_prompt(m, "Python preference")
print(result.rendered)
3. Use with another agent
# OpenClaw — wire the plugin slot, then bring your memory along
harness-memory openclaw setup
harness-memory portable adopt my-agent.hmpkg --as openclaw
# Hermes
pip install harness-memory-hermes
harness-memory-hermes install --hermes-source /path/to/hermes-agent
harness-memory portable adopt my-agent.hmpkg --as hermes
📑 Contents
- Highlights
- Overview
- Core Technology
- Features
- Quick Start
- Reference
- Project Info
🏗️ Architecture
harness_memory/
├─ core.py Memory facade + backend factory
├─ service.py in-process adapter over application runtime
├─ application/ MemoryRuntime, config, host files, path projection
├─ pipeline/ extractor · promotion · page · episode · recall · lifecycle
├─ storage/ MemoryBackend Protocol · sqlite · postgres · vector
├─ ports/ LLMClient protocol and clients
├─ adapters/ bridge · CLI · dashboard
└─ operations/migration/ export/import/rename/portable pack → .hmpkg → adopt
📖 CLI reference
Global options come before the subcommand and select which store to act on:
harness-memory [--backend sqlite|postgres] [--db PATH] [--dsn DSN] \
[--namespace NAME] [--json] [--config FILE] <command> ...
--json makes any command emit machine-readable output. Every group supports --help.
Env-var equivalents: HARNESS_MEMORY_BACKEND / _DB / _DSN / _NAMESPACE / _CONFIG.
Search & recall
| Command | Description |
|---|---|
recall "<query>" |
Run the full recall pipeline from the terminal (what an agent would see) |
atom search "<query>" |
FTS over atom assertion + quote + search terms |
raw search "<query>" |
FTS over raw event content |
episode search "<query>" |
FTS over episodes (summary, quote, people, topics) |
memory recall "<query>" |
Recall over the manual memory-node tree |
Inspect the memory layers
| Command | Description |
|---|---|
raw list / show / add |
L0 raw events — the evidence everything else derives from |
candidate list / show / extract |
L1 candidates; extract runs the extractor over a session's raw events |
candidate promote / review / fallback |
Drive the 5-check promotion worker, the interactive review queue, or the 7-day auto-promote rules |
atom list / show |
L2 atoms (promoted facts) |
entity list / show |
L3 entities and their non-deprecated atoms |
page show / list-dirty / regen / edit |
L3 entity pages; regen drives the LLM regenerator, edit opens $EDITOR |
episode list / get |
L2.5 diary episodes |
digest generate / list / show |
Daily/weekly/monthly digests over episodes |
journal list |
L4 append-only audit log |
memory store / get / update / delete / tree |
Manual memory-node tree (user-authored notes) |
thread show <thread-id> |
Per-thread active-entity LRU stack |
Storage maintenance
Cleanup and space reclaim are separate concerns: gc / consolidate / thread prune delete rows, db gives the freed space back to the OS. None of them run automatically — schedule them yourself.
| Command | Description |
|---|---|
db check |
Read-only health report: wasted space, and exactly what db vacuum would reclaim. Safe any time |
db vacuum |
Reclaim freed space in small, bounded batches — safe to run with live traffic |
db compact --yes |
Deep compaction; holds an exclusive lock, so only run during an idle window |
gc run [--dry-run] |
Delete rejected candidates, deprecated atoms and orphan raw events past their retention windows |
thread prune [--keep-last N] [--keep-days N] |
Trim LangGraph checkpoint history (the largest single source of file growth) |
db checkpoints [--apply --offline --backup FILE] |
Inspect/migrate repeated checkpoint fields; optional conservative retention and --vacuum |
consolidate run |
Intra-entity semantic dedup |
Migration & backup
SQLite Memory checkpoints now reuse large skills_metadata and workspace file contents by default.
In documentation, workspace_file_contents means the loaded AGENTS.md, MEMORY.md, USER.md, and
other configured files, separate from dynamically recalled snippets. The underlying DeepAgents state key
remains memory_contents; workspace_file_contents is a documentation label, not an API or schema change.
Existing inline checkpoints stay readable and are migrated only by an explicit db checkpoints invocation.
Set HARNESS_MEMORY_CHECKPOINT_DEDUP=0 to disable new reference writes while keeping compatible reads.
Older binaries cannot read the new format; use the offline --expand migration before reverting the reader.
See checkpoint storage and migration for maintenance and rollback steps.
| Command | Description |
|---|---|
portable list-sources |
Discover migratable memory stores on this machine |
portable pack --from <host:name> |
Export memory to a .hmpkg |
portable adopt <pkg> --as <host[:ns]> |
Import a .hmpkg into a target host |
portable doctor --host <host[:ns]> |
Health-check the target store, optionally comparing counts with a .hmpkg |
export / import |
Dump / restore the active namespace as JSONL |
migrate |
Rename or copy a namespace |
backfill |
Replay the candidate extractor over historical raw events |
Host integration & tooling
| Command | Description |
|---|---|
openclaw setup / doctor / uninstall / print-config |
Manage the OpenClaw integration |
harness-memory-hermes install / doctor (separate harness-memory-hermes package) |
Manage the Hermes integration |
dashboard |
Launch the local web dashboard ([dashboard] extra) |
config show / set / path |
Inspect and edit ~/.harness-memory/config.json |
🛠️ Development
Prerequisites: Python 3.11+, uv
make install # uv sync --group dev
make all # lint + typecheck + test
🤝 Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Run
make allbefore submitting - Open a Pull Request
🔗 Related projects
| Project | Description |
|---|---|
| harness-agent | Agent runtime that consumes the memory |
| harness-browser | Browser automation for memory-backed agents |
| harness-gateway | Multi-platform IM channel bridge |
| Octop | The self-hosted assistant that composes the Harness stack |
📄 License
This project is licensed under the MIT License.
Metadata
Release files for harness-memory 0.9.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| harness_memory-0.9.10.tar.gz | 1.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| harness_memory-0.9.10-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.5 MB
Release files / harness_memory-0.9.10.tar.gz
| Download URL | harness_memory-0.9.10.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d732ebd81e0fce44b3263f42e967895dec53d1bf7ac0efb10e7477b5920fde84
|
|
BLAKE2b-256 checksum How to use checksums |
ab079adef1b44381cc83f91bcb83780d504e2986baefee5a16c967d08b929c92
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.7
|
Release files / harness_memory-0.9.10-py3-none-any.whl
| Download URL | harness_memory-0.9.10-py3-none-any.whl |
|---|---|
| Size | 366.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
352446508c7398a2798cc4017365b48c855bbcfd08fe2eee57dd2a6756713559
|
|
BLAKE2b-256 checksum How to use checksums |
09d001dbdb8cf4cd3d349cc4a5c999fcf22767456d7634d965faad8a2d9ae034
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.7
|