feat(mem0): add Ebbinghaus decay-based time-series awareness#12987
feat(mem0): add Ebbinghaus decay-based time-series awareness#12987quinnmacro wants to merge 1 commit into
Conversation
005bab0 to
89e3036
Compare
Major Rewrite: Clean Rebase + Minimal DiffThis PR has been completely rewritten to be a minimal, surgical addition on top of the current upstream What Changed
Problems FixedThe original PR was based on an older upstream and had drifted significantly. Git's auto-merge succeeded without conflict markers, but silently reverted upstream improvements:
All of these are now fixed. The new version starts from upstream's current code and only adds the Ebbinghaus functionality — nothing else is touched. Code Quality Improvements (vs original PR)
How to Verifygit diff upstream/main -- plugins/memory/mem0/__init__.py
# Should show ONLY additions (Ebbinghaus helpers + time-aware field injection)
# Zero modifications to upstream codeReady for review. |
89e3036 to
5b64638
Compare
Update: Tests + Docs + Code QualityPushed a comprehensive update to this PR: What's New84 unit tests (
99/99 tests pass (84 new + 15 existing Code Quality Fixes
DocumentationAdded Time-Series Awareness section to
Diff SummaryAll changes are additive only — no upstream code modified. |
5b64638 to
454a7db
Compare
454a7db to
9769c37
Compare
9769c37 to
128b3a8
Compare
a4c85ef to
ffd053e
Compare
Rebased onto latest
|
| Domain | Half-life | Example |
|---|---|---|
| Volatile | 2 days | Market data, breaking news |
| Normal | 7 days | Project status, tool configs |
| Stable | 30 days | User preferences, infra facts |
Self-hosted compatible — uses the existing created_at field from Mem0. No schema changes, no extra DB columns, no Neo4j modifications.
Test coverage
84 tests across 6 classes:
TestDetectDomain— keyword classification (volatile/normal/stable)TestCalculateAgeSeconds— ISO-8601 age calculation, future timestamp clampingTestCalculateEbbinghausScore— decay formula invariants, half-life correctnessTestDetermineLifecycle— state transitions and thresholdsTestAddTimeAwareFields— enrichment logic, original field preservationTestParameterConsistency— configuration sanity checks
84 passed in 1.13s
What this does NOT do
- Does not modify upstream Mem0 — all changes are in the Hermes plugin layer
- Does not add API calls or network overhead — O(1) math per memory
- Does not change existing behavior — purely additive fields
- Does not require a Mem0 version upgrade
This is a building block for the broader time-awareness work tracked in #17459/#17476. Happy to address any review feedback.
Adds Ebbinghaus decay-based time-series awareness to the Mem0 memory plugin, enabling agents to reason about memory freshness and prioritize recent/actively-used memories over stale ones. Core implementation: - Continuous Ebbinghaus decay formula: score(t) = (n_use)^b * e^(-l*dt) * s - Domain-aware half-life tuning (volatile/normal/stable) - Power-law use count reinforcement with trust-weighted acceleration - Lifecycle states: active -> warm -> cold -> archive -> forgotten Key changes: - plugins/memory/mem0/__init__.py: Pure functions for domain detection, age calculation, Ebbinghaus scoring, lifecycle determination, and time-aware field enrichment. Additive integration to mem0_profile and mem0_search. - plugins/memory/mem0/README.md: Time-Series Awareness section. - tests/plugins/memory/test_ebbinghaus_decay.py: 84 new tests across 6 test classes. Zero breaking changes. Zero performance impact. Self-hosted compatible. Rebased onto upstream/main (v2026.5.29).
ffd053e to
c3e6fab
Compare
Rebased onto v2026.6.5 (commit c94e93a)Clean rebase, zero conflicts. 84 tests all passing. Diff: +808/-3 across 3 files. |
What does this PR do?
Adds Ebbinghaus decay-based time-series awareness to the Mem0 memory plugin, enabling agents to reason about memory freshness and prioritize recent/actively-used memories over stale ones.
Problem
Current Mem0 plugin returns memories without any time-series context:
Industry Context
Implements techniques from CortexGraph and SuperLocalMemory V3.3:
score(t) = (n_use)^β · e^(-λ·Δt) · sChanges Made
Core Logic (
plugins/memory/mem0/__init__.py, +213/-3)Pure functions (no class modifications, no config changes):
_detect_domain(text)— keyword-based domain classification (volatile/normal/stable)_calculate_age_seconds(created_at)— ISO-8601 age calculation (future timestamps → 0)_calculate_ebbinghaus_score(age, n_use, domain, strength, trust)— core decay formula_determine_lifecycle(score, domain)— score → lifecycle state mapping_add_time_aware_fields(memory)— enrich a memory dict with all time-series fieldsConstants (module-private,
_prefixed):_EBBINGHAUS_PARAMS— domain profiles with half-life/beta/threshold_DOMAIN_KEYWORDS— English-only keyword patterns for domain detection_LIFECYCLE_STATES— retention→bit-width→tag mappingIntegration (additive, no existing code modified):
mem0_profile— enriched results includememoriesarray with time-series fieldsmem0_search— each result includesage_days,domain,retention_score,lifecycle_state, etc.Tests (
tests/plugins/memory/test_ebbinghaus_decay.py, 84 tests)TestDetectDomainTestCalculateAgeSecondsTestCalculateEbbinghausScoreTestDetermineLifecycleTestAddTimeAwareFieldsTestParameterConsistencyAll 84 tests pass ✅ (plus 15 existing
test_mem0_v2.py= 99 total, 0 failures)Documentation (
plugins/memory/mem0/README.md)Added "Time-Series Awareness" section with:
Verification
Half-Life Invariant (Core Correctness)
Use Count Reinforcement
Trust Acceleration
Lifecycle Transitions
Impact
__init__.py, README, and new test filecreated_atonly, no extra DB fields neededType of Change
Checklist
References