Skip to content

Data Persistence

Vector Companion uses a single WAL-mode SQLite database as the canonical persistence layer. This replaces scattered JSON files with a transactional store supporting CRUD operations across nine entity types.

SQLiteStore — Canonical Store

SQLiteStore (core/data/sqlite_store.py) is the primary persistence mechanism for all runtime artifacts: conversations, messages, settings, memories, audit events, tool grants, and background tasks.

Configuration

  • WAL mode: PRAGMA journal_mode=WAL for concurrent read/write access
  • Synchronous: PRAGMA synchronous=NORMAL for balanced durability
  • Foreign keys: Enabled with cascade deletes
  • Schema versioning: Current schema v3, auto-migration on first use
  • Concurrency: asyncio lock protects concurrent writes

Database Tables

Table Record Class Description
conversations ConversationRecord Chat sessions with title, agent, mode flags
messages MessageRecord Individual messages with role, content, metadata, tool_name
folders FolderRecord Conversation organization and grouping
settings SettingRecord Key-value app settings
memories MemoryRecord User memories and training data
attachments AttachmentRecord File references and binary blobs
audit_events AuditEvent Tool execution audit trail
tool_grants ToolGrantRecord Persistent approval grants
background_tasks BackgroundTaskRecord Async task state and results

Query Limits

  • get_messages(limit=None) — returns all messages (no LIMIT clause). Default limit=100 for backward compatibility.
  • list_conversations(limit=None) — returns all conversations. Default limit=50.
  • Always pass limit=None for full history loads (switch conversation, startup init, embedding context, forget conversation).
  • Use message_count(conversation_id) for O(1) count instead of len(get_messages(...)).

Schema Migration v3

The v3 migration adds a tool_name column to the messages table. This preserves tool call identity across session reloads — without it, tool results lose their attribution on restart. Existing pre-v3 rows get default empty string after migration.

Protocol Conformance

SQLiteStore implements LocalStoreProtocol. In tests, use FakeLocalStore from tests/testkit/ to verify protocol conformance:

assert isinstance(store, LocalStoreProtocol)

Vector Embedding (memory_mode only)

Memory Mode Only

Embedding is only used for memory_mode conversation context recall. It has been retired from web_search and read_file paths to conserve VRAM.

  • Model: qwen3-embedding:0.6b via Ollama
  • Storage: ChromaDB persistent client, lazy-initialized via config.get_db_client()
  • Operations: Upsert conversation context, query by similarity
  • Telemetry: embedding.query_ms, embedding.upsert_ms, embedding.doc_count

CrossEncoder Reranker (memory_mode only)

Memory Mode Only — Lazy Loaded

Like embedding, the reranker is only active for memory_mode. Retired from web_search and read_file paths. Unlike other heavy models (ASR/TTS), the reranker is not loaded at startup — it's lazy-loaded via LazyLoader on first use when memory_mode activates folder-scoped RAG, saving ~250MB GPU memory for users who never enable memory_mode.

  • Model: tomaarsen/Qwen3-Reranker-0.6B-seq-cls via CrossEncoder
  • Purpose: Second filtering pass after embedding-based retrieval for improved relevance
  • Loading: Deferred via LazyLoader.ensure_loaded("reranker") in the RAG code path
  • Telemetry: reranker.duration_ms, reranker.doc_count

Conversation Backup

The backup system exports and imports conversations as JSON files with defensive type validation:

  • Exporter: Exports from SQLiteStore with optional content redaction
  • Importer: Validates schema version, rejects malformed data gracefully
  • Format: Structured sections for metadata, folders, conversations, messages, settings, memories, tool grants

Full-text search across conversation history stored in SQLiteStore. Supports keyword matching with context line retrieval.

Memory Lifecycle

Automatic memory extraction from conversations. Integrates with both the memories table in SQLite and ChromaDB for semantic search when memory_mode is active.

See Also