Metadata-Version: 2.4
Name: arandu
Version: 0.11.1
Summary: Long-term memory for AI agents — wisdom acquired through experience. Extraction, entity resolution, reconciliation, and retrieval.
Project-URL: Homepage, https://pe-menezes.github.io/arandu/
Project-URL: Repository, https://github.com/pe-menezes/arandu
Project-URL: Documentation, https://pe-menezes.github.io/arandu/
Project-URL: Issues, https://github.com/pe-menezes/arandu/issues
Project-URL: Changelog, https://github.com/pe-menezes/arandu/releases
Author-email: Pedro Menezes <pedromenezesrs@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,knowledge-graph,llm,memory
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Requires-Dist: pgvector>=0.3
Requires-Dist: psycopg[binary]>=3.1
Requires-Dist: pydantic>=2.0
Requires-Dist: sqlalchemy[asyncio]>=2.0
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.30; extra == 'anthropic'
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == 'openai'
Provides-Extra: server
Requires-Dist: fastapi>=0.100; extra == 'server'
Requires-Dist: uvicorn>=0.20; extra == 'server'
Description-Content-Type: text/markdown

# arandu

[![CI](https://github.com/pe-menezes/arandu/actions/workflows/ci.yml/badge.svg)](https://github.com/pe-menezes/arandu/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/arandu)](https://pypi.org/project/arandu/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/pe-menezes/arandu/blob/main/LICENSE)
[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://pe-menezes.github.io/arandu/)
[![llms.txt](https://img.shields.io/badge/llms.txt-available-blue)](https://pe-menezes.github.io/arandu/llms-full.txt)

Long-term memory system for AI agents. Extract facts from conversations, resolve entities, reconcile updates, and retrieve relevant context — works with any LLM provider.

> **[Read the full documentation →](https://pe-menezes.github.io/arandu/)**

## Quickstart

```bash
pip install arandu[openai]
```

```python
import asyncio
from arandu import MemoryClient
from arandu.providers.openai import OpenAIProvider

provider = OpenAIProvider(api_key="sk-...")
memory = MemoryClient(
    database_url="postgresql+psycopg://user:pass@localhost/mydb",
    llm=provider,
    embeddings=provider,
)

async def main():
    await memory.initialize()  # creates tables (idempotent)

    # Write — extracts facts automatically
    result = await memory.write(user_id="user_123", message="I live in São Paulo with my wife Ana")
    print(result.facts_added)  # [{"fact_text": "Lives in São Paulo", ...}]

    # Retrieve — semantic search + keyword + LLM reranking
    context = await memory.retrieve(user_id="user_123", query="where does the user live?")
    print(context.context)  # "## Known facts about the user:\n- Lives in São Paulo ..."

asyncio.run(main())
```

## Requirements

- Python 3.11+
- PostgreSQL with [pgvector](https://github.com/pgvector/pgvector) extension
- An LLM provider (OpenAI included, or implement your own)

## Custom Providers

Implement the `LLMProvider` and `EmbeddingProvider` protocols to use any backend:

```python
from arandu.protocols import LLMProvider, EmbeddingProvider

class MyProvider:
    async def complete(self, messages, temperature=0, response_format=None, max_tokens=None) -> str:
        ...  # your LLM call

    async def embed(self, texts: list[str]) -> list[list[float]]:
        ...  # your embedding call

    async def embed_one(self, text: str) -> list[float] | None:
        ...  # single text embedding
```

## Configuration

```python
from arandu import MemoryConfig

config = MemoryConfig(
    topk_facts=20,              # max facts to retrieve
    min_similarity=0.20,        # cosine similarity threshold
    min_confidence=0.55,        # minimum fact confidence
    enable_reranker=True,       # LLM reranking of results
    recency_half_life_days=14,  # exponential decay half-life
)

memory = MemoryClient(database_url="...", llm=provider, embeddings=provider, config=config)
```

## Architecture

The SDK implements a 4-stage write pipeline and a 3-signal read pipeline:

**Write:** Message → Extract (LLM) → Entity Resolution (exact/fuzzy/LLM) → Reconcile (ADD/UPDATE/NOOP/DELETE) → Upsert

**Read:** Query → Semantic Search (pgvector) + Keyword Search (ILIKE) + Recency Scoring → LLM Rerank → Context Formatting

## Documentation

For comprehensive documentation including conceptual guides, configuration reference, and cookbook examples:

**[https://pe-menezes.github.io/arandu/](https://pe-menezes.github.io/arandu/)**

## Contributing

Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md) before submitting a pull request.

## License

[MIT](LICENSE)
