memoria-agent 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- memoria_agent-0.1.0/.github/ISSUE_TEMPLATE/bug.yml +29 -0
- memoria_agent-0.1.0/.github/ISSUE_TEMPLATE/feature.yml +16 -0
- memoria_agent-0.1.0/.github/workflows/ci.yml +42 -0
- memoria_agent-0.1.0/.gitignore +14 -0
- memoria_agent-0.1.0/CHANGELOG.md +28 -0
- memoria_agent-0.1.0/CONTRIBUTING.md +47 -0
- memoria_agent-0.1.0/PKG-INFO +417 -0
- memoria_agent-0.1.0/README.md +354 -0
- memoria_agent-0.1.0/dashboard/index.html +13 -0
- memoria_agent-0.1.0/dashboard/package-lock.json +2613 -0
- memoria_agent-0.1.0/dashboard/package.json +24 -0
- memoria_agent-0.1.0/dashboard/src/App.tsx +182 -0
- memoria_agent-0.1.0/dashboard/src/components/Header.tsx +113 -0
- memoria_agent-0.1.0/dashboard/src/components/HealthDashboard.tsx +106 -0
- memoria_agent-0.1.0/dashboard/src/components/MemoryGraph.tsx +142 -0
- memoria_agent-0.1.0/dashboard/src/components/MemoryInspector.tsx +99 -0
- memoria_agent-0.1.0/dashboard/src/components/MemoryTimeline.tsx +65 -0
- memoria_agent-0.1.0/dashboard/src/hooks/useMemoriaAPI.ts +43 -0
- memoria_agent-0.1.0/dashboard/src/hooks/useWebSocket.ts +36 -0
- memoria_agent-0.1.0/dashboard/src/main.tsx +10 -0
- memoria_agent-0.1.0/dashboard/src/styles/index.css +48 -0
- memoria_agent-0.1.0/dashboard/src/types.ts +51 -0
- memoria_agent-0.1.0/dashboard/tsconfig.json +17 -0
- memoria_agent-0.1.0/dashboard/vite.config.ts +20 -0
- memoria_agent-0.1.0/docs/benchmarks.md +93 -0
- memoria_agent-0.1.0/docs/deployment.md +255 -0
- memoria_agent-0.1.0/docs/design-decisions.md +147 -0
- memoria_agent-0.1.0/docs/integration-guide.md +231 -0
- memoria_agent-0.1.0/docs/launch-post.md +68 -0
- memoria_agent-0.1.0/examples/basic_usage.py +117 -0
- memoria_agent-0.1.0/examples/dev_assistant.py +147 -0
- memoria_agent-0.1.0/examples/langgraph_integration.py +97 -0
- memoria_agent-0.1.0/pyproject.toml +77 -0
- memoria_agent-0.1.0/pytest.ini +3 -0
- memoria_agent-0.1.0/src/memoria/__init__.py +56 -0
- memoria_agent-0.1.0/src/memoria/api/server.py +358 -0
- memoria_agent-0.1.0/src/memoria/cli/__init__.py +0 -0
- memoria_agent-0.1.0/src/memoria/cli/main.py +115 -0
- memoria_agent-0.1.0/src/memoria/core/__init__.py +0 -0
- memoria_agent-0.1.0/src/memoria/core/config.py +105 -0
- memoria_agent-0.1.0/src/memoria/core/exceptions.py +25 -0
- memoria_agent-0.1.0/src/memoria/core/memoria.py +520 -0
- memoria_agent-0.1.0/src/memoria/core/models.py +250 -0
- memoria_agent-0.1.0/src/memoria/embedding/__init__.py +0 -0
- memoria_agent-0.1.0/src/memoria/embedding/base.py +143 -0
- memoria_agent-0.1.0/src/memoria/engines/__init__.py +0 -0
- memoria_agent-0.1.0/src/memoria/engines/awareness.py +289 -0
- memoria_agent-0.1.0/src/memoria/engines/decay.py +248 -0
- memoria_agent-0.1.0/src/memoria/engines/feedback.py +271 -0
- memoria_agent-0.1.0/src/memoria/mcp/__init__.py +0 -0
- memoria_agent-0.1.0/src/memoria/storage/__init__.py +0 -0
- memoria_agent-0.1.0/src/memoria/storage/base.py +120 -0
- memoria_agent-0.1.0/src/memoria/storage/lancedb_adapter.py +417 -0
- memoria_agent-0.1.0/src/memoria/storage/memory_adapter.py +169 -0
- memoria_agent-0.1.0/src/memoria/storage/qdrant_adapter.py +325 -0
- memoria_agent-0.1.0/src/memoria/storage/redis_adapter.py +186 -0
- memoria_agent-0.1.0/src/memoria/storage/router.py +266 -0
- memoria_agent-0.1.0/tests/benchmarks/test_search_benchmark.py +117 -0
- memoria_agent-0.1.0/tests/conftest.py +17 -0
- memoria_agent-0.1.0/tests/test_engines.py +241 -0
- memoria_agent-0.1.0/tests/test_memoria.py +122 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug in Memoria
|
|
3
|
+
labels: [bug]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
attributes:
|
|
7
|
+
label: Description
|
|
8
|
+
description: What happened? What did you expect to happen?
|
|
9
|
+
validations:
|
|
10
|
+
required: true
|
|
11
|
+
- type: textarea
|
|
12
|
+
attributes:
|
|
13
|
+
label: Reproduction
|
|
14
|
+
description: Minimal code to reproduce the issue
|
|
15
|
+
render: python
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: input
|
|
19
|
+
attributes:
|
|
20
|
+
label: Memoria Version
|
|
21
|
+
description: "`pip show memoria-agent`"
|
|
22
|
+
- type: input
|
|
23
|
+
attributes:
|
|
24
|
+
label: Python Version
|
|
25
|
+
description: "`python --version`"
|
|
26
|
+
- type: input
|
|
27
|
+
attributes:
|
|
28
|
+
label: Storage Backend
|
|
29
|
+
description: LanceDB / Qdrant / PostgreSQL / etc.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a feature for Memoria
|
|
3
|
+
labels: [enhancement]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
attributes:
|
|
7
|
+
label: Feature Description
|
|
8
|
+
description: What should Memoria do that it doesn't today?
|
|
9
|
+
validations:
|
|
10
|
+
required: true
|
|
11
|
+
- type: textarea
|
|
12
|
+
attributes:
|
|
13
|
+
label: Use Case
|
|
14
|
+
description: How would you use this feature?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: |
|
|
26
|
+
pip install -e ".[dev]"
|
|
27
|
+
|
|
28
|
+
- name: Run tests
|
|
29
|
+
run: pytest -v
|
|
30
|
+
|
|
31
|
+
- name: Run benchmarks
|
|
32
|
+
run: python tests/benchmarks/test_search_benchmark.py
|
|
33
|
+
|
|
34
|
+
lint:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.12"
|
|
41
|
+
- run: pip install ruff
|
|
42
|
+
- run: ruff check src/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Memoria will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] — 2026-06-06
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Awareness Engine**: proactive memory recall via semantic fingerprinting and hybrid search
|
|
9
|
+
- **Decay Engine**: Ebbinghaus-based mathematical forgetting with type-specific half-lives
|
|
10
|
+
- **Feedback Engine**: usage-tracking reinforcement loop with contradiction detection
|
|
11
|
+
- **Graph Engine**: entity-relationship reasoning via NetworkX with optional Neo4j
|
|
12
|
+
- **Storage Router**: multi-backend dispatch with plugin architecture
|
|
13
|
+
- LanceDB adapter (default, embedded, zero-config)
|
|
14
|
+
- Qdrant adapter (HNSW vector index + BM25 hybrid search)
|
|
15
|
+
- PostgreSQL+pgvector adapter (infrastructure reuse)
|
|
16
|
+
- Redis adapter (sub-millisecond hot-layer cache)
|
|
17
|
+
- InMemory adapter (testing and lightweight usage)
|
|
18
|
+
- FastAPI REST API: 16 endpoints (CRUD, search, recall, stats, admin)
|
|
19
|
+
- WebSocket server: real-time memory event streaming
|
|
20
|
+
- React + D3.js Memory Dynamics Dashboard
|
|
21
|
+
- CLI: `memoria serve`, `memoria dashboard`, `memoria stats`, `memoria search`, `memoria remember`
|
|
22
|
+
- Python SDK: `Memoria.remember()`, `Memoria.recall()`, `Memoria.search()`, `Memoria.forget()`, `Memoria.edit()`, `Memoria.reinforce()`
|
|
23
|
+
- 7 memory types: FACT, PREFERENCE, EVENT, DECISION, SKILL, RELATIONSHIP, CONSTRAINT
|
|
24
|
+
- 4 memory layers: HOT, WARM, COLD, OBLIVION
|
|
25
|
+
- OpenTelemetry + Prometheus observability integration
|
|
26
|
+
- Configuration via YAML file or programmatic API
|
|
27
|
+
- 23 tests covering engines, models, and API
|
|
28
|
+
- Documentation: design decisions, integration guide, benchmarks, deployment guide
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Contributing to Memoria
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/Oxygen56/memoria.git
|
|
9
|
+
cd memoria
|
|
10
|
+
pip install -e ".[dev]"
|
|
11
|
+
pytest
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Running Tests
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pytest -v # Unit tests
|
|
18
|
+
python tests/benchmarks/test_search_benchmark.py # Benchmarks
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Project Structure
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
src/memoria/
|
|
25
|
+
core/ # Models, config, main Memoria class
|
|
26
|
+
storage/ # Storage adapters (LanceDB, Qdrant, etc.)
|
|
27
|
+
engines/ # Awareness, Decay, Feedback, Graph engines
|
|
28
|
+
embedding/ # Embedding providers (OpenAI, local)
|
|
29
|
+
api/ # FastAPI REST API + WebSocket
|
|
30
|
+
cli/ # CLI entry point
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Pull Request Process
|
|
34
|
+
|
|
35
|
+
1. Fork the repository
|
|
36
|
+
2. Create a feature branch
|
|
37
|
+
3. Add tests for new functionality
|
|
38
|
+
4. Ensure all tests pass (`pytest`)
|
|
39
|
+
5. Submit a PR against `main`
|
|
40
|
+
|
|
41
|
+
## Adding a Storage Adapter
|
|
42
|
+
|
|
43
|
+
Implement `MemoryStoreAdapter` from `memoria.storage.base`. See existing adapters in `src/memoria/storage/` for examples.
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memoria-agent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Production-grade memory infrastructure for AI agents — storage-agnostic, self-evolving, observable.
|
|
5
|
+
Project-URL: Homepage, https://github.com/memoria/memoria
|
|
6
|
+
Project-URL: Documentation, https://memoria.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/memoria/memoria
|
|
8
|
+
Project-URL: Issues, https://github.com/memoria/memoria/issues
|
|
9
|
+
Author: Memoria Authors
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: agent,ai,llm,memory,rag,vector-database
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Requires-Dist: httpx>=0.25
|
|
23
|
+
Requires-Dist: networkx>=3.0
|
|
24
|
+
Requires-Dist: openai>=1.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0
|
|
26
|
+
Requires-Dist: pyyaml>=6.0
|
|
27
|
+
Requires-Dist: rich>=13.0
|
|
28
|
+
Requires-Dist: tiktoken>=0.5
|
|
29
|
+
Provides-Extra: all
|
|
30
|
+
Requires-Dist: memoria[dashboard,dev,elasticsearch,neo4j,pgvector,qdrant,redis,server]; extra == 'all'
|
|
31
|
+
Provides-Extra: dashboard
|
|
32
|
+
Requires-Dist: fastapi>=0.110; extra == 'dashboard'
|
|
33
|
+
Requires-Dist: uvicorn>=0.29; extra == 'dashboard'
|
|
34
|
+
Requires-Dist: websockets>=12.0; extra == 'dashboard'
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
41
|
+
Provides-Extra: elasticsearch
|
|
42
|
+
Requires-Dist: elasticsearch[async]>=8.0; extra == 'elasticsearch'
|
|
43
|
+
Provides-Extra: lancedb
|
|
44
|
+
Requires-Dist: lancedb>=0.17; extra == 'lancedb'
|
|
45
|
+
Requires-Dist: numpy>=1.24; extra == 'lancedb'
|
|
46
|
+
Requires-Dist: pyarrow>=12.0; extra == 'lancedb'
|
|
47
|
+
Requires-Dist: tantivy>=0.22; extra == 'lancedb'
|
|
48
|
+
Provides-Extra: neo4j
|
|
49
|
+
Requires-Dist: neo4j>=5.0; extra == 'neo4j'
|
|
50
|
+
Provides-Extra: pgvector
|
|
51
|
+
Requires-Dist: asyncpg>=0.29; extra == 'pgvector'
|
|
52
|
+
Requires-Dist: pgvector>=0.3; extra == 'pgvector'
|
|
53
|
+
Provides-Extra: qdrant
|
|
54
|
+
Requires-Dist: qdrant-client>=1.9; extra == 'qdrant'
|
|
55
|
+
Provides-Extra: redis
|
|
56
|
+
Requires-Dist: hiredis>=2.0; extra == 'redis'
|
|
57
|
+
Requires-Dist: redis>=5.0; extra == 'redis'
|
|
58
|
+
Provides-Extra: server
|
|
59
|
+
Requires-Dist: fastapi>=0.110; extra == 'server'
|
|
60
|
+
Requires-Dist: uvicorn>=0.29; extra == 'server'
|
|
61
|
+
Requires-Dist: websockets>=12.0; extra == 'server'
|
|
62
|
+
Description-Content-Type: text/markdown
|
|
63
|
+
|
|
64
|
+
# Memoria
|
|
65
|
+
|
|
66
|
+
<h3 align="center">Memory Infrastructure for AI Agents</h3>
|
|
67
|
+
|
|
68
|
+
<p align="center">
|
|
69
|
+
<strong>Storage-agnostic. Self-evolving. Observable.</strong>
|
|
70
|
+
</p>
|
|
71
|
+
|
|
72
|
+
<p align="center">
|
|
73
|
+
<a href="https://pypi.org/project/memoria-agent"><img src="https://img.shields.io/pypi/v/memoria" alt="PyPI"></a>
|
|
74
|
+
<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>
|
|
75
|
+
<a href="https://github.com/Oxygen56/memoria"><img src="https://img.shields.io/github/stars/Oxygen56/memoria" alt="Stars"></a>
|
|
76
|
+
<a href="https://pypi.org/project/memoria-agent"><img src="https://img.shields.io/pypi/pyversions/memoria" alt="Python"></a>
|
|
77
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
|
|
78
|
+
</p>
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## What is Memoria?
|
|
83
|
+
|
|
84
|
+
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.
|
|
85
|
+
|
|
86
|
+
**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.
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from memoria import Memoria, MemoryType
|
|
90
|
+
|
|
91
|
+
async with Memoria() as mem:
|
|
92
|
+
# Your agent remembers across sessions
|
|
93
|
+
await mem.remember("User prefers Redis pool size of 10",
|
|
94
|
+
memory_type=MemoryType.PREFERENCE, importance=0.9)
|
|
95
|
+
|
|
96
|
+
# Memories are proactively injected — no explicit query needed
|
|
97
|
+
context = await mem.recall("I need database connection settings")
|
|
98
|
+
# → Injects: "User prefers Redis pool size of 10" automatically
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Why Memoria?
|
|
102
|
+
|
|
103
|
+
Existing solutions each solve part of the problem, but leave critical gaps:
|
|
104
|
+
|
|
105
|
+
| Capability | Mem0 | Letta | Zep | **Memoria** |
|
|
106
|
+
|-----------|------|-------|-----|-------------|
|
|
107
|
+
| **Semantic search** | ✅ | ✅ | ✅ | ✅ |
|
|
108
|
+
| **Keyword search** | ❌ | ❌ | ❌ | ✅ (Tantivy FTS) |
|
|
109
|
+
| **Hybrid search** | ⚠️ | ❌ | ❌ | ✅ (RRF fusion) |
|
|
110
|
+
| **Proactive recall** | ❌ | ❌ | ❌ | ✅ **Awareness Engine** |
|
|
111
|
+
| **Mathematical forgetting** | ❌ | ❌ | ❌ | ✅ **Ebbinghaus Decay** |
|
|
112
|
+
| **Feedback learning** | ❌ | ❌ | ❌ | ✅ **Reinforcement Loop** |
|
|
113
|
+
| **Graph reasoning** | ⚠️ | ❌ | ✅ | ✅ **NetworkX + Neo4j** |
|
|
114
|
+
| **Real-time Dashboard** | ❌ | ❌ | 💰 Enterprise | ✅ **Open Source** |
|
|
115
|
+
| **pip install** | ✅ | ✅ (Docker) | ❌ (Neo4j) | ✅ |
|
|
116
|
+
| **Framework lock-in** | ❌ | ❌ (Letta runtime) | ❌ | ✅ **Framework-agnostic** |
|
|
117
|
+
| **Storage backend lock-in** | ⚠️ (vector DB only) | ❌ (proprietary) | ❌ (Neo4j) | ✅ **Multi-backend** |
|
|
118
|
+
|
|
119
|
+
## Architecture
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
┌──────────────────────────┐
|
|
123
|
+
│ Python SDK │ REST API │
|
|
124
|
+
│ MCP Server │ Dashboard │
|
|
125
|
+
└──────────────┬───────────┘
|
|
126
|
+
│
|
|
127
|
+
┌──────────────────────────┼──────────────────────────┐
|
|
128
|
+
│ │ │
|
|
129
|
+
┌────────▼────────┐ ┌────────────▼────────┐ ┌────────────▼────────┐
|
|
130
|
+
│ Awareness │ │ Decay Engine │ │ Feedback Engine │
|
|
131
|
+
│ Engine │ │ │ │ │
|
|
132
|
+
│ Proactive │ │ Ebbinghaus-based │ │ Usage-tracking │
|
|
133
|
+
│ context recall │ │ mathematical │ │ reinforcement │
|
|
134
|
+
│ (no query │ │ forgetting │ │ loop │
|
|
135
|
+
│ required) │ │ (automated) │ │ (self-improving) │
|
|
136
|
+
└────────┬────────┘ └────────────┬────────┘ └────────────┬────────┘
|
|
137
|
+
│ │ │
|
|
138
|
+
└──────────────────────────┼──────────────────────────┘
|
|
139
|
+
│
|
|
140
|
+
┌──────────────▼──────────────┐
|
|
141
|
+
│ Storage Router │
|
|
142
|
+
│ (multi-backend dispatch) │
|
|
143
|
+
└──────────────┬──────────────┘
|
|
144
|
+
│
|
|
145
|
+
┌────────────┬──────────────────┼──────────────────┬────────────┐
|
|
146
|
+
▼ ▼ ▼ ▼ ▼
|
|
147
|
+
┌─────────┐ ┌─────────┐ ┌──────────────┐ ┌─────────┐ ┌─────────┐
|
|
148
|
+
│ LanceDB │ │ Qdrant │ │ PostgreSQL │ │ Neo4j │ │ Redis │
|
|
149
|
+
│(default)│ │(production)│ │ + pgvector │ │ (graph) │ │ (cache) │
|
|
150
|
+
└─────────┘ └─────────┘ └──────────────┘ └─────────┘ └─────────┘
|
|
151
|
+
▲ ▲ ▲ ▲ ▲
|
|
152
|
+
│ │ │ │ │
|
|
153
|
+
└────────────┴──────────────────┴──────────────────┴────────────┘
|
|
154
|
+
MemoryStoreAdapter (plugin interface)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### The Four Engines
|
|
158
|
+
|
|
159
|
+
**Awareness Engine** — Proactive Memory Recall
|
|
160
|
+
- Computes a semantic fingerprint of every conversation turn
|
|
161
|
+
- Automatically injects relevant memories without requiring explicit queries
|
|
162
|
+
- Solves the "memaware problem": existing systems have 2.8% accuracy when the user doesn't name what to recall
|
|
163
|
+
|
|
164
|
+
**Decay Engine** — Mathematical Forgetting
|
|
165
|
+
- Ebbinghaus forgetting curve: `retention = ε × e^(-t/τ)`
|
|
166
|
+
- Each memory type has a different half-life: Preferences ∞, Facts 30d, Events 14d
|
|
167
|
+
- Automatically archives stale memories; deletes truly forgotten ones
|
|
168
|
+
- Deterministic, explainable, tunable — no LLM hallucination risk
|
|
169
|
+
|
|
170
|
+
**Feedback Engine** — Self-Improving Through Usage
|
|
171
|
+
- Tracks which memories are actually used vs. ignored
|
|
172
|
+
- Used memories → reinforced (boost importance, slow decay)
|
|
173
|
+
- Ignored memories → penalized (accelerate decay)
|
|
174
|
+
- Detects contradictions between memories
|
|
175
|
+
|
|
176
|
+
**Graph Engine** — Relationship Reasoning
|
|
177
|
+
- Entity extraction + relationship inference via NetworkX + optional Neo4j
|
|
178
|
+
- Multi-hop traversal for "why" questions
|
|
179
|
+
- Causal chain reconstruction from decision-type memories
|
|
180
|
+
|
|
181
|
+
## Dashboard
|
|
182
|
+
|
|
183
|
+
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.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
memoria serve --dashboard
|
|
187
|
+
# → http://localhost:7890/ Memory Dynamics Dashboard
|
|
188
|
+
# → http://localhost:7890/docs REST API Reference (Swagger)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
<!-- TODO: insert dashboard screenshot here -->
|
|
192
|
+
<!-- Run: memoria serve --dashboard, open http://localhost:7890, take screenshot -->
|
|
193
|
+
|
|
194
|
+
### Dashboard panels:
|
|
195
|
+
|
|
196
|
+
- **Memory Graph** — D3 force-directed layout. Node size = importance. Color = layer (red=hot, yellow=warm, blue=cold). Real-time updates via WebSocket.
|
|
197
|
+
- **Live Timeline** — Streaming log of every memory event: created, accessed, decayed, reinforced, forgotten.
|
|
198
|
+
- **System Health** — A-F grade across recall rate, injection efficiency, storage efficiency, and decay health.
|
|
199
|
+
- **Memory Inspector** — Per-memory view with decay curve, access history, relationship graph, and manual controls.
|
|
200
|
+
|
|
201
|
+
## Storage Backends
|
|
202
|
+
|
|
203
|
+
Memoria is storage-agnostic. Choose the backend that matches your infrastructure:
|
|
204
|
+
|
|
205
|
+
| Backend | Best For | Deploy | Vector | FTS | Hybrid | Graph |
|
|
206
|
+
|---------|----------|--------|--------|-----|--------|-------|
|
|
207
|
+
| **LanceDB** | Default / Single-server | Embedded | ✅ Native | ✅ Tantivy | ✅ Built-in | — |
|
|
208
|
+
| **Qdrant** | Production / Scale | Docker / Cloud | ✅ HNSW | ✅ BM25 | ✅ Dual-vector | — |
|
|
209
|
+
| **PostgreSQL + pgvector** | Infrastructure reuse | Existing PG | ✅ pgvector | ✅ tsvector | ✅ SQL fusion | — |
|
|
210
|
+
| **Elasticsearch** | Search-heavy workloads | Cluster | ✅ Native | ✅ BM25 | ✅ Native | — |
|
|
211
|
+
| **Neo4j** | Graph reasoning | Docker / Cloud | — | — | — | ✅ Cypher |
|
|
212
|
+
| **Redis** | Hot-layer cache | Existing Redis | — | — | — | — |
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
# Zero config — LanceDB embedded, no external services
|
|
216
|
+
mem = Memoria()
|
|
217
|
+
|
|
218
|
+
# Production — Qdrant for vector search, Redis for hot cache
|
|
219
|
+
mem = Memoria(
|
|
220
|
+
warm_backend="qdrant://qdrant.internal:6333",
|
|
221
|
+
hot_backend="redis://redis.internal:6379/0",
|
|
222
|
+
graph_backend="neo4j://neo4j.internal:7687",
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Infrastructure reuse — PostgreSQL you already have
|
|
226
|
+
mem = Memoria(warm_backend="pgvector://postgresql://user:pass@host:5432/db")
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Installation
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
pip install memoria-agent # Core: LanceDB (embedded, zero-config)
|
|
233
|
+
|
|
234
|
+
# Production backends
|
|
235
|
+
pip install memoria-agent[qdrant] # Qdrant adapter
|
|
236
|
+
pip install memoria-agent[pgvector] # PostgreSQL + pgvector adapter
|
|
237
|
+
pip install memoria-agent[neo4j] # Neo4j graph adapter
|
|
238
|
+
pip install memoria-agent[redis] # Redis hot-cache adapter
|
|
239
|
+
|
|
240
|
+
# Server + Dashboard
|
|
241
|
+
pip install memoria-agent[server] # FastAPI + WebSocket + Dashboard
|
|
242
|
+
|
|
243
|
+
# Everything
|
|
244
|
+
pip install memoria-agent[all]
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Quick Start
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
import asyncio
|
|
251
|
+
from memoria import Memoria, MemoryType
|
|
252
|
+
|
|
253
|
+
async def main():
|
|
254
|
+
# Start memory system — LanceDB embedded, no config needed
|
|
255
|
+
async with Memoria() as mem:
|
|
256
|
+
# ── Remember ────────────────────────────
|
|
257
|
+
await mem.remember(
|
|
258
|
+
"Production database is PostgreSQL 16 on AWS RDS, us-east-1",
|
|
259
|
+
memory_type=MemoryType.FACT,
|
|
260
|
+
importance=0.9,
|
|
261
|
+
tags=["database", "postgresql", "aws"],
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
await mem.remember(
|
|
265
|
+
"User prefers Redis connection pool of 10 with 5-second timeout",
|
|
266
|
+
memory_type=MemoryType.PREFERENCE,
|
|
267
|
+
importance=0.9,
|
|
268
|
+
tags=["redis", "config"],
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
# ── Proactive Recall ────────────────────
|
|
272
|
+
# No explicit query needed — Awareness Engine injects relevant context
|
|
273
|
+
ctx = await mem.recall("I need database credentials for the migration")
|
|
274
|
+
print(f"Auto-injected {len(ctx.relevant)} relevant memories "
|
|
275
|
+
f"({ctx.total_tokens} tokens)")
|
|
276
|
+
for item in ctx.relevant:
|
|
277
|
+
print(f" [{item.memory.memory_type.value}] {item.memory.content}")
|
|
278
|
+
|
|
279
|
+
# ── Explicit Search ─────────────────────
|
|
280
|
+
results = await mem.search("Redis configuration", top_k=3)
|
|
281
|
+
for r in results:
|
|
282
|
+
print(f" [{r.memory_type.value}] {r.content} (score: {r.decay_score:.2f})")
|
|
283
|
+
|
|
284
|
+
# ── System Stats ────────────────────────
|
|
285
|
+
stats = await mem.stats()
|
|
286
|
+
print(f"Total: {stats.storage.total_memories} | "
|
|
287
|
+
f"Health: {stats.health_score:.0f}/100 | "
|
|
288
|
+
f"Backend: {stats.storage.backend_type}")
|
|
289
|
+
|
|
290
|
+
asyncio.run(main())
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Integrations
|
|
294
|
+
|
|
295
|
+
Memoria is framework-agnostic. It works with any agent that can make function calls.
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
# LangGraph
|
|
299
|
+
from memoria import Memoria
|
|
300
|
+
mem = Memoria()
|
|
301
|
+
|
|
302
|
+
class MemoryAwareNode:
|
|
303
|
+
async def __call__(self, state: State) -> State:
|
|
304
|
+
ctx = await mem.recall(state["messages"][-1].content)
|
|
305
|
+
state["system_prompt"] += ctx.to_prompt()
|
|
306
|
+
return state
|
|
307
|
+
|
|
308
|
+
# CrewAI
|
|
309
|
+
from crewai import Agent
|
|
310
|
+
from memoria import Memoria
|
|
311
|
+
mem = Memoria()
|
|
312
|
+
|
|
313
|
+
async def memory_tool(query: str) -> str:
|
|
314
|
+
ctx = await mem.recall(query)
|
|
315
|
+
return ctx.to_prompt()
|
|
316
|
+
|
|
317
|
+
agent = Agent(tools=[memory_tool], ...)
|
|
318
|
+
|
|
319
|
+
# OpenAI Agents SDK
|
|
320
|
+
from agents import Agent, function_tool
|
|
321
|
+
from memoria import Memoria
|
|
322
|
+
mem = Memoria()
|
|
323
|
+
|
|
324
|
+
@function_tool
|
|
325
|
+
async def recall_memories(query: str) -> str:
|
|
326
|
+
ctx = await mem.recall(query)
|
|
327
|
+
return ctx.to_prompt()
|
|
328
|
+
|
|
329
|
+
agent = Agent(tools=[recall_memories], ...)
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Dashboard
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
memoria serve --dashboard
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
The Memory Dynamics Dashboard provides real-time visibility into your agent's memory system:
|
|
339
|
+
|
|
340
|
+
- **Memory Graph** — D3 force-directed visualization of all memories, colored by layer and importance
|
|
341
|
+
- **Live Timeline** — Real-time stream of memory events (created, accessed, decayed, forgotten)
|
|
342
|
+
- **Health Panel** — A-F scoring across recall rate, injection efficiency, storage efficiency, decay health
|
|
343
|
+
- **Memory Inspector** — Per-memory decay curve, access history, relationships, contradiction flags
|
|
344
|
+
- **WebSocket Stream** — All state changes pushed in real time, no polling
|
|
345
|
+
|
|
346
|
+
## Observability
|
|
347
|
+
|
|
348
|
+
```yaml
|
|
349
|
+
# memoria.yaml
|
|
350
|
+
observability:
|
|
351
|
+
metrics:
|
|
352
|
+
enabled: true
|
|
353
|
+
prometheus_port: 9090
|
|
354
|
+
tracing:
|
|
355
|
+
enabled: true
|
|
356
|
+
provider: opentelemetry
|
|
357
|
+
endpoint: "http://jaeger:4317"
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Prometheus metrics exposed: `memoria_memories_total`, `memoria_search_latency_seconds`, `memoria_decay_cycle_duration_seconds`, `memoria_awareness_hit_rate`, `memoria_contradictions_unresolved`.
|
|
361
|
+
|
|
362
|
+
## Configuration
|
|
363
|
+
|
|
364
|
+
```yaml
|
|
365
|
+
# memoria.yaml
|
|
366
|
+
storage:
|
|
367
|
+
warm_backend:
|
|
368
|
+
type: qdrant
|
|
369
|
+
params:
|
|
370
|
+
host: localhost
|
|
371
|
+
port: 6333
|
|
372
|
+
collection_name: memoria
|
|
373
|
+
vector_size: 1536
|
|
374
|
+
|
|
375
|
+
awareness:
|
|
376
|
+
relevance_threshold: 0.35
|
|
377
|
+
token_budget_default: 200
|
|
378
|
+
|
|
379
|
+
decay:
|
|
380
|
+
cycle_interval_hours: 6
|
|
381
|
+
half_life_overrides:
|
|
382
|
+
fact: 45
|
|
383
|
+
event: 21
|
|
384
|
+
|
|
385
|
+
feedback:
|
|
386
|
+
boost_per_access: 0.05
|
|
387
|
+
contradiction_detection: true
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Documentation
|
|
391
|
+
|
|
392
|
+
- [Design Decisions](docs/design-decisions.md) — Why Memoria is built the way it is
|
|
393
|
+
- [Integration Guide](docs/integration-guide.md) — Adding memory to LangGraph, CrewAI, OpenAI Agents SDK
|
|
394
|
+
- [Performance Benchmarks](docs/benchmarks.md) — Search latency, decay accuracy, throughput
|
|
395
|
+
- [Production Deployment](docs/deployment.md) — Docker, Kubernetes, monitoring, backup
|
|
396
|
+
|
|
397
|
+
## Contributing
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
git clone https://github.com/Oxygen56/memoria.git
|
|
401
|
+
cd memoria
|
|
402
|
+
pip install -e ".[dev]"
|
|
403
|
+
pytest
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
407
|
+
|
|
408
|
+
## License
|
|
409
|
+
|
|
410
|
+
MIT © Memoria Authors
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
<p align="center">
|
|
415
|
+
<strong>Stop building amnesiac agents.</strong><br>
|
|
416
|
+
<code>pip install memoria-agent</code>
|
|
417
|
+
</p>
|