Metadata-Version: 2.4
Name: thread-recall
Version: 0.1.0
Summary: Governed, on-prem conversation memory for AI agents: per-thread history and semantic recall, with optional PII masking on write and tamper-evident audit. Zero-dependency SQLite by default.
Project-URL: Homepage, https://github.com/Pawansingh3889/thread-recall
Project-URL: Repository, https://github.com/Pawansingh3889/thread-recall
Project-URL: Governed Agent Stack, https://github.com/Pawansingh3889/governed-agent-stack
Author: Pawan Singh Kapkoti
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,conversation,embeddings,governance,memory,on-prem,pgvector,pii,semantic-search,sqlite
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: mask
Requires-Dist: pii-veil>=0.1; extra == 'mask'
Provides-Extra: mcp
Requires-Dist: fastmcp>=2.0; extra == 'mcp'
Provides-Extra: postgres
Requires-Dist: pgvector>=0.2; extra == 'postgres'
Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
Requires-Dist: sqlalchemy>=2.0; extra == 'postgres'
Description-Content-Type: text/markdown

# thread-recall

[![PyPI](https://img.shields.io/pypi/v/thread-recall)](https://pypi.org/project/thread-recall/) [![Downloads](https://static.pepy.tech/badge/thread-recall)](https://pepy.tech/projects/thread-recall)

[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/)

> Part of the [Governed Agent Stack](https://github.com/Pawansingh3889/governed-agent-stack): free, on-prem building blocks for an AI agent you can point at a real database and audit.

Governed, on-prem conversation memory for AI agents. It stores what an agent should remember across turns — per-thread history and optional semantic recall — and makes that memory **governable**: PII can be masked before it is ever written, and every write can be mirrored into a tamper-evident audit log.

The default backend is **SQLite with embeddings as JSON and cosine in Python**: zero dependencies, works immediately, nothing leaves the building. A Postgres + pgvector backend (for scale) is the next step; the scoring logic is backend-agnostic so it drops in cleanly.

This is the **write-side** companion to [sql-steward](https://github.com/Pawansingh3889/sql-steward). sql-steward is the read-only query gateway and stays read-only; thread-recall is where agent state lives, kept separate on purpose.

## Quickstart

```bash
pip install thread-recall
thread-recall demo
```

```python
from thread_recall import Memory

mem = Memory("agent.db")                      # or ":memory:"; mask=True / audit=True optional

mem.remember("thread-42", "user", "How much MRR did the pro plan make?", embedding=embed(q))
mem.remember("thread-42", "assistant", "Pro plan MRR was 297.")

mem.recent("thread-42", k=10)                 # last 10 turns, chronological
mem.search("thread-42", embed("revenue"), k=5) # nearest turns by embedding
```

## Why it's "governed"

- **PII masked on write.** `Memory(..., mask=True)` runs content through [pii-veil](https://github.com/Pawansingh3889/pii-veil) before it is stored, so raw personal data never lands in the memory store. No-op if pii-veil isn't installed.
- **Tamper-evident audit.** `Memory(..., audit=True)` mirrors every write into an [agent-blackbox](https://github.com/Pawansingh3889/agent-blackbox) hash-chained ledger, so "what did the agent choose to remember" has a checkable answer. No-op if agent-blackbox isn't installed.
- **On-prem by default.** SQLite file on your disk; embeddings generated by whatever local model you choose. Nothing is sent out.

## API

| Method | Purpose |
|---|---|
| `remember(thread_id, role, content, embedding=None, metadata=None)` | Store a turn (PII-masked first if enabled). Returns its id. |
| `recent(thread_id, k=10)` | Last k turns, chronological. |
| `search(thread_id, query_embedding, k=5)` | Semantic recall: nearest turns by cosine over stored embeddings. |
| `forget(thread_id)` | Delete a thread's memory. |
| `count(thread_id=None)` | Turn count for a thread, or overall. |

Embeddings are supplied by the caller (generate them with any local model). thread-recall stores and scores them; it does not call out to any embedding service itself.

## Roadmap

- **Postgres + pgvector backend** for scale and native nearest-neighbour (the SQLite backend computes cosine in Python, fine for thread-scoped recall, not for millions of rows).
- A thin LangGraph adapter, to use thread-recall alongside a LangGraph checkpointer.

## Develop

```bash
git clone https://github.com/Pawansingh3889/thread-recall
cd thread-recall
pip install -e ".[dev]"
pytest -q
```

## License

MIT
