Metadata-Version: 2.4
Name: memoria-agent
Version: 0.1.0
Summary: Production-grade memory infrastructure for AI agents — storage-agnostic, self-evolving, observable.
Project-URL: Homepage, https://github.com/memoria/memoria
Project-URL: Documentation, https://memoria.dev
Project-URL: Repository, https://github.com/memoria/memoria
Project-URL: Issues, https://github.com/memoria/memoria/issues
Author: Memoria Authors
License: MIT
Keywords: agent,ai,llm,memory,rag,vector-database
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: httpx>=0.25
Requires-Dist: networkx>=3.0
Requires-Dist: openai>=1.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0
Requires-Dist: tiktoken>=0.5
Provides-Extra: all
Requires-Dist: memoria[dashboard,dev,elasticsearch,neo4j,pgvector,qdrant,redis,server]; extra == 'all'
Provides-Extra: dashboard
Requires-Dist: fastapi>=0.110; extra == 'dashboard'
Requires-Dist: uvicorn>=0.29; extra == 'dashboard'
Requires-Dist: websockets>=12.0; extra == 'dashboard'
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: elasticsearch
Requires-Dist: elasticsearch[async]>=8.0; extra == 'elasticsearch'
Provides-Extra: lancedb
Requires-Dist: lancedb>=0.17; extra == 'lancedb'
Requires-Dist: numpy>=1.24; extra == 'lancedb'
Requires-Dist: pyarrow>=12.0; extra == 'lancedb'
Requires-Dist: tantivy>=0.22; extra == 'lancedb'
Provides-Extra: neo4j
Requires-Dist: neo4j>=5.0; extra == 'neo4j'
Provides-Extra: pgvector
Requires-Dist: asyncpg>=0.29; extra == 'pgvector'
Requires-Dist: pgvector>=0.3; extra == 'pgvector'
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.9; extra == 'qdrant'
Provides-Extra: redis
Requires-Dist: hiredis>=2.0; extra == 'redis'
Requires-Dist: redis>=5.0; extra == 'redis'
Provides-Extra: server
Requires-Dist: fastapi>=0.110; extra == 'server'
Requires-Dist: uvicorn>=0.29; extra == 'server'
Requires-Dist: websockets>=12.0; extra == 'server'
Description-Content-Type: text/markdown

# Memoria

<h3 align="center">Memory Infrastructure for AI Agents</h3>

<p align="center">
  <strong>Storage-agnostic. Self-evolving. Observable.</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/memoria-agent"><img src="https://img.shields.io/pypi/v/memoria" alt="PyPI"></a>
  <a href="https://github.com/Oxygen56/memoria/actions"><img src="https://img.shields.io/github/actions/workflow/status/Oxygen56/memoria/ci.yml" alt="CI"></a>
  <a href="https://github.com/Oxygen56/memoria"><img src="https://img.shields.io/github/stars/Oxygen56/memoria" alt="Stars"></a>
  <a href="https://pypi.org/project/memoria-agent"><img src="https://img.shields.io/pypi/pyversions/memoria" alt="Python"></a>
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
</p>

---

## What is Memoria?

Every AI agent forgets. Claude Code doesn't remember your preferences between sessions. LangGraph agents restart from zero context. CrewAI crews have no persistent team knowledge.

**Memoria is the memory infrastructure that fixes this** — a framework-agnostic, storage-agnostic layer that gives every agent persistent, self-evolving memory. It works with Claude Code, LangGraph, CrewAI, OpenAI Agents SDK, and any agent that makes function calls.

```python
from memoria import Memoria, MemoryType

async with Memoria() as mem:
    # Your agent remembers across sessions
    await mem.remember("User prefers Redis pool size of 10", 
                        memory_type=MemoryType.PREFERENCE, importance=0.9)
    
    # Memories are proactively injected — no explicit query needed
    context = await mem.recall("I need database connection settings")
    # → Injects: "User prefers Redis pool size of 10" automatically
```

## Why Memoria?

Existing solutions each solve part of the problem, but leave critical gaps:

| Capability | Mem0 | Letta | Zep | **Memoria** |
|-----------|------|-------|-----|-------------|
| **Semantic search** | ✅ | ✅ | ✅ | ✅ |
| **Keyword search** | ❌ | ❌ | ❌ | ✅ (Tantivy FTS) |
| **Hybrid search** | ⚠️ | ❌ | ❌ | ✅ (RRF fusion) |
| **Proactive recall** | ❌ | ❌ | ❌ | ✅ **Awareness Engine** |
| **Mathematical forgetting** | ❌ | ❌ | ❌ | ✅ **Ebbinghaus Decay** |
| **Feedback learning** | ❌ | ❌ | ❌ | ✅ **Reinforcement Loop** |
| **Graph reasoning** | ⚠️ | ❌ | ✅ | ✅ **NetworkX + Neo4j** |
| **Real-time Dashboard** | ❌ | ❌ | 💰 Enterprise | ✅ **Open Source** |
| **pip install** | ✅ | ✅ (Docker) | ❌ (Neo4j) | ✅ |
| **Framework lock-in** | ❌ | ❌ (Letta runtime) | ❌ | ✅ **Framework-agnostic** |
| **Storage backend lock-in** | ⚠️ (vector DB only) | ❌ (proprietary) | ❌ (Neo4j) | ✅ **Multi-backend** |

## Architecture

```
                          ┌──────────────────────────┐
                          │   Python SDK  │  REST API │
                          │   MCP Server  │ Dashboard │
                          └──────────────┬───────────┘
                                         │
              ┌──────────────────────────┼──────────────────────────┐
              │                          │                          │
     ┌────────▼────────┐   ┌────────────▼────────┐   ┌────────────▼────────┐
     │  Awareness      │   │  Decay Engine       │   │  Feedback Engine    │
     │  Engine         │   │                     │   │                     │
     │  Proactive      │   │  Ebbinghaus-based   │   │  Usage-tracking     │
     │  context recall │   │  mathematical       │   │  reinforcement      │
     │  (no query      │   │  forgetting         │   │  loop               │
     │   required)     │   │  (automated)        │   │  (self-improving)   │
     └────────┬────────┘   └────────────┬────────┘   └────────────┬────────┘
              │                          │                          │
              └──────────────────────────┼──────────────────────────┘
                                         │
                          ┌──────────────▼──────────────┐
                          │     Storage Router           │
                          │  (multi-backend dispatch)    │
                          └──────────────┬──────────────┘
                                         │
        ┌────────────┬──────────────────┼──────────────────┬────────────┐
        ▼            ▼                  ▼                  ▼            ▼
   ┌─────────┐ ┌─────────┐    ┌──────────────┐    ┌─────────┐  ┌─────────┐
   │ LanceDB │ │ Qdrant  │    │  PostgreSQL  │    │  Neo4j  │  │  Redis  │
   │(default)│ │(production)│  │  + pgvector  │    │ (graph) │  │ (cache) │
   └─────────┘ └─────────┘    └──────────────┘    └─────────┘  └─────────┘
        ▲            ▲                  ▲                  ▲            ▲
        │            │                  │                  │            │
        └────────────┴──────────────────┴──────────────────┴────────────┘
                        MemoryStoreAdapter (plugin interface)
```

### The Four Engines

**Awareness Engine** — Proactive Memory Recall
- Computes a semantic fingerprint of every conversation turn
- Automatically injects relevant memories without requiring explicit queries
- Solves the "memaware problem": existing systems have 2.8% accuracy when the user doesn't name what to recall

**Decay Engine** — Mathematical Forgetting
- Ebbinghaus forgetting curve: `retention = ε × e^(-t/τ)`
- Each memory type has a different half-life: Preferences ∞, Facts 30d, Events 14d
- Automatically archives stale memories; deletes truly forgotten ones
- Deterministic, explainable, tunable — no LLM hallucination risk

**Feedback Engine** — Self-Improving Through Usage
- Tracks which memories are actually used vs. ignored
- Used memories → reinforced (boost importance, slow decay)
- Ignored memories → penalized (accelerate decay)
- Detects contradictions between memories

**Graph Engine** — Relationship Reasoning
- Entity extraction + relationship inference via NetworkX + optional Neo4j
- Multi-hop traversal for "why" questions
- Causal chain reconstruction from decision-type memories

## Dashboard

Memoria includes a real-time observability dashboard for agent memory — D3 force-directed memory graph, live WebSocket event stream, system health scoring, and per-memory decay curve inspection.

```bash
memoria serve --dashboard
# → http://localhost:7890/     Memory Dynamics Dashboard
# → http://localhost:7890/docs  REST API Reference (Swagger)
```

<!-- TODO: insert dashboard screenshot here -->
<!-- Run: memoria serve --dashboard, open http://localhost:7890, take screenshot -->

### Dashboard panels:

- **Memory Graph** — D3 force-directed layout. Node size = importance. Color = layer (red=hot, yellow=warm, blue=cold). Real-time updates via WebSocket.
- **Live Timeline** — Streaming log of every memory event: created, accessed, decayed, reinforced, forgotten.
- **System Health** — A-F grade across recall rate, injection efficiency, storage efficiency, and decay health.
- **Memory Inspector** — Per-memory view with decay curve, access history, relationship graph, and manual controls.

## Storage Backends

Memoria is storage-agnostic. Choose the backend that matches your infrastructure:

| Backend | Best For | Deploy | Vector | FTS | Hybrid | Graph |
|---------|----------|--------|--------|-----|--------|-------|
| **LanceDB** | Default / Single-server | Embedded | ✅ Native | ✅ Tantivy | ✅ Built-in | — |
| **Qdrant** | Production / Scale | Docker / Cloud | ✅ HNSW | ✅ BM25 | ✅ Dual-vector | — |
| **PostgreSQL + pgvector** | Infrastructure reuse | Existing PG | ✅ pgvector | ✅ tsvector | ✅ SQL fusion | — |
| **Elasticsearch** | Search-heavy workloads | Cluster | ✅ Native | ✅ BM25 | ✅ Native | — |
| **Neo4j** | Graph reasoning | Docker / Cloud | — | — | — | ✅ Cypher |
| **Redis** | Hot-layer cache | Existing Redis | — | — | — | — |

```python
# Zero config — LanceDB embedded, no external services
mem = Memoria()

# Production — Qdrant for vector search, Redis for hot cache
mem = Memoria(
    warm_backend="qdrant://qdrant.internal:6333",
    hot_backend="redis://redis.internal:6379/0",
    graph_backend="neo4j://neo4j.internal:7687",
)

# Infrastructure reuse — PostgreSQL you already have
mem = Memoria(warm_backend="pgvector://postgresql://user:pass@host:5432/db")
```

## Installation

```bash
pip install memoria-agent                    # Core: LanceDB (embedded, zero-config)

# Production backends
pip install memoria-agent[qdrant]            # Qdrant adapter
pip install memoria-agent[pgvector]          # PostgreSQL + pgvector adapter
pip install memoria-agent[neo4j]             # Neo4j graph adapter
pip install memoria-agent[redis]             # Redis hot-cache adapter

# Server + Dashboard
pip install memoria-agent[server]            # FastAPI + WebSocket + Dashboard

# Everything
pip install memoria-agent[all]
```

## Quick Start

```python
import asyncio
from memoria import Memoria, MemoryType

async def main():
    # Start memory system — LanceDB embedded, no config needed
    async with Memoria() as mem:
        # ── Remember ────────────────────────────
        await mem.remember(
            "Production database is PostgreSQL 16 on AWS RDS, us-east-1",
            memory_type=MemoryType.FACT,
            importance=0.9,
            tags=["database", "postgresql", "aws"],
        )
        
        await mem.remember(
            "User prefers Redis connection pool of 10 with 5-second timeout",
            memory_type=MemoryType.PREFERENCE,
            importance=0.9,
            tags=["redis", "config"],
        )
        
        # ── Proactive Recall ────────────────────
        # No explicit query needed — Awareness Engine injects relevant context
        ctx = await mem.recall("I need database credentials for the migration")
        print(f"Auto-injected {len(ctx.relevant)} relevant memories "
              f"({ctx.total_tokens} tokens)")
        for item in ctx.relevant:
            print(f"  [{item.memory.memory_type.value}] {item.memory.content}")
        
        # ── Explicit Search ─────────────────────
        results = await mem.search("Redis configuration", top_k=3)
        for r in results:
            print(f"  [{r.memory_type.value}] {r.content} (score: {r.decay_score:.2f})")
        
        # ── System Stats ────────────────────────
        stats = await mem.stats()
        print(f"Total: {stats.storage.total_memories} | "
              f"Health: {stats.health_score:.0f}/100 | "
              f"Backend: {stats.storage.backend_type}")

asyncio.run(main())
```

## Integrations

Memoria is framework-agnostic. It works with any agent that can make function calls.

```python
# LangGraph
from memoria import Memoria
mem = Memoria()

class MemoryAwareNode:
    async def __call__(self, state: State) -> State:
        ctx = await mem.recall(state["messages"][-1].content)
        state["system_prompt"] += ctx.to_prompt()
        return state

# CrewAI
from crewai import Agent
from memoria import Memoria
mem = Memoria()

async def memory_tool(query: str) -> str:
    ctx = await mem.recall(query)
    return ctx.to_prompt()

agent = Agent(tools=[memory_tool], ...)

# OpenAI Agents SDK
from agents import Agent, function_tool
from memoria import Memoria
mem = Memoria()

@function_tool
async def recall_memories(query: str) -> str:
    ctx = await mem.recall(query)
    return ctx.to_prompt()

agent = Agent(tools=[recall_memories], ...)
```

## Dashboard

```bash
memoria serve --dashboard
```

The Memory Dynamics Dashboard provides real-time visibility into your agent's memory system:

- **Memory Graph** — D3 force-directed visualization of all memories, colored by layer and importance
- **Live Timeline** — Real-time stream of memory events (created, accessed, decayed, forgotten)
- **Health Panel** — A-F scoring across recall rate, injection efficiency, storage efficiency, decay health
- **Memory Inspector** — Per-memory decay curve, access history, relationships, contradiction flags
- **WebSocket Stream** — All state changes pushed in real time, no polling

## Observability

```yaml
# memoria.yaml
observability:
  metrics:
    enabled: true
    prometheus_port: 9090
  tracing:
    enabled: true
    provider: opentelemetry
    endpoint: "http://jaeger:4317"
```

Prometheus metrics exposed: `memoria_memories_total`, `memoria_search_latency_seconds`, `memoria_decay_cycle_duration_seconds`, `memoria_awareness_hit_rate`, `memoria_contradictions_unresolved`.

## Configuration

```yaml
# memoria.yaml
storage:
  warm_backend:
    type: qdrant
    params:
      host: localhost
      port: 6333
      collection_name: memoria
      vector_size: 1536

awareness:
  relevance_threshold: 0.35
  token_budget_default: 200

decay:
  cycle_interval_hours: 6
  half_life_overrides:
    fact: 45
    event: 21

feedback:
  boost_per_access: 0.05
  contradiction_detection: true
```

## Documentation

- [Design Decisions](docs/design-decisions.md) — Why Memoria is built the way it is
- [Integration Guide](docs/integration-guide.md) — Adding memory to LangGraph, CrewAI, OpenAI Agents SDK
- [Performance Benchmarks](docs/benchmarks.md) — Search latency, decay accuracy, throughput
- [Production Deployment](docs/deployment.md) — Docker, Kubernetes, monitoring, backup

## Contributing

```bash
git clone https://github.com/Oxygen56/memoria.git
cd memoria
pip install -e ".[dev]"
pytest
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

MIT © Memoria Authors

---

<p align="center">
  <strong>Stop building amnesiac agents.</strong><br>
  <code>pip install memoria-agent</code>
</p>
