Skip to main content

Dagestan

Temporal Graph Memory Layer for LLMs

Dagestan stores LLM memory as a typed temporal knowledge graph instead of flat vector embeddings. It tracks entities, concepts, events, preferences, and goals — with time-aware confidence decay, contradiction detection, and relationship-based retrieval.

Why

Current LLM memory solutions (vector DBs) treat memory as a pile of embeddings retrieved by similarity. They don't understand:

  • Time — old information and new information are treated the same
  • Relationships — there's no structure between memories
  • Contradictions — conflicting facts coexist silently
  • Decay — nothing fades; nothing is curated

Dagestan addresses these gaps with a graph-based approach where memory has structure, relationships, and temporal awareness.

Status

v0.1 — Foundation release. Working memory layer with:

  • Typed temporal graph (Entity, Concept, Event, Preference, Goal nodes)
  • LLM-based knowledge extraction from conversations
  • Contradiction detection between conflicting preferences/goals
  • Exponential temporal decay on confidence scores
  • Gap detection (incomplete entity profiles)
  • Bridge node detection (cross-cluster connections)
  • Centrality-based importance scoring
  • Query-driven graph retrieval (keyword + structure, no embeddings)
  • JSON persistence
  • CLI for graph inspection
  • 63 passing unit tests

Install

# Core (no LLM dependencies)
pip install -e .

# With OpenAI
pip install -e ".[openai]"

# With Anthropic
pip install -e ".[anthropic]"

# Development
pip install -e ".[dev]"

Quick Start

from dagestan import Dagestan

# Initialize with an LLM provider for extraction
mem = Dagestan(provider="openai", db_path="./memory.json")

# Ingest conversation text
mem.ingest("User mentioned they love Python and want to build a startup focused on graph databases.")

# Retrieve relevant context
context = mem.retrieve("What does the user care about?")
print(context)

# Run curation (applies decay, finds contradictions)
report = mem.curate()
print(f"Contradictions found: {report.contradictions_found}")

# Get structured context for next conversation
strategy = mem.strategy()
print(strategy)

Without an LLM (manual graph building)

from dagestan import Dagestan, Node, Edge, NodeType, EdgeType

mem = Dagestan(db_path="./memory.json", auto_save=True)

# Add nodes directly
user = mem.add_node(Node(type=NodeType.ENTITY, label="User"))
pref = mem.add_node(Node(type=NodeType.PREFERENCE, label="Prefers tea"))
goal = mem.add_node(Node(type=NodeType.GOAL, label="Build Dagestan"))

mem.add_edge(Edge(source_id=user.id, target_id=pref.id, type=EdgeType.HAS_PREFERENCE))
mem.add_edge(Edge(source_id=user.id, target_id=goal.id, type=EdgeType.WANTS))

# Query the graph
results = mem.retrieve("user preferences")
print(results)

CLI

# Show graph summary
dagestan info --db ./memory.json

# List all nodes
dagestan nodes --db ./memory.json

# Filter by type
dagestan nodes --type preference --db ./memory.json

# Query the graph
dagestan retrieve "user goals" --db ./memory.json

# Run curation
dagestan curate --db ./memory.json

# Export full graph
dagestan export --db ./memory.json

Architecture

Conversation → Extraction (LLM) → Temporal Graph → Operations → Retrieval
                                       ↓
                                   Curation
                                 (decay, contradictions,
                                  gaps, bridges)

Node Types: Entity, Concept, Event, Preference, Goal

Edge Types: relates_to, caused, contradicts, happened_before, has_preference, wants

Temporal Metadata: Every node carries created_at, last_reinforced, confidence_score, and decay_rate. Confidence degrades exponentially unless reinforced by new conversation.

Graph Operations

These run on the graph structure — no LLM needed for computation.

Operation What it does
Contradiction Detection Finds conflicting preferences/goals for the same entity
Temporal Decay Reduces confidence based on time since last reinforcement
Gap Detection Identifies entities with incomplete knowledge profiles
Bridge Detection Finds nodes connecting otherwise disconnected clusters
Centrality Scoring Ranks nodes by connection count + recency

Project Structure

dagestan/
├── __init__.py              # Main Dagestan class (public API)
├── cli.py                   # Command-line interface
├── graph/
│   ├── schema.py            # Node, Edge, NodeType, EdgeType
│   ├── temporal_graph.py    # Core graph with CRUD + snapshots
│   └── operations.py        # Contradiction, decay, gap, bridge, centrality
├── extraction/
│   ├── extractor.py         # Conversation → graph via LLM
│   └── prompts.py           # Extraction prompt templates
├── curation/
│   ├── curator.py           # Curation pipeline orchestrator
│   └── strategy.py          # Context strategy generation
├── retrieval/
│   └── retriever.py         # Query-driven graph traversal
├── storage/
│   └── store.py             # JSON persistence (SQLite planned for v0.2)
├── integrations/            # Planned: drop-in OpenAI/Anthropic wrappers
viz/
├── __init__.py
├── __main__.py              # Entry point (python -m viz)
├── server.py                # Stdlib HTTP server + REST API + SSE
├── watcher.py               # File-change polling (no deps)
├── export.py                # LaTeX/TikZ, DOT, CSV export
├── generate_demo.py         # Demo graph generator
└── static/
    ├── index.html           # Main UI page
    ├── style.css            # Dark-theme styling
    └── app.js               # vis-network graph rendering

Visualization

Dagestan ships with a zero-dependency interactive graph visualizer for debugging and exploring your knowledge graphs in the browser.

# Launch with auto-detected graph file
python -m viz.server

# Or point at a specific file and port
python -m viz.server --file demo_memory.json --port 8765

Then open http://localhost:8765.

Features

Feature Description
Live Graph Rendering Interactive force-directed layout via vis-network
Auto-Refresh / SSE File watcher detects changes and pushes updates via Server-Sent Events
Diff Highlighting New nodes glow green with a ✦ marker; removed counts shown in dashboard
Node & Edge Inspector Click any element to view full metadata, confidence, decay rate
Neighborhood Explorer Double-click a node to zoom into its local neighborhood
Stats Dashboard Node/edge counts, type distributions, confidence histograms
Temporal Decay View Color-coded confidence levels (green → yellow → red)
Filter by Type Toggle node types on/off
Search Find nodes by label (keyboard shortcut: /)
LaTeX / DOT / CSV Export Export graphs for research papers (TikZ, Graphviz DOT, CSV)
File Switcher Browse and switch between graph JSON files in the project
Keyboard Shortcuts R refresh, F fit view, / search, ? help, Esc clear

Generate a Demo Graph

python -m viz.generate_demo --output viz_demo_graph.json --nodes 25
python -m viz.server --file viz_demo_graph.json

See viz/README.md for full details.

Roadmap

Version Focus Status
v0.1 Core graph, extraction, basic operations, JSON storage Done
v0.2 SQLite backend, all 5 operations fully tuned Planned
v0.3 Query-driven traversal improvements, context compression Planned
v1.0 Benchmarks, paper, honest evaluation vs baselines Planned
v2.0 Graph operations as reasoning substrate Research

Evaluation (LOCOMO Benchmarks)

Dagestan includes an evaluation harness for benchmarking against the LOCOMO benchmark.

Evaluation code/config lives under evals/:

  • evals/run_locomo_eval.py — main evaluation runner (QA, summarization, coherence)
  • evals/run_ablations.py — ablation study runner
  • evals/configs/*.yaml — model/data settings (e.g., smoke_test.yaml, locomo_gemini_flash.yaml)

Quick commands (from repo root):

# Install eval-only dependencies (dataset download / caching)
pip install datasets huggingface_hub pyyaml

# Download/cache the LOCOMO dataset locally
make download-locomo

# Smoke run (fast dry-run)
make smoke

# Full benchmark run
make locomo

# Single tasks
make qa
make summarization
make coherence

# Ablations
make ablations
make ablations-baselines

Notes:

  • The runner writes outputs under evals/results/<run_id>/.
  • The make smoke target uses the provider: stub setting from evals/configs/smoke_test.yaml. If your current Dagestan backend does not support provider="stub" for extraction/ingestion, run with a real provider (e.g., openai / anthropic) by editing the config.

Performance claims should be made only after you complete the benchmark runs.

Constraints

  • Zero GPU required — runs on CPU only
  • Minimal dependencies — core is stdlib only, LLM client is optional
  • LLM-agnostic — works with any provider via simple callable interface
  • Storage-agnostic — JSON now, SQLite/Neo4j planned
  • Honest evaluation — we measure where it fails, not just where it wins

License

MIT

Metadata

Release files for dagestan 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dagestan 1.0.0
File Size Uploaded
dagestan-1.0.0.tar.gz 48.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dagestan 1.0.0
File Interpreter ABI Platform
dagestan-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 92.2 kB

Release files / dagestan-1.0.0.tar.gz

Download URL dagestan-1.0.0.tar.gz
Size 48.8 kB
Tags Source
SHA-256 checksum
How to use checksums
967eba673eb619bd9f5dbd72e9dddf3bd52c3a9a38b77f52802846befab73e52
BLAKE2b-256 checksum
How to use checksums
882c5a1e6d88d286027e7326390aff6520314930ccbeb7300f9601516bfbf86a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / dagestan-1.0.0-py3-none-any.whl

Download URL dagestan-1.0.0-py3-none-any.whl
Size 43.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b3cb99516ae3d7efc644be2a0e087df362120b383e49731ec4ec27afcb9c6c51
BLAKE2b-256 checksum
How to use checksums
ca0cc7749dd3c77205e99cf3038fbde4e9e75ad21686f4f6b2cf27cf835f0440
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page