agent-memory-engine 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.
- agent_memory_engine-0.1.0/.claude/settings.local.json +18 -0
- agent_memory_engine-0.1.0/.github/workflows/ci.yml +21 -0
- agent_memory_engine-0.1.0/.gitignore +14 -0
- agent_memory_engine-0.1.0/LICENSE +22 -0
- agent_memory_engine-0.1.0/PKG-INFO +228 -0
- agent_memory_engine-0.1.0/README.md +194 -0
- agent_memory_engine-0.1.0/benchmarks/__init__.py +2 -0
- agent_memory_engine-0.1.0/benchmarks/bench_retrieval.py +48 -0
- agent_memory_engine-0.1.0/benchmarks/bench_storage.py +41 -0
- agent_memory_engine-0.1.0/benchmarks/locomo_lite/README.md +29 -0
- agent_memory_engine-0.1.0/benchmarks/locomo_lite/evaluate.py +182 -0
- agent_memory_engine-0.1.0/benchmarks/locomo_lite/latest_results.json +67 -0
- agent_memory_engine-0.1.0/benchmarks/locomo_lite/sample_dialogues.jsonl +30 -0
- agent_memory_engine-0.1.0/benchmarks/locomo_lite/sample_questions.jsonl +150 -0
- agent_memory_engine-0.1.0/docs/benchmark-results.md +38 -0
- agent_memory_engine-0.1.0/docs/mcp-integration.md +90 -0
- agent_memory_engine-0.1.0/docs/plans/2026-03-24-agent-memory-expansion-review.md +367 -0
- agent_memory_engine-0.1.0/docs/plans/2026-03-24-agent-memory-mvp.md +143 -0
- agent_memory_engine-0.1.0/docs/project-delivery-and-tutorial.md +601 -0
- agent_memory_engine-0.1.0/docs/screenshots/.gitkeep +1 -0
- agent_memory_engine-0.1.0/examples/basic_usage.py +14 -0
- agent_memory_engine-0.1.0/examples/benchmark_runner.py +13 -0
- agent_memory_engine-0.1.0/examples/chatbot_with_memory.py +19 -0
- agent_memory_engine-0.1.0/examples/demo_cross_session.py +105 -0
- agent_memory_engine-0.1.0/examples/interactive_chat.py +127 -0
- agent_memory_engine-0.1.0/examples/mcp_server.py +11 -0
- agent_memory_engine-0.1.0/pyproject.toml +59 -0
- agent_memory_engine-0.1.0/src/agent_memory/__init__.py +33 -0
- agent_memory_engine-0.1.0/src/agent_memory/cli.py +142 -0
- agent_memory_engine-0.1.0/src/agent_memory/client.py +355 -0
- agent_memory_engine-0.1.0/src/agent_memory/config.py +28 -0
- agent_memory_engine-0.1.0/src/agent_memory/controller/__init__.py +15 -0
- agent_memory_engine-0.1.0/src/agent_memory/controller/conflict.py +95 -0
- agent_memory_engine-0.1.0/src/agent_memory/controller/consolidation.py +136 -0
- agent_memory_engine-0.1.0/src/agent_memory/controller/forgetting.py +29 -0
- agent_memory_engine-0.1.0/src/agent_memory/controller/router.py +62 -0
- agent_memory_engine-0.1.0/src/agent_memory/controller/trust.py +31 -0
- agent_memory_engine-0.1.0/src/agent_memory/embedding/__init__.py +5 -0
- agent_memory_engine-0.1.0/src/agent_memory/embedding/base.py +11 -0
- agent_memory_engine-0.1.0/src/agent_memory/embedding/local_provider.py +38 -0
- agent_memory_engine-0.1.0/src/agent_memory/embedding/openai_provider.py +11 -0
- agent_memory_engine-0.1.0/src/agent_memory/extraction/__init__.py +5 -0
- agent_memory_engine-0.1.0/src/agent_memory/extraction/entity_extractor.py +13 -0
- agent_memory_engine-0.1.0/src/agent_memory/extraction/pipeline.py +123 -0
- agent_memory_engine-0.1.0/src/agent_memory/extraction/prompts.py +40 -0
- agent_memory_engine-0.1.0/src/agent_memory/governance/__init__.py +6 -0
- agent_memory_engine-0.1.0/src/agent_memory/governance/audit.py +14 -0
- agent_memory_engine-0.1.0/src/agent_memory/governance/export.py +72 -0
- agent_memory_engine-0.1.0/src/agent_memory/governance/health.py +40 -0
- agent_memory_engine-0.1.0/src/agent_memory/interfaces/__init__.py +14 -0
- agent_memory_engine-0.1.0/src/agent_memory/interfaces/mcp_server.py +128 -0
- agent_memory_engine-0.1.0/src/agent_memory/interfaces/rest_api.py +71 -0
- agent_memory_engine-0.1.0/src/agent_memory/llm/__init__.py +5 -0
- agent_memory_engine-0.1.0/src/agent_memory/llm/base.py +23 -0
- agent_memory_engine-0.1.0/src/agent_memory/llm/ollama_client.py +64 -0
- agent_memory_engine-0.1.0/src/agent_memory/llm/openai_client.py +94 -0
- agent_memory_engine-0.1.0/src/agent_memory/models.py +149 -0
- agent_memory_engine-0.1.0/src/agent_memory/storage/__init__.py +4 -0
- agent_memory_engine-0.1.0/src/agent_memory/storage/base.py +59 -0
- agent_memory_engine-0.1.0/src/agent_memory/storage/schema.sql +125 -0
- agent_memory_engine-0.1.0/src/agent_memory/storage/sqlite_backend.py +762 -0
- agent_memory_engine-0.1.0/tests/conftest.py +33 -0
- agent_memory_engine-0.1.0/tests/test_benchmarks.py +15 -0
- agent_memory_engine-0.1.0/tests/test_cli.py +63 -0
- agent_memory_engine-0.1.0/tests/test_client.py +44 -0
- agent_memory_engine-0.1.0/tests/test_conflict.py +62 -0
- agent_memory_engine-0.1.0/tests/test_extraction.py +48 -0
- agent_memory_engine-0.1.0/tests/test_forgetting.py +38 -0
- agent_memory_engine-0.1.0/tests/test_governance.py +86 -0
- agent_memory_engine-0.1.0/tests/test_interfaces.py +31 -0
- agent_memory_engine-0.1.0/tests/test_llm_clients.py +56 -0
- agent_memory_engine-0.1.0/tests/test_mcp_server.py +60 -0
- agent_memory_engine-0.1.0/tests/test_router.py +29 -0
- agent_memory_engine-0.1.0/tests/test_sqlite_backend.py +122 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"WebSearch",
|
|
5
|
+
"Bash(pip3 list:*)",
|
|
6
|
+
"Bash(.venv/bin/python -m pytest:*)",
|
|
7
|
+
"Bash(python -m pytest:*)",
|
|
8
|
+
"Bash(ls:*)",
|
|
9
|
+
"Bash(python3 -m pytest:*)",
|
|
10
|
+
"Bash(/Users/xjf/Public/Code/Agent-Project/.venv/bin/python3 -m pytest:*)",
|
|
11
|
+
"Bash(wc:*)",
|
|
12
|
+
"Bash(python3:*)"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"disabledMcpjsonServers": [
|
|
16
|
+
"apple-notes"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
matrix:
|
|
12
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: ${{ matrix.python-version }}
|
|
18
|
+
- run: python -m pip install --upgrade pip
|
|
19
|
+
- run: pip install -e .[dev]
|
|
20
|
+
- run: pytest -q
|
|
21
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xjf
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-memory-engine
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Zero-config, traceable, MCP-native long-term memory for agents.
|
|
5
|
+
Project-URL: Homepage, https://github.com/xjf/agent-memory
|
|
6
|
+
Project-URL: Repository, https://github.com/xjf/agent-memory
|
|
7
|
+
Project-URL: Issues, https://github.com/xjf/agent-memory/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/xjf/agent-memory/tree/main/docs
|
|
9
|
+
Author: xjf
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: agent,llm,mcp,memory,rag,sqlite
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Database
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: sentence-transformers>=3.0.0
|
|
25
|
+
Requires-Dist: sqlite-vec>=0.1.0
|
|
26
|
+
Provides-Extra: api
|
|
27
|
+
Requires-Dist: fastapi>=0.115.0; extra == 'api'
|
|
28
|
+
Requires-Dist: uvicorn>=0.30.0; extra == 'api'
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
31
|
+
Provides-Extra: mcp
|
|
32
|
+
Requires-Dist: fastmcp>=2.0.0; extra == 'mcp'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# agent-memory
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+

|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
Zero-config, traceable, MCP-native long-term memory for agents.
|
|
42
|
+
|
|
43
|
+
`agent-memory` targets a gap in the current memory stack: a local-first engine that works with `pip install`, runs on pure SQLite, and makes memory evolution explainable instead of opaque.
|
|
44
|
+
|
|
45
|
+
PyPI distribution name: `agent-memory-engine`
|
|
46
|
+
|
|
47
|
+
## Why this exists
|
|
48
|
+
|
|
49
|
+
- `Mem0` proves demand, but pulls in heavier infra such as Neo4j or Qdrant.
|
|
50
|
+
- Local agents and personal copilots need a memory layer that is easy to embed, debug, export, and ship.
|
|
51
|
+
- Interviews love this surface area: storage, retrieval, ranking, decay, provenance, conflict handling, MCP, and evaluation.
|
|
52
|
+
|
|
53
|
+
## Current Status
|
|
54
|
+
|
|
55
|
+
- SQLite backend with WAL, FTS5, audit log, evolution log, entity index, and causal parent links
|
|
56
|
+
- Schema indexes for type, layer, recency, trust, source, relation, and audit hot paths
|
|
57
|
+
- Python SDK via `MemoryClient`
|
|
58
|
+
- Rule-based intent router with Reciprocal Rank Fusion
|
|
59
|
+
- Adaptive forgetting utilities with dual-threshold layer transitions
|
|
60
|
+
- Heuristic conflict detection with contradiction edges and trust-score adjustment
|
|
61
|
+
- Optional LLM-backed conflict adjudication for top semantic candidates
|
|
62
|
+
- Governance helpers for health reports, audit reads, and JSONL export/import
|
|
63
|
+
- Optional MCP server and REST API adapters with dependency-friendly fallbacks
|
|
64
|
+
- `sqlite-vec` integration with safe fallback to Python cosine scan when unavailable
|
|
65
|
+
- Deterministic local fallback embeddings for testability and zero-friction startup
|
|
66
|
+
- LLM-first conversation extraction with heuristic fallback
|
|
67
|
+
- Trace graph reports with ancestors, descendants, relations, and evolution history
|
|
68
|
+
- Idempotent maintenance cycle for decay, promotion/demotion, conflict upkeep, and consolidation
|
|
69
|
+
- Benchmark helpers and LOCOMO-Lite style starter data
|
|
70
|
+
|
|
71
|
+
## Quickstart
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install -e .[dev]
|
|
75
|
+
.venv/bin/python -m pytest -q
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
agent-memory store "User prefers SQLite for local-first agents." --source-id demo
|
|
80
|
+
agent-memory search "Why SQLite?"
|
|
81
|
+
agent-memory health
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from agent_memory import MemoryClient
|
|
86
|
+
|
|
87
|
+
client = MemoryClient()
|
|
88
|
+
item = client.add(
|
|
89
|
+
"The user prefers SQLite for local-first agent projects.",
|
|
90
|
+
source_id="demo-session",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
results = client.search("What database does the user prefer?")
|
|
94
|
+
print(results[0].item.content)
|
|
95
|
+
|
|
96
|
+
trace = client.trace_graph(item.id)
|
|
97
|
+
print(trace.descendants)
|
|
98
|
+
|
|
99
|
+
health = client.health()
|
|
100
|
+
print(health.suggestions)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Architecture
|
|
104
|
+
|
|
105
|
+
```mermaid
|
|
106
|
+
graph TD
|
|
107
|
+
A["Python SDK / CLI"] --> B["MemoryClient"]
|
|
108
|
+
C["MCP Server"] --> B
|
|
109
|
+
D["REST API"] --> B
|
|
110
|
+
B --> E["Intent Router"]
|
|
111
|
+
B --> F["Conflict Detector"]
|
|
112
|
+
B --> G["Trust Scorer"]
|
|
113
|
+
B --> H["Forgetting Engine"]
|
|
114
|
+
E --> I["SQLite Backend"]
|
|
115
|
+
F --> I
|
|
116
|
+
G --> I
|
|
117
|
+
H --> I
|
|
118
|
+
I --> J[("SQLite + FTS5 + sqlite-vec")]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Core components
|
|
122
|
+
|
|
123
|
+
- `src/agent_memory/client.py` — high-level SDK entry point
|
|
124
|
+
- `src/agent_memory/storage/sqlite_backend.py` — SQLite persistence, FTS, vector fallback, trace queries
|
|
125
|
+
- `src/agent_memory/controller/router.py` — intent-aware retrieval routing and RRF fusion
|
|
126
|
+
- `src/agent_memory/controller/forgetting.py` — Ebbinghaus-inspired adaptive forgetting
|
|
127
|
+
- `src/agent_memory/controller/conflict.py` — contradiction detection and conflict records
|
|
128
|
+
- `src/agent_memory/controller/consolidation.py` — overlap grouping and merge-draft generation
|
|
129
|
+
- `src/agent_memory/controller/trust.py` — multi-factor trust scoring
|
|
130
|
+
- `src/agent_memory/governance/health.py` — stale/orphan/conflict monitoring
|
|
131
|
+
- `src/agent_memory/interfaces/mcp_server.py` — eight MCP tools
|
|
132
|
+
- `src/agent_memory/extraction/pipeline.py` — conversation-to-memory extraction
|
|
133
|
+
- `benchmarks/` — storage/retrieval microbenchmarks and synthetic eval seeds
|
|
134
|
+
|
|
135
|
+
### Design choices
|
|
136
|
+
|
|
137
|
+
- **SQLite + WAL** keeps deployment zero-config while fitting agent workloads: many reads, occasional writes.
|
|
138
|
+
- **Rule routing over LLM routing** keeps routing latency predictable and testable.
|
|
139
|
+
- **RRF instead of score averaging** avoids calibration problems across lexical, entity, and semantic retrieval.
|
|
140
|
+
- **`sqlite-vec` plus fallback** gives C/SQL vector search when available while keeping the package runnable everywhere.
|
|
141
|
+
- **Soft delete** preserves provenance and causal trace integrity.
|
|
142
|
+
- **Hash fallback embeddings** make the package runnable even before a local embedding model is available.
|
|
143
|
+
- **Unique relation edges** keep maintenance idempotent and health metrics stable.
|
|
144
|
+
|
|
145
|
+
## Project layout
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
agent-memory/
|
|
149
|
+
├── docs/plans/
|
|
150
|
+
├── examples/
|
|
151
|
+
├── src/agent_memory/
|
|
152
|
+
│ ├── controller/
|
|
153
|
+
│ ├── embedding/
|
|
154
|
+
│ ├── extraction/
|
|
155
|
+
│ └── storage/
|
|
156
|
+
└── tests/
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Benchmarks
|
|
160
|
+
|
|
161
|
+
Synthetic LOCOMO-Lite run on the bundled starter dataset (`30` dialogues / `150` questions):
|
|
162
|
+
|
|
163
|
+
| Metric | `agent-memory` | Semantic-only baseline |
|
|
164
|
+
|--------|----------------|------------------------|
|
|
165
|
+
| Overall hit rate | 50.0% | 23.3% |
|
|
166
|
+
| Factual recall | 53.3% | 6.7% |
|
|
167
|
+
| Temporal recall | 36.7% | 3.3% |
|
|
168
|
+
| Causal recall | 53.3% | 6.7% |
|
|
169
|
+
| p95 retrieval latency | 16.64ms | 11.50ms |
|
|
170
|
+
|
|
171
|
+
- Full report: `docs/benchmark-results.md`
|
|
172
|
+
- Re-run locally: `python benchmarks/locomo_lite/evaluate.py`
|
|
173
|
+
|
|
174
|
+
## MCP Usage
|
|
175
|
+
|
|
176
|
+
Install MCP support and launch the stdio server:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
pip install -e .[mcp]
|
|
180
|
+
python -m agent_memory.interfaces.mcp_server
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Claude Desktop configuration:
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"mcpServers": {
|
|
188
|
+
"agent-memory": {
|
|
189
|
+
"command": "python",
|
|
190
|
+
"args": ["-m", "agent_memory.interfaces.mcp_server"],
|
|
191
|
+
"env": {
|
|
192
|
+
"AGENT_MEMORY_DB_PATH": "/absolute/path/to/default.db"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Typical tools:
|
|
200
|
+
|
|
201
|
+
- `memory_store` — store a memory with provenance
|
|
202
|
+
- `memory_search` — run intent-aware retrieval
|
|
203
|
+
- `memory_trace` — inspect causal ancestry and evolution
|
|
204
|
+
- `memory_health` — inspect stale/conflict/orphan metrics
|
|
205
|
+
|
|
206
|
+
More details: `docs/mcp-integration.md`
|
|
207
|
+
|
|
208
|
+
## Demos
|
|
209
|
+
|
|
210
|
+
- `python examples/demo_cross_session.py --db /tmp/agent-memory-demo.db`
|
|
211
|
+
- `python examples/interactive_chat.py --db chat_memory.db --provider none`
|
|
212
|
+
- `python examples/mcp_server.py`
|
|
213
|
+
|
|
214
|
+
## Release Notes
|
|
215
|
+
|
|
216
|
+
- `benchmarks/locomo_lite/latest_results.json` is regenerated by the evaluation script
|
|
217
|
+
- `docs/screenshots/` is reserved for verified MCP client screenshots
|
|
218
|
+
- Update GitHub URLs if you publish under a different org/user
|
|
219
|
+
- Delivery record and full tutorial: `docs/project-delivery-and-tutorial.md`
|
|
220
|
+
- Expansion and optimization review: `docs/plans/2026-03-24-agent-memory-expansion-review.md`
|
|
221
|
+
|
|
222
|
+
## Dev Notes
|
|
223
|
+
|
|
224
|
+
- Run all tests with `.venv/bin/python -m pytest -q`
|
|
225
|
+
- Use the built-in CLI with `agent-memory --help`
|
|
226
|
+
- `sqlite-vec` is installed as a package dependency; if the extension cannot be loaded at runtime, vector search safely falls back to Python cosine scan
|
|
227
|
+
- Try microbenchmarks with `python benchmarks/bench_storage.py` and `python benchmarks/bench_retrieval.py`
|
|
228
|
+
- Try the demo runner with `python examples/benchmark_runner.py`
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# agent-memory
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
Zero-config, traceable, MCP-native long-term memory for agents.
|
|
8
|
+
|
|
9
|
+
`agent-memory` targets a gap in the current memory stack: a local-first engine that works with `pip install`, runs on pure SQLite, and makes memory evolution explainable instead of opaque.
|
|
10
|
+
|
|
11
|
+
PyPI distribution name: `agent-memory-engine`
|
|
12
|
+
|
|
13
|
+
## Why this exists
|
|
14
|
+
|
|
15
|
+
- `Mem0` proves demand, but pulls in heavier infra such as Neo4j or Qdrant.
|
|
16
|
+
- Local agents and personal copilots need a memory layer that is easy to embed, debug, export, and ship.
|
|
17
|
+
- Interviews love this surface area: storage, retrieval, ranking, decay, provenance, conflict handling, MCP, and evaluation.
|
|
18
|
+
|
|
19
|
+
## Current Status
|
|
20
|
+
|
|
21
|
+
- SQLite backend with WAL, FTS5, audit log, evolution log, entity index, and causal parent links
|
|
22
|
+
- Schema indexes for type, layer, recency, trust, source, relation, and audit hot paths
|
|
23
|
+
- Python SDK via `MemoryClient`
|
|
24
|
+
- Rule-based intent router with Reciprocal Rank Fusion
|
|
25
|
+
- Adaptive forgetting utilities with dual-threshold layer transitions
|
|
26
|
+
- Heuristic conflict detection with contradiction edges and trust-score adjustment
|
|
27
|
+
- Optional LLM-backed conflict adjudication for top semantic candidates
|
|
28
|
+
- Governance helpers for health reports, audit reads, and JSONL export/import
|
|
29
|
+
- Optional MCP server and REST API adapters with dependency-friendly fallbacks
|
|
30
|
+
- `sqlite-vec` integration with safe fallback to Python cosine scan when unavailable
|
|
31
|
+
- Deterministic local fallback embeddings for testability and zero-friction startup
|
|
32
|
+
- LLM-first conversation extraction with heuristic fallback
|
|
33
|
+
- Trace graph reports with ancestors, descendants, relations, and evolution history
|
|
34
|
+
- Idempotent maintenance cycle for decay, promotion/demotion, conflict upkeep, and consolidation
|
|
35
|
+
- Benchmark helpers and LOCOMO-Lite style starter data
|
|
36
|
+
|
|
37
|
+
## Quickstart
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install -e .[dev]
|
|
41
|
+
.venv/bin/python -m pytest -q
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
agent-memory store "User prefers SQLite for local-first agents." --source-id demo
|
|
46
|
+
agent-memory search "Why SQLite?"
|
|
47
|
+
agent-memory health
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from agent_memory import MemoryClient
|
|
52
|
+
|
|
53
|
+
client = MemoryClient()
|
|
54
|
+
item = client.add(
|
|
55
|
+
"The user prefers SQLite for local-first agent projects.",
|
|
56
|
+
source_id="demo-session",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
results = client.search("What database does the user prefer?")
|
|
60
|
+
print(results[0].item.content)
|
|
61
|
+
|
|
62
|
+
trace = client.trace_graph(item.id)
|
|
63
|
+
print(trace.descendants)
|
|
64
|
+
|
|
65
|
+
health = client.health()
|
|
66
|
+
print(health.suggestions)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Architecture
|
|
70
|
+
|
|
71
|
+
```mermaid
|
|
72
|
+
graph TD
|
|
73
|
+
A["Python SDK / CLI"] --> B["MemoryClient"]
|
|
74
|
+
C["MCP Server"] --> B
|
|
75
|
+
D["REST API"] --> B
|
|
76
|
+
B --> E["Intent Router"]
|
|
77
|
+
B --> F["Conflict Detector"]
|
|
78
|
+
B --> G["Trust Scorer"]
|
|
79
|
+
B --> H["Forgetting Engine"]
|
|
80
|
+
E --> I["SQLite Backend"]
|
|
81
|
+
F --> I
|
|
82
|
+
G --> I
|
|
83
|
+
H --> I
|
|
84
|
+
I --> J[("SQLite + FTS5 + sqlite-vec")]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Core components
|
|
88
|
+
|
|
89
|
+
- `src/agent_memory/client.py` — high-level SDK entry point
|
|
90
|
+
- `src/agent_memory/storage/sqlite_backend.py` — SQLite persistence, FTS, vector fallback, trace queries
|
|
91
|
+
- `src/agent_memory/controller/router.py` — intent-aware retrieval routing and RRF fusion
|
|
92
|
+
- `src/agent_memory/controller/forgetting.py` — Ebbinghaus-inspired adaptive forgetting
|
|
93
|
+
- `src/agent_memory/controller/conflict.py` — contradiction detection and conflict records
|
|
94
|
+
- `src/agent_memory/controller/consolidation.py` — overlap grouping and merge-draft generation
|
|
95
|
+
- `src/agent_memory/controller/trust.py` — multi-factor trust scoring
|
|
96
|
+
- `src/agent_memory/governance/health.py` — stale/orphan/conflict monitoring
|
|
97
|
+
- `src/agent_memory/interfaces/mcp_server.py` — eight MCP tools
|
|
98
|
+
- `src/agent_memory/extraction/pipeline.py` — conversation-to-memory extraction
|
|
99
|
+
- `benchmarks/` — storage/retrieval microbenchmarks and synthetic eval seeds
|
|
100
|
+
|
|
101
|
+
### Design choices
|
|
102
|
+
|
|
103
|
+
- **SQLite + WAL** keeps deployment zero-config while fitting agent workloads: many reads, occasional writes.
|
|
104
|
+
- **Rule routing over LLM routing** keeps routing latency predictable and testable.
|
|
105
|
+
- **RRF instead of score averaging** avoids calibration problems across lexical, entity, and semantic retrieval.
|
|
106
|
+
- **`sqlite-vec` plus fallback** gives C/SQL vector search when available while keeping the package runnable everywhere.
|
|
107
|
+
- **Soft delete** preserves provenance and causal trace integrity.
|
|
108
|
+
- **Hash fallback embeddings** make the package runnable even before a local embedding model is available.
|
|
109
|
+
- **Unique relation edges** keep maintenance idempotent and health metrics stable.
|
|
110
|
+
|
|
111
|
+
## Project layout
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
agent-memory/
|
|
115
|
+
├── docs/plans/
|
|
116
|
+
├── examples/
|
|
117
|
+
├── src/agent_memory/
|
|
118
|
+
│ ├── controller/
|
|
119
|
+
│ ├── embedding/
|
|
120
|
+
│ ├── extraction/
|
|
121
|
+
│ └── storage/
|
|
122
|
+
└── tests/
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Benchmarks
|
|
126
|
+
|
|
127
|
+
Synthetic LOCOMO-Lite run on the bundled starter dataset (`30` dialogues / `150` questions):
|
|
128
|
+
|
|
129
|
+
| Metric | `agent-memory` | Semantic-only baseline |
|
|
130
|
+
|--------|----------------|------------------------|
|
|
131
|
+
| Overall hit rate | 50.0% | 23.3% |
|
|
132
|
+
| Factual recall | 53.3% | 6.7% |
|
|
133
|
+
| Temporal recall | 36.7% | 3.3% |
|
|
134
|
+
| Causal recall | 53.3% | 6.7% |
|
|
135
|
+
| p95 retrieval latency | 16.64ms | 11.50ms |
|
|
136
|
+
|
|
137
|
+
- Full report: `docs/benchmark-results.md`
|
|
138
|
+
- Re-run locally: `python benchmarks/locomo_lite/evaluate.py`
|
|
139
|
+
|
|
140
|
+
## MCP Usage
|
|
141
|
+
|
|
142
|
+
Install MCP support and launch the stdio server:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
pip install -e .[mcp]
|
|
146
|
+
python -m agent_memory.interfaces.mcp_server
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Claude Desktop configuration:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"mcpServers": {
|
|
154
|
+
"agent-memory": {
|
|
155
|
+
"command": "python",
|
|
156
|
+
"args": ["-m", "agent_memory.interfaces.mcp_server"],
|
|
157
|
+
"env": {
|
|
158
|
+
"AGENT_MEMORY_DB_PATH": "/absolute/path/to/default.db"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Typical tools:
|
|
166
|
+
|
|
167
|
+
- `memory_store` — store a memory with provenance
|
|
168
|
+
- `memory_search` — run intent-aware retrieval
|
|
169
|
+
- `memory_trace` — inspect causal ancestry and evolution
|
|
170
|
+
- `memory_health` — inspect stale/conflict/orphan metrics
|
|
171
|
+
|
|
172
|
+
More details: `docs/mcp-integration.md`
|
|
173
|
+
|
|
174
|
+
## Demos
|
|
175
|
+
|
|
176
|
+
- `python examples/demo_cross_session.py --db /tmp/agent-memory-demo.db`
|
|
177
|
+
- `python examples/interactive_chat.py --db chat_memory.db --provider none`
|
|
178
|
+
- `python examples/mcp_server.py`
|
|
179
|
+
|
|
180
|
+
## Release Notes
|
|
181
|
+
|
|
182
|
+
- `benchmarks/locomo_lite/latest_results.json` is regenerated by the evaluation script
|
|
183
|
+
- `docs/screenshots/` is reserved for verified MCP client screenshots
|
|
184
|
+
- Update GitHub URLs if you publish under a different org/user
|
|
185
|
+
- Delivery record and full tutorial: `docs/project-delivery-and-tutorial.md`
|
|
186
|
+
- Expansion and optimization review: `docs/plans/2026-03-24-agent-memory-expansion-review.md`
|
|
187
|
+
|
|
188
|
+
## Dev Notes
|
|
189
|
+
|
|
190
|
+
- Run all tests with `.venv/bin/python -m pytest -q`
|
|
191
|
+
- Use the built-in CLI with `agent-memory --help`
|
|
192
|
+
- `sqlite-vec` is installed as a package dependency; if the extension cannot be loaded at runtime, vector search safely falls back to Python cosine scan
|
|
193
|
+
- Try microbenchmarks with `python benchmarks/bench_storage.py` and `python benchmarks/bench_retrieval.py`
|
|
194
|
+
- Try the demo runner with `python examples/benchmark_runner.py`
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from statistics import mean
|
|
5
|
+
import sys
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
if __package__ in {None, ""}:
|
|
9
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
10
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
11
|
+
|
|
12
|
+
from agent_memory import MemoryClient
|
|
13
|
+
from agent_memory.config import AgentMemoryConfig
|
|
14
|
+
from agent_memory.storage.sqlite_backend import SQLiteBackend
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def build_client(num_memories: int = 500) -> MemoryClient:
|
|
18
|
+
backend = SQLiteBackend(":memory:")
|
|
19
|
+
client = MemoryClient(config=AgentMemoryConfig(database_path=":memory:"), backend=backend)
|
|
20
|
+
for index in range(num_memories):
|
|
21
|
+
client.add(
|
|
22
|
+
f"Project note {index}: SQLite, MCP, trust scoring, and traceability are important.",
|
|
23
|
+
source_id="bench-retrieval",
|
|
24
|
+
tags=["benchmark", "memory"],
|
|
25
|
+
)
|
|
26
|
+
return client
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def run_retrieval_benchmark(iterations: int = 100, num_memories: int = 500) -> dict[str, float]:
|
|
30
|
+
client = build_client(num_memories=num_memories)
|
|
31
|
+
latencies_ms: list[float] = []
|
|
32
|
+
for _ in range(iterations):
|
|
33
|
+
start = time.perf_counter()
|
|
34
|
+
client.search("Why does the project prefer SQLite and traceability?", limit=5)
|
|
35
|
+
latencies_ms.append((time.perf_counter() - start) * 1000)
|
|
36
|
+
latencies_ms.sort()
|
|
37
|
+
return {
|
|
38
|
+
"iterations": float(iterations),
|
|
39
|
+
"num_memories": float(num_memories),
|
|
40
|
+
"avg_latency_ms": mean(latencies_ms),
|
|
41
|
+
"p50_latency_ms": latencies_ms[int(len(latencies_ms) * 0.5)],
|
|
42
|
+
"p95_latency_ms": latencies_ms[int(len(latencies_ms) * 0.95)],
|
|
43
|
+
"p99_latency_ms": latencies_ms[min(len(latencies_ms) - 1, int(len(latencies_ms) * 0.99))],
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
print(run_retrieval_benchmark())
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from statistics import mean
|
|
5
|
+
import sys
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
if __package__ in {None, ""}:
|
|
9
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
10
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
11
|
+
|
|
12
|
+
from agent_memory import MemoryClient
|
|
13
|
+
from agent_memory.config import AgentMemoryConfig
|
|
14
|
+
from agent_memory.storage.sqlite_backend import SQLiteBackend
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def run_storage_benchmark(num_memories: int = 1000) -> dict[str, float]:
|
|
18
|
+
backend = SQLiteBackend(":memory:")
|
|
19
|
+
client = MemoryClient(config=AgentMemoryConfig(database_path=":memory:"), backend=backend)
|
|
20
|
+
latencies_ms: list[float] = []
|
|
21
|
+
start = time.perf_counter()
|
|
22
|
+
for index in range(num_memories):
|
|
23
|
+
op_start = time.perf_counter()
|
|
24
|
+
client.add(
|
|
25
|
+
f"User preference #{index}: prefers deterministic local memory pipelines.",
|
|
26
|
+
source_id="bench-storage",
|
|
27
|
+
tags=["benchmark"],
|
|
28
|
+
)
|
|
29
|
+
latencies_ms.append((time.perf_counter() - op_start) * 1000)
|
|
30
|
+
total_seconds = time.perf_counter() - start
|
|
31
|
+
return {
|
|
32
|
+
"num_memories": float(num_memories),
|
|
33
|
+
"total_seconds": total_seconds,
|
|
34
|
+
"throughput_ops_per_sec": num_memories / total_seconds,
|
|
35
|
+
"avg_latency_ms": mean(latencies_ms),
|
|
36
|
+
"max_latency_ms": max(latencies_ms),
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
print(run_storage_benchmark())
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# LOCOMO-Lite
|
|
2
|
+
|
|
3
|
+
This folder contains a synthetic evaluation starter set for `agent-memory`.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
- sanity-check long-context memory retrieval
|
|
8
|
+
- compare full intent-aware routing against semantic-only retrieval
|
|
9
|
+
- provide a reproducible benchmark for README and release notes
|
|
10
|
+
|
|
11
|
+
## Files
|
|
12
|
+
|
|
13
|
+
- `sample_dialogues.jsonl` — 30 multi-turn synthetic sessions
|
|
14
|
+
- `sample_questions.jsonl` — 150 benchmark questions with expected answers
|
|
15
|
+
- `evaluate.py` — benchmark runner
|
|
16
|
+
|
|
17
|
+
## Evaluation Loop
|
|
18
|
+
|
|
19
|
+
1. ingest each dialogue into `MemoryClient`
|
|
20
|
+
2. run each question through `client.search()` in `full` mode
|
|
21
|
+
3. run the same questions through a semantic-only baseline
|
|
22
|
+
4. compute hit rate by intent and latency statistics
|
|
23
|
+
|
|
24
|
+
## Run
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
.venv/bin/python benchmarks/locomo_lite/evaluate.py
|
|
28
|
+
cat benchmarks/locomo_lite/latest_results.json
|
|
29
|
+
```
|