Skip to main content

Megan Memory Prototype

Python/Flask prototype for a personal AI assistant with long-term graph-style memory, inspired by the architecture diagrams in the project brief.

What It Does

  • Stores production memories in Neo4j as a knowledge graph.
  • Keeps a SQLite local graph fallback so terminal tests run without external services.
  • Extracts memory summaries, importance, nodes, and relationships with OpenAI when OPENAI_API_KEY is set.
  • Falls back to deterministic local extraction when no API key is present.
  • Answers questions by retrieving a graph neighborhood first: query terms -> seed entities -> related entities -> mentioned memories -> model answer.
  • Runs Celery-powered sleep cycles that consolidate recent memories, strengthen useful graph links, rescore importance, and archive low-value noise.
  • Maintains long-running teaching conversations with persisted messages and rolling summaries.
  • Tracks token usage by conversation, day, week, and month.
  • Exposes API endpoints for remembering, querying, graph inspection, and consolidation.

Setup

uv sync --extra test
copy .env.example .env

Add your key to .env when you want live OpenAI calls.

OPENAI_API_KEY=your_key_here
OPENAI_MODEL=gpt-4.1-mini

Production Graph DB

Use Neo4j for the real memory graph:

docker run --name megan-neo4j -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:5

Then set:

NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=password
NEO4J_DATABASE=neo4j

When NEO4J_URI is absent, the app uses instance/megan.sqlite3 as a local graph-compatible fallback for terminal-only development.

Live Data Stores

For a commercial/live deployment, Megan is configured for:

  • Railway Postgres via DATABASE_URL or APP_DATABASE_URL as the main app data store.
  • Neo4j Aura via NEO4J_URI for long-term graph memory.
  • Railway Redis via REDIS_URL for Celery/background work.
  • Local SQLite as a development/offline cache with a sync outbox at SYNC_DATABASE.
  • Tenant/user/device scope via MEGAN_TENANT_ID, MEGAN_USER_ID, and SYNC_DEVICE_ID.

See docs/live-data-architecture.md for the production store map and sync rules. At runtime, GET /api/data/topology reports configured storage targets without exposing credentials.

Background Sleep Cycle

Celery runs the memory sleep cycle. Redis is the default broker/result backend:

docker run --name megan-redis -p 6379:6379 redis:7

Start the worker:

uv run celery -A megan.celery_app.celery_app worker --loglevel=info

Start the scheduler that triggers sleep every 4 hours:

uv run celery -A megan.celery_app.celery_app beat --loglevel=info

Trigger a background sleep cycle through Flask:

curl -X POST http://127.0.0.1:5000/api/sleep-cycle

For terminal-only testing without Redis/Celery worker:

uv run python -m megan.cli sleep-cycle

Native Desktop Direction

The commercial Windows desktop direction lives in desktop/.

It is a Windows App SDK / WinUI app backed by Megan.Desktop.Core, which writes local tenant-scoped data under %APPDATA%\Megan and syncs through the Megan API. This path is intended to replace the development-only Tauri/Flask desktop bridge so users do not need to run app.py or install Python.

The older Tauri shell remains available for experimentation. It no longer auto-starts the Flask backend unless MEGAN_TAURI_AUTOSTART_BACKEND=1 is set.

Native Android Direction

The Android companion app lives in android/.

It is a Kotlin / Jetpack Compose app focused on the two mobile surfaces Megan needs first:

  • Conversation
  • Settings

Android talks to the same Flask API as web and desktop. For emulator testing, set the mobile server URL to http://10.0.2.2:5000. For a real phone, bind Flask to 0.0.0.0 and use your PC's LAN address.

Local model support is routed through Megan's provider/model contract. The recommended first setup is to configure the Flask server with an OpenAI-compatible local endpoint, then select the local route from Android settings.

Run The App

uv run python app.py

Health check:

curl http://127.0.0.1:5000/api/health

Run The Vite React Client

The Flask app is the API server on port 5000. The React voice client runs through Vite on port 5173.

Terminal 1:

uv run python app.py

For local speaker recognition testing with SpeechBrain, run Flask without the debug reloader so Werkzeug does not scan SpeechBrain's lazy optional modules:

uv run flask --app app run --no-reload

Appearance recognition uses the optional InsightFace provider when installed. On Windows, prefer Python 3.10 or 3.11 for this stack, then install:

uv pip install insightface onnxruntime opencv-python

Terminal 2:

cd client
npm install
npm run dev

Open:

http://127.0.0.1:5173

The client supports browser speech input, optional spoken replies, direct memory capture, graph inspection, and per-request provider/model selection.

Model credentials stay server-side in .env. The default provider is OpenAI:

DEFAULT_AI_PROVIDER=openai
OPENAI_API_KEY=your_key_here
OPENAI_MODEL=gpt-4.1-mini
OPENAI_MODEL_OPTIONS=gpt-4.1-mini,gpt-4.1,gpt-4o,gpt-4o-mini

DeepSeek:

DEEPSEEK_API_KEY=your_key_here
DEEPSEEK_BASE_URL=https://api.deepseek.com
DEEPSEEK_MODEL=deepseek-chat
DEEPSEEK_MODEL_OPTIONS=deepseek-chat,deepseek-reasoner

Anthropic Claude:

ANTHROPIC_API_KEY=your_key_here
ANTHROPIC_MODEL=claude-sonnet-4-20250514
ANTHROPIC_MODEL_OPTIONS=claude-sonnet-4-20250514,claude-opus-4-20250514,claude-3-7-sonnet-20250219,claude-3-5-haiku-latest

When credentials are configured, Megan asks the provider API for its available models and caches the result for five minutes. The configured model lists are used as an offline fallback.

For an OpenAI-compatible endpoint, configure:

OPENAI_COMPATIBLE_API_KEY=your_key_here
OPENAI_COMPATIBLE_BASE_URL=http://127.0.0.1:11434/v1
OPENAI_COMPATIBLE_MODEL=local-model
OPENAI_COMPATIBLE_MODEL_OPTIONS=local-model,another-model

If the selected provider is not configured, Megan falls back to local deterministic behavior.

Test In The Terminal

uv run pytest
uv run python -m megan.cli smoke-test
uv run python -m megan.cli remember "Megan met John at Hospital Nairobi and discussed diabetes follow-up."
uv run python -m megan.cli ask "What does Megan remember about John?"
uv run python -m megan.cli chat "Teach me graph memory from where we left off."
uv run python -m megan.cli usage
uv run python -m megan.cli graph
uv run python -m megan.cli sleep-cycle

smoke-test deliberately disables OpenAI and Neo4j and runs the sleep cycle inline, so it proves the terminal path works anywhere.

Knowledge Graph Shape

Neo4j stores:

  • (:Memory) nodes for timestamped experiences.
  • (:Entity {label, kind}) nodes for people, places, concepts, events, emotions, states, and procedures.
  • (:Memory)-[:MENTIONS]->(:Entity) links for provenance.
  • (:Entity)-[:RELATED_TO {relation, confidence}]->(:Entity) links for semantic, episodic, and procedural relationships.

The answer path is:

question -> query terms -> seed Entity nodes -> related Entity nodes + Memory provenance -> graph context -> OpenAI answer

Sleep Cycle

The sleep cycle is the offline learning loop:

active memories -> graph neighborhoods -> cluster repeated themes -> rescore importance -> archive noise -> write consolidated memory -> strengthen useful edges

It is implemented in megan/sleep_cycle.py and can run either inline for testing or through Celery for background processing.

Long Conversations And Token Usage

Megan stores every conversation turn in CONVERSATION_DATABASE. For sessions that last more than an hour, it keeps continuity with:

  • full persisted message history
  • a rolling summary of older turns
  • recent message window
  • graph memory retrieval for the newest user message

The answer prompt is built from:

rolling summary + recent messages + graph context + latest user message

Token usage is recorded after every model operation. The client at http://127.0.0.1:5000/ shows daily, weekly, and monthly totals. The same data is available through:

curl http://127.0.0.1:5000/api/usage/summary

API

POST /api/memory/event

{
  "event": "On June 1, 2026, Megan met John at Hospital Nairobi..."
}

POST /api/memory/query

{
  "question": "What does Megan remember about John?"
}

GET /api/memory/graph

POST /api/memory/consolidate

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

megan-0.1.10.tar.gz (444.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

megan-0.1.10-py3-none-any.whl (426.6 kB view details)

Uploaded Python 3

File details

Details for the file megan-0.1.10.tar.gz.

File metadata

  • Download URL: megan-0.1.10.tar.gz
  • Upload date:
  • Size: 444.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for megan-0.1.10.tar.gz
Algorithm Hash digest
SHA256 b7d3a17c6412cfe6016da4d6953b0956427324162dcbc798d8d7788e4ae65482
MD5 6ac9c1b11c94325e284716c6fcc2a03a
BLAKE2b-256 3a67f761472e1e93e04c58c99eacd9f0ed7349474d52745732d702ed90e72507

See more details on using hashes here.

File details

Details for the file megan-0.1.10-py3-none-any.whl.

File metadata

  • Download URL: megan-0.1.10-py3-none-any.whl
  • Upload date:
  • Size: 426.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for megan-0.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 52585a08c1c3be8d301240d7200aaccdacec9e6cbd7cd3037353081aeb166fc6
MD5 2ef22c90844cb64e31fdd1960c212fae
BLAKE2b-256 50b3dd962ec53b596dcc65dc7b6d59497242d2d3ba1d70905780aecc970839db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page