# recollect

Cognitive memory system for AI applications. Activation-based retrieval with time decay, spreading activation, and token-budgeted recall.

## Install

```bash
pip install recollect                 # Includes Anthropic provider
pip install recollect[openai]         # Adds OpenAI/OpenAI-compatible provider support
```

## Quick Start

```python
import asyncio
from recollect import CognitiveMemory

async def main():
    memory = CognitiveMemory()
    await memory.connect()

    await memory.experience(
        "The team decided to migrate from Redis to PostgreSQL for persistence."
    )

    thoughts = await memory.think_about("database decisions", token_budget=500)
    for thought in thoughts:
        print(f"[{thought.activation:.2f}] {thought.content}")

    await memory.close()

asyncio.run(main())
```

## API

| Method | Description |
|--------|-------------|
| `connect(db_url=None)` | Connect to PostgreSQL. Uses `DATABASE_URL` env var if no argument. |
| `experience(content)` | Store a memory trace. LLM extracts entities, concepts, significance. |
| `think_about(query, token_budget)` | Retrieve memories that fit within a token limit. Returns `list[Thought]`. |
| `consolidate(threshold=None)` | Merge and prune weak traces. |
| `forget(trace_id)` | Remove a trace. |
| `reinforce(trace_id, factor=1.1)` | Strengthen a trace. |
| `facts(subject=None)` | List persona facts. |
| `start_session(user_id)` | Begin a scoped session. |
| `close()` | Disconnect and release resources. |

## Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `DATABASE_URL` | Yes | `postgresql://localhost:5432/memory_sdk` | PostgreSQL connection string. |
| `ANTHROPIC_API_KEY` | For Anthropic provider | -- | Anthropic API key. SDK resolves automatically. |
| `OPENAI_API_KEY` | For OpenAI provider | -- | OpenAI API key. Required by `OpenAIProvider`. |
| `ANTHROPIC_MODEL` | No | `claude-haiku-4-5-20251001` | Override default Anthropic extraction model. |
| `OPENAI_MODEL` | No | `gpt-5-mini` | Override default OpenAI extraction model. |
| `OLLAMA_MODEL` | No | `qwen3.5` | Override default Ollama extraction model. |
| `ANTHROPIC_BASE_URL` | No | api.anthropic.com | Override Anthropic API endpoint. |
| `OPENAI_BASE_URL` | No | api.openai.com | Override OpenAI API endpoint. |
| `OLLAMA_BASE_URL` | No | `http://localhost:11434/v1` | Ollama API endpoint. |
| `MEMORY_CONFIG` | No | -- | Path to custom TOML config file. |
| `MEMORY_EXTRACTION_INSTRUCTIONS` | No | -- | Override extraction prompt instructions. |

## Configuration

Defaults ship in `config.toml`. Override by placing a `memory.toml` in your working directory, or set `MEMORY_CONFIG` to a custom path. Only include keys you want to change:

```toml
[memory]
decay_rate = 0.05

[retrieval]
max_retrievals = 10

[extraction]
max_tokens = 2048
```

### Config sections

| Section | Controls | Key parameters |
|---------|----------|----------------|
| `[database]` | PostgreSQL connection | `url` |
| `[memory]` | Core memory model | `initial_strength`, `consolidation_threshold`, `decay_rate` |
| `[working_memory]` | Working memory capacity | `capacity` (default 7, range 5-9) |
| `[retrieval]` | Retrieval pipeline tuning | `max_retrievals`, `search_limit`, `selection_threshold` |
| `[extraction]` | LLM extraction | `max_tokens`, `max_concepts`, `max_relations` |
| `[embedding]` | Local embedding model | `model`, `dimensions` |
| `[persona]` | Persona fact management | `auto_extract`, `confidence_threshold` |
| `[session]` | Session summaries | `summary_strength`, `summary_max_tokens` |

Full defaults: [`config.toml`](src/recollect/config.toml)

Or pass a path directly:

```python
from recollect.config import MemoryConfig

config = MemoryConfig(config_path=Path("./my-config.toml"))
memory = CognitiveMemory(config=config)
```

## LLM Providers

Three providers behind the `LLMProvider` protocol. All share the same constructor signature: `(model, api_key, base_url, defaults)`.

### Anthropic (default)

```python
from recollect.llm.anthropic import AnthropicProvider
from recollect.extraction import PatternExtractor

provider = AnthropicProvider()  # uses ANTHROPIC_API_KEY
extractor = PatternExtractor(provider)
memory = CognitiveMemory(extractor=extractor)
```

### OpenAI

Requires `pip install recollect[openai]`.

```python
from recollect.llm.openai import OpenAIProvider

provider = OpenAIProvider()  # uses OPENAI_API_KEY
```

### Ollama / LM Studio (OpenAI-compatible)

```python
from recollect.llm.openai_compat import OpenAICompatProvider

# Ollama
provider = OpenAICompatProvider(
    model="qwen3.5",
    base_url="http://localhost:11434/v1",
)

# LM Studio
provider = OpenAICompatProvider(
    model="your-model",
    base_url="http://localhost:1234/v1",
)
```

### Reasoning models

Models that use internal chain-of-thought (OpenAI o1/o3, Qwen3, DeepSeek-R1) consume thinking tokens from the `max_tokens` budget. If extraction returns empty responses, increase the token budget:

```toml
# memory.toml
[extraction]
max_tokens = 8192
```

The default is 4096, which provides sufficient headroom for most models.

## Requirements

- Python 3.12+
- PostgreSQL 17 with [pgvector](https://github.com/pgvector/pgvector)
- `DATABASE_URL` environment variable

## License

MIT
