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.12.tar.gz (446.0 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.12-py3-none-any.whl (428.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: megan-0.1.12.tar.gz
  • Upload date:
  • Size: 446.0 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.12.tar.gz
Algorithm Hash digest
SHA256 f94a9bea5905bc7be33e66e872b3b16a86821b8b51d61d3de1c8da531cc7b2d4
MD5 459615313005ee40cc29edcc89d77f57
BLAKE2b-256 1728b2d4c6f0943bf1c05615fbd3968f63af3c7e40a8100f5ab5c46a50219aea

See more details on using hashes here.

File details

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

File metadata

  • Download URL: megan-0.1.12-py3-none-any.whl
  • Upload date:
  • Size: 428.0 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.12-py3-none-any.whl
Algorithm Hash digest
SHA256 3b0db89b802f6ad6b9b1dfcb8f468351cf41f56de0c7277b66709622a8ecf85a
MD5 a272f8c481280a141522935b1c316b6b
BLAKE2b-256 b0d2aee066824aa5e10cba9dfaa9752706aa3954ac91c7b65271fbd70343c57e

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