Skip to main content

Memory System

OWL uses a three-layer memory system to maintain persistent context across sessions.

Overview

┌─────────────────────────────────────────────────────────┐
│ Memory Layers │
├─────────────────────────────────────────────────────────┤
│ Layer 1: Memory File (~/.owl/memory.md) │
│ - Human-readable markdown │
│ - Preferences, notes, decisions │
│ - Loaded into every conversation │
├─────────────────────────────────────────────────────────┤
│ Layer 2: SQLite Database (~/.owl/memory/owl.db) │
│ - Conversation history │
│ - Auto-extracted learnings │
│ - Project context cache │
├─────────────────────────────────────────────────────────┤
│ Layer 3: Session Summaries │
│ - Compressed old conversations │
│ - Prevents context bloat │
│ - Maintains continuity │
└─────────────────────────────────────────────────────────┘

Layer 1: Memory File

The memory file (~/.owl/memory.md) stores facts you want OWL to always remember.

Structure

# Memory

## Preferences
- I prefer tabs over spaces
- Use pytest for Python testing
- Always include type hints

## Notes
- Project uses PostgreSQL database
- API keys are in .env file
- Deployment is via Docker

## Decisions
- Chose FastAPI over Flask for performance
- Using SQLAlchemy for ORM

Commands

# View memory
/memory

# Add to memory (auto-categorized)
/remember I prefer functional programming style
/remember Database password is in vault

# Remove from memory
/forget I prefer functional programming style

How It's Used

The memory file content is included in every LLM request, ensuring OWL always has access to your preferences and project facts.

Layer 2: SQLite Database

The SQLite database stores structured data that's too detailed for the memory file.

Tables

conversations

Stores all messages by session and project:

ColumnTypeDescription
idINTEGERPrimary key
session_idTEXTSession identifier
project_pathTEXTAssociated project
roleTEXTuser/assistant/tool
contentTEXTMessage content
timestampDATETIMEWhen sent
metadataJSONExtra data

learnings

Auto-extracted insights from conversations:

ColumnTypeDescription
idINTEGERPrimary key
categoryTEXTpreference/project/style/technical
observationTEXTWhat was observed
learningTEXTWhat to remember
project_pathTEXTIf project-specific
scopeTEXTglobal/project
confidenceFLOATHow certain
sourceTEXTuser/auto

sessions

Session metadata:

ColumnTypeDescription
idTEXTSession ID
started_atDATETIMEStart time
last_activeDATETIMELast activity
message_countINTEGERTotal messages
summaryTEXTCompressed summary

Automatic Reflection

Every 3 conversation exchanges, OWL reflects and extracts learnings:

Exchange 1: User asks about Python testing
Exchange 2: OWL suggests pytest, user agrees
Exchange 3: User mentions preference for fixtures
→ Reflection triggers
→ Learning extracted: "User prefers pytest fixtures over setup methods"

Project-Scoped History

Conversation history is scoped by project to prevent context contamination:

Project A history stays separate from Project B
When you switch projects, you get relevant history

Layer 3: Session Summaries

Long conversations are automatically summarized to prevent context overflow.

How It Works

  1. After 20 messages in a session
  2. OWL summarizes the oldest 10 messages
  3. Summary replaces detailed messages
  4. Most recent 10 messages stay fresh

Summary Format

Session Summary:
- Discussed Python testing approaches
- Decided on pytest with fixtures
- Reviewed authentication implementation
- Fixed bug in user registration

Configuration

Thresholds are set in the code:

  • SUMMARIZE_THRESHOLD = 20 (when to summarize)
  • SUMMARIZE_BATCH = 10 (how many to summarize, leaves 10 recent)

Memory Best Practices

What to Remember

Good candidates for /remember:

  • Coding style preferences
  • Project-specific facts
  • Tool and framework choices
  • Team conventions
  • Important decisions

What NOT to Remember

Avoid storing:

  • Sensitive credentials (use environment variables)
  • Frequently changing information
  • Very specific implementation details

Organizing Memory

The memory file auto-categorizes, but you can be explicit:

# Preferences (coding style, tools)
/remember I prefer descriptive variable names

# Notes (project facts)
/remember API rate limit is 100 requests/minute

# Decisions (architectural choices)
/remember Chose event sourcing for audit trail

Viewing Memory Data

Memory File

cat ~/.owl/memory.md

SQLite Database

sqlite3 ~/.owl/memory/owl.db

# Recent messages
SELECT role, substr(content, 1, 50) FROM conversations
ORDER BY timestamp DESC LIMIT 10;

# Learnings
SELECT category, learning FROM learnings;

# Sessions
SELECT id, message_count, last_active FROM sessions;

Data Persistence

DataLocationSurvives Restart
Memory file~/.owl/memory.mdYes
Conversationsowl.dbYes
Learningsowl.dbYes
Session stateMemoryNo

When you restart the daemon:

  • Memory file is reloaded
  • Recent session can be resumed (within 2 hours)
  • All learnings persist