Memory

VoxGraph persists two kinds of memory in SQLite (voxgraph.db, gitignored). Both are loaded before every LLM call and injected into the prompt or chat history.

Semantic facts

Stable keyed facts extracted from user speech (name, preferences, location):

  • Table: semantic_facts — (user_id, fact_key, fact)
  • Extracted via regex in extract_facts_from_transcript()
  • Example: "My name is Raj" → User's name is Raj.
  • Injected in the LLM system prompt as authoritative user facts

Episodic turns

Every completed exchange is appended as a user/assistant pair:

  • Table: episodic_turns — user text, AI text, timestamp
  • Rolling window: EPISODIC_MAX_TURNS (default 30)
  • Character cap: EPISODIC_MAX_CHARS (default 12000) — oldest turns dropped first
  • For Ollama: passed as alternating user / assistant messages in/api/chat
  • For Gemini: formatted as a text block in the prompt

What the model sees

System: You are VoxGraph…
        KNOWN FACTS: User's name is Raj.
        Conversation rules: stay on topic…

[user message history — turn 1, 2, … N-1]

User: <current utterance>

Direct intents (no LLM)

High-confidence phrases in voxgraph/voice/intents.py (greetings, "what is my name", "who are you") bypass the LLM for speed and accuracy on small models.

Reset memory

Delete or rename voxgraph.db while the server is stopped. A fresh file is created on next run.

Extending

  • Add extraction patterns in voxgraph/memory/store.py
  • Call MemoryStore.upsert_fact() from your own tools
  • Replace SQLite with Postgres/Redis for multi-user production (same interface idea)