Skip to content

Commit fc10d19

Browse files
authored
feat: add langgraph support (MemMachine#491)
As title.
1 parent 8e1d83c commit fc10d19

File tree

3 files changed

+588
-0
lines changed

3 files changed

+588
-0
lines changed

examples/langgraph/README.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# LangGraph Integration with MemMachine
2+
3+
This directory contains examples and tools for integrating MemMachine with LangGraph workflows.
4+
5+
## Overview
6+
7+
MemMachine provides memory tools that can be integrated into LangGraph workflows to enable AI agents with persistent memory capabilities. This allows agents to remember past interactions, user preferences, and context across multiple sessions.
8+
9+
## Configuration
10+
11+
The demo can be configured via environment variables:
12+
13+
| Variable | Description | Default |
14+
|----------|-------------|---------|
15+
| `MEMORY_BACKEND_URL` | URL of the MemMachine backend service | `http://localhost:8080` |
16+
| `LANGGRAPH_GROUP_ID` | Group identifier for the demo | `langgraph_demo` |
17+
| `LANGGRAPH_AGENT_ID` | Agent identifier for the demo | `demo_agent` |
18+
| `LANGGRAPH_USER_ID` | User identifier for the demo | `demo_user` |
19+
| `LANGGRAPH_SESSION_ID` | Session identifier for the demo | `demo_session_001` |
20+
21+
## Usage
22+
23+
### Setting Environment Variables
24+
25+
```bash
26+
# Set environment variables (optional)
27+
export MEMORY_BACKEND_URL="http://localhost:8080"
28+
export LANGGRAPH_GROUP_ID="my_group"
29+
export LANGGRAPH_AGENT_ID="my_agent"
30+
export LANGGRAPH_USER_ID="my_user"
31+
export LANGGRAPH_SESSION_ID="my_session"
32+
33+
# Run the demo
34+
python examples/langgraph/demo.py
35+
```
36+
37+
### Running the Demo
38+
39+
```bash
40+
cd examples/langgraph
41+
python demo.py
42+
```
43+
44+
## Integration Guide
45+
46+
### 1. Initialize MemMachineTools
47+
48+
```python
49+
import os
50+
from tool import MemMachineTools
51+
52+
# Get configuration from environment variables or use defaults
53+
base_url = os.getenv("MEMORY_BACKEND_URL", "http://localhost:8080")
54+
group_id = os.getenv("LANGGRAPH_GROUP_ID", "my_group")
55+
agent_id = os.getenv("LANGGRAPH_AGENT_ID", "my_agent")
56+
user_id = os.getenv("LANGGRAPH_USER_ID", "user123")
57+
58+
tools = MemMachineTools(
59+
base_url=base_url,
60+
group_id=group_id,
61+
agent_id=agent_id,
62+
user_id=user_id,
63+
)
64+
```
65+
66+
### 2. Create Tool Functions
67+
68+
```python
69+
from tool import create_add_memory_tool, create_search_memory_tool
70+
71+
add_memory = create_add_memory_tool(tools)
72+
search_memory = create_search_memory_tool(tools)
73+
```
74+
75+
### 3. Use in LangGraph Nodes
76+
77+
```python
78+
from langgraph.graph import StateGraph, END
79+
80+
def memory_node(state: AgentState):
81+
# Search for relevant memories
82+
search_result = search_memory(
83+
query=state["messages"][-1].content,
84+
user_id=state["user_id"],
85+
)
86+
87+
# Add new memory
88+
add_memory(
89+
content=state["messages"][-1].content,
90+
user_id=state["user_id"],
91+
)
92+
93+
return {
94+
"context": search_result.get("summary", ""),
95+
"memory_tool_results": [search_result],
96+
}
97+
98+
# Build graph
99+
workflow = StateGraph(AgentState)
100+
workflow.add_node("memory", memory_node)
101+
workflow.set_entry_point("memory")
102+
workflow.add_edge("memory", END)
103+
```
104+
105+
### 4. Run the Workflow
106+
107+
```python
108+
app = workflow.compile()
109+
result = app.invoke({
110+
"messages": [{"content": "I like Python"}],
111+
"user_id": "user123",
112+
"context": "",
113+
"memory_tool_results": [],
114+
})
115+
```
116+
117+
## Requirements
118+
119+
- MemMachine server running (default: http://localhost:8080)
120+
- Python 3.12+
121+
- LangGraph (for full workflow integration)

examples/langgraph/demo.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import json
2+
import os
3+
from typing import Annotated, TypedDict
4+
5+
from tool import MemMachineTools, create_add_memory_tool, create_search_memory_tool
6+
7+
# ============================================================================
8+
# Configuration
9+
# ============================================================================
10+
# Configuration values can be set via environment variables or use defaults
11+
MEMORY_BACKEND_URL = os.getenv("MEMORY_BACKEND_URL", "http://localhost:8080")
12+
LANGGRAPH_GROUP_ID = os.getenv("LANGGRAPH_GROUP_ID", "langgraph_demo")
13+
LANGGRAPH_AGENT_ID = os.getenv("LANGGRAPH_AGENT_ID", "demo_agent")
14+
LANGGRAPH_USER_ID = os.getenv("LANGGRAPH_USER_ID", "demo_user")
15+
LANGGRAPH_SESSION_ID = os.getenv("LANGGRAPH_SESSION_ID", "demo_session_001")
16+
17+
18+
# State definition for LangGraph workflow
19+
class AgentState(TypedDict):
20+
"""State for the agent workflow."""
21+
22+
messages: Annotated[list, "List of messages in the conversation"]
23+
user_id: str
24+
context: str
25+
memory_tool_results: Annotated[list, "Results from memory tool calls"]
26+
27+
28+
def simple_memory_workflow_demo():
29+
"""
30+
Simple demo showing basic memory operations without LangGraph dependency.
31+
32+
This demonstrates the MemMachine tools functionality that can be integrated
33+
into LangGraph workflows.
34+
"""
35+
print("=" * 60)
36+
print("MemMachine LangGraph Tools Demo")
37+
print("=" * 60)
38+
39+
# Initialize tools
40+
print("\n1. Initializing MemMachine tools...")
41+
print(" Configuration:")
42+
print(f" - Backend URL: {MEMORY_BACKEND_URL}")
43+
print(f" - Group ID: {LANGGRAPH_GROUP_ID}")
44+
print(f" - Agent ID: {LANGGRAPH_AGENT_ID}")
45+
print(f" - User ID: {LANGGRAPH_USER_ID}")
46+
print(f" - Session ID: {LANGGRAPH_SESSION_ID}")
47+
48+
tools = MemMachineTools(
49+
base_url=MEMORY_BACKEND_URL,
50+
group_id=LANGGRAPH_GROUP_ID,
51+
agent_id=LANGGRAPH_AGENT_ID,
52+
user_id=LANGGRAPH_USER_ID,
53+
session_id=LANGGRAPH_SESSION_ID,
54+
)
55+
56+
# Check if server is available
57+
try:
58+
health = tools.client.health_check()
59+
print(f"✅ MemMachine server is healthy: {health.get('status', 'ok')}")
60+
except Exception as e:
61+
print(f"❌ MemMachine server not available: {e}")
62+
print(f" Please start MemMachine server on {MEMORY_BACKEND_URL}")
63+
return
64+
65+
# Create tool functions
66+
add_memory = create_add_memory_tool(tools)
67+
search_memory = create_search_memory_tool(tools)
68+
69+
print("\n2. Adding memories...")
70+
# Add some memories
71+
memories_to_add = [
72+
{
73+
"content": "User prefers working with Python for backend development",
74+
"metadata": {"category": "preference", "technology": "Python"},
75+
},
76+
{
77+
"content": "User mentioned they are working on a project deadline this Friday",
78+
"metadata": {"category": "task", "urgency": "high"},
79+
},
80+
{
81+
"content": "User enjoys hiking on weekends and lives in San Francisco",
82+
"metadata": {"category": "personal", "hobby": "hiking"},
83+
},
84+
{
85+
"content": "User is interested in machine learning and AI agents",
86+
"metadata": {"category": "interest", "field": "AI"},
87+
},
88+
]
89+
90+
for mem in memories_to_add:
91+
result = add_memory(
92+
content=mem["content"],
93+
metadata=mem["metadata"],
94+
)
95+
if result["status"] == "success":
96+
print(f" ✅ Added: {mem['content'][:50]}...")
97+
else:
98+
print(f" ❌ Failed: {result.get('message', 'Unknown error')}")
99+
100+
print("\n3. Searching memories...")
101+
# Search for memories
102+
search_queries = [
103+
"What does the user prefer for development?",
104+
"What are the user's upcoming deadlines?",
105+
"What are the user's hobbies?",
106+
"What is the user interested in?",
107+
]
108+
109+
for query in search_queries:
110+
print(f"\n 🔍 Query: {query}")
111+
result = search_memory(query=query, limit=3)
112+
113+
if result["status"] == "success":
114+
results = result["results"]
115+
episodic = results.get("episodic_memory", [])
116+
117+
if episodic:
118+
print(f" Found {len(episodic)} relevant memories:")
119+
for i, mem in enumerate(episodic[:3], 1):
120+
content = (
121+
mem.get("content", "") if isinstance(mem, dict) else str(mem)
122+
)
123+
print(f" {i}. {content[:80]}...")
124+
else:
125+
print(" No memories found")
126+
else:
127+
print(f" ❌ Search failed: {result.get('message', 'Unknown error')}")
128+
129+
print("\n4. Getting context...")
130+
context = tools.get_context()
131+
print(f" Context: {json.dumps(context, indent=2)}")
132+
133+
# Cleanup
134+
tools.close()
135+
136+
137+
def main():
138+
"""Main demo function."""
139+
try:
140+
# Run simple demo
141+
simple_memory_workflow_demo()
142+
except KeyboardInterrupt:
143+
print("\n\nDemo interrupted by user.")
144+
except Exception as e:
145+
print(f"\n❌ Demo failed with error: {e}")
146+
import traceback
147+
148+
traceback.print_exc()
149+
150+
151+
if __name__ == "__main__":
152+
main()

0 commit comments

Comments
 (0)