Skip to content

Production-Grade Agent Memory Framework for Agentic AI

License

Notifications You must be signed in to change notification settings

Al-aminI/GraphMem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

133 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧠 GraphMem

The Human Brain for Your AI Agents

PyPI Python 3.9+ License: MIT GitHub

"Memory is the treasury and guardian of all things." β€” Cicero

GraphMem is the first memory system that thinks like a human brain. It doesn't just store dataβ€”it forgets, consolidates, prioritizes, and evolves exactly like biological memory does.

This is the future of enterprise AI agents.


🧬 Why GraphMem Changes Everything

The Problem with Current AI Memory

Every production AI agent faces the same crisis:

Day 1:     "Who is the CEO?" β†’ "Elon Musk" βœ…
Day 100:   Context window: OVERFLOW πŸ’₯
Day 365:   "Who is the CEO?" β†’ "John... or was it Jane... maybe Elon?" 🀯

Vector databases don't forget. They accumulate garbage until your agent drowns in irrelevant, conflicting, outdated information.

The GraphMem Solution: Memory That Thinks

GraphMem implements the four pillars of human memory:

Human Brain GraphMem Why It Matters
🧠 Forgetting Curve Memory Decay Irrelevant memories fade naturally
πŸ”— Neural Networks Knowledge Graph Relationships between concepts
⭐ Importance Weighting PageRank Centrality Hub concepts (Elon Musk) > peripheral ones
⏰ Episodic Memory Temporal Validity "CEO in 2015" vs "CEO now"

πŸš€ Revolutionary Features

1. πŸ•°οΈ Point-in-Time Memory (Temporal Validity)

"Who was CEO in 2015?" β€” No other memory system can answer this.

from datetime import datetime
from graphmem import GraphMem, MemoryConfig

memory = GraphMem(config)

# GraphMem tracks WHEN facts are true
memory.ingest("John Smith was CEO of ACME from 2010 to 2018")
memory.ingest("Jane Doe became CEO of ACME in July 2018")

# Point-in-time queries - like human episodic memory!
memory.query("Who was CEO in 2015?")      # β†’ "John Smith" βœ…
memory.query("Who is CEO now?")           # β†’ "Jane Doe" βœ…
memory.query("Who was CEO in 2019?")      # β†’ "Jane Doe" βœ…

Use Cases:

  • πŸ“‹ "What contracts were active last quarter?"
  • πŸ‘” "Who was our legal counsel before 2020?"
  • πŸ“ˆ "What was our strategy during COVID?"

2. ⭐ PageRank Centrality (Hub Detection)

GraphMem uses Google's PageRank algorithm to identify important entities:

Importance Formula: ρ(e) = w1·f1 + w2·f2 + w3·f3 + w4·f4

where:
  f1 = Temporal recency    (recent = important)
  f2 = Access frequency    (used often = important)  
  f3 = PageRank centrality (well-connected = important) ← NEW!
  f4 = User feedback       (explicit signals)

Result: "Elon Musk" (connected to Tesla, SpaceX, Neuralink) scores 3x higher than "Austin, Texas" (connected only to Tesla HQ).

# PageRank automatically identifies hub entities
Elon Musk:      PR = 1.000 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  # Hub - many connections
Tesla:          PR = 0.774 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ       # Important company
Austin:         PR = 0.520 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ            # Just a location

3. 🧠 Self-Evolution (Like Human Memory)

memory.evolve()  # This single line triggers:
Mechanism What Happens Human Equivalent
Decay Old unused memories fade (importance β†’ 0) Forgetting curve
Consolidation 5 mentions of "user likes Python" β†’ 1 strong memory Sleep consolidation
Rehydration Contradictions resolved ("CEO is John" β†’ "CEO is Jane") Memory updating
Importance Scoring PageRank recalculated Synaptic strengthening

Result: 80% memory reduction while keeping what matters.

4. 🏒 Enterprise Multi-Tenant Isolation

Each user gets their own brain. Complete data separation.

# Alice's memory
alice = GraphMem(config, user_id="alice", memory_id="chat")
alice.ingest("I work at Google as a senior engineer")

# Bob's memory (COMPLETELY ISOLATED)
bob = GraphMem(config, user_id="bob", memory_id="chat")
bob.ingest("I'm a doctor at Mayo Clinic")

# Alice can NEVER see Bob's data
alice.query("What does Bob do?")  # β†’ "No information found" βœ…

# Bob can NEVER see Alice's data  
bob.query("Where does Alice work?")  # β†’ "No information found" βœ…

Architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Neo4j Global Instance                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚           USER: alice              β”‚            USER: bob                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ 🏒 Google  β†’ πŸ‘€ Alice       β”‚   β”‚   β”‚ πŸ₯ Mayo Clinic β†’ πŸ‘€ Bob     β”‚   β”‚
β”‚  β”‚     ↓                       β”‚   β”‚   β”‚       ↓                     β”‚   β”‚
β”‚  β”‚ πŸ’Ό Senior Engineer          β”‚   β”‚   β”‚   🩺 Doctor                 β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                    Redis Cache (Also Isolated by user_id)                 β”‚
β”‚  alice:query:*  alice:search:*     β”‚     bob:query:*  bob:search:*       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ’‘ The 3-Line API

from graphmem import GraphMem, MemoryConfig

# Initialize (works with ANY OpenAI-compatible API)
config = MemoryConfig(
    llm_provider="openai_compatible",
    llm_api_key="your-key",
    llm_api_base="https://openrouter.ai/api/v1",
    llm_model="google/gemini-2.0-flash-001",
    embedding_provider="openai_compatible",
    embedding_api_key="your-key",
    embedding_api_base="https://openrouter.ai/api/v1",
    embedding_model="openai/text-embedding-3-small",
)

memory = GraphMem(config)

# That's it. 3 methods:
memory.ingest("Tesla is led by CEO Elon Musk...")  # ← Extract knowledge
memory.query("Who is the CEO?")                    # ← Ask questions
memory.evolve()                                    # ← Let memory mature

πŸ—οΈ Architecture

High-Level Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                  🧠 GraphMem                                     β”‚
β”‚                         The Human Brain for AI Agents                            β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                 β”‚
β”‚   β”‚  ingest()   β”‚        β”‚   query()   β”‚        β”‚  evolve()   β”‚                 β”‚
β”‚   β”‚  Learn new  β”‚        β”‚  Recall +   β”‚        β”‚  Mature     β”‚                 β”‚
β”‚   β”‚  knowledge  β”‚        β”‚  Reasoning  β”‚        β”‚  memories   β”‚                 β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚                      β”‚                      β”‚
           β–Ό                      β–Ό                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           πŸ” MULTI-TENANT LAYER                                  β”‚
β”‚                                                                                  β”‚
β”‚   Every operation is scoped by: user_id + memory_id                             β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚   β”‚       USER: alice           β”‚    β”‚        USER: bob            β”‚            β”‚
β”‚   β”‚   memory_id: chat_1         β”‚    β”‚    memory_id: chat_1        β”‚            β”‚
β”‚   β”‚   memory_id: notes          β”‚    β”‚    memory_id: work          β”‚            β”‚
β”‚   β”‚   ════════════════════      β”‚    β”‚    ════════════════════     β”‚            β”‚
β”‚   β”‚   Complete isolation βœ…     β”‚    β”‚    Complete isolation βœ…    β”‚            β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        πŸ•ΈοΈ KNOWLEDGE GRAPH ENGINE                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚   β”‚ ENTITY EXTRACTION β”‚   β”‚   RELATIONSHIP    β”‚   β”‚    COMMUNITY      β”‚         β”‚
β”‚   β”‚                   β”‚   β”‚    DETECTION      β”‚   β”‚    DETECTION      β”‚         β”‚
β”‚   β”‚ β€’ LLM-powered     β”‚   β”‚                   β”‚   β”‚                   β”‚         β”‚
β”‚   β”‚ β€’ Named entities  β”‚   β”‚ β€’ Semantic links  β”‚   β”‚ β€’ Louvain algo    β”‚         β”‚
β”‚   β”‚ β€’ Type inference  β”‚   β”‚ β€’ Temporal bounds β”‚   β”‚ β€’ Auto-clustering β”‚         β”‚
β”‚   β”‚ β€’ Descriptions    β”‚   β”‚ β€’ [t_s, t_e]      β”‚   β”‚ β€’ LLM summaries   β”‚         β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚   β”‚ ENTITY RESOLUTION β”‚   β”‚    SEMANTIC       β”‚   β”‚   QUERY ENGINE    β”‚         β”‚
β”‚   β”‚                   β”‚   β”‚     SEARCH        β”‚   β”‚                   β”‚         β”‚
β”‚   β”‚ β€’ Alias merging   β”‚   β”‚                   β”‚   β”‚ β€’ Multi-hop       β”‚         β”‚
β”‚   β”‚ β€’ Canonicalizationβ”‚   β”‚ β€’ Vector index    β”‚   β”‚ β€’ Cross-cluster   β”‚         β”‚
β”‚   β”‚ β€’ 95% accuracy    β”‚   β”‚ β€’ Cosine sim      β”‚   β”‚ β€’ Context assemblyβ”‚         β”‚
β”‚   β”‚ β€’ user_id aware   β”‚   β”‚ β€’ user_id filter  β”‚   β”‚ β€’ LLM synthesis   β”‚         β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         πŸ”„ EVOLUTION ENGINE                                      β”‚
β”‚                      (Human Memory Simulation)                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚                      ⭐ PAGERANK CENTRALITY                              β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   PR(A) = (1-d) + d Γ— Ξ£(PR(Ti)/C(Ti))    where d = 0.85                 β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   Hub Detection:                                                         β”‚   β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚   β”‚
β”‚   β”‚   β”‚ Elon Musk ─────┬───→ Tesla ───→ Austin                          β”‚   β”‚   β”‚
β”‚   β”‚   β”‚    (HUB)       β”œβ”€β”€β”€β†’ SpaceX ───→ Hawthorne                      β”‚   β”‚   β”‚
β”‚   β”‚   β”‚   PR=1.00      └───→ Neuralink                                  β”‚   β”‚   β”‚
β”‚   β”‚   β”‚                                                                  β”‚   β”‚   β”‚
β”‚   β”‚   β”‚ PageRank: Elon(1.00) > Tesla(0.77) > SpaceX(0.77) > Austin(0.52)β”‚   β”‚   β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚   β”‚    MEMORY DECAY      β”‚  β”‚   CONSOLIDATION      β”‚  β”‚ TEMPORAL VALIDITY  β”‚    β”‚
β”‚   β”‚                      β”‚  β”‚                      β”‚  β”‚                    β”‚    β”‚
β”‚   β”‚ Ebbinghaus Curve:    β”‚  β”‚ LLM-based merging:   β”‚  β”‚ Time bounds:       β”‚    β”‚
β”‚   β”‚                      β”‚  β”‚                      β”‚  β”‚                    β”‚    β”‚
β”‚   β”‚ I(t) = Iβ‚€Β·e^(-Ξ»t)    β”‚  β”‚ 5 mentions β†’         β”‚  β”‚ valid_from: t_s    β”‚    β”‚
β”‚   β”‚                      β”‚  β”‚ 1 strong memory      β”‚  β”‚ valid_until: t_e   β”‚    β”‚
β”‚   β”‚ Ξ» = decay rate       β”‚  β”‚                      β”‚  β”‚                    β”‚    β”‚
β”‚   β”‚                      β”‚  β”‚ 80% reduction        β”‚  β”‚ is_valid_at(t)     β”‚    β”‚
β”‚   β”‚ Unused β†’ archived    β”‚  β”‚ while keeping value  β”‚  β”‚ supersede(end)     β”‚    β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                                  β”‚
β”‚   Importance Formula: ρ(e) = w1Β·f1 + w2Β·f2 + w3Β·f3 + w4Β·f4                      β”‚
β”‚   β”œβ”€β”€ f1: Recency (0.3)     - Recent access = important                         β”‚
β”‚   β”œβ”€β”€ f2: Frequency (0.3)   - Used often = important                            β”‚
β”‚   β”œβ”€β”€ f3: PageRank (0.2)    - Well-connected = important (HUB)                  β”‚
β”‚   └── f4: User signal (0.2) - Explicit importance                               β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            πŸ’Ύ STORAGE LAYER                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                       CHOOSE YOUR STORAGE BACKEND                           β”‚β”‚
β”‚  β”‚                                                                             β”‚β”‚
β”‚  β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚β”‚
β”‚  β”‚   β”‚  InMemory   β”‚     β”‚   πŸ”₯ TURSO πŸ”₯    β”‚     β”‚      NEO4J          β”‚      β”‚β”‚
β”‚  β”‚   β”‚  (Default)  β”‚     β”‚    (Embedded)   β”‚     β”‚    (Enterprise)     β”‚      β”‚β”‚
β”‚  β”‚   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€      β”‚β”‚
β”‚  β”‚   β”‚ No persist  β”‚     β”‚ SQLite file     β”‚     β”‚ Full graph DB       β”‚      β”‚β”‚
β”‚  β”‚   β”‚ Zero config β”‚     β”‚ Works offline   β”‚     β”‚ ACID + clustering   β”‚      β”‚β”‚
β”‚  β”‚   β”‚ Dev/testing β”‚     β”‚ Cloud sync opt  β”‚     β”‚ Native Cypher       β”‚      β”‚β”‚
β”‚  β”‚   β”‚ Python vec  β”‚     β”‚ Native vec πŸš€   β”‚     β”‚ HNSW vec πŸš€         β”‚      β”‚β”‚
β”‚  β”‚   β”‚             β”‚     β”‚ ~10ms search    β”‚     β”‚ ~5ms search         β”‚      β”‚β”‚
β”‚  β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚β”‚
β”‚  β”‚         β”‚                     β”‚                        β”‚                    β”‚β”‚
β”‚  β”‚         β”‚      ALL BACKENDS GET THE SAME FEATURES:     β”‚                    β”‚β”‚
β”‚  β”‚         β”‚   βœ… Multi-tenant  βœ… Temporal validity       β”‚                    β”‚β”‚
β”‚  β”‚         β”‚   βœ… PageRank      βœ… Memory evolution         β”‚                    β”‚β”‚
β”‚  β”‚         β”‚   βœ… Communities   βœ… Entity resolution        β”‚                    β”‚β”‚
β”‚  β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚β”‚
β”‚  β”‚                               β”‚                                             β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚   β”‚         πŸ—ƒοΈ NEO4J GRAPH                 β”‚   β”‚         ⚑ REDIS CACHE        β”‚ β”‚
β”‚   β”‚         (Enterprise Option)            β”‚   β”‚        (Optional Layer)       β”‚ β”‚
β”‚   β”‚                                        β”‚   β”‚                               β”‚ β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚ β”‚
β”‚   β”‚  β”‚      ENTITY NODES               β”‚  β”‚   β”‚  β”‚   EMBEDDING CACHE      β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ id, name, type               β”‚  β”‚   β”‚  β”‚                        β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ embedding[1536]              β”‚  β”‚   β”‚  β”‚  Key: emb:{text_hash}  β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ user_id ← ISOLATION          β”‚  β”‚   β”‚  β”‚  TTL: 24 hours         β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ memory_id                    β”‚  β”‚   β”‚  β”‚  3x faster embeddings  β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ importance, access_count     β”‚  β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚ β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚                               β”‚ β”‚
β”‚   β”‚                                        β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚ β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚  β”‚   QUERY CACHE          β”‚   β”‚ β”‚
β”‚   β”‚  β”‚    RELATIONSHIP EDGES           β”‚  β”‚   β”‚  β”‚   (Multi-Tenant!)      β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ valid_from  ← TEMPORAL       β”‚  β”‚   β”‚  β”‚                        β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ valid_until ← VALIDITY       β”‚  β”‚   β”‚  β”‚  Key: query:{user}:*   β”‚   β”‚ β”‚
β”‚   β”‚  β”‚  β€’ user_id ← ISOLATION          β”‚  β”‚   β”‚  β”‚  TTL: 5 minutes        β”‚   β”‚ β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚  β”‚  Instant repeat: 0ms   β”‚   β”‚ β”‚
β”‚   β”‚                                        β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚ β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚                               β”‚ β”‚
β”‚   β”‚  β”‚  VECTOR INDEX (HNSW)            β”‚  β”‚   β”‚  Auto-Invalidation:           β”‚ β”‚
β”‚   β”‚  β”‚  Dimension: 1536, cosine        β”‚  β”‚   β”‚  β€’ ingest() β†’ clear cache     β”‚ β”‚
β”‚   β”‚  β”‚  ~5ms similarity search         β”‚  β”‚   β”‚  β€’ evolve() β†’ clear cache     β”‚ β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚  β€’ clear()  β†’ clear cache     β”‚ β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚   β”‚   πŸ”₯ TURSO (SQLite) - RECOMMENDED!    β”‚   β”‚      πŸ”₯ TURSO CACHE           β”‚ β”‚
β”‚   β”‚      (Edge/Offline Option)            β”‚   β”‚     (Built-in to TursoStore)  β”‚ β”‚
β”‚   β”‚                                        β”‚   β”‚                               β”‚ β”‚
β”‚   β”‚  pip install "agentic-graph-mem[libsql]"  β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚ β”‚
β”‚   β”‚                                        β”‚   β”‚  β”‚ No Redis needed!       β”‚   β”‚ β”‚
β”‚   β”‚  βœ… Persists to local .db file         β”‚   β”‚  β”‚ SQLite-based cache     β”‚   β”‚ β”‚
β”‚   β”‚  βœ… Works completely offline           β”‚   β”‚  β”‚ TTL support            β”‚   β”‚ β”‚
β”‚   β”‚  βœ… Optional Turso Cloud sync          β”‚   β”‚  β”‚ Multi-tenant keys      β”‚   β”‚ β”‚
β”‚   β”‚  βœ… Native F32_BLOB vector search      β”‚   β”‚  β”‚ Survives restarts      β”‚   β”‚ β”‚
β”‚   β”‚  βœ… ~10ms vector similarity            β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚ β”‚
β”‚   β”‚                                        β”‚   β”‚                               β”‚ β”‚
β”‚   β”‚  SAME FEATURES AS NEO4J:              β”‚   β”‚  Great for:                   β”‚ β”‚
β”‚   β”‚  β€’ Temporal validity βœ…                β”‚   β”‚  β€’ Edge AI devices           β”‚ β”‚
β”‚   β”‚  β€’ PageRank centrality βœ…              β”‚   β”‚  β€’ Offline agents            β”‚ β”‚
β”‚   β”‚  β€’ Multi-tenant isolation βœ…           β”‚   β”‚  β€’ Mobile apps               β”‚ β”‚
β”‚   β”‚  β€’ Point-in-time queries βœ…            β”‚   β”‚  β€’ Cost-sensitive deploys    β”‚ β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           πŸ€– LLM PROVIDERS                                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚   β”‚  OpenAI  β”‚ β”‚  Azure   β”‚ β”‚Anthropic β”‚ β”‚  Groq    β”‚ β”‚ Together β”‚ β”‚  Ollama  β”‚ β”‚
β”‚   β”‚  GPT-4o  β”‚ β”‚  OpenAI  β”‚ β”‚  Claude  β”‚ β”‚  Llama   β”‚ β”‚    AI    β”‚ β”‚  Local   β”‚ β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚                    OpenRouter (100+ Models)                              β”‚   β”‚
β”‚   β”‚   google/gemini-2.0-flash β”‚ anthropic/claude-3.5 β”‚ meta-llama/llama-3   β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow: Ingest β†’ Query β†’ Evolve

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              INGEST FLOW                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Input Document                    Knowledge Extraction                  Storage
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚ "Tesla is    β”‚   ──────────▢   β”‚ LLM extracts:    β”‚  ──────────▢  β”‚ Neo4j OR  β”‚
 β”‚  led by CEO  β”‚                  β”‚                  β”‚               β”‚ πŸ”₯Turso   β”‚
 β”‚  Elon Musk"  β”‚                  β”‚ Entities:        β”‚               β”‚           β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚ β€’ Tesla [Org]    β”‚               β”‚ (Tesla)───│
        β”‚                          β”‚ β€’ Elon Musk [Per]β”‚               β”‚     β”‚     β”‚
        β”‚                          β”‚                  β”‚               β”‚     β–Ό     β”‚
        β”‚                          β”‚ Relations:       β”‚               β”‚ CEO_OF    β”‚
        β”‚                          β”‚ β€’ (Elon)─CEO─▢   β”‚               β”‚     β”‚     β”‚
        β”‚                          β”‚   (Tesla)        β”‚               β”‚     β–Ό     β”‚
        β”‚                          β”‚                  β”‚               β”‚ (Elon)    β”‚
        β”‚                          β”‚ Temporal:        β”‚               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                          β”‚ β€’ valid_from=now β”‚                     β”‚
        β”‚                          β”‚ β€’ valid_until=∞  β”‚                     β–Ό
        β”‚                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                                   β”‚                         β”‚ Redis OR  β”‚
        β”‚                                   β”‚                         β”‚ TursoCacheβ”‚
        β”‚                                   β–Ό                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                          β”‚ Entity Resolutionβ”‚
        β”‚                          β”‚                  β”‚
        β”‚                          β”‚ "Elon" = "Musk"  β”‚
        β”‚                          β”‚ = "Elon Musk"    β”‚
        β”‚                          β”‚ β†’ Canonical: "Elon Musk"
        β”‚                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        └─── user_id + memory_id tagged on ALL nodes/edges


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                               QUERY FLOW                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  User Question              Cache Check           Retrieval              Answer
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚ "Who is the  β”‚   ───▢   β”‚  Redis    β”‚  HIT   β”‚           β”‚   ───▢  β”‚ "Elon    β”‚
 β”‚  CEO?"       β”‚          β”‚  Cache    β”‚  ───▢  β”‚  SKIP!    β”‚         β”‚  Musk"   β”‚
 β”‚              β”‚          β”‚           β”‚        β”‚           β”‚         β”‚          β”‚
 β”‚ user: alice  β”‚          β”‚ Key:      β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚ mem: chat_1  β”‚          β”‚ query:    β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚ alice:    β”‚  MISS
        β”‚                  β”‚ chat_1:   β”‚  ───▢  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                  β”‚ {hash}    β”‚        β”‚         RETRIEVAL              β”‚
        β”‚                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚                                β”‚
        β”‚                                       β”‚  1. Embed query                β”‚
        β”‚                                       β”‚  2. Vector search (Neo4j/Turso)β”‚
        β”‚                                       β”‚     WHERE user_id = 'alice'    β”‚
        β”‚                                       β”‚     AND memory_id = 'chat_1'   β”‚
        β”‚                                       β”‚  3. Get related edges          β”‚
        β”‚                                       β”‚  4. Filter by temporal         β”‚
        β”‚                                       β”‚     is_valid_at(now) βœ…        β”‚
        β”‚                                       β”‚  5. Rank by importance         β”‚
        β”‚                                       β”‚     (PageRank score)           β”‚
        β”‚                                       β”‚  6. Build context              β”‚
        β”‚                                       β”‚  7. LLM generates answer       β”‚
        β”‚                                       β”‚  8. Cache result in Redis      β”‚
        β”‚                                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        └─── user_id ensures Alice NEVER sees Bob's data


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              EVOLVE FLOW                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Trigger                    Evolution Cycle                         Result
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚ memory       β”‚   ───▢   β”‚                                β”‚     β”‚            β”‚
 β”‚ .evolve()    β”‚          β”‚  1. PAGERANK RECALCULATION     β”‚     β”‚ β€’ Hubs     β”‚
 β”‚              β”‚          β”‚     Build graph from edges     β”‚     β”‚   identifiedβ”‚
 β”‚ user: alice  β”‚          β”‚     Compute PR scores          β”‚     β”‚            β”‚
 β”‚              β”‚          β”‚     Update importance          β”‚     β”‚ β€’ 80%      β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚                                β”‚     β”‚   memory   β”‚
        β”‚                  β”‚  2. MEMORY DECAY               β”‚     β”‚   reduced  β”‚
        β”‚                  β”‚     I(t) = Iβ‚€ Γ— e^(-Ξ»t)        β”‚     β”‚            β”‚
        β”‚                  β”‚     Archive if I < 0.1         β”‚     β”‚ β€’ Conflictsβ”‚
        β”‚                  β”‚                                β”‚     β”‚   resolved β”‚
        β”‚                  β”‚  3. CONSOLIDATION              β”‚     β”‚            β”‚
        β”‚                  β”‚     Find similar memories      β”‚     β”‚ β€’ Cache    β”‚
        β”‚                  β”‚     LLM merges duplicates      β”‚     β”‚   cleared  β”‚
        β”‚                  β”‚                                β”‚     β”‚            β”‚
        β”‚                  β”‚  4. REHYDRATION                β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                  β”‚     Update contradictions      β”‚
        β”‚                  β”‚     "CEO=John" β†’ "CEO=Jane"    β”‚
        β”‚                  β”‚                                β”‚
        β”‚                  β”‚  5. CACHE INVALIDATION         β”‚
        β”‚                  β”‚     Clear Redis for user       β”‚
        β”‚                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        └─── Only evolves Alice's data (user_id scoped)

Multi-Tenant Data Isolation

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     πŸ” MULTI-TENANT ARCHITECTURE                                 β”‚
β”‚              (Works identically with Neo4j, Turso, or InMemory)                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚                    STORAGE BACKEND (Neo4j / Turso / InMemory)                    β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚                       GLOBAL VECTOR INDEX                                β”‚   β”‚
β”‚   β”‚                    (Entity.embedding, HNSW)                              β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   Query: db.index.vector.queryNodes(                                     β”‚   β”‚
β”‚   β”‚            'entity_embedding_index',                                     β”‚   β”‚
β”‚   β”‚            $top_k * 10,     ← Fetch extra for filtering                  β”‚   β”‚
β”‚   β”‚            $query_embedding                                              β”‚   β”‚
β”‚   β”‚          )                                                               β”‚   β”‚
β”‚   β”‚          WHERE node.user_id = $user_id   ← ISOLATION                     β”‚   β”‚
β”‚   β”‚          AND node.memory_id = $memory_id                                 β”‚   β”‚
β”‚   β”‚          RETURN node LIMIT $top_k                                        β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚   β”‚         USER: alice           β”‚   β”‚          USER: bob                β”‚     β”‚
β”‚   β”‚                               β”‚   β”‚                                   β”‚     β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚     β”‚
β”‚   β”‚  β”‚    memory: chat_1       β”‚  β”‚   β”‚  β”‚    memory: chat_1           β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”     β”‚  β”‚   β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”        β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β”‚Alice│───▢│Googleβ”‚    β”‚  β”‚   β”‚  β”‚  β”‚ Bob │───▢│Mayo  β”‚       β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜     β”‚  β”‚   β”‚  β”‚  β””β”€β”€β”€β”€β”€β”˜    β”‚Clinicβ”‚       β”‚  β”‚     β”‚
β”‚   β”‚  β”‚     β”‚                   β”‚  β”‚   β”‚  β”‚     β”‚       β””β”€β”€β”€β”€β”€β”˜        β”‚  β”‚     β”‚
β”‚   β”‚  β”‚     β–Ό                   β”‚  β”‚   β”‚  β”‚     β–Ό                      β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚  β”‚   β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”                  β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β”‚Engineerβ”‚             β”‚  β”‚   β”‚  β”‚  β”‚Doctorβ”‚                  β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚  β”‚   β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”˜                  β”‚  β”‚     β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚     β”‚
β”‚   β”‚                               β”‚   β”‚                                   β”‚     β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚     β”‚
β”‚   β”‚  β”‚    memory: notes        β”‚  β”‚   β”‚  β”‚    memory: work             β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”     β”‚  β”‚   β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”      β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β”‚Python│──▢│ ML  β”‚     β”‚  β”‚   β”‚  β”‚  β”‚Patient│──▢│Recordβ”‚      β”‚  β”‚     β”‚
β”‚   β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”˜     β”‚  β”‚   β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”˜      β”‚  β”‚     β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚     β”‚
β”‚   β”‚                               β”‚   β”‚                                   β”‚     β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                                                                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                           REDIS CACHE (ISOLATED)                                 β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   Alice's Keys:                      Bob's Keys:                         β”‚   β”‚
β”‚   β”‚   ─────────────                      ──────────                          β”‚   β”‚
β”‚   β”‚   query:alice:chat_1:abc123          query:bob:chat_1:xyz789             β”‚   β”‚
β”‚   β”‚   search:alice:chat_1:def456         search:bob:chat_1:uvw321            β”‚   β”‚
β”‚   β”‚   search:alice:notes:ghi789          search:bob:work:rst654              β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   Shared (same text = same embedding):                                   β”‚   β”‚
β”‚   β”‚   ─────────────────────────────────────                                  β”‚   β”‚
β”‚   β”‚   emb:sha256_of_text β†’ [0.1, 0.2, ...]                                   β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                  β”‚
β”‚   βœ… Alice can NEVER access Bob's cached queries                                β”‚
β”‚   βœ… Bob can NEVER access Alice's cached queries                                β”‚
β”‚   βœ… Embeddings shared (efficiency) - no sensitive data in embeddings           β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Temporal Validity Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       ⏰ TEMPORAL VALIDITY                                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚   Every RELATIONSHIP has a time interval: [valid_from, valid_until]             β”‚
β”‚                                                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚                         CEO TRANSITIONS                                  β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   Timeline:  2010      2015      2018      2020      2025               β”‚   β”‚
β”‚   β”‚              β”‚         β”‚         β”‚         β”‚         β”‚                   β”‚   β”‚
β”‚   β”‚              β–Ό         β–Ό         β–Ό         β–Ό         β–Ό                   β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   John ──CEO_OF──▢ ACME   ════════════════╗                             β”‚   β”‚
β”‚   β”‚   valid: [2010-01-01, 2018-06-30]         β•‘                             β”‚   β”‚
β”‚   β”‚                                            β•‘                             β”‚   β”‚
β”‚   β”‚   Jane ──CEO_OF──▢ ACME                   β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•     β”‚   β”‚
β”‚   β”‚   valid: [2018-07-01, NULL]                ← NULL = still current       β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                  β”‚
β”‚   Point-in-Time Queries:                                                         β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   Q: "Who was CEO in 2015?"                                              β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   1. Find edges WHERE relation_type = 'CEO_OF'                           β”‚   β”‚
β”‚   β”‚   2. Filter: is_valid_at(datetime(2015, 6, 1))                           β”‚   β”‚
β”‚   β”‚      β”œβ”€β”€ John: valid_from=2010 ≀ 2015 ≀ valid_until=2018 βœ…             β”‚   β”‚
β”‚   β”‚      └── Jane: valid_from=2018 > 2015 ❌                                 β”‚   β”‚
β”‚   β”‚   3. Return: "John Smith"                                                β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   Q: "Who is CEO now?"                                                   β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   1. Filter: is_valid_at(datetime.utcnow())                              β”‚   β”‚
β”‚   β”‚      β”œβ”€β”€ John: valid_until=2018 < now ❌                                 β”‚   β”‚
β”‚   β”‚      └── Jane: valid_from=2018 ≀ now, valid_until=NULL βœ…                β”‚   β”‚
β”‚   β”‚   2. Return: "Jane Doe"                                                  β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                  β”‚
β”‚   API:                                                                           β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   # Check validity at any point in time                                  β”‚   β”‚
β”‚   β”‚   edge.is_valid_at(datetime(2015, 6, 1))  # True/False                   β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   # Mark relationship as ended                                           β”‚   β”‚
β”‚   β”‚   edge.supersede(end_time=datetime(2018, 6, 30))                         β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β”‚   # Query edges at specific time                                         β”‚   β”‚
β”‚   β”‚   store.query_edges_at_time(                                             β”‚   β”‚
β”‚   β”‚       memory_id="company_kb",                                            β”‚   β”‚
β”‚   β”‚       query_time=datetime(2015, 6, 1),                                   β”‚   β”‚
β”‚   β”‚       relation_type="CEO_OF"                                             β”‚   β”‚
β”‚   β”‚   )                                                                      β”‚   β”‚
β”‚   β”‚                                                                          β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

File Structure

graphmem/
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ memory.py              # GraphMem main class
β”‚   β”œβ”€β”€ memory_types.py        # MemoryNode, MemoryEdge (+ temporal validity)
β”‚   └── exceptions.py          # Custom exceptions
β”‚
β”œβ”€β”€ graph/
β”‚   β”œβ”€β”€ knowledge_graph.py     # LLM-based extraction
β”‚   β”œβ”€β”€ entity_resolver.py     # Deduplication (user_id aware)
β”‚   └── community_detector.py  # Topic clustering
β”‚
β”œβ”€β”€ evolution/
β”‚   β”œβ”€β”€ memory_evolution.py    # Evolution orchestrator
β”‚   β”œβ”€β”€ importance_scorer.py   # PageRank + multi-factor scoring
β”‚   β”œβ”€β”€ decay.py               # Ebbinghaus forgetting curve
β”‚   β”œβ”€β”€ consolidation.py       # LLM-based merging (user_id aware)
β”‚   └── rehydration.py         # Contradiction resolution
β”‚
β”œβ”€β”€ retrieval/
β”‚   β”œβ”€β”€ query_engine.py        # Multi-hop + cross-cluster
β”‚   β”œβ”€β”€ retriever.py           # Context retrieval
β”‚   └── semantic_search.py     # Vector search (user_id filtered)
β”‚
β”œβ”€β”€ stores/
β”‚   β”œβ”€β”€ neo4j_store.py         # Graph + temporal + HNSW vector index
β”‚   β”œβ”€β”€ turso_store.py         # SQLite + temporal + native vector (NEW!)
β”‚   β”œβ”€β”€ memory_store.py        # In-memory (default)
β”‚   └── redis_cache.py         # Multi-tenant cache
β”‚
β”œβ”€β”€ llm/
β”‚   β”œβ”€β”€ providers.py           # 10+ LLM providers
β”‚   └── embeddings.py          # Embedding + cache
β”‚
└── context/
    β”œβ”€β”€ context_engine.py      # Context assembly
    β”œβ”€β”€ chunker.py             # Semantic chunking
    └── multimodal.py          # JSON, CSV, Markdown, Code, Web

πŸ“Š Why Enterprise Teams Choose GraphMem

Production Scale Performance

Metric Naive RAG GraphMem Advantage
1K conversations πŸ’₯ Context overflow βœ… Bounded Handles growth
10K entities O(n) = 2.3s O(1) = 50ms 46x faster
1 year history 3,650 entries ~100 consolidated 97% reduction
Entity conflicts Duplicates Auto-resolved Clean data
Temporal queries ❌ Impossible βœ… Native Unique capability

Cost Efficiency

Naive RAG:  Send entire history every query    = $$$$$
GraphMem:   Retrieve only relevant subgraph    = $
                                                 ─────
                                                 99% savings

Enterprise Requirements

Requirement GraphMem
Multi-tenant isolation βœ… user_id on every node
ACID transactions βœ… Neo4j backend
Horizontal scaling βœ… Neo4j cluster + Redis
Audit trail βœ… Temporal validity history
Data sovereignty βœ… Self-hosted option

πŸ”§ Installation

# Core only (in-memory, for development)
pip install agentic-graph-mem

# πŸ”₯ RECOMMENDED: Turso (SQLite persistence + offline)
pip install "agentic-graph-mem[libsql]"

# Enterprise: Neo4j + Redis (full graph power)
pip install "agentic-graph-mem[all]"

🎯 Which Backend Should You Choose?

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         STORAGE BACKEND DECISION TREE                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚   "Do you need data to persist between restarts?"                               β”‚
β”‚                           β”‚                                                      β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                        β”‚
β”‚              β”‚                         β”‚                                        β”‚
β”‚              NO                       YES                                       β”‚
β”‚              β”‚                         β”‚                                        β”‚
β”‚              β–Ό                         β–Ό                                        β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    "Do you need complex graph queries                    β”‚
β”‚    β”‚   InMemory      β”‚     (multi-hop traversals, GDS algorithms)?"             β”‚
β”‚    β”‚                 β”‚                 β”‚                                        β”‚
β”‚    β”‚ β€’ Development   β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”‚
β”‚    β”‚ β€’ Testing       β”‚    β”‚                         β”‚                          β”‚
β”‚    β”‚ β€’ Quick POCs    β”‚   NO                        YES                         β”‚
β”‚    β”‚ β€’ Zero config   β”‚    β”‚                         β”‚                          β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β–Ό                         β–Ό                          β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚                    β”‚   πŸ”₯ TURSO       β”‚    β”‚   NEO4J         β”‚                  β”‚
β”‚                    β”‚                 β”‚    β”‚                 β”‚                  β”‚
β”‚                    β”‚ β€’ Edge/offline  β”‚    β”‚ β€’ Enterprise    β”‚                  β”‚
β”‚                    β”‚ β€’ Mobile apps   β”‚    β”‚ β€’ Complex graphsβ”‚                  β”‚
β”‚                    β”‚ β€’ Single-user   β”‚    β”‚ β€’ Multi-tenant  β”‚                  β”‚
β”‚                    β”‚ β€’ No server     β”‚    β”‚ β€’ Horizontal    β”‚                  β”‚
β”‚                    β”‚ β€’ Simple setup  β”‚    β”‚   scaling       β”‚                  β”‚
β”‚                    β”‚ β€’ SQLite-based  β”‚    β”‚ β€’ ACID + clusterβ”‚                  β”‚
β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚                                                    β”‚                            β”‚
β”‚                                      "Add high-performance caching?"            β”‚
β”‚                                                    β”‚                            β”‚
β”‚                                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”                    β”‚
β”‚                                          YES              NO                    β”‚
β”‚                                           β”‚               β”‚                    β”‚
β”‚                                           β–Ό               β–Ό                    β”‚
β”‚                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚                                    β”‚  + REDIS  β”‚    β”‚ Neo4j onlyβ”‚              β”‚
β”‚                                    β”‚  Cache    β”‚    β”‚ (still    β”‚              β”‚
β”‚                                    β”‚           β”‚    β”‚  great!)  β”‚              β”‚
β”‚                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Feature Comparison

Feature InMemory Turso πŸ”₯ Neo4j
Persistence ❌ βœ… SQLite file βœ… Server
Works Offline βœ… βœ… ❌
Vector Search Python Native F32_BLOB Native HNSW
Cloud Sync ❌ βœ… Optional βœ…
Setup Complexity None One file path Server required
Multi-hop Queries βœ… NetworkX βœ… NetworkX βœ… Native Cypher
PageRank βœ… βœ… βœ…
Temporal Validity βœ… βœ… βœ…
Multi-tenant βœ… βœ… βœ…
Best For Dev/Test Edge/Offline Enterprise

πŸ“– Complete Examples

Basic Usage (In-Memory)

from graphmem import GraphMem, MemoryConfig

config = MemoryConfig(
    llm_provider="openai_compatible",
    llm_api_key="sk-or-v1-your-key",
    llm_api_base="https://openrouter.ai/api/v1",
    llm_model="google/gemini-2.0-flash-001",
    embedding_provider="openai_compatible",
    embedding_api_key="sk-or-v1-your-key",
    embedding_api_base="https://openrouter.ai/api/v1",
    embedding_model="openai/text-embedding-3-small",
)

memory = GraphMem(config)

# Learn
memory.ingest("Tesla is led by CEO Elon Musk. Founded in 2003.")
memory.ingest("SpaceX, founded by Elon Musk in 2002, builds rockets.")
memory.ingest("Neuralink develops brain-computer interfaces.")

# Recall
response = memory.query("What companies does Elon Musk lead?")
print(response.answer)  # "Elon Musk leads Tesla, SpaceX, and Neuralink."

# Mature
memory.evolve()  # Consolidates, decays, re-ranks importance

With Turso (SQLite Persistence + Offline Support) πŸ†•

from graphmem import GraphMem, MemoryConfig

# Turso gives you persistence without running Neo4j!
# Data survives restarts, works offline, can sync to cloud

config = MemoryConfig(
    llm_provider="openai_compatible",
    llm_api_key="sk-or-v1-your-key",
    llm_api_base="https://openrouter.ai/api/v1",
    llm_model="google/gemini-2.0-flash-001",
    embedding_provider="openai_compatible",
    embedding_api_key="sk-or-v1-your-key",
    embedding_api_base="https://openrouter.ai/api/v1",
    embedding_model="openai/text-embedding-3-small",
    
    # πŸ”₯ Just add a file path - that's it!
    turso_db_path="my_agent_memory.db",
    
    # Optional: Sync to Turso Cloud for backups/multi-device
    # turso_url="https://your-db.turso.io",
    # turso_auth_token="your-token",
)

memory = GraphMem(config, user_id="alice")

# All data persists in my_agent_memory.db
memory.ingest("Alice is a software engineer at Google.")
memory.save()  # Data survives restart!

# Later, in a new session:
memory2 = GraphMem(config, user_id="alice")
response = memory2.query("Where does Alice work?")  # Still knows! βœ…

Why Turso over InMemory?

  • βœ… Data survives restarts (SQLite file)
  • βœ… Works offline (no network needed)
  • βœ… Optional cloud sync (Turso Cloud)
  • βœ… No server to manage (unlike Neo4j)
  • βœ… Per-user database files (true isolation)

Production: Multi-Tenant Chat System

from graphmem import GraphMem, MemoryConfig

# Base config (shared across all users)
base_config = MemoryConfig(
    llm_provider="openai_compatible",
    llm_api_key="sk-or-v1-your-key",
    llm_api_base="https://openrouter.ai/api/v1",
    llm_model="google/gemini-2.0-flash-001",
    embedding_provider="openai_compatible",
    embedding_api_key="sk-or-v1-your-key",
    embedding_api_base="https://openrouter.ai/api/v1",
    embedding_model="openai/text-embedding-3-small",
    # Production storage
    neo4j_uri="neo4j+ssc://xxx.databases.neo4j.io",
    neo4j_username="neo4j",
    neo4j_password="your-password",
    redis_url="redis://default:password@your-redis.cloud.redislabs.com:17983",
)

class ChatService:
    def get_memory(self, user_id: str, session_id: str) -> GraphMem:
        """Each user gets isolated memory."""
        return GraphMem(
            base_config,
            user_id=user_id,      # ← Complete isolation
            memory_id=session_id,  # ← Per-session memory
        )
    
    def chat(self, user_id: str, session_id: str, message: str) -> str:
        memory = self.get_memory(user_id, session_id)
        
        # Store user message as memory
        memory.ingest(message)
        
        # Generate response using memory
        response = memory.query(message)
        
        return response.answer

# Usage
service = ChatService()

# Alice's session (isolated)
alice_response = service.chat("alice", "session_1", "I'm a software engineer at Google")
alice_response = service.chat("alice", "session_1", "What do I do?")  # β†’ "Software engineer at Google"

# Bob's session (completely separate)
bob_response = service.chat("bob", "session_1", "I'm a doctor")
bob_response = service.chat("bob", "session_1", "What does Alice do?")  # β†’ "No information found"

Temporal Queries: Track Changes Over Time

from datetime import datetime
from graphmem.core.memory_types import MemoryEdge
from graphmem.stores.neo4j_store import Neo4jStore

store = Neo4jStore(uri, user, password)

# Track CEO transitions
john_ceo = MemoryEdge(
    id="john_ceo",
    source_id="john_smith",
    target_id="acme_corp",
    relation_type="CEO_OF",
    valid_from=datetime(2010, 1, 1),
    valid_until=datetime(2018, 6, 30),  # John left
)

jane_ceo = MemoryEdge(
    id="jane_ceo",
    source_id="jane_doe",
    target_id="acme_corp",
    relation_type="CEO_OF",
    valid_from=datetime(2018, 7, 1),
    valid_until=None,  # Current CEO
)

# Query by time period
ceo_2015 = store.query_edges_at_time(
    memory_id="company_kb",
    query_time=datetime(2015, 6, 1),
    relation_type="CEO_OF"
)
# β†’ Returns John Smith's edge

ceo_now = store.query_edges_at_time(
    memory_id="company_kb",
    query_time=datetime.utcnow(),
    relation_type="CEO_OF"
)
# β†’ Returns Jane Doe's edge

# Mark relationship as ended
store.supersede_relationship(
    memory_id="company_kb",
    edge_id="jane_ceo",
    end_time=datetime(2025, 12, 31)  # Jane leaves
)

πŸ§ͺ Run the Evaluation

cd graphmem/evaluation
python run_eval.py

Uses MultiHopRAG dataset (2,556 QA samples, 609 documents).


πŸ”¬ The Science Behind GraphMem

Ebbinghaus Forgetting Curve

importance(t) = importance_0 Γ— e^(-Ξ» Γ— (t - last_access))

Just like human memory, unused information fades exponentially.

PageRank for Entity Importance

PR(A) = (1-d) + d Γ— Ξ£(PR(Ti)/C(Ti))

Hub entities (connected to many concepts) are more importantβ€”exactly like neural hubs in the brain.

Temporal Validity

valid(r, t) = 1[t_s(r) ≀ t ≀ t_e(r)]

Every relationship has a time interval, enabling episodic memory recall.


🏭 Deployment Tiers

Scale Users Strategy Infrastructure
Development 1 InMemory (no persistence) Nothing required
Personal/Edge 1-10 πŸ”₯ Turso (local SQLite) Single .db file per user
Startup 1-100 Turso + Cloud sync Turso Cloud (free tier)
Growth 100-10K Neo4j + Redis Neo4j Aura Pro + Redis Cloud
Enterprise 10K-100K Sharded by region Neo4j Enterprise Cluster
Global 100K+ Database per tenant Multi-region Neo4j Fabric

When to Use Each Storage

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           STORAGE SELECTION GUIDE                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                  β”‚
β”‚  πŸ§ͺ DEVELOPMENT / TESTING                                                       β”‚
β”‚     └─▢ InMemory (default)                                                      β”‚
β”‚         β€’ pip install agentic-graph-mem                                         β”‚
β”‚         β€’ config = MemoryConfig(...)  # No storage params needed                β”‚
β”‚                                                                                  β”‚
β”‚  πŸ“± EDGE / OFFLINE / SIMPLE APPS                                                β”‚
β”‚     └─▢ πŸ”₯ Turso (RECOMMENDED)                                                  β”‚
β”‚         β€’ pip install "agentic-graph-mem[libsql]"                               β”‚
β”‚         β€’ config = MemoryConfig(..., turso_db_path="agent.db")                  β”‚
β”‚         β€’ Works offline, data persists, no server!                              β”‚
β”‚                                                                                  β”‚
β”‚  🏒 ENTERPRISE / HIGH-SCALE                                                     β”‚
β”‚     └─▢ Neo4j + Redis                                                           β”‚
β”‚         β€’ pip install "agentic-graph-mem[all]"                                  β”‚
β”‚         β€’ config = MemoryConfig(..., neo4j_uri=..., redis_url=...)              β”‚
β”‚         β€’ Complex graph queries, horizontal scaling, ACID                       β”‚
β”‚                                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“¦ Dependencies

# Core (no external services, in-memory only)
pip install agentic-graph-mem

# With Turso (SQLite persistence, offline-first) - SIMPLEST OPTION!
pip install agentic-graph-mem libsql

# With Neo4j persistence (full graph database)
pip install "agentic-graph-mem[neo4j]"

# With Redis caching (high-performance cache)
pip install "agentic-graph-mem[redis]"

# Full production stack (Neo4j + Redis)
pip install "agentic-graph-mem[all]"

Storage Backend Comparison

Backend Persistence Vector Search Graph Algorithms Offline Use Case
InMemory ❌ βœ… (in Python) βœ… (NetworkX) βœ… Development, testing
Turso βœ… βœ… (native) βœ… (NetworkX) βœ… Edge/offline AI, simple deploys
Neo4j βœ… βœ… (HNSW) βœ… (GDS, native) ❌ Enterprise, complex graphs
Redis ⚠️ (volatile) ❌ ❌ ❌ Caching layer only

🎯 The Future of AI Memory

GraphMem isn't just another vector database wrapper. It's a paradigm shift:

Old Way GraphMem Way
Store everything Remember what matters
Static forever Evolves over time
No relationships Rich knowledge graph
"Who is CEO?" "Who was CEO in 2015?"
One user fits all Enterprise multi-tenant
Hope for the best PageRank prioritization

The agents of tomorrow will have memories that think.


🀝 Contributing

We're building the future of AI memory. Join us!


πŸ“„ License

MIT License - see LICENSE.


πŸ™ Acknowledgments

  • Inspired by cognitive neuroscience research on human memory
  • Built on Neo4j, Redis, Turso (libSQL), and OpenAI
  • PageRank algorithm by Larry Page and Sergey Brin
  • Turso team for the amazing embedded SQLite with vector search

Made with 🧠 by Al-Amin Ibrahim

GitHub PyPI

"Give your AI agents the memory they deserve."

About

Production-Grade Agent Memory Framework for Agentic AI

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages