mcal-ai-langgraph
LangGraph integration for MCAL — Goal-aware memory for AI agents.
Installation
pip install mcal-ai-langgraph
This will automatically install mcal-ai and langgraph as dependencies.
Quick Start
from mcal import MCAL
from mcal_langgraph import MCALStore
# Initialize MCAL
mcal = MCAL(llm_provider="anthropic")
# Create LangGraph-compatible store
store = MCALStore(mcal)
# Use with LangGraph
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(
model=your_model,
tools=your_tools,
store=store # Goal-aware memory!
)
What's New in 0.5.0
- Query-Aware Subgraph Retrieval — New seed-and-expand pipeline replaces 6 query-blind retrieval paths with a single query-aware pass. Reduces context tokens by 53% at 1020 turns while improving DRR by 4.5pp.
QuerySubgraphdataclass — New public API for structured subgraph results, partitioned by node type (goals, decisions, facts, entities, actions) with structural edge resolution.- Adjacency index — Lazy-built bidirectional adjacency index on
UnifiedGraphenables O(1) neighbor lookups for graph traversal. - Improved DRR at scale — CTO-1020 DRR improved from 85.3% to 89.9% (+4.6pp); CTO-300 improved from 92.2% to 94.4% (+2.2pp).
- LoCoMo-10 Evaluation — Full 10-conversation, 1,540 QA binary evaluation: 46.1% overall accuracy.
What's New in 0.4.1
- First-Class FACT Nodes — 3 new typed edges (
measures,evidence_for,quantifies) improve fact retrieval; quantitative queries automatically boost fact content - Importance Scoring Boost — FACT nodes with numeric values score higher in retrieval
search_facts()API — Filter facts by category and value range onUnifiedGraph- Version Metadata Fix —
__version__now correctly reports 0.4.1 (was stuck at 0.2.9)
What's New in 0.4.0
- Graph Compaction Fixes — Improved retrieval quality with facts-in-context, expanded edge types, chunk boost scoring
- CTO-1020 Benchmark — 85.3% decision retention over 1020 turns, 95.6% cross-era recall, 88% token reduction
- Statistical Rigor — Multi-run validation with Fisher's exact test, Wilson score confidence intervals
What's New in 0.3.0
- Expanded Relationship Edge Types — 10 new edge types (
family,friend,colleague,likes,prefers,lives_in,works_at, etc.) for richer relationship graphs - Key Facts & Entities in Search Context —
search()now surfaces extracted facts and background entities directly inresult.context - Improved Chunk Retrieval — More results returned with equal weighting; conversation excerpts prioritized in context
Older releases
What's New in 0.2.9
- Configurable Extraction Profiles — Choose
decision,conversational, orcomprehensiveviaMCALMemoryConfig - Hybrid Retrieval with ChunkStore — Graph traversal + embedding search for maximum recall
- FACT/PERSON Node Protection — Graph compaction preserves factual and identity nodes
# Configuration options
memory = MCALMemory(
llm_provider="anthropic",
extraction_profile="decision", # "decision" | "conversational" | "comprehensive"
enable_chunk_store=True, # hybrid retrieval
)
Features
MCALStore (BaseStore)
Drop-in replacement for LangGraph's built-in stores with goal-aware memory:
from mcal_langgraph import MCALStore
store = MCALStore(mcal)
# Store memories
await store.aput(
namespace=("user_123", "memories"),
key="decision_1",
value={"text": "Decided to use PostgreSQL for ACID compliance"}
)
# Goal-aware search — returns memories relevant to current goals
results = await store.asearch(
namespace_prefix=("user_123",),
query="database choice"
)
# Results include goal context and decisions
for item in results:
print(item.value)
MCALMemory
Memory nodes for custom LangGraph workflows:
from mcal_langgraph import MCALMemory
# Initialize with provider (uses get_mcal() factory internally)
memory = MCALMemory(llm_provider="anthropic")
# Or pass an existing MCAL instance
memory = MCALMemory(mcal=mcal, user_id="user_123")
# Add as nodes in your graph
graph.add_node("update_memory", memory.update_node())
graph.add_node("get_context", memory.context_node())
MCALCheckpointer
State persistence for LangGraph graphs:
from mcal_langgraph import MCALCheckpointer
checkpointer = MCALCheckpointer(storage_path="~/.mcal")
graph = builder.compile(checkpointer=checkpointer)
Why mcal-ai-langgraph?
| Feature | LangGraph InMemoryStore | MCALStore |
|---|---|---|
| BaseStore interface | ✅ | ✅ |
| Namespace organization | ✅ | ✅ |
| TTL support | ❌ | ✅ |
| Filter operators ($eq, $gt, etc.) | ❌ | ✅ |
| Goal-aware search | ❌ | ✅ |
| Decision tracking | ❌ | ✅ |
| Intent preservation | ❌ | ✅ |
API Reference
MCALStore
class MCALStore(BaseStore):
def __init__(self, mcal: MCAL): ...
# Async API
async def aput(self, namespace, key, value, index=None): ...
async def aget(self, namespace, key) -> Optional[Item]: ...
async def adelete(self, namespace, key): ...
async def asearch(self, namespace_prefix, /, *, query=None, filter=None, limit=10, offset=0) -> list[Item]: ...
async def alist_namespaces(self, *, prefix=None, suffix=None, max_depth=None, limit=100, offset=0) -> list[tuple[str, ...]]: ...
# Sync API (also available)
def put(self, namespace, key, value, index=None): ...
def get(self, namespace, key) -> Optional[Item]: ...
def delete(self, namespace, key): ...
def search(self, namespace_prefix, /, *, query=None, filter=None, limit=10, offset=0) -> list[Item]: ...
MCALMemory
class MCALMemory:
def __init__(
self,
mcal: Optional[MCAL] = None,
llm_provider: str = "anthropic",
embedding_provider: str = "openai",
storage_path: Optional[str] = None,
user_id: str = "default",
**mcal_kwargs,
): ...
def update_node(self) -> Callable: ...
def context_node(self) -> Callable: ...
async def add(self, messages, user_id=None): ...
async def get_context(self, query, user_id=None): ...
async def search(self, query, user_id=None, limit=5): ...
MCALCheckpointer
class MCALCheckpointer(BaseCheckpointSaver):
def __init__(self, storage_path: Optional[str] = None): ...
def get(self, config) -> Optional[dict]: ...
def put(self, config, checkpoint): ...
def list(self, config) -> list[dict]: ...
Migrating from mcal[langgraph]
If you were using the old extras-based installation:
# Old way (deprecated)
from mcal.integrations.langgraph import MCALStore
# New way (recommended)
from mcal_langgraph import MCALStore
The old import path still works but will show a deprecation warning.
Requirements
- Python >= 3.11
- mcal-ai >= 0.2.0
- langgraph >= 0.2.0
- langchain-core >= 0.3.0
License
MIT
Release files for mcal-ai-langgraph 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcal_ai_langgraph-0.5.0.tar.gz | 16.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcal_ai_langgraph-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.3 kB
Release files / mcal_ai_langgraph-0.5.0.tar.gz
| Download URL | mcal_ai_langgraph-0.5.0.tar.gz |
|---|---|
| Size | 16.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
889be80fabab8442d1358df59a44607a12d2653992aa5b73f17f5017527d8f19
|
|
BLAKE2b-256 checksum How to use checksums |
189677c4273b8e95c5b4d7c8c74c5288576e98ca6db529ab67e8196e74dd17bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.11
|
Release files / mcal_ai_langgraph-0.5.0-py3-none-any.whl
| Download URL | mcal_ai_langgraph-0.5.0-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1e25d3d402119060cba48e88056520ade478422dd295437123374f3be29d6a4f
|
|
BLAKE2b-256 checksum How to use checksums |
9b36b6732dfccd9a94729fa88aa7348b0f74cdf99cf2cb9585284cbb3615b75e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.11
|