Skip to content
tysonnbtPublic

About

Memolo Long-term shared memory system for multi-agent AI. Self-hosted with PostgreSQL, Qdrant, Ollama/MiniMax. Includes OpenClaw plugin, real-time dashboard, and Node.js SDK.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

🧠 Memolo β€” Intelligent Memory System for Multi-Agent AI

Persistent, self-organizing memory for AI agents β€” atomic fact extraction, knowledge graph, LLM deduplication, and semantic recall across your LAN

Quick Start

Prerequisites

  • Docker Desktop β€” runs PostgreSQL, Qdrant, Server, Dashboard
  • Ollama β€” runs locally on host for embedding generation (needs GPU)
  • MiniMax API Key β€” cloud LLM for fact extraction & deduplication

Installation

# 1. Clone
git clone https://github.com/thdeptrai/memolo.git
cd memolo

# 2. Pull embedding model
ollama pull qwen3-embedding:8b

# 3. Configure
cp .env.example .env
# Edit .env β†’ set these 2 required values:
#   MEMOLO_MASTER_KEY=<random string for API security>
#   MINIMAX_API_KEY=<your MiniMax API key>

# 4. Start everything
docker compose up -d

# βœ… Done!
# API:       http://localhost:7437
# Dashboard: http://localhost:3001

Update to Latest Version

bash update.sh
# Or: git pull && docker compose up -d --build memolo

How Memolo Works

Memolo is a local-first AI memory system that turns raw agent conversations into structured, searchable, and self-maintaining knowledge. Here's what happens when an agent sends a message:

πŸ“₯ Store Flow β€” What happens when POST /api/memory/store is called

USER MESSAGE + AGENT RESPONSE
            β”‚
            β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 1. Save Raw Data  β”‚  Exchange saved to PostgreSQL with sequence number
    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 2. Batch Queue    β”‚  Exchange enqueued into in-memory buffer
    β”‚ (if batch enabled)β”‚  (reduces LLM API calls for cloud providers)
    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β”œβ”€β”€β”€β”€ (flush every 10s or when batch full) ────┐
            β”‚                                               β”‚
            β–Ό                                               β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 3. Extract Facts  β”‚                           β”‚ 5. Update Graph  β”‚
    β”‚ + Dedup (combined)β”‚  1 LLM call per batch:    β”‚                  β”‚
    β”‚                   β”‚   β€’ Extract atomic facts   β”‚ Entities β†’ DB    β”‚
    β”‚                   β”‚   β€’ ADD/UPDATE/DELETE/NONE  β”‚ Co-occurring β†’   β”‚
    β”‚                   β”‚   β€’ User + Agent facts      β”‚ relationships    β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 4. Embed & Store  β”‚  Generate 4096-dim embedding via Ollama,
    β”‚                   β”‚  store in Qdrant for semantic search
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“€ Recall Flow β€” What happens when POST /api/memory/recall is called

QUERY: "What tools does the user prefer?"
            β”‚
            β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 1. Query Enrich   β”‚  Enrich query using conversation profile
    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  (active topic, preferences, context)
            β”‚
            β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β–Ό                    β–Ό                   β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 2. Semantic   β”‚   β”‚ 3. Cross-    β”‚    β”‚ 4. Knowledge β”‚
    β”‚    Search     β”‚   β”‚    Agent     β”‚    β”‚    Graph     β”‚
    β”‚ (Qdrant,      β”‚   β”‚    Search   β”‚    β”‚    Query     β”‚
    β”‚  topic-aware)β”‚   β”‚ (shared KB) β”‚    β”‚ (neighbors)  β”‚
    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚                  β”‚                   β”‚
            β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 5. LLM Rerank     β”‚  Score each result 0.0-1.0 by
    β”‚ (configurable)    β”‚  semantic relevance to query
    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β–Ό
        RANKED RESULTS

Core Mechanisms

πŸ” Atomic Fact Extraction

Unlike batch summarization that processes groups of messages, Memolo extracts atomic facts from every individual exchange in real-time. Each fact is a standalone, searchable unit of knowledge. Facts from both user messages and agent responses (configurable) are extracted.

Example:

User:  "Tao dang lam project ecommerce bang Next.js va Prisma ORM, database la PostgreSQL"
Agent: "Hay lam! Stack rat manh."

Extracted Facts:
 1. "User Δ‘ang lΓ m project ecommerce"
 2. "Project sα»­ dα»₯ng Next.js framework"
 3. "Database lΓ  PostgreSQL"

🧠 Combined Extract + Dedup (1 LLM call)

When a new exchange arrives, Memolo performs extraction AND deduplication in a single LLM call (optimized for cloud providers like MiniMax to minimize API costs):

  1. Extract atomic facts from user + agent messages
  2. Compare against existing memories (fetched via vector search)
  3. Decide action for each fact: ADD / UPDATE / DELETE / NONE

This prevents memory bloat and handles contradictions automatically:

Existing:  "Database lΓ  PostgreSQL"
New fact:  "Đã chuyển sang MySQL thay vΓ¬ PostgreSQL"

LLM Decision: UPDATE
Result:    "Đã chuyển sang sα»­ dα»₯ng MySQL thay vΓ¬ PostgreSQL" (old superseded)

Key technique: UUIDs are mapped to integers [0], [1], [2]... before sending to the LLM to prevent hallucination (inspired by mem0).

πŸ“¦ Batch Processing

Exchanges are queued and processed in batches (configurable interval + max size) to dramatically reduce LLM API calls for cloud providers. A batch of 10 exchanges β†’ 1 LLM call instead of 10.

πŸ•ΈοΈ Knowledge Graph

Entities mentioned in conversations are automatically extracted and linked:

Entities:  [Next.js, TypeScript, PostgreSQL, Vercel]
Relations: Next.js --related_to--> TypeScript
           PostgreSQL --related_to--> Next.js

During recall, the graph provides contextual connections β€” asking about "Next.js" also surfaces related technologies, preferences, and decisions.

πŸ“Š Search Reranking

After initial vector similarity search, an LLM scores each result's relevance (0.0-1.0) to the actual query. This catches cases where vector similarity alone misses semantic nuance. Can be disabled via config.

πŸ“œ Memory History (Audit Trail)

Every ADD, UPDATE, and DELETE operation is logged with:

  • Before/after content
  • Who changed it (agent ID or system)
  • Why (dedup_merge, contradiction, manual, etc.)

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Agent 1    β”‚   β”‚   Agent 2    β”‚   β”‚   Agent N    β”‚
β”‚ (Device A)   β”‚   β”‚ (Device B)   β”‚   β”‚ (Device C)   β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚ X-API-Key        β”‚ X-API-Key        β”‚ X-API-Key
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚ LAN (WiFi)
                   β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
                   β”‚   Memolo    β”‚ ← 0.0.0.0:7437
                   β”‚   Server    β”‚   API + Dashboard
                   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                   β”‚ Batch Queue β”‚ ← queue + flush periodically
                   β”‚ Fact Extractβ”‚ ← per-exchange atomic facts
                   β”‚ Deduplicatorβ”‚ ← LLM ADD/UPDATE/DELETE
                   β”‚ Graph Engineβ”‚ ← entities + relationships
                   β”‚ Reranker    β”‚ ← LLM relevance scoring
                   β”‚ Contradict. β”‚ ← detect & supersede conflicts
                   β”‚ Intelligenceβ”‚ ← decay, dedup
                   β”‚ LLM Service β”‚ ← MiniMax M2.5
                   β”‚ Auth Layer  β”‚ ← master + per-agent keys
                   β”‚ Config API  β”‚ ← live runtime settings
                   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
         β”‚PostgreSQLβ”‚ β”‚ Qdrant  β”‚ β”‚ Ollama  β”‚
         β”‚ 9 tables β”‚ β”‚ vectors β”‚ β”‚ (host)  β”‚
         β”‚ + graph  β”‚ β”‚ 4096dim β”‚ β”‚embed onlyβ”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Technology Stack

Component Technology
Server Node.js + Express 4.18
Database PostgreSQL 16 (9 tables, 11 migrations)
Vector Store Qdrant (Cosine similarity, 4096 dim)
Embeddings Ollama qwen3-embedding:8b (local)
LLM (Facts/Dedup/Rerank) MiniMax M2.5 (cloud, Anthropic-compatible API)
Auth API key (master + per-agent) via X-API-Key header
Dashboard Next.js 16 + TailwindCSS v4 + shadcn/ui (dark theme)
Deployment Docker Compose (single command)

Database Schema

Table Purpose
agents Registered AI agents with API keys
conversations Conversation sessions per agent
exchanges Raw user/agent message pairs
memories Extracted facts, decisions, insights (with content_hash, actor_id, superseded_by)
knowledge_base Curated knowledge entries
memory_history Audit trail for all memory mutations
entities Named entities from the knowledge graph
relationships Typed links between entities
memory_conversations Many-to-many memory ↔ conversation linking

Authentication

2-Tier API Keys

Key Type Set In Purpose
Master key .env (MEMOLO_MASTER_KEY) Admin: register agents, full access
Per-agent key Auto-generated on register Agent: store, recall, search
  • GET /api/health β€” no auth required
  • If MEMOLO_MASTER_KEY not set β†’ auth disabled (dev mode)

Agent Integration

SDK (Node.js)

const { MemoryClient } = require('memolo');
const memory = new MemoryClient({
  agentId: 'my-agent',
  apiKey: 'agent-api-key-from-register',
  serverUrl: 'http://192.168.1.100:7437',
});

const ctx = await memory.recall('user question', { format: 'context' });
const result = await memory.store({ userMessage: '...', agentResponse: '...' });

OpenClaw Plugin (Example Integration)

{
  "memolo": {
    "agentId": "my-agent",
    "apiKey": "${MEMOLO_API_KEY}",
    "serverUrl": "http://192.168.1.100:7437"
  }
}

API Reference

Memory

Method Path Description
POST /api/memory/store Store exchange β†’ triggers fact extraction
POST /api/memory/recall Recall memories (semantic + graph + rerank)
POST /api/memory/search Full-text + semantic search
POST /api/memory/summarize Manual summarization trigger
GET /api/memory/history Global memory audit log
GET /api/memory/memories/:id/history Per-memory audit trail
GET /api/memory/memories List memories (filterable by topic/scope/type/agent)
GET /api/memory/topics List unique topics with counts
GET /api/memory/exchanges List all exchanges
GET /api/memory/conversations List all conversations
GET /api/memory/conversations/:id Get conversation details
POST /api/memory/conversations/:id/end End conversation
PATCH /api/memory/:id Update memory (confirm/reject/supersede/update)
DELETE /api/memory/:id Delete memory

Agents

Method Path Description
POST /api/memory/agents/register Register agent β†’ returns API key
POST /api/memory/agents/:id/regenerate-key Rotate API key
GET /api/memory/agents List agents
GET /api/memory/agents/:agentId/recent Recent memories for agent

Knowledge Graph

Method Path Description
GET /api/graph/entities/:agentId List entities for agent
GET /api/graph/entities/search?query=X Search entities by name
GET /api/graph/neighborhood/:id?agentId=X Entity + connections
GET /api/graph/:agentId Full agent graph (visualization)

Intelligence & System

Method Path Description
POST /api/intelligence/run Run intelligence tasks (decay/dedup)
POST /api/intelligence/permissions/grant Grant read permission
POST /api/intelligence/permissions/revoke Revoke read permission
POST /api/intelligence/permissions/team Grant all-to-all team access
GET /api/intelligence/knowledge Knowledge base entries
GET /api/intelligence/knowledge/search?q=X Search knowledge base
GET /api/intelligence/stats System stats
GET /api/health Health check (no auth)
GET /api/logs/stream SSE live event stream
GET /api/logs Recent logs
GET /api/logs/events Recent typed events

Runtime Config

Method Path Description
GET /api/config Get all runtime settings with metadata
PUT /api/config Update settings (live, no restart needed)
POST /api/config/reset Reset one or all settings to defaults

Configuration

Environment Variables

# Required
MEMOLO_MASTER_KEY=your-secret-key

# MiniMax M2.5 (Required β€” LLM for fact extraction, dedup, reranking)
MINIMAX_API_KEY=your-minimax-api-key
MINIMAX_MODEL=MiniMax-M2.5
MINIMAX_BASE_URL=https://api.minimax.io/anthropic/v1/messages

# Server
PORT=7437                                    # Server port (default: 7437)

# Ollama (Embeddings only)
OLLAMA_BASE_URL=http://host.docker.internal:11434
OLLAMA_EMBED_MODEL=qwen3-embedding:8b

# Feature Flags (all default: true)
ENABLE_FACT_EXTRACTION=true                  # Per-exchange atomic fact extraction
ENABLE_RERANKING=true                        # LLM search result reranking
ENABLE_GRAPH=true                            # Knowledge graph processing

# Tuning
EMBEDDING_DIMENSIONS=4096                    # Embedding vector dimensions
FACT_EXTRACT_TIMEOUT=60000                   # Fact extraction timeout (ms)
DEDUP_TIMEOUT=60000                          # Dedup decision timeout (ms)
RERANK_TIMEOUT=30000                         # Reranking timeout (ms)

# Database (no need to change for Docker)
PG_HOST=postgres
PG_PORT=5432
PG_USER=memolo
PG_PASSWORD=memolo_secret
PG_DATABASE=memolo
QDRANT_HOST=qdrant
QDRANT_PORT=6333

Scripts

Script Platform Purpose
setup.sh Linux/macOS Automated full setup (Docker, Ollama, .env, start services)
setup.bat Windows Same as above for Windows
update.sh Linux/macOS Pull latest code from Git and rebuild Docker image
scripts/install-plugin.sh Linux/macOS Install Memolo plugin into OpenClaw

First-time Setup

# Linux/macOS
bash setup.sh

# Windows
setup.bat

The setup script will:

  1. Check prerequisites (Docker, Ollama)
  2. Generate .env with random master key
  3. Pull required embedding model
  4. Start all Docker services
  5. Register a default agent

Update to Latest Version

bash update.sh
# Or manually:
git pull origin master
docker compose up -d --build memolo

Install OpenClaw Plugin

From inside your OpenClaw project directory:

curl -sL https://raw.githubusercontent.com/thdeptrai/memolo/master/scripts/install-plugin.sh | bash

This downloads the plugin, installs dependencies, and registers it with OpenClaw CLI.


Documentation

  • πŸ“‹ SETUP.md β€” Detailed setup & troubleshooting
  • πŸ“¦ SDK README β€” Node.js client SDK
  • πŸ”Œ Plugin README β€” OpenClaw plugin integration docs

About

Memolo Long-term shared memory system for multi-agent AI. Self-hosted with PostgreSQL, Qdrant, Ollama/MiniMax. Includes OpenClaw plugin, real-time dashboard, and Node.js SDK.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages