Metadata-Version: 2.4
Name: harness-memory
Version: 0.7.0
Summary: Pluggable memory system with hierarchical recall, FTS search, and multiple backend support.
Project-URL: Homepage, https://github.com/orcakit/harness-memory
Project-URL: Repository, https://github.com/orcakit/harness-memory
Project-URL: Issues, https://github.com/orcakit/harness-memory/issues
Project-URL: Changelog, https://github.com/orcakit/harness-memory/blob/main/CHANGELOG.md
Author: orcakit
License-Expression: MIT
License-File: LICENSE
Keywords: agent,fts,llm,memory,recall,sqlite
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Provides-Extra: cli
Requires-Dist: click>=8.0; extra == 'cli'
Provides-Extra: dev
Requires-Dist: click>=8.0; extra == 'dev'
Requires-Dist: langgraph-checkpoint-sqlite>=2.0; extra == 'dev'
Requires-Dist: langgraph-checkpoint>=2.0; extra == 'dev'
Requires-Dist: langgraph>=0.2; extra == 'dev'
Requires-Dist: mypy>=1.13; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Provides-Extra: langgraph
Requires-Dist: langgraph-checkpoint-sqlite>=2.0; extra == 'langgraph'
Requires-Dist: langgraph-checkpoint>=2.0; extra == 'langgraph'
Provides-Extra: langgraph-postgres
Requires-Dist: langgraph-checkpoint-postgres>=2.0; extra == 'langgraph-postgres'
Requires-Dist: langgraph-checkpoint>=2.0; extra == 'langgraph-postgres'
Requires-Dist: psycopg[binary]>=3.1; extra == 'langgraph-postgres'
Provides-Extra: postgres
Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.7; extra == 'qdrant'
Description-Content-Type: text/markdown

<p align="center">
  <img src="assets/images/banner.jpeg" alt="Harness Memory Banner" width="100%" />
</p>

<h1 align="center">Harness Memory</h1>

<p align="center">
  <strong>Lightweight, agent-neutral memory system — hierarchical memory tree with pluggable backends and seamless migration.</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/harness-memory/"><img src="https://img.shields.io/pypi/v/harness-memory.svg" alt="PyPI version" /></a>
  <a href="https://github.com/orcakit/harness-memory/actions/workflows/ci.yml"><img src="https://github.com/orcakit/harness-memory/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
  <a href="https://pypi.org/project/harness-memory/"><img src="https://img.shields.io/pypi/pyversions/harness-memory.svg" alt="Python versions" /></a>
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
</p>

<p align="center">
  <b>English</b> · <a href="README_CN.md">中文</a>
</p>

---

## Highlights

- **Lightweight Architecture** — A minimal memory layer that complements (not replaces) your agent's native memory, achieving a 1+1 > 2 effect
- **Agent-Neutral** — Works alongside any LLM agent without direct model interaction; never interferes with existing agent workflows
- **Pluggable & Migratable** — Swap backends freely (SQLite, PostgreSQL, Qdrant); migrate memory data seamlessly across different agents
- **Hierarchical Memory Tree** — Root → branch → leaf structure for organized long-term recall
- **Dual-Database Design** — Stores both raw conversation records and distilled memory tree for complete knowledge retention
- **Zero Dependencies** — Core package uses only Python stdlib + sqlite3; no heavy ML frameworks required
- **Full-Text Search** — FTS5/BM25 powered search across conversations and memories
- **CLI Tooling** — Complete command-line interface for ingesting, querying, and managing memories

---

## Overview

Harness Memory is a lightweight, agent-neutral memory system that provides persistent, structured memory for AI agents. It does **not** interact with LLMs directly — instead, it operates as an independent storage and recall layer that any agent can plug into, enhancing the agent's native memory without disrupting its existing workflows.

### Design Philosophy

- **Complement, not replace** — Your agent already has its own memory mechanisms. Harness Memory acts as a supplementary layer, enriching context without taking over.
- **No model coupling** — The system never calls LLMs itself. It prepares and organizes data; the agent decides when and how to use it.
- **Portable knowledge** — Memory data lives in an independent backend that can be migrated across different agents, frameworks, or deployments without loss.

### How It Differs from Other Memory Systems

| Aspect | Other Systems | Harness Memory |
|--------|--------------|----------------|
| **Backend portability** | Tied to specific agent/framework | Independent storage backend — migrate freely between agents. Supports local SQLite, remote PostgreSQL, or vector databases (Qdrant). Users can implement custom backends. |
| **Memory recall** | Tool-call only, model must request | **Pre-injection into system prompt** before reaching the model (feeds relevant context proactively) + tool-call as supplement |
| **Memory storage** | Single representation | **Dual-database**: raw conversation records (archival source of truth) + distilled memory tree (structured knowledge). Periodically cleans raw conversations into archival data, then distills them — like a "dreaming" process — into hierarchical memory nodes. |
| **Agent coupling** | Deep integration required | Agent-neutral; pluggable via CLI, Python API, or system prompt injection. Zero interference with existing agent memory. |

### Three-Phase Workflow

1. **Ingest** — Archive conversation history (Claude Code, OpenAI, generic JSONL) as raw records
2. **Distill** — Periodically "dream": clean and summarize raw conversations, then organize into the memory tree
3. **Recall** — Inject relevant memories into system prompts before model invocation; also available as agent tools

---

## Core Technology

| Component | Technology | Purpose |
|-----------|-----------|---------|
| Storage | SQLite + FTS5 | Zero-dep local persistence with BM25 search |
| Memory Model | Hierarchical tree | Root → branch → leaf organization |
| Search | FTS5/BM25 | Full-text search across conversations and memory nodes |
| Backends | Pluggable interface | SQLite (default), PostgreSQL, Qdrant |
| CLI | Click | Command-line management and automation |
| Integration | LangGraph checkpoint | Compatible with LangGraph agent state |

---

## Features

- **Memory Tree** — Hierarchical summaries (root → branch → leaf) for long-term recall
- **System Prompt Injection** — Pre-injects relevant memories before model invocation for proactive recall
- **Full-Text Search** — FTS5/BM25 powered search across conversations and memories
- **Dual Storage** — Raw conversation archives + distilled memory tree, two databases working together
- **Dream-like Distillation** — Periodically processes raw conversations into structured memory nodes
- **Conversation Records** — Standardized chat history storage and retrieval
- **CLI Tooling** — Command-line interface for ingesting, querying, and managing memories
- **Agent Skill** — Cross-platform skill for automated archival, summarization, and memory tree construction
- **Pluggable Backends** — SQLite (default, zero-dep), PostgreSQL, Qdrant, or custom
- **Zero Dependencies** — Core package uses only Python stdlib + sqlite3
- **Namespace Isolation** — Multiple agents share one database safely
- **LangGraph Integration** — Optional checkpoint backend for LangGraph agents

---

## Quick Start

### Installation

```bash
pip install harness-memory
```

With CLI support:

```bash
pip install "harness-memory[cli]"
```

Optional backends:

```bash
pip install "harness-memory[postgres]"   # PostgreSQL backend
pip install "harness-memory[qdrant]"     # Qdrant vector backend
```

### Python API

```python
from harness_memory import Memory

# Create with default SQLite backend
memory = Memory(namespace="my-agent")

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

# Recall relevant memories
results = memory.recall("programming language")
for node in results:
    print(f"[{node.topic}] {node.content}")
```

### CLI

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

# Search memories
harness-memory --namespace my-agent memory recall "user preferences"

# Store a new memory
harness-memory --namespace my-agent memory store --content "User prefers TDD" --topic "workflow"

# View the memory tree
harness-memory --namespace my-agent memory tree
```

---

## CLI Reference

The CLI provides five command groups for managing conversations and memories:

```
harness-memory [GLOBAL OPTIONS] COMMAND [ARGS]
```

**Global options:**
- `--config PATH` — Config file path (default: `~/.harness-memory/config.json`)
- `--backend, -b TYPE` — Backend type: `sqlite`, `postgres`, `qdrant`
- `--db PATH` — SQLite database path
- `--dsn DSN` — PostgreSQL connection string
- `--namespace, -n NS` — Memory namespace for isolation (default: `default`)
- `--json` — Output machine-readable JSON

### Commands

| Command | Description |
|---------|-------------|
| `config show` | Show resolved configuration |
| `config set KEY VALUE` | Set a config value |
| `ingest --source PATH` | Archive conversation files |
| `conversations list` | List stored conversations |
| `conversations export ID` | Export a conversation as JSON |
| `summary pending` | List conversations needing summaries |
| `summary set ID --content TEXT` | Set a conversation summary |
| `memory store --content TEXT` | Store a memory node |
| `memory recall QUERY` | Full-text search |
| `memory tree` | Display the memory tree |

---

## Agent Skill

The `skills/memory-agent/` directory contains a cross-platform agent skill for automated memory management. It works with Claude Code, Copilot CLI, Gemini CLI, or any agent that can invoke Bash commands.

### Workflow

```bash
# 1. Ingest recent conversations
harness-memory --namespace my-agent --json ingest --source ~/.claude/projects/

# 2. Check what needs summarizing
harness-memory --namespace my-agent --json summary pending

# 3. Export for summarization
harness-memory --namespace my-agent conversations export conv-abc123

# 4. Write summary back
harness-memory --namespace my-agent summary set conv-abc123 --content "Implemented OAuth login flow"

# 5. Store extracted knowledge
harness-memory --namespace my-agent --json memory store --content "Auth uses JWT with 24h expiry" --topic "architecture"

# 6. Recall later
harness-memory --namespace my-agent --json memory recall "authentication"
```

### Scheduling

| Task | Interval | Purpose |
|------|----------|---------|
| Ingest | Every 4 hours | Archive new conversations |
| Summarize | Daily | Generate missing summaries |
| Memory Tree | Weekly | Organize knowledge hierarchy |

---

## Python API Reference

### Memory

```python
from harness_memory import Memory

memory = Memory(namespace="my-agent", backend_config={"db_path": "~/my-memory.db"})
```

| Method | Description |
|--------|-------------|
| `store(content, topic=None)` | Store a memory as a leaf node |
| `recall(query, limit=5)` | Recall relevant memories via FTS |
| `add_conversation(record)` | Persist a conversation record |
| `search(query, limit=10)` | Full-text search across messages |
| `list_conversations(**filters)` | List conversations with filters |
| `get_conversation(id)` | Get full conversation by ID |
| `get_tree()` | Get the complete memory tree |

### Backend Configuration

```python
# SQLite (default) — zero dependencies
memory = Memory(namespace="agent", backend="sqlite")

# PostgreSQL — requires [postgres] extra
memory = Memory(namespace="agent", backend="postgres", backend_config={
    "dsn": "postgresql://user:pass@localhost/memdb"
})

# Custom backend
memory = Memory(namespace="agent", backend=my_custom_backend)
```

---

## 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

**Prerequisites:** Python 3.11+, [uv](https://docs.astral.sh/uv/)

```bash
git clone https://github.com/orcakit/harness-memory.git
cd harness-memory
make install
make all              # lint + typecheck + test (CI ship bar)
```

| Command | Description |
|---------|-------------|
| `make lint` | Ruff check + format check |
| `make format` | Auto-fix and format |
| `make typecheck` | mypy strict |
| `make test` | pytest with coverage |
| `make build` | Build wheel + sdist |

---

## Contributing

Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) and run `make all` before opening a PR.

Security issues: see [SECURITY.md](SECURITY.md).

---

## Related Projects

| Project | Description |
|---------|-------------|
| [orca (Octop)](https://github.com/orcakit/orca) | Self-hosted multi-user AI control plane |
| [harness-agent](https://github.com/orcakit/harness-agent) | Production-grade AI agent platform built on LangChain Deep Agents |
| [harness-browser](https://github.com/orcakit/harness-browser) | AI-friendly browser automation via CDP |
| [harness-gateway](https://github.com/orcakit/harness-gateway) | Multi-platform IM channel bridge for AI agents |

---

## License

[MIT](LICENSE)
