Skip to main content

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.

Project description

Shaheen DB

PyPI version Version Python Version License Tests Database

GitHub Repository

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:

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:

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:

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

without guessing.


Install

Core install:

pip install shaheen-db

Local semantic recall with FastEmbed/ONNX:

pip install shaheen-db[fastembed]

Claude extraction support:

pip install shaheen-db[anthropic]

From this repo:

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.

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:

remember -> consolidate -> recall

Manual Cognitive Database Mode

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

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.

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:

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

consolidate

Turns raw observations into beliefs and relationships.

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

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

recall

Builds useful context for an agent.

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

print(result.context)

Example:

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:

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.

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.

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

timeline

See how a belief changed.

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

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

contradictions

Inspect belief changes.

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

relationships

Shaheen stores graph relationships.

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:

user BUILDS shaheen
shaheen USES sqlite

explain

Ask why Shaheen believes something.

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

Example:

Shaheen believes favorite_language = Zig. Previous value was Rust.

reinforce and forget

Strengthen or archive a memory.

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

stats and benchmark

print(memory.stats())

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

Embeddings

Shaheen works without embeddings by default.

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:

pip install shaheen-db[fastembed]
memory = Shaheen("agent.db", embeddings="fastembed")

embeddings=True is shorthand for FastEmbed:

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

Use the legacy/provider embedding adapter:

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:

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:

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

extractor="llm" auto-selects from SHAHEEN_LLM_PROVIDER.

You can also choose explicitly:

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.

export SHAHEEN_LLM_PROVIDER="openai"
export SHAHEEN_LLM_API_KEY="your-key"
export SHAHEEN_LLM_MODEL="gpt-4o-mini"
memory = Shaheen("agent.db", extractor="llm")
# or
memory = Shaheen("agent.db", extractor="openai")

Local OpenAI-compatible server:

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

export SHAHEEN_LLM_PROVIDER="gemini"
export GEMINI_API_KEY="your-gemini-key"
export SHAHEEN_LLM_MODEL="gemini-2.5-flash"
memory = Shaheen("agent.db", extractor="llm")
# or
memory = Shaheen("agent.db", extractor="gemini")

Claude

Install the optional Anthropic extra:

pip install shaheen-db[anthropic]

Configure:

export SHAHEEN_LLM_PROVIDER="anthropic"
export ANTHROPIC_API_KEY="your-anthropic-key"
export SHAHEEN_LLM_MODEL="claude-3-5-sonnet-20241022"
memory = Shaheen("agent.db", extractor="llm")
# or
memory = Shaheen("agent.db", extractor="claude")

Development

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:

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

Architecture

See:

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shaheen_db-1.0.0.tar.gz (42.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shaheen_db-1.0.0-py3-none-any.whl (40.6 kB view details)

Uploaded Python 3

File details

Details for the file shaheen_db-1.0.0.tar.gz.

File metadata

  • Download URL: shaheen_db-1.0.0.tar.gz
  • Upload date:
  • Size: 42.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for shaheen_db-1.0.0.tar.gz
Algorithm Hash digest
SHA256 e40b10896d30c0b48bf444461ecef91c0a547bc92f5cd36cbba2f942e5df9ddd
MD5 567385c77f3cb03e47807f1ee4b3ec64
BLAKE2b-256 6411ff50e0a9255afee53ea1107f05bc93782cd265a0cbe5f6d3109dab311c5d

See more details on using hashes here.

File details

Details for the file shaheen_db-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: shaheen_db-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 40.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for shaheen_db-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a390016e4517d4c0830f2f73c21b7b6a0e60d46e42b33a4fcba81dbbffd6d839
MD5 068a0a8b28df2d2a392322f815d7a399
BLAKE2b-256 b9d08700ad2d0f71b1a51ad39e07a21dc534968bba783cf8c3d95e7cf07f08b6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page