Initial commit: LangMem fact-based AI memory system with docs and MCP integration

- Complete fact-based memory API with mem0-inspired approach
- Individual fact extraction and deduplication
- ADD/UPDATE/DELETE memory actions
- Precision search with 0.86+ similarity scores
- MCP server for Claude Code integration
- Neo4j graph relationships and PostgreSQL vector storage
- Comprehensive documentation with architecture and API docs
- Matrix communication integration
- Production-ready Docker setup with Ollama and Supabase

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Docker Config Backup
2025-07-17 13:16:19 +02:00
commit 46faa78237
43 changed files with 9086 additions and 0 deletions

699
docs/api/index.html Normal file
View File

@@ -0,0 +1,699 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Documentation - LangMem Fact-Based Memory System</title>
<meta name="description" content="Complete API documentation for LangMem fact-based memory system with individual fact extraction, deduplication, memory updates, and precision search capabilities.">
<link rel="stylesheet" href="../assets/css/style.css">
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.css">
</head>
<body>
<header>
<nav>
<a href="../" class="logo">🧠 LangMem</a>
<ul class="nav-links">
<li><a href="../">Home</a></li>
<li><a href="../architecture/">Architecture</a></li>
<li><a href="../implementation/">Implementation</a></li>
<li><a href="../api/">API Docs</a></li>
</ul>
</nav>
</header>
<main>
<section class="hero">
<h1>LangMem API Documentation</h1>
<p>Complete reference for the fact-based LangMem API with individual fact extraction, intelligent deduplication, memory updates, and precision search (0.86+ similarity scores).</p>
</section>
<section class="mb-4">
<h2>Base URL & Authentication</h2>
<div class="card">
<h3>🔗 Base URL</h3>
<div class="code-block">
<pre><code>http://localhost:8765</code></pre>
</div>
<h3>🔐 Authentication</h3>
<p>All API requests require Bearer token authentication:</p>
<div class="code-block">
<pre><code>Authorization: Bearer langmem_api_key_2025</code></pre>
</div>
</div>
</section>
<section class="mb-4">
<h2>Core Memory Endpoints</h2>
<div class="card">
<h3>📥 POST /v1/memories/store</h3>
<p>Store a memory with fact-based extraction, deduplication, and intelligent memory actions (ADD/UPDATE/DELETE)</p>
<h4>Request Body</h4>
<div class="code-block">
<pre><code class="language-json">{
"content": "Ondrej has a son named Cyril who is 8 years old and loves playing soccer. Cyril goes to elementary school in Prague.",
"user_id": "user123",
"session_id": "session1",
"metadata": {
"category": "family",
"importance": "high",
"privacy_level": "personal",
"tags": ["family", "son", "personal"]
}
}</code></pre>
</div>
<h4>Response</h4>
<div class="code-block">
<pre><code class="language-json">{
"total_facts": 5,
"stored_facts": 5,
"status": "stored",
"approach": "fact_based_with_deduplication",
"facts": [
{
"action": "added",
"fact": "Ondrej's son, Cyril, is 8 years old.",
"id": "550e8400-e29b-41d4-a716-446655440001"
},
{
"action": "added",
"fact": "Cyril loves playing soccer.",
"id": "550e8400-e29b-41d4-a716-446655440002"
},
{
"action": "added",
"fact": "Cyril attends elementary school in Prague.",
"id": "550e8400-e29b-41d4-a716-446655440003"
}
],
"created_at": "2025-07-17T19:30:00Z"
}</code></pre>
</div>
<h4>cURL Example</h4>
<div class="code-block">
<pre><code class="language-bash">curl -X POST "http://localhost:8765/v1/memories/store" \
-H "Authorization: Bearer langmem_api_key_2025" \
-H "Content-Type: application/json" \
-d '{
"content": "John works for Google in California",
"user_id": "user123",
"metadata": {"category": "business"}
}'</code></pre>
</div>
</div>
<div class="card">
<h3>🔍 POST /v1/memories/search</h3>
<p>Search individual facts using precision vector search with 0.86+ similarity scores for specific queries</p>
<h4>Request Body</h4>
<div class="code-block">
<pre><code class="language-json">{
"query": "How old is Cyril?",
"user_id": "user123",
"limit": 10,
"threshold": 0.5,
"include_graph": true
}</code></pre>
</div>
<h4>Response</h4>
<div class="code-block">
<pre><code class="language-json">{
"memories": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"content": "Ondrej's son, Cyril, is 8 years old.",
"metadata": {
"type": "fact",
"extraction_method": "llm_fact_extraction",
"category": "family"
},
"user_id": "user123",
"session_id": "session1",
"similarity": 0.759,
"created_at": "2025-07-17T19:30:00Z",
"relationships": [
{
"entity1_name": "Ondrej",
"entity1_type": "Person",
"relationship": "IS_FATHER_OF",
"entity2_name": "Cyril",
"entity2_type": "Person",
"confidence": 0.9
}
]
},
{
"id": "550e8400-e29b-41d4-a716-446655440004",
"content": "Cyril is currently 9 years old.",
"metadata": {
"type": "fact",
"extraction_method": "llm_fact_extraction"
},
"similarity": 0.913
}
],
"context": {
"query": "How old is Cyril?",
"user_id": "user123",
"threshold": 0.5,
"search_type": "fact_based_hybrid",
"approach": "fact_based_with_deduplication"
},
"total_count": 2
}</code></pre>
</div>
<h4>cURL Example</h4>
<div class="code-block">
<pre><code class="language-bash">curl -X POST "http://localhost:8765/v1/memories/search" \
-H "Authorization: Bearer langmem_api_key_2025" \
-H "Content-Type: application/json" \
-d '{
"query": "Where does John work?",
"user_id": "user123",
"limit": 5,
"threshold": 0.5,
"include_graph": true
}'</code></pre>
</div>
</div>
<div class="card">
<h3>🧠 POST /v1/memories/retrieve</h3>
<p>Retrieve relevant memories for conversation context</p>
<h4>Request Body</h4>
<div class="code-block">
<pre><code class="language-json">{
"messages": [
{
"role": "user",
"content": "Tell me about my family"
},
{
"role": "assistant",
"content": "I'd be happy to help with family information. What would you like to know?"
},
{
"role": "user",
"content": "Who are my children?"
}
],
"user_id": "user123",
"session_id": "session1"
}</code></pre>
</div>
<h4>Response</h4>
<div class="code-block">
<pre><code class="language-json">{
"memories": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"content": "Ondrej has a son named Cyril who is 8 years old",
"similarity": 0.745,
"relationships": [
{
"entity_name": "Cyril",
"entity_type": "Person",
"relationship": "HAS_SON",
"confidence": 1.0
}
]
}
],
"context": {
"session_id": "session1",
"message_count": 3,
"user_context": {},
"retrieved_at": "2025-07-16T19:30:00Z"
},
"total_count": 1
}</code></pre>
</div>
</div>
<div class="card">
<h3>👤 GET /v1/memories/users/{user_id}</h3>
<p>Get all memories for a specific user</p>
<h4>Query Parameters</h4>
<div class="table-container">
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>limit</td>
<td>integer</td>
<td>50</td>
<td>Maximum number of memories to return</td>
</tr>
<tr>
<td>offset</td>
<td>integer</td>
<td>0</td>
<td>Number of memories to skip</td>
</tr>
</tbody>
</table>
</div>
<h4>Response</h4>
<div class="code-block">
<pre><code class="language-json">{
"memories": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"content": "Ondrej has a son named Cyril who is 8 years old",
"metadata": {
"category": "family",
"importance": "high"
},
"user_id": "user123",
"session_id": "session1",
"created_at": "2025-07-16T19:30:00Z",
"updated_at": "2025-07-16T19:30:00Z"
}
],
"total_count": 1,
"limit": 50,
"offset": 0
}</code></pre>
</div>
<h4>cURL Example</h4>
<div class="code-block">
<pre><code class="language-bash">curl -X GET "http://localhost:8765/v1/memories/users/user123?limit=10&offset=0" \
-H "Authorization: Bearer langmem_api_key_2025"</code></pre>
</div>
</div>
<div class="card">
<h3>🗑️ DELETE /v1/memories/{memory_id}</h3>
<p>Delete a specific memory and its graph relationships</p>
<h4>Response</h4>
<div class="code-block">
<pre><code class="language-json">{
"status": "deleted",
"id": "550e8400-e29b-41d4-a716-446655440000"
}</code></pre>
</div>
<h4>cURL Example</h4>
<div class="code-block">
<pre><code class="language-bash">curl -X DELETE "http://localhost:8765/v1/memories/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer langmem_api_key_2025"</code></pre>
</div>
</div>
</section>
<section class="mb-4">
<h2>System Endpoints</h2>
<div class="card">
<h3>🏠 GET /</h3>
<p>Root endpoint with system information</p>
<h4>Response</h4>
<div class="code-block">
<pre><code class="language-json">{
"message": "LangMem API - Long-term Memory System",
"version": "1.0.0",
"status": "running"
}</code></pre>
</div>
</div>
<div class="card">
<h3>❤️ GET /health</h3>
<p>Health check with service status</p>
<h4>Response</h4>
<div class="code-block">
<pre><code class="language-json">{
"status": "healthy",
"services": {
"ollama": "healthy",
"supabase": "healthy",
"neo4j": "healthy",
"postgres": "healthy"
},
"timestamp": "2025-07-16T19:30:00Z"
}</code></pre>
</div>
<h4>cURL Example</h4>
<div class="code-block">
<pre><code class="language-bash">curl -X GET "http://localhost:8765/health"</code></pre>
</div>
</div>
</section>
<section class="mb-4">
<h2>AI Relationship Extraction</h2>
<div class="card">
<h3>🤖 Automatic Relationship Extraction</h3>
<p>LangMem automatically extracts relationships from content using Llama3.2 model. Here are examples of relationship types that are dynamically generated:</p>
<h4>Relationship Types</h4>
<div class="table-container">
<table>
<thead>
<tr>
<th>Category</th>
<th>Example Relationships</th>
<th>Entity Types</th>
</tr>
</thead>
<tbody>
<tr>
<td>Family</td>
<td>IS_FATHER_OF, IS_SON_OF, IS_PARENT_OF</td>
<td>Person → Person</td>
</tr>
<tr>
<td>Business</td>
<td>FOUNDED, WORKS_FOR, EMPLOYED</td>
<td>Person → Organization</td>
</tr>
<tr>
<td>Technology</td>
<td>CREATED_BY, USES, DEVELOPED</td>
<td>Technology → Person</td>
</tr>
<tr>
<td>Geography</td>
<td>LOCATED_IN, DESIGNED</td>
<td>Location → Location</td>
</tr>
<tr>
<td>Science</td>
<td>REVOLUTIONIZED, WORKED_AT</td>
<td>Person → Concept</td>
</tr>
</tbody>
</table>
</div>
<h4>Example AI Extraction</h4>
<div class="code-block">
<pre><code class="language-json">{
"input": "Steve Jobs founded Apple Inc. in Cupertino, California",
"extracted_relationships": [
{
"entity1": "Steve Jobs",
"entity1_type": "Person",
"relationship": "FOUNDED",
"entity2": "Apple Inc.",
"entity2_type": "Organization",
"confidence": 0.9
},
{
"entity1": "Apple Inc.",
"entity1_type": "Organization",
"relationship": "LOCATED_IN",
"entity2": "Cupertino, California",
"entity2_type": "Location",
"confidence": 0.9
}
]
}</code></pre>
</div>
</div>
</section>
<section class="mb-4">
<h2>Error Handling</h2>
<div class="card">
<h3>🚨 Error Response Format</h3>
<div class="code-block">
<pre><code class="language-json">{
"detail": "Failed to store memory: Invalid content format"
}</code></pre>
</div>
<h4>Common Error Codes</h4>
<div class="table-container">
<table>
<thead>
<tr>
<th>HTTP Status</th>
<th>Description</th>
<th>Common Causes</th>
</tr>
</thead>
<tbody>
<tr>
<td>400</td>
<td>Bad Request</td>
<td>Invalid JSON, missing required fields</td>
</tr>
<tr>
<td>401</td>
<td>Unauthorized</td>
<td>Missing or invalid Bearer token</td>
</tr>
<tr>
<td>404</td>
<td>Not Found</td>
<td>Memory ID not found</td>
</tr>
<tr>
<td>500</td>
<td>Internal Server Error</td>
<td>Database connection, AI processing errors</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section class="mb-4">
<h2>Database Access</h2>
<div class="card">
<h3>🗄️ Direct Database Access</h3>
<p>For advanced users, direct database access is available:</p>
<h4>PostgreSQL (Vector Storage)</h4>
<div class="code-block">
<pre><code class="language-sql">-- Connect to PostgreSQL
psql "postgresql://postgres:CzkaYmRvc26Y@localhost:5435/postgres"
-- Query memories
SELECT id, content, user_id, metadata
FROM langmem_documents
WHERE user_id = 'user123'
ORDER BY created_at DESC;
-- Vector similarity search
SELECT id, content, 1 - (embedding <=> '[0.1, 0.2, ...]') as similarity
FROM langmem_documents
WHERE user_id = 'user123'
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 10;</code></pre>
</div>
<h4>Neo4j (Graph Relationships)</h4>
<div class="code-block">
<pre><code class="language-cypher">// Connect to Neo4j Browser: http://localhost:7474
// Username: neo4j, Password: langmem_neo4j_password
// View all relationships
MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 25;
// Find specific relationship types
MATCH (p:Person)-[r:IS_FATHER_OF]->(c:Person)
RETURN p.name, r, c.name;
// Complex graph traversal
MATCH (p:Person)-[:FOUNDED]->(org:Organization)-[:LOCATED_IN]->(loc:Location)
RETURN p.name, org.name, loc.name;</code></pre>
</div>
</div>
</section>
<section class="mb-4">
<h2>Integration Examples</h2>
<div class="grid grid-2">
<div class="card">
<h3>🐍 Python Client</h3>
<div class="code-block">
<pre><code class="language-python">import requests
import json
class LangMemClient:
def __init__(self, base_url="http://localhost:8765", api_key="langmem_api_key_2025"):
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
def store_memory(self, content, user_id, session_id=None, metadata=None):
"""Store a memory with AI relationship extraction."""
data = {
'content': content,
'user_id': user_id,
'session_id': session_id,
'metadata': metadata or {}
}
response = requests.post(
f"{self.base_url}/v1/memories/store",
headers=self.headers,
json=data
)
return response.json()
def search_memories(self, query, user_id, limit=10, threshold=0.5):
"""Search memories with hybrid search."""
data = {
'query': query,
'user_id': user_id,
'limit': limit,
'threshold': threshold,
'include_graph': True
}
response = requests.post(
f"{self.base_url}/v1/memories/search",
headers=self.headers,
json=data
)
return response.json()
# Usage
client = LangMemClient()
# Store memory
result = client.store_memory(
content="John works for Google in California",
user_id="user123",
metadata={"category": "business"}
)
print(f"Memory stored: {result['id']}")
# Search memories
results = client.search_memories(
query="Where does John work?",
user_id="user123"
)
print(f"Found {results['total_count']} memories")
for memory in results['memories']:
print(f"- {memory['content']} (similarity: {memory['similarity']:.3f})")
if 'relationships' in memory:
for rel in memory['relationships']:
print(f" → {rel['relationship']} {rel['entity_name']}")</code></pre>
</div>
</div>
<div class="card">
<h3>🟨 JavaScript Client</h3>
<div class="code-block">
<pre><code class="language-javascript">class LangMemClient {
constructor(baseUrl = 'http://localhost:8765', apiKey = 'langmem_api_key_2025') {
this.baseUrl = baseUrl;
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}
async storeMemory(content, userId, sessionId = null, metadata = {}) {
const response = await fetch(`${this.baseUrl}/v1/memories/store`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
content,
user_id: userId,
session_id: sessionId,
metadata
})
});
return await response.json();
}
async searchMemories(query, userId, limit = 10, threshold = 0.5) {
const response = await fetch(`${this.baseUrl}/v1/memories/search`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
query,
user_id: userId,
limit,
threshold,
include_graph: true
})
});
return await response.json();
}
}
// Usage
const client = new LangMemClient();
// Store memory
const result = await client.storeMemory(
'John works for Google in California',
'user123',
null,
{ category: 'business' }
);
console.log('Memory stored:', result.id);
// Search memories
const results = await client.searchMemories(
'Where does John work?',
'user123'
);
console.log(`Found ${results.total_count} memories`);
results.memories.forEach(memory => {
console.log(`- ${memory.content} (similarity: ${memory.similarity.toFixed(3)})`);
if (memory.relationships) {
memory.relationships.forEach(rel => {
console.log(` → ${rel.relationship} ${rel.entity_name}`);
});
}
});</code></pre>
</div>
</div>
</div>
</section>
<section class="text-center">
<h2>Ready to Build?</h2>
<p class="mb-3">Use the LangMem API to integrate AI-powered memory with automatic relationship extraction into your applications.</p>
<div class="cta-buttons">
<a href="../implementation/" class="btn btn-primary">📚 Implementation Guide</a>
<a href="../architecture/" class="btn btn-secondary">🏗️ Architecture Overview</a>
</div>
</section>
</main>
<footer style="text-align: center; padding: 2rem; margin-top: 4rem; color: var(--text-secondary);">
<p>&copy; 2025 LangMem Documentation. AI-Powered Memory System with Dynamic Relationship Extraction.</p>
<p>API Version: 1.0.0 - Production Ready</p>
</footer>
<script src="../assets/js/main.js"></script>
</body>
</html>