Overview
Omi uses a dual-collection architecture for storing user data:Conversations
Primary storage for recorded interactions - transcripts, audio, structured summaries
Memories
Secondary storage for extracted facts/learnings FROM conversations
On-device summaries in desktop reads
The app conversation response may carry a display-onlyclient_processing projection.
Binding it does not modify canonical structured or create authoritative tasks or memories.
The macOS ServerConversation adapter selects the projection once for every display consumer:
only schema v1 is understood, and a response containing transcript segments must match the
projection’s transcript_sha256 using encoding v5, including speaker identity and attribution.
A list response omitting the transcript relies on the server’s transactional binding and
invalidation when the transcript changes; it cannot independently prove freshness.
An enriched canonical overview, sections, events, or non-default category wins over a retained
projection, including after an upgrade and cloud reprocessing. processing_state is not a
cloud-origin discriminator: it can be absent with a projection, or remain local_pending after
late binding. Title-only/default-field cloud results are indistinguishable from the deterministic
minimum in this wire contract, so that ambiguous shape follows the projection-first rule.
Canonical action items win exact-description collisions, preserving both completed and reopened
state; unmatched projected items are display-only additions with no canonical task identity.
Selected provenance remains available as ServerConversation.localSummary and is cached in
transcription_sessions.localSummaryJson. The producer’s clientProcessingJson retry bytes are
separate. Revision-aware sync replaces the selected summary atomically; older or unversioned
snapshots cannot fill fields across projection/canonical sources. A cached transcript whose hash
differs from the selected projection is left unloaded until detail refresh.
Run the desktop regressions from the repository root:
Architecture Diagram
Firestore Structure
Part 1: Storing Conversations
Processing Flow
API Request
The app sends a POST request to
/v1/conversations with transcript dataProcessing
process_conversation() in utils/conversations/process_conversation.py handles the logicStructure Extraction
LLM extracts title, overview, action items, and events from the transcript
Storage
upsert_conversation() in database/conversations.py saves to FirestoreVector Embedding
Conversation is embedded and stored in Pinecone for semantic search
Conversation Model Fields
Structured Information
Thestructured field contains LLM-extracted information:
Transcript Segments
Each segment intranscript_segments includes:
Action Items
Action items are stored both inline (instructured.action_items) and in a standalone collection:
Events
Calendar events extracted from conversations:Part 2: Extracting & Storing Memories
Memories are facts about the user extracted from conversations. They represent learnings, preferences, habits, and other personal information.Memory Extraction Process
Duringprocess_conversation(), the system:
Analyze Transcript
Reviews the conversation transcript for personal information
Extract Facts
Identifies facts worth remembering about the user (~15 words max)
Store with Link
Saves to
memories collection with a link back to the source conversationMemory Model Fields
Memory Categories
Interesting
Notable facts about the user: hobbies, opinions, stories
System
Preferences and patterns: work habits, sleep schedule
Manual
User-created memories: explicitly added facts
Legacy categories (
core, hobbies, lifestyle, interests, habits, work, skills, learnings, other) are automatically mapped to the new primary categories for backward compatibility.Memory Extraction Rules
The system follows these guidelines when extracting memories:- Maximum ~15 words per memory
- Must pass the “shareability test” - would this be worth telling someone?
- Maximum 2
interesting+ 2systemmemories per conversation - No duplicate or near-duplicate facts
- Skip mundane details (eating, sleeping, commuting)
Part 3: Data Protection & Encryption
Both conversations and memories support encryption for sensitive data.- Standard
- Enhanced
Standard Protection Level
No encryption, stored as plaintext. This is the default for most users.- Fastest read/write performance
- Data visible in Firestore console
- Suitable for general use
Implementation
Part 4: Vector Embeddings
Conversations are also stored as vector embeddings in Pinecone for semantic search.What Gets Embedded
Vector Creation
Vectors are created in a background thread after conversation processing:save_structured_vector() function:
- Generates embedding from
conversation.structured(title + overview + action_items + events) - Extracts metadata via LLM (people, topics, entities, dates)
- Upserts to Pinecone with metadata filters
Key Code Locations
API Endpoints
Conversations
Memories
Related Documentation
Chat System Architecture
How conversations are retrieved for chat using LangGraph
Real-time Transcription
WebSocket-based real-time speech-to-text
Backend Deep Dive
General backend architecture overview
Backend Setup
Environment setup and configuration