Causal-graph cross-session memory for LLM agents (memento_v4 import name preserved)
Project description
Memento v4
A causal-graph-based cross-session memory system for LLM agents, with a benchmark harness for comparing it against MemPalace on LoCoMo and LongMemEval.
What's in this repo
memento_v4/
├── memento_v4/ ← the memory system (Python package)
│ ├── adapter.py ← MemoryV4Adapter — the end-to-end pipeline
│ ├── ablation.py ← AblationFlags: 5 independent feature toggles
│ ├── bm25.py ← pure-Python Okapi BM25
│ ├── text_utils.py ← tokenization, stop words, boost helpers
│ ├── llm.py ← sync LLM client (finalize / classify / conflict / reflect)
│ ├── types.py ← Conversation / Session / Turn dataclasses
│ └── causal/ ← the underlying causal-memory graph
│ ├── models.py ← SessionNode, CausalEdge, DomainRecord
│ ├── storage.py ← pure-file JSON + JSONL + MEMORY.md storage
│ ├── finalize.py ← LLM session summarisation (1 call/session)
│ └── recall.py ← rule-based retrieval helpers
├── benchmarks/ ← benchmark harness
│ ├── base.py ← MemoryAdapter ABC + RecallContext
│ ├── llm.py ← async httpx client (QA + judge)
│ ├── qa.py ← shared QA prompt + answerer
│ ├── metrics.py ← F1 / BLEU-1 / LLM-judge
│ ├── report.py ← JSON + Markdown report writer
│ ├── dataset_locomo.py ← LoCoMo loader
│ ├── dataset_longmemeval.py ← LongMemEval loader
│ ├── mempalace_adapter.py ← MemPalace baseline
│ ├── v4_adapter.py ← thin wrapper around memento_v4.MemoryV4Adapter
│ ├── run_locomo.py ← LoCoMo runner
│ └── run_longmemeval.py ← LongMemEval runner
├── data/ ← benchmark datasets (copy here after download)
├── scripts/
│ ├── download_data.py ← fetch LoCoMo + LongMemEval
│ ├── run_locomo.sh ← one-shot LoCoMo runner
│ └── run_longmemeval.sh ← one-shot LongMemEval runner (with stratified sampling)
└── results/ ← benchmark outputs (per-run log + JSON + MD)
Quick start (5 minutes)
1. Install
pip install memory-os-causal
Distribution name is memory-os-causal; the import name remains memento_v4.
To run the benchmark harness from a clone of this repo, also install the extra dev/benchmark requirements:
cd memento_v4
pip install -r requirements.txt
Python 3.12+ recommended.
2. (Optional) Download datasets
The data/ directory already ships with LoCoMo + both LongMemEval variants
populated. If you need fresh copies:
python scripts/download_data.py # all
python scripts/download_data.py locomo # just LoCoMo
3. Run the LoCoMo benchmark
bash scripts/run_locomo.sh
Default: mempalace vs memento_v4 on 2 conversations (~10 min). Output
goes to results/locomo/.
4. Run LongMemEval
# Quick: 120 stratified questions covering all 6 types (~45 min)
STRATIFIED=1 MAX_Q=120 bash scripts/run_longmemeval.sh
# Focused: only v4's strongest category (knowledge-update, 78 Qs)
QTYPE=knowledge-update bash scripts/run_longmemeval.sh
# Full: 500 questions (~2 h)
MAX_Q=500 bash scripts/run_longmemeval.sh
Configuring the API
By default both scripts call ppapi.ai (a Chinese OpenAI-compatible proxy). Override via env vars:
# OpenRouter
PROVIDER=openrouter OPENROUTER_API_KEY=sk-or-xxx \
bash scripts/run_locomo.sh
# Direct OpenAI
PROVIDER=openai OPENROUTER_API_KEY=sk-xxx QA_MODEL=gpt-4o-mini \
bash scripts/run_locomo.sh
# Any custom OpenAI-compatible endpoint (vLLM, LiteLLM, etc.)
OPENROUTER_BASE_URL=http://localhost:8000/v1 OPENROUTER_API_KEY=anything \
QA_MODEL=local-model \
bash scripts/run_locomo.sh
The script picks model names per provider; override QA_MODEL /
JUDGE_MODEL / FINALIZE_MODEL as needed.
The 5 ablation flags
v4 adds five independently-toggleable optimizations on top of v3 (vector search + causal chain). Each is motivated by a specific insight from 10 other AI memory systems.
| Flag | Inspired by | What it does |
|---|---|---|
classify_memories |
Hindsight 4-network | At ingest, classify each finding as fact / preference / lesson with confidence |
conflict_detection |
EverOS lifecycle + Zep validity | Detect cross-session contradictions, mark superseded sessions, down-rank at recall |
reflect_synthesis |
Hindsight reflect | At recall, synthesize a concise cross-session answer via LLM (smart-routed — skipped for single-hop factuals) |
bm25_scoring |
standard hybrid retrieval | Weighted (0.45 vector + 0.55 BM25) fusion for precise term matching |
memory_summary |
MemPalace lightweight startup | Always prepend the domain-level MEMORY.md hot summary |
All five are on by default. Toggle via adapter suffix in --adapters:
# Disable one
ADAPTERS=memento_v4-no_reflect bash scripts/run_locomo.sh
# Disable two
ADAPTERS=memento_v4-no_bm25-no_summary bash scripts/run_locomo.sh
# All off (equivalent to v3 baseline, inside the v4 harness)
ADAPTERS=memento_v4-none bash scripts/run_locomo.sh
# Compare all-on vs one-variant in a single run
ADAPTERS=memento_v4,memento_v4-no_reflect bash scripts/run_locomo.sh
Supported suffixes: no_classify, no_conflict, no_reflect, no_bm25,
no_summary, none (all off).
Using memento_v4 programmatically (outside the benchmarks)
import asyncio
from pathlib import Path
from memento_v4 import MemoryV4Adapter, AblationFlags
from memento_v4.types import Conversation, Session, Turn
async def main():
conv = Conversation(
conv_id=1,
speaker_a="user",
speaker_b="assistant",
sessions=[
Session(
session_num=1,
date_time="2026-04-01",
turns=[
Turn(speaker="user", text="Let's pick a database."),
Turn(speaker="assistant", text="How about PostgreSQL?"),
Turn(speaker="user", text="Sounds good, let's go with PG."),
],
),
Session(
session_num=2,
date_time="2026-04-15",
turns=[
Turn(speaker="user", text="PG latency p99 > 5s, we need to move."),
Turn(speaker="assistant", text="Let's migrate to MongoDB."),
],
),
],
)
adapter = MemoryV4Adapter(
memory_root=Path("./my_memory"),
model="gemini-3-flash-preview",
ablation=AblationFlags(), # all 5 features on
)
await adapter.setup()
await adapter.ingest(conv, conv_id="demo")
ctx = await adapter.recall("Why did we switch databases?", "demo")
print(ctx.raw_text)
await adapter.teardown()
asyncio.run(main())
Expected runtimes (reference)
| Benchmark | Config | mempalace | memento_v4 |
|---|---|---|---|
| LoCoMo (2 convs) | 304 QAs, concurrency=5 | ~12 min | ~16 min |
| LongMemEval-oracle | 120 stratified | ~14 min | ~94 min |
| LongMemEval-oracle | 500 questions | ~60 min | ~6 h |
| LongMemEval-S | 100 Qs, 53-sess haystack | ~3 h | ~10 h |
v4 is ~6× slower than mempalace due to the extra LLM calls
(classify_memories + conflict_detection per session during ingest,
reflect_synthesis per query during recall). Turn off optimizations you
don't need with the no_* adapter suffixes.
Troubleshooting
ModuleNotFoundError: No module named 'chromadb' — the scripts default
to the locomo conda env at /Users/huichi/miniconda3/envs/locomo. Override
with PYTHON=/path/to/your/python, or install deps into your active env:
pip install -r requirements.txt.
401 / Missing Authentication header — OPENROUTER_API_KEY is unset
or the wrong key for the current PROVIDER. See the API configuration
section.
Error code: 503 — the upstream provider rate-limited. The runners retry
3× with exponential backoff; if you see many "GAVE UP" messages, lower
CONCURRENCY or switch to a different provider.
response.text is None / AttributeError — a known issue with thinking
models returning content: null when the reasoning budget is exhausted.
Already handled defensively across qa.py, metrics.py, and llm.py.
License
MIT (TBD — see original memento-s / cc-mini licenses).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file memory_os_causal-0.1.1.tar.gz.
File metadata
- Download URL: memory_os_causal-0.1.1.tar.gz
- Upload date:
- Size: 40.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a85d6b5e4e376dbc90c8c8424243a8e40dc6d9d4c0c0953986bf34a587e7d670
|
|
| MD5 |
e7feb06016c1b828d83d79bfbe78dee6
|
|
| BLAKE2b-256 |
fce4d9f85ed6be173d52a2158a710dd7727ee99e1812621efba6a35aa1b848fd
|
Provenance
The following attestation bundles were made for memory_os_causal-0.1.1.tar.gz:
Publisher:
release.yml on martinei1/memento_v4
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memory_os_causal-0.1.1.tar.gz -
Subject digest:
a85d6b5e4e376dbc90c8c8424243a8e40dc6d9d4c0c0953986bf34a587e7d670 - Sigstore transparency entry: 1409158300
- Sigstore integration time:
-
Permalink:
martinei1/memento_v4@3c663dfe893097398583311907c74ef221ac89fc -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/martinei1
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3c663dfe893097398583311907c74ef221ac89fc -
Trigger Event:
push
-
Statement type:
File details
Details for the file memory_os_causal-0.1.1-py3-none-any.whl.
File metadata
- Download URL: memory_os_causal-0.1.1-py3-none-any.whl
- Upload date:
- Size: 43.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77a52461342608cb2f852034d83ad73f64c784f624252a4f773e5fa035ee2027
|
|
| MD5 |
7858f969c1517389dbaa4051ce0d4725
|
|
| BLAKE2b-256 |
0900e40f8b0a0607ac113383773265b531f16d8fbe4e3b67958de6dc26c28122
|
Provenance
The following attestation bundles were made for memory_os_causal-0.1.1-py3-none-any.whl:
Publisher:
release.yml on martinei1/memento_v4
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memory_os_causal-0.1.1-py3-none-any.whl -
Subject digest:
77a52461342608cb2f852034d83ad73f64c784f624252a4f773e5fa035ee2027 - Sigstore transparency entry: 1409158334
- Sigstore integration time:
-
Permalink:
martinei1/memento_v4@3c663dfe893097398583311907c74ef221ac89fc -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/martinei1
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3c663dfe893097398583311907c74ef221ac89fc -
Trigger Event:
push
-
Statement type: