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 |
db slim FILE [--apply --offline] |
SQLite shortcut: preview by default; apply creates a unique backup, deduplicates checkpoint fields and runs VACUUM without deleting history |
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 against
main
See CONTRIBUTING.md for branching, PR, and release details (release/* → main auto-publishes to PyPI).
🔗 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.11
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| harness_memory-0.9.11.tar.gz | 1.2 MB | Without provenance | Details for harness_memory-0.9.11.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| harness_memory-0.9.11-py3-none-any.whl | Python 3 | none | any | Details for harness_memory-0.9.11-py3-none-any.whl |
Total release size: 1.6 MB
Release files / harness_memory-0.9.11.tar.gz
| Download URL | harness_memory-0.9.11.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b03dfa7d5543455da858732ab5edcbd7875cbfcb219b0306a56ae920ba4b8e78
|
|
BLAKE2b-256 checksum How to use checksums |
58cc6dbe35a4917e3edf378223e61f03a021ce48be45d6320a260d4a46af0ef6
|
| 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.11-py3-none-any.whl
| Download URL | harness_memory-0.9.11-py3-none-any.whl |
|---|---|
| Size | 370.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
65bb58689c537b6f9adef2b6a19b711dff226833318205ab21b7724fceb93c8f
|
|
BLAKE2b-256 checksum How to use checksums |
87828a0c5c6624d4bc845449f76823ce424c13802a32629fe4590cc903727d7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.7
|
Security for harness-memory 0.9.11
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.