Metadata-Version: 2.4
Name: anima-mem
Version: 0.1.0
Summary: Long-term structured memory for AI agents — facts, hybrid search, profiles, and MCP.
Project-URL: Homepage, https://github.com/themillenniumfalcon/anima
Project-URL: Repository, https://github.com/themillenniumfalcon/anima
Author: Nishank Priydarshi
License-Expression: MIT
License-File: LICENSE
Keywords: agents,llm,mcp,memory,rag
Requires-Python: >=3.12
Requires-Dist: faiss-cpu>=1.14.2
Requires-Dist: httpx>=0.28.1
Requires-Dist: mcp>=1.27.2
Requires-Dist: networkx>=3.4
Requires-Dist: numpy>=2.4.6
Requires-Dist: pydantic>=2.13.4
Requires-Dist: rank-bm25>=0.2.2
Requires-Dist: sentence-transformers>=5.5.1
Requires-Dist: sqlalchemy>=2.0.50
Provides-Extra: benchmark
Requires-Dist: huggingface-hub>=0.25.0; extra == 'benchmark'
Requires-Dist: python-dotenv>=1.2.2; extra == 'benchmark'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=1.4.0; extra == 'dev'
Requires-Dist: pytest>=9.0.3; extra == 'dev'
Requires-Dist: python-dotenv>=1.2.2; extra == 'dev'
Description-Content-Type: text/markdown

# anima

Long-term, structured memory for AI agents. Extract facts from conversations, deduplicate and supersede them over time, search with hybrid semantic + BM25 retrieval, maintain user profiles, and expose everything over a clean Python library or MCP server.

## Features

- **Fact extraction** — LLM-backed extraction from conversation turns (OpenRouter by default)
- **Deduplication** — embedding similarity + slot rules + LLM review; supersede outdated facts
- **Temporal validity** — facts are superseded, not deleted, so you can answer “what did we know before?”
- **Production embeddings** — local `sentence-transformers` or OpenAI by default (not random vectors)
- **Hybrid search** — FAISS semantic recall + BM25 rerank, fused with confidence and recency
- **Document ingestion** — chunk and index Markdown (extensible ingester registry)
- **User profiles** — incremental O(1) profile updates on every `add()` (requires LLM)
- **Entity graph** — optional NetworkX graph of entities and relationships (requires LLM)
- **Lifecycle** — confidence decay, TTL expiry, signal-based `watch()` auto-save
- **MCP server** — six tools for Cursor, Claude Desktop, or any MCP client
- **Export / import** — JSON backup and restore of memories + profile

## Requirements

- Python 3.12+
- [uv](https://docs.astral.sh/uv/) (recommended for development) or pip

## Quickstart

### Install

```bash
pip install anima-mem
```

Optional extras:

```bash
pip install "anima-mem[dev]"        # pytest, pytest-asyncio, python-dotenv
pip install "anima-mem[benchmark]"  # LoCoMo benchmark runner deps (see Development)
```

### Python API

```python
import asyncio
from anima import Config, Memory

async def main():
    mem = Memory(config=Config.from_env())

    await mem.add("User: I moved to Berlin last week.", user_id="alice")
    result = mem.search("Where does Alice live?", user_id="alice")
    print(result.injected_prompt)

    page = mem.list("alice", limit=20)
    print(f"{len(page.items)} of {page.total} memories")

asyncio.run(main())
```

Without `OPENROUTER_API_KEY`, `Memory()` still works for storage and search: each message is stored as a single raw fact and embeddings default to local `sentence-transformers`. LLM extraction, dedup review, profiles, and entity graph population require `OPENROUTER_API_KEY`.

### MCP server

After installing from PyPI:

```json
{
  "mcpServers": {
    "anima": {
      "command": "anima-mcp"
    }
  }
}
```

From a local clone (stdio transport):

```json
{
  "mcpServers": {
    "anima": {
      "command": "uv",
      "args": ["run", "anima-mcp"],
      "cwd": "/path/to/anima"
    }
  }
}
```

**Tools:** `memory_add`, `memory_search`, `memory_profile`, `memory_ingest_file`, `memory_list`, `memory_delete`

### User-controlled memory API

| Method | Description |
|--------|-------------|
| `mem.list(user_id, offset=0, limit=50)` | Paginated memory list |
| `mem.pin(memory_id)` | Mark permanent (no decay / TTL deletion) |
| `mem.export(user_id)` | `MemoryExport` JSON snapshot |
| `mem.import_memories(data)` | Restore from export |

```python
export_data = mem.export("alice").model_dump(mode="json")
# ... later or on another machine ...
mem.import_memories(export_data)
```

## Configuration

Set environment variables before creating `Memory(config=Config.from_env())`. The library reads `os.environ` only — export variables in your shell or use a tool that loads `.env` (e.g. `uv run`).

Full list: [.env.example](https://github.com/themillenniumfalcon/anima/blob/main/.env.example)

| Variable | Default | Purpose |
|----------|---------|---------|
| `OPENROUTER_API_KEY` | — | LLM extraction, dedup, profiles, graph |
| `DATABASE_URL` | `sqlite:///./anima.db` | SQLAlchemy URL |
| `VECTOR_STORE_PATH` | `./data/faiss` | FAISS index directory |
| `GRAPH_STORE_PATH` | `./data/graph` | Entity graph JSON |
| `EMBEDDER` | `st` (or `openai` if `OPENAI_API_KEY` set) | `st` or `openai` |
| `EMBEDDING_DIM` | `1536` (OpenAI) / auto for ST | Set for OpenAI; ST uses model dim |
| `ST_MODEL` | `all-MiniLM-L6-v2` | Local embedding model |
| `DECAY_RATE_PER_WEEK` | `0.05` | Confidence decay rate |
| `WATCH_KEYWORDS` | `remember,...` | `watch()` trigger phrases |

`Memory(config=Config.from_env())` picks a production embedder automatically. Override explicitly if needed:

```python
from anima import Memory, Config, build_embedder

embed_fn, dim = build_embedder()
cfg = Config.from_env()
cfg.embedding_dim = dim
mem = Memory(config=cfg, embed_fn=embed_fn)
```

## Development

Clone the repository (required for tests, benchmarks, and lint):

```bash
git clone https://github.com/themillenniumfalcon/anima.git
cd anima
cp .env.example .env   # OPENROUTER_API_KEY — extraction, dedup, profile, graph
uv sync --extra dev    # or: pip install -e ".[dev]"
uv run pytest -v
uv run ruff check src tests
```

### Benchmarks

LoCoMo evaluation requires a repo checkout (the runner is not shipped on PyPI):

```bash
uv sync --extra benchmark   # or: pip install -e ".[benchmark]"
uv run python benchmarks/run_locomo.py
```

Methodology: [benchmarks/README.md](https://github.com/themillenniumfalcon/anima/benchmarks/README.md)

## License

MIT — see [LICENSE](LICENSE).
