Skip to content

Repository files navigation

RecallOS

Adaptive memory system for conversational AI.

RecallOS gives AI assistants persistent, structured memory. It ingests conversations, extracts episodic memories, atomic facts, and foresight predictions, then retrieves them with purpose-aware search that adapts over time. Memories decay naturally, consolidate when redundant, and strengthen when useful — mimicking how human memory actually works.


Why RecallOS

Most AI memory systems are glorified vector databases — they store embeddings and do similarity search. RecallOS is fundamentally different:

It understands conversation structure. A 3-tier boundary detector (heuristics, embedding similarity, LLM) identifies where one topic ends and another begins — at 93% less cost than calling an LLM on every message.

It extracts multiple memory types. Each conversation segment produces episodes (narrative summaries), atomic facts (structured knowledge with subject-predicate-object triples), and foresight predictions (anticipated future impacts). Not just raw text chunks.

It organizes memories into clusters. Related episodes are grouped by topic using weighted multi-feature affinity scoring (semantic similarity, temporal proximity, participant overlap, entity overlap). Clusters enable neighborhood recall — finding related memories you didn't explicitly search for.

It builds user profiles automatically. Preferences, routines, commitments, active projects, and communication style are extracted incrementally and merged with contradiction detection.

It learns from usage. Retrieved memories that get cited in AI responses are reinforced. Memories that are consistently ignored decay faster. Fusion weights adapt based on what actually helps.

It consolidates over time. Duplicate facts are merged. Superseded information is archived. Expired predictions are resolved. Repetitive episodes are generalized ("weekly standup meetings in January" replaces 4 individual standup records).

Memories have lifecycles. Each memory has a temporal relevance score that decays based on its type (preferences decay over years, event details decay in days). Dormant memories are pruned from vector indexes to keep search fast, but can be reactivated if referenced again.


Quick Start

# Start PostgreSQL and Redis
docker compose up -d

# Install dependencies
uv sync

# Configure environment
cp .env.example .env
# Edit .env with your LLM API keys

# Run database migrations
uv run alembic upgrade head

# Start the server
uv run recall

The server starts at http://localhost:1995. Interactive API docs at http://localhost:1995/docs.


API

Core Operations

# Ingest a message
curl -X POST http://localhost:1995/v2/messages \
  -H "Content-Type: application/json" \
  -d '{
    "message_id": "msg-001",
    "sender_id": "alice",
    "sender_name": "Alice",
    "content": "I prefer morning meetings and tea over coffee",
    "group_id": "project-alpha"
  }'

# Search memories
curl -X POST http://localhost:1995/v2/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What does Alice prefer?",
    "top_k": 10,
    "assemble_context": true
  }'

# Batch ingest a conversation
curl -X POST http://localhost:1995/v2/messages/batch \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"message_id": "m1", "sender_id": "alice", "content": "Lets discuss the API migration"},
      {"message_id": "m2", "sender_id": "bob", "content": "Sure, I finished the auth endpoints"},
      {"message_id": "m3", "sender_id": "alice", "content": "Great, the deadline is April 15th"}
    ]
  }'

Full Endpoint Reference

Method Path Description
POST /v2/messages Ingest a message into the memory pipeline
POST /v2/messages/batch Batch ingest multiple messages
POST /v2/search Search memories with purpose-aware retrieval
GET /v2/memories List memories with filtering and pagination
GET /v2/memories/{id} Get a single memory with full detail
DELETE /v2/memories Soft-delete memories by ID
POST /v2/memories/{id}/pin Pin a memory to prevent decay
POST /v2/feedback Submit feedback (thumbs up/down, flag, pin)
GET /v2/profiles/{user_id} View user profile (preferences, routines, projects)
GET /v2/conversations/{group_id} Conversation metadata and participants
PATCH /v2/conversations/{group_id} Update conversation metadata
GET /v2/groups/{group_id}/clusters Browse topic clusters
GET /v2/status/{group_id} Pipeline processing status
GET /v2/stats System-wide statistics
DELETE /v2/users/{id}/data Delete all user data (GDPR Art. 17)
GET /v2/users/{id}/data/export Export all user data (GDPR Art. 20)
GET /health Service health check

Architecture

Write Path

Message arrives
    -> Boundary Detection (3-tier: heuristics -> embedding -> LLM)
        -> If boundary: seal conversation segment, enqueue extraction job
        -> If no boundary: accumulate in conversation window

Extraction Worker (async, background):
    -> Episode extraction (group + per-participant perspectives)
    -> Atomic fact extraction (with SPO triples and categorization)
    -> Foresight extraction (gated — only when commitment/decision language detected)
    -> Cluster assignment (weighted multi-feature affinity scoring)
    -> Profile update (gated — only when profile-relevant signals detected)
    -> Persist to PostgreSQL + emit outbox events for index sync

Read Path

Search query arrives
    -> Query understanding (rule-based fast path, LLM for ambiguous queries)
    -> Parallel candidate generation across memory types
    -> Score fusion (per-purpose weights + type priors + freshness + group)
    -> Reranking (gate decides if worth the cost)
    -> Optional: agentic multi-round retrieval (evidence gap analysis + action planning)
    -> Context assembly (deduplication, token budgeting, narrative formatting)

Intelligence Layer (Background)

Temporal Relevance Worker (periodic):
    -> Compute decay per memory (type-specific half-lives)
    -> Manage lifecycle transitions (active -> cooling -> dormant -> archived)
    -> Prune dormant memories from vector indexes

Consolidation Worker (periodic):
    -> Deduplicate semantically identical facts
    -> Detect superseded facts (newer contradicts older)
    -> Resolve expired foresight predictions
    -> Generalize repetitive episodes into summaries

Feedback Loop (post-response):
    -> Detect which memories were cited in AI responses
    -> Update per-memory retrieval usefulness scores
    -> Adapt fusion weights via online learning

Operating Modes

RecallOS supports three operating modes that control cost vs. quality tradeoffs:

Feature Cheap Balanced Premium
Boundary detection Heuristics + LLM Heuristics + Embedding + LLM Full 3-tier
Foresight extraction Off On On
Persona profiles Off Off On
Feedback learning Off Capture only Capture + online learning
Consolidation Embedding-only dedup Monthly episode generalization Weekly + LLM verification
Temporal worker Every 24h Every 6h Every 3h

Set via OPERATING_MODE=cheap|balanced|premium in .env, or programmatically:

from recall.config import RecallAppConfig
from recall.domain.enums import OperatingMode

config = RecallAppConfig.from_operating_mode(OperatingMode.PREMIUM)

Stack

Layer Technology
Language Python 3.12
Web framework FastAPI + uvicorn
Database PostgreSQL 16 + pgvector
Cache / Queue Redis 7 (Streams for async job queue)
LLM integration Direct aiohttp (no LangChain)
Configuration pydantic-settings with env var + .env support
Migrations Alembic
Observability structlog + Prometheus + OpenTelemetry
Testing pytest + testcontainers
Linting ruff

Development

# Run all tests (251 total)
uv run pytest

# Unit tests only (fast, no Docker needed)
uv run pytest tests/unit/

# Integration tests (requires Docker for PostgreSQL)
uv run pytest tests/integration/ --timeout=120

# Lint and format
uv run ruff check src/ tests/
uv run ruff format src/ tests/

Project Structure

src/recall/
├── api/            # 17 REST endpoints
├── llm/            # LLM client with pooled connections and tier routing
├── prompts/        # YAML prompt templates with token budgeting
├── boundary/       # 3-tier conversation boundary detection
├── pipeline/       # Async memorize pipeline with Redis Streams
├── extraction/     # Episode, fact, foresight extractors with partial failure handling
├── clustering/     # Multi-feature affinity clustering with EMA centroids
├── profiles/       # Two-layer profile system with delta-based updates
├── vectorize/      # Purpose-aware embedding with 3-layer cache
├── rerank/         # Score fusion with gate and cascade
├── retrieval/      # Multi-form search with query understanding
├── agentic/        # Multi-round retrieval reasoning
├── assembly/       # Context assembly with token budgeting
├── feedback/       # Citation detection and online learning
├── temporal/       # Decay, reinforcement, lifecycle management
├── consolidation/  # Fact dedup, supersession, episode generalization
├── persistence/    # PostgreSQL repositories and search backends
├── core/           # DI container, lifecycle, middleware, observability
└── migrations/     # Alembic schema (17 tables, 30+ indexes)

License

Apache 2.0

About

Adaptive conversational memory — LoCoMo ~88% vs EverMemOS 92%, with published failure analysis

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages