Skip to main content

Pluggable memory system with hierarchical recall, FTS search, and multiple backend support.

Project description

Harness Memory Banner

Harness Memory

Pluggable long-term memory system for LLM agents — structured recall, full-text search, and automatic knowledge extraction from conversations.

PyPI version CI Python versions License: MIT

English · 中文


Highlights

  • Zero Dependencies — Core package uses only Python stdlib + sqlite3; no heavy ML frameworks required
  • L0→L4 Memory Pipeline — Automatic extraction of facts from conversations, promotion to structured atoms, entity pages, and audit journal
  • Multi-Stage Recall — 8-stage pipeline: query parsing, routing, rerank, diversify, suppress, token budget, cache, co-reference resolution
  • Hierarchical Memory Tree — Manual root → branch → leaf structure; auto-mirrored from the pipeline
  • Pluggable Backends — SQLite (default), PostgreSQL
  • Host Integrations — Native plugins for OpenClaw and Hermes agent platforms
  • Full CLI — 20+ command groups for every layer of the system

How It Works

Harness Memory runs a five-layer pipeline that converts raw conversation events into structured, searchable knowledge:

L0  RawEvent       Every message/tool-call captured from the host agent (immutable)
      │  LLM extraction (session_end or daily)
      ▼
L1  Candidate      LLM-extracted fact awaiting promotion (Fact/Decision/Task/Preference)
      │  5-check promotion worker (value → evidence → entity → duplicate → conflict)
      ▼
L2  AtomCard       Structured fact linked to an entity, FTS-indexed, append-only
      │  grouped by
      ▼
L3  Entity         Anchor node (User/Person/Project/…) + alias table
    EntityPage     LLM-generated markdown summary, auto-regenerated on change
      │  every mutation logged to
      ▼
L4  Journal        Append-only audit log (promote/merge/conflict/deprecate/gc)

At recall time, a query runs through the recall pipeline (router → multi-source gather → rerank → diversify → suppress → budget) and returns snippets from atoms, entity page headlines, the memory tree, and raw events — merged and ranked in a single pass.


Quick Start

Installation

pip install harness-memory

With CLI support:

pip install "harness-memory[cli]"

Optional backends:

pip install "harness-memory[postgres]"   # PostgreSQL backend

Python API

from harness_memory import Memory
from harness_memory.recall import recall_for_prompt_v2

memory = Memory(namespace="my-agent")

# Store a memory node manually
memory.store("User prefers Python over Java", topic="preferences")

# Recall via the full M4 pipeline (atom + tree + raw, reranked)
result = recall_for_prompt_v2(memory, "programming language preference")
print(result.rendered)   # markdown block ready for prompt injection

# Or recall manually stored tree nodes
for node in memory.recall("programming language"):
    print(f"[{node.topic}] {node.content}")

Auto-extraction from conversations

from harness_memory import Memory
from harness_memory.extractor import CandidateExtractor
from harness_memory.llm import LLMClient  # plug in your host LLM

memory = Memory(namespace="my-agent")
extractor = CandidateExtractor(llm=my_llm_client)

# At session end: extract candidates from L0 raw events
from harness_memory.extractor import extract_session
result = extract_session(memory=memory, extractor=extractor, session_id="sess-123")

# Promote pending candidates to structured atoms
promotion = memory.promote_candidates()
print(f"promoted={promotion.promoted}, merged={promotion.merged}, conflicts={promotion.conflicts}")

CLI

# Ingest conversation files
harness-memory --namespace my-agent ingest --source ~/.claude/projects/myapp/

# Recall
harness-memory --namespace my-agent recall "user authentication preferences"

# Inspect the pipeline
harness-memory --namespace my-agent candidate list --status pending
harness-memory --namespace my-agent atom list --entity-id <id>
harness-memory --namespace my-agent entity list
harness-memory --namespace my-agent memory tree

# Operations
harness-memory --namespace my-agent export --out backup.jsonl
harness-memory --namespace my-agent gc run

Architecture

Storage Layers

Layer Type Table(s) Description
L0 RawEvent raw_events Immutable event log; source of truth
L1 Candidate candidates LLM-extracted facts awaiting promotion
L2 AtomCard atoms Promoted structured facts; primary recall source
L3 Entity, EntityPage, Alias entities, entity_pages, aliases Entity anchors + auto-generated summaries
L4 JournalEntry journal Append-only audit log
MemoryNode memory_nodes Manual / auto-mirrored hierarchical tree

Promotion Pipeline (L1 → L2)

The promotion worker runs 5 checks in order. First terminal result wins:

  1. Value — drop if importance=low AND confidence=low (chit-chat noise)
  2. Evidence — verify cited raw event IDs exist in L0
  3. Entity — resolve or create the entity this fact belongs to (alias → name → LLM → new)
  4. Duplicate — merge if an identical assertion already exists on the entity
  5. Conflict — flag if polarity flips vs an existing atom (negation detection)

Recall Pipeline (M4)

recall_for_prompt_v2 runs 8 stages per query:

parse query → route (entity/time/coref hints) → gather (atom+tree+raw)
→ rerank (BM25 + importance + confidence + recency + layer_prior)
→ diversify (≤N per entity) → suppress (Jaccard dedup)
→ token budget enforcement → cache → render markdown

Memory Tree ↔ Pipeline Bridge

The MemoryNode tree and the L0–L4 pipeline are bridged in both directions:

  • Write: every promoted AtomCard is auto-mirrored as a leaf node under an entity branch in the tree (tagged metadata["mirror"]="auto"). Best-effort — tree failure never rolls back the atom.
  • Read: recall_for_prompt_v2 queries atom + tree + raw and merges results through the rerank/suppress pipeline. Tree layer prior = 0.70 (between atom 1.0 and raw 0.50).

CLI Reference

harness-memory [GLOBAL OPTIONS] COMMAND [ARGS]

Global options: --config PATH, --backend sqlite|postgres, --db PATH, --dsn DSN, --namespace NS, --json

Command group Description
config show/set Show or set configuration values
ingest Archive conversation files (Claude Code, OpenAI, generic JSONL)
conversations list/export Manage stored conversations
summary pending/set Manage conversation summaries
raw add/list/search/show L0 raw event management
candidate list/show/review L1 candidate inspection and manual review
atom list/show/search L2 atom inspection
entity list/show L3 entity management
page show/regen/edit L3 entity page management
journal list L4 audit log
memory store/get/update/delete/tree/recall MemoryNode tree management
recall Run the full M4 recall pipeline
thread list/show/delete LangGraph checkpoint thread management
export / import / migrate / backfill Migration and data operations
gc run Garbage collection
openclaw setup/doctor OpenClaw host integration
hermes install/doctor Hermes host integration

Host Integrations

Harness Memory can run as a native memory provider inside agent hosting platforms.

OpenClaw

pip install "harness-memory[cli]"
openclaw plugins install npm:@agentmemory/openclaw-plugin
harness-memory openclaw setup    # register the plugin and bridge Python
harness-memory openclaw doctor   # verify the integration

The OpenClaw plugin (plugins/openclaw/agentmemory/) is a TypeScript shell that spawns the Python bridge (agentmemory-bridge) and registers registerMemoryCapability with the host runtime.

Hermes

pip install harness-memory-hermes
harness-memory-hermes install    # install the Hermes adapter
harness-memory-hermes doctor     # verify the integration

See docs/release-packaging.md for release artifact boundaries and docs/agentmemory-openclaw-hermes-usage.md for source-checkout setup guides.


Python API Reference

Memory

from harness_memory import Memory

memory = Memory(namespace="my-agent", backend="sqlite",
                backend_config={"db_path": "~/my-memory.db"})
Method Layer Description
store(content, topic, level, parent_id, metadata) Tree Create a MemoryNode
recall(query, limit) Tree FTS search over tree nodes
add_raw(content, event_type, ...) L0 Append a raw event
add_candidate(candidate) L1 Persist a candidate
promote_candidates(candidates, limit, llm_hook) L1→L2 Run promotion worker
add_atom(atom) L2 Persist an atom directly
search_atoms(query, limit) L2 FTS search over atoms
add_entity(entity) L3 Persist an entity
upsert_entity_page(page) L3 Upsert an entity page
append_journal(entry) L4 Append an audit entry
list_journal(...) L4 Query the audit log
add_conversation(record) Conv Persist a conversation
search(query, limit) Conv FTS over conversation messages

Recall

from harness_memory.recall import recall_for_prompt_v2

result = recall_for_prompt_v2(
    memory,
    query="authentication flow",
    thread_id="thread-abc",   # enables co-reference resolution
    limit=5,
    total_budget_tokens=1500,
)
print(result.rendered)        # inject directly into prompt
for snippet in result.snippets:
    print(snippet.layer, snippet.text)   # "atom" | "tree" | "raw"

Supported Conversation Formats

Format Extension Detection
Claude Code .jsonl type field: human_message / assistant_message
Generic JSONL .jsonl role + content fields per line
OpenAI JSON .json messages array with role/content objects

Development

make dev          # Install dev dependencies
make lint         # Ruff check + format check
make typecheck    # mypy strict
make test         # pytest
make all          # lint + typecheck + test

Related Projects

Project Description
harness-agent Production-grade AI agent platform built on LangChain Deep Agents
harness-browser AI-friendly browser automation via CDP
harness-im-bridge Multi-platform IM channel bridge for AI agents

License

MIT

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

harness_memory-0.1.2.tar.gz (34.5 MB view details)

Uploaded Source

Built Distribution

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

harness_memory-0.1.2-py3-none-any.whl (229.8 kB view details)

Uploaded Python 3

File details

Details for the file harness_memory-0.1.2.tar.gz.

File metadata

  • Download URL: harness_memory-0.1.2.tar.gz
  • Upload date:
  • Size: 34.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.20

File hashes

Hashes for harness_memory-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f1f2d20f0406bd521fc69257027aa69ccf0839782d7dca9a045e9bfb3bbb5d2e
MD5 d4f04b064d4dad8174dac96f7c2ee93a
BLAKE2b-256 7e9ca765ad08a245878c3215695f42ff6acf17b6dee909528e1000415c2cd439

See more details on using hashes here.

File details

Details for the file harness_memory-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for harness_memory-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 11e4f110b5d006a596f306d3db463f8e49ecc42572babed6f854aa7f3208ab04
MD5 d0aead4318530109ec1adf0977d677be
BLAKE2b-256 6fc6da0b755ec8d5b91ef1a9657ebdd9fa40cd59444655a01f13b319da2d377b

See more details on using hashes here.

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