Correctness-First Structured Memory Layer for LLM Agents
Project description
gmem is a correctness-first memory runtime for LLM agents.
It stores only grounded facts, keeps temporal history, and stays adapter-driven instead of usecase-coupled.
Why gmem
Most memory layers optimize retrieval speed first. gmem optimizes correctness first:
- candidate tuples are proposed by the LLM
- constraints validate before persistence
- accepted facts become durable memory with supersession
- retrieval builds compact context from governed state
Core Model
gmem keeps six objects explicit:
Interaction(immutable observed event)Entity(symbolic anchor)CandidateFact(untrusted proposal)ValidatedFact(accepted fact with valid-time boundaries)Constraint(write-time governance)AnswerContext(ephemeral retrieval view)
Quick Start
Install:
pip install -e .[llm]
Minimal usage:
from gmem import Memory
memory = Memory(adapter="generic", storage_backend="memory")
memory.add("My project codename is Atlas.", user_id="demo")
results = memory.search("What is my project codename?", user_id="demo", limit=3)
print(results)
memory.close()
Intent routing (auto-classify and route natural-language input):
from gmem import Memory
memory = Memory(adapter="generic", storage_backend="memory")
# Explicit intent classification
intent = memory.route("What is my project codename?")
print(intent.action) # "recall"
# Auto-routing: REMEMBER -> add(), RECALL -> search(), etc.
result = memory.process("My project codename is Atlas.", user_id="demo")
print(result["intent"]["action"]) # "remember"
memory.close()
OpenRouter Setup
In .env:
LLM_PROVIDER=openrouter
LLM_MODEL=z-ai/glm-4.5-air:free
OPENROUTER_API_KEY=...
Quick API smoke check:
make smoke-openrouter
Local Dev UX
Start databases:
make services-up
Stop databases:
make services-down
Run memory smoke behavior test:
make smoke-memory
Run deterministic hybrid write + backend inspection (in-memory facts, Neo4j graph, PostgreSQL counts):
make inspect-backends
Run the healthcare medication-reconciliation demo stack:
make services-up
PYTHONPATH=src python demos/demo_bitemporal.py
Then query the same data interactively (scope values match automatically):
PYTHONPATH=src python demos/demo_interactive.py --adapter healthcare
Scope alignment note: Both demos use
require_scope=Trueby default. Facts are tagged with scope fields (tenant_id,app_id,user_id,agent_id,run_id). To query data written by one demo from another, the scope values must match. The demos share default scope values so they align automatically; override with--user-id,--agent-id,--run-id, or env vars (GM_SCOPE_*) if needed.
Run the Postgres + Neo4j healthcare smoke check:
make smoke-healthcare-backends
Adapter-Decoupled Runtime
The runtime is no longer tied to repository usecases/ trees.
GM_ADAPTERselects behavior profile (default:generic)- adapters are registered via runtime adapter registry APIs
domain_profileremains as compatibility alias in the API- experiment-stage labels for research ablations stay in the sibling ClinicaLongMem-Interact benchmark repository and docs, not as hardcoded runtime stage classes
Engineering Workflow
- contribution guide: CONTRIBUTING.md
- development conventions: DEVELOPING.md
API Stability
Stable entry points:
gmemfacade importsgrounded_memory.memory.MemorySDK facade- FastAPI service endpoints under
grounded_memory.service
Internal modules may evolve faster as research and storage internals iterate.
Repository Layout
src/
gmem/ # facade package
grounded_memory/ # implementation runtime
adapters/ # adapter registry + generic agent
core/ # models, constraints, stores
llm/ # LLM client + extraction
retrieval/ # graph retrieval
service/ # FastAPI service layer
assets/ # brand and diagram assets
demos/ # runnable demos and showcase scripts
tests/ # regression tests
configs/ # runtime yaml configs
scripts/ # operational and migration scripts
docs/
architecture/ # architecture and roadmap docs
sdk/ # SDK reference docs
Benchmark runners, scenarios, and evaluation scripts live in the sibling repository ClinicaLongMem-Interact.
Compose Stack
The compose stack is intentionally simple:
- PostgreSQL: source of truth store
- Neo4j: active graph projection
Configured via docker-compose.yml and .env.example.
Demos
| Demo | Command | What it shows |
|---|---|---|
| Bitemporal medication reconciliation | python demos/demo_bitemporal.py |
Write-time constraints, supersession, discontinuation, current + historical retrieval |
| Multi-patient write | python demos/demo_multi_patient_write.py |
Scale write-phase with 10 patients, allergy/interaction rejection |
| Multi-patient retrieval | python demos/demo_multi_patient_retrieval.py |
Cross-patient isolation, shared entity queries, historical as-of |
| Interactive REPL | python demos/demo_interactive.py --adapter healthcare |
Intent routing, auto-routing of natural language, real-time grounding diagnostics |
| OpenRouter system | python demos/demo_openrouter.py |
Full OpenRouter pipeline with extraction, grounding, and retrieval |
Tests
Run all regression tests:
pytest tests/ -q
Key test suites:
| Test file | Coverage |
|---|---|
tests/test_governance.py |
Supersession, duplicate detection, conflict resolution strategies, constraint enforcement |
tests/test_healthcare_reconciliation.py |
Allergy conflict, drug interaction, therapeutic duplication, dose supersession |
tests/test_healthcare_retrieval.py |
Retrieval planning, seed resolution, discontinuation closure, historical as-of, scope isolation |
tests/test_end_to_end.py |
Engineering knowledge graph, multi-domain facts, constraint rejection with audit trail |
tests/test_adapters.py |
Adapter registry, YAML constraint configs, entity/relation type coverage |
Healthcare Demo
The demo uses the healthcare adapter with PostgreSQL as the durable bitemporal store and Neo4j as the active graph projection:
Memory(
adapter="healthcare",
storage_backend="postgres_hybrid",
require_scope=True,
)
It demonstrates LLM-backed clinical extraction, write-time safety constraints, allergy/interaction rejections, dose supersession, discontinuation lifecycle closure, current retrieval, and historical as-of retrieval.
Academic Direction
The current roadmap emphasizes novelty around:
- bitemporal memory semantics for grounded tuples
- constraint lifecycle governance (
proposed -> shadow -> active -> deprecated) - adapter-level safety policies without domain hard-coding into core memory runtime
See docs/architecture/ARCHITECTURE.md for the implementation-aligned architecture and docs/architecture/GMEM_V2_BLUEPRINT.md for the broader roadmap.
Status
This repository is under active demo development.
License
MIT
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 grounded_memory-0.1.0.tar.gz.
File metadata
- Download URL: grounded_memory-0.1.0.tar.gz
- Upload date:
- Size: 171.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acfb25c4a497f3c0c8ebea9bdeb83e6cfab752d075b32fccae73543a1a745b2e
|
|
| MD5 |
103932607f4ba02f9a613876103145c6
|
|
| BLAKE2b-256 |
5c0d68d79f4013c1fe8321b5b30491ba9d9cb4e634f0b94ff1d6f7f036b10ccd
|
File details
Details for the file grounded_memory-0.1.0-py3-none-any.whl.
File metadata
- Download URL: grounded_memory-0.1.0-py3-none-any.whl
- Upload date:
- Size: 172.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f0e95e18dbf2034996951f591945cd9a4cf0c267e207b98652c592c9aa62b4a
|
|
| MD5 |
5c332b12ff6d088a920ad98a95ce1778
|
|
| BLAKE2b-256 |
ab93978100132ad8235afb812f37e679ebaafc4911f5303517a5c989db34ecef
|