Metadata-Version: 2.4
Name: shaheen-db
Version: 1.0.0
Summary: A lightweight, self-consolidating cognitive memory layer for AI agents. Combines SQLite, vector search, and a knowledge graph with a biologically-inspired sleep/forget cycle.
Author-email: Saif <spellsaif@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/spellsaif/shaheen-db
Project-URL: Repository, https://github.com/spellsaif/shaheen-db
Project-URL: Bug Tracker, https://github.com/spellsaif/shaheen-db/issues
Keywords: ai,agent,memory,cognitive,database,vector,knowledge-graph,graphrag,llm,rag,sqlite,embeddings,openai,gemini,anthropic
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.20.0
Requires-Dist: openai>=1.0.0
Requires-Dist: google-genai>=0.1.0
Requires-Dist: pydantic>=2.0
Provides-Extra: fastembed
Requires-Dist: fastembed>=0.8.0; extra == "fastembed"
Provides-Extra: local
Requires-Dist: fastembed>=0.8.0; extra == "local"
Provides-Extra: sentence
Requires-Dist: sentence-transformers>=2.2.0; extra == "sentence"
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.18.0; extra == "anthropic"
Provides-Extra: all
Requires-Dist: fastembed>=0.8.0; extra == "all"
Requires-Dist: anthropic>=0.18.0; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-mock>=3.6.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: hypothesis>=6.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Dynamic: license-file

# Shaheen DB

[![PyPI version](https://img.shields.io/pypi/v/shaheen-db.svg)](https://pypi.org/project/shaheen-db/)
[![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://github.com/spellsaif/shaheen-db)
[![Python Version](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-32%20passing-brightgreen.svg)]()
[![Database](https://img.shields.io/badge/database-SQLite--WAL-orange.svg)]()

[GitHub Repository](https://github.com/spellsaif/shaheen-db)

```bash
pip install shaheen-db
```

**Shaheen DB** is a local-first cognitive memory database for AI agents.

It is named after my adorable cousin, **Shaheen**. The name was already taken in the family, so the database has big expectations to live up to.

Shaheen is not another vector database. It stores observations, evolves beliefs, keeps history, tracks contradictions, remembers relationships, and helps agents recall useful context over time.

The core idea:

> Memories are evidence. Beliefs are evolving interpretations of evidence.

---

## What Changed

Most memory systems store old messages and search them later.

Shaheen does more:

```text
User says in 2025:
"My favorite language is Rust."

User says in 2026:
"Actually Zig is my favorite language now."
```

Shaheen stores both messages, but it also creates:

```text
Current belief:
- favorite_language = Zig

History:
- 2025-01-12: favorite_language = Rust
- 2026-02-03: favorite_language = Zig

Contradiction:
- Rust -> Zig
```

So your agent can answer:

```text
"What language do I prefer now?"      -> Zig
"What language did I prefer in 2025?" -> Rust
```

without guessing.

---

## Install

Core install:

```bash
pip install shaheen-db
```

Local semantic recall with FastEmbed/ONNX:

```bash
pip install shaheen-db[fastembed]
```

Claude extraction support:

```bash
pip install shaheen-db[anthropic]
```

From this repo:

```bash
pip install -e .[dev]
```

Python 3.12+ is required.

---

## Two Ways To Use Shaheen

Shaheen can be used in two styles.

**Simple Agent Mode**

Use this when you want Shaheen to provide memory context to an AI agent.

```python
from shaheen import Shaheen

memory = Shaheen("agent.db")
turns_since_sleep = 0


def handle_message(user_message: str) -> str:
    global turns_since_sleep

    # 1. Store the raw observation immediately.
    memory.remember(user_message, subject="user")
    turns_since_sleep += 1

    # 2. Consolidate every few turns so Shaheen can update beliefs,
    # contradictions, timelines, and graph relationships.
    if turns_since_sleep >= 10:
        memory.consolidate(subject="user")
        turns_since_sleep = 0

    # 3. Retrieve useful memory context for the agent.
    context = memory.recall(user_message, subject="user")

    answer = llm.chat(
        message=user_message,
        context=context.to_prompt(),
    )

    # 4. Optionally store the assistant response too.
    memory.remember(answer, subject="assistant")
    return answer
```

For small apps, this threshold-based pattern is enough. For production apps, you can run `memory.consolidate(subject="user")` in a background worker, idle-time job, or scheduled task.

The usual loop is:

```text
remember -> consolidate -> recall
```

**Manual Cognitive Database Mode**

Use this when you want direct control over beliefs, timelines, contradictions, and relationships.

```python
from shaheen import Shaheen

memory = Shaheen("agent.db")

memory.remember(
    "My favorite language is Rust.",
    subject="user",
    observed_at="2025-01-12",
)
memory.consolidate(subject="user")

memory.remember(
    "Actually Zig is my favorite language now.",
    subject="user",
    observed_at="2026-02-03",
)
memory.consolidate(subject="user")

current = memory.belief("favorite_language", subject="user")
old = memory.belief("favorite_language", subject="user", at="2025-06-01")

print(current.value)
# Zig

print(old.value)
# Rust
```

---

## Core APIs

### remember

Stores an observation.

```python
receipt = memory.remember(
    "I prefer concise answers.",
    subject="user",
)

print(receipt.memory_id)
```

`subject="user"` means the memory is about the user. You can also use subjects like:

```python
subject="assistant"
subject="project:shaheen"
subject="user:alice"
```

### consolidate

Turns raw observations into beliefs and relationships.

```python
report = memory.consolidate(subject="user")

print(report.processed)
print(report.created_beliefs)
print(report.contradictions)
```

### recall

Builds useful context for an agent.

```python
result = memory.recall(
    "What language should I use for a systems project?",
    subject="user",
)

print(result.context)
```

Example:

```text
Current beliefs:
- favorite_language = Zig (confidence: 0.85, importance: 0.85)

Relevant memories:
- [2026-02-03] Actually Zig is my favorite language now. (score: 0.52)
```

Historical recall:

```python
result = memory.recall(
    "What was my favorite language?",
    subject="user",
    at="2025-06-01",
)

print(result.context)
```

### belief and beliefs

Ask what Shaheen currently believes.

```python
belief = memory.belief("favorite_language", subject="user")
print(belief.value)

for belief in memory.beliefs(subject="user"):
    print(belief.key, belief.value, belief.confidence)
```

### preferences

List learned preferences.

```python
for preference in memory.preferences(subject="user"):
    print(preference.key, preference.value)
```

### timeline

See how a belief changed.

```python
timeline = memory.timeline("favorite_language", subject="user")

for event in timeline.events:
    print(event.timestamp.date(), event.value, event.confidence)
```

### contradictions

Inspect belief changes.

```python
for contradiction in memory.contradictions(subject="user"):
    print(contradiction.old_value, "->", contradiction.new_value)
```

### relationships

Shaheen stores graph relationships.

```python
memory.remember(
    "I am building Shaheen and Shaheen uses SQLite.",
    subject="user",
)
memory.consolidate(subject="user")

for relationship in memory.relationships(subject="user"):
    print(relationship.source, relationship.type, relationship.target)
```

Output:

```text
user BUILDS shaheen
shaheen USES sqlite
```

### explain

Ask why Shaheen believes something.

```python
print(memory.explain("favorite_language", subject="user"))
```

Example:

```text
Shaheen believes favorite_language = Zig. Previous value was Rust.
```

### reinforce and forget

Strengthen or archive a memory.

```python
reinforced = memory.reinforce(receipt.memory_id, amount=3)
archived = memory.forget(receipt.memory_id)
```

### stats and benchmark

```python
print(memory.stats())

bench = memory.benchmark(iterations=100, subject="bench")
print(bench["insertion_per_second"])
```

---

## Embeddings

Shaheen works without embeddings by default.

```python
memory = Shaheen("agent.db")
```

This keeps the base package lightweight. You still get:

- memory insertion;
- consolidation;
- beliefs;
- belief history;
- contradictions;
- graph relationships;
- lexical recall;
- temporal recall.

Turn on local semantic recall with FastEmbed:

```bash
pip install shaheen-db[fastembed]
```

```python
memory = Shaheen("agent.db", embeddings="fastembed")
```

`embeddings=True` is shorthand for FastEmbed:

```python
memory = Shaheen("agent.db", embeddings=True)
```

Use the legacy/provider embedding adapter:

```python
memory = Shaheen("agent.db", embeddings="provider")
```

Embeddings improve fuzzy natural-language recall. They are optional.

---

## Extractors And AI Providers

The extractor turns raw memories into structured beliefs and graph relationships.

Default extractor, no API key:

```python
memory = Shaheen("agent.db")
# same as:
memory = Shaheen("agent.db", extractor="heuristic")
```

This is deterministic, offline, and testable.

Use an LLM extractor when you want richer extraction:

```python
memory = Shaheen("agent.db", extractor="llm")
```

`extractor="llm"` auto-selects from `SHAHEEN_LLM_PROVIDER`.

You can also choose explicitly:

```python
memory = Shaheen("agent.db", extractor="openai")
memory = Shaheen("agent.db", extractor="gemini")
memory = Shaheen("agent.db", extractor="claude")
```

If the provider is missing or fails, Shaheen falls back to the heuristic extractor.

### OpenAI-Compatible

Works with OpenAI, OpenRouter, Groq, DeepSeek, Ollama, LM Studio, and other OpenAI-compatible APIs.

```bash
export SHAHEEN_LLM_PROVIDER="openai"
export SHAHEEN_LLM_API_KEY="your-key"
export SHAHEEN_LLM_MODEL="gpt-4o-mini"
```

```python
memory = Shaheen("agent.db", extractor="llm")
# or
memory = Shaheen("agent.db", extractor="openai")
```

Local OpenAI-compatible server:

```bash
export SHAHEEN_LLM_PROVIDER="openai"
export SHAHEEN_LLM_BASE_URL="http://localhost:11434/v1"
export SHAHEEN_LLM_API_KEY="ollama"
export SHAHEEN_LLM_MODEL="llama3"
```

### Gemini

```bash
export SHAHEEN_LLM_PROVIDER="gemini"
export GEMINI_API_KEY="your-gemini-key"
export SHAHEEN_LLM_MODEL="gemini-2.5-flash"
```

```python
memory = Shaheen("agent.db", extractor="llm")
# or
memory = Shaheen("agent.db", extractor="gemini")
```

### Claude

Install the optional Anthropic extra:

```bash
pip install shaheen-db[anthropic]
```

Configure:

```bash
export SHAHEEN_LLM_PROVIDER="anthropic"
export ANTHROPIC_API_KEY="your-anthropic-key"
export SHAHEEN_LLM_MODEL="claude-3-5-sonnet-20241022"
```

```python
memory = Shaheen("agent.db", extractor="llm")
# or
memory = Shaheen("agent.db", extractor="claude")
```

---

## Development

```bash
pip install -e .[dev]
python -m pytest -q
python -m ruff check shaheen tests demo.py
python -m mypy shaheen demo.py
python demo.py
```

Current verification:

```text
32 tests passing
Ruff passing
Mypy passing
Demo passing
Package build passing
Twine check passing
```

---

## Architecture

See:

- [Architecture](docs/architecture.md)
- [ADRs](docs/adr)

Key decisions:

- SQLite-first, adapter-ready;
- no legacy migration promise;
- belief history is never destroyed;
- graph relationships are first-class;
- LLM extraction is optional with deterministic fallback;
- embeddings are optional and FastEmbed is the recommended local path.

---

## License

Shaheen DB is open-source software licensed under the [MIT License](LICENSE).
