Reference
Stores
BeliefState persists extracted beliefs in a configurable store backend. Choose based on your deployment model.
Stores Overview
The store acts as the memory bank of the tracking layer. Extracted belief structures are persisted to the backend to support session consistency across multiple turns.
In-Memory
- Best for: unit tests, local scripts, prototyping
- Persistence: none — lost on restart
- Concurrency: single process only
- Setup: zero configuration
SQLite
- Best for: single-server apps, low-traffic
- Persistence: file-based, survives restarts
- Concurrency: single process (WAL mode reads)
- Setup: single file path config
Redis
- Best for: multi-worker, load-balanced
- Persistence: configurable (RDB/AOF)
- Concurrency: multi-process safe
- Setup: Redis server connection
The tracking store backend is configured by passing the store_type and store_kwargs properties within your TrackerConfig.
Store Protocol
All store backends implement the Store protocol, which defines the public interface for belief persistence. Any custom backend must implement these methods:
| Method | Signature | Description |
|---|---|---|
upsert |
async upsert(belief, session_id, conversation_id, turn) |
Insert or update a belief with turn-based optimistic concurrency. |
get_beliefs |
async get_beliefs(session_id, conversation_id=None, category=None, belief_type=None) |
Query beliefs with optional filters. |
get_by_key |
async get_by_key(subject, predicate, session_id) |
O(1) exact lookup by belief triple key. |
search_beliefs |
async search_beliefs(session_id, embedding, threshold, limit, conversation_id=None) |
Semantic search via cosine similarity on stored embeddings. |
get_audit_history |
async get_audit_history(subject, predicate, session_id, limit=10) |
Retrieve version history for a belief from the audit trail. |
clear_session |
async clear_session(session_id) |
GDPR deletion — removes all beliefs for a session. |
Turn-Based Optimistic Concurrency
All store backends enforce turn-based optimistic concurrency on upsert(). Each write includes a turn parameter — the store compares it against the stored belief's turn and only overwrites if the incoming turn is newer or equal. This prevents stale background writes from overwriting fresh data when concurrent tasks race.
Turn-based concurrency is a lightweight guard. For coordinated writes within a single session, the tracker also applies per-session async write locks to serialize concurrent background tasks.
Audit Trail
SQLite and PostgreSQL backends maintain a beliefs_audit table that logs every belief mutation. Each row records the full belief state at the time of change, enabling version history queries via get_audit_history().
| Column | Type | Description |
|---|---|---|
id |
INTEGER |
Auto-incrementing audit record ID. |
session_id |
TEXT |
Session that owns this belief. |
subject |
TEXT |
Belief subject. |
predicate |
TEXT |
Belief predicate. |
value |
TEXT |
Belief value at mutation time. |
confidence |
REAL |
Confidence score at mutation time. |
turn |
INTEGER |
Turn number when the mutation occurred. |
changed_at |
TEXT |
ISO 8601 timestamp of the mutation. |
SQLite Store
The SQLite backend persists belief triples directly to a local database file. It operates asynchronously using aiosqlite connection pools.
| Parameter | Type | Default | Description |
|---|---|---|---|
db_path |
str | "beliefs.db" | Path pointing to the SQLite database file. Provide ":memory:" to use in-memory SQLite tables. |
WAL Mode
Write-Ahead Logging (WAL) is activated automatically on connection. WAL mode allows concurrent read queries to progress without lockouts from background write tasks.
The store applies these PRAGMA operations during initialization:
Connection Management
The store opens one persistent sqlite database connection via open() and closes it via close(). The client supports async context managers.
Schema
The tracking database creates a structured table layout to record conversational context:
| Column | Type | Description |
|---|---|---|
session_id |
TEXT |
Active conversation session identifier. Part of primary key. |
conversation_id |
TEXT |
Active thread identifier. Used to isolate thread pools. |
subject |
TEXT |
Subject part of the belief triple. Part of primary key. |
predicate |
TEXT |
Predicate part of the belief triple. Part of primary key. |
value |
TEXT |
Normalized factual claim value. |
confidence |
REAL |
Confidence score (0.0 to 1.0) generated by the extraction model. |
turn |
INTEGER |
The turn number index when this claim was established. |
source |
TEXT |
Source actor that asserted the claim: "user" or "assistant". |
belief_type |
TEXT |
Fact type: "assertion" or "update". |
is_hypothetical |
INTEGER |
Boolean flag indicating speculative statements (0 or 1). |
embedding |
BLOB |
Binary representation of the vector embedding array. |
embedding_model |
TEXT |
Name of the embedding model used to calculate vectors. |
embedding_dim |
INTEGER |
Dimensionality of the vector embedding array. |
created_at |
TEXT |
ISO 8601 timestamp logging row creation. |
last_referenced_at |
TEXT |
ISO 8601 timestamp logging last access. |
Do not use :memory: with multiple connections. Each connection sees a separate empty database. Use a file path for persistence.
Redis Store
The Redis backend offloads tracking state to an external server. It supports concurrent connections across multiple worker nodes.
| Parameter | Type | Default | Description |
|---|---|---|---|
redis_url |
str | "redis://localhost:6379/0" | Connection connection URI indicating server IP, port, and logical database index. |
Key Structure
The store maps belief triples to redis keys using a hash-based structure. All beliefs for a session are stored in a single Redis hash keyed by session ID:
Each hash field is {conversation_id}:{subject}:{predicate} and the value is a JSON-serialized Belief object.
Example keys generated by the store backend:
Embedding Storage
To save memory and preserve float precision, the store packages embedding vectors into binary byte BLOBs using the Python struct library. This prevents precision loss and shrinks payload size by 4x.
TTL Support
Allows setting expiration intervals on session keys. Keys expire automatically after the TTL duration ends, cleaning up inactive records.
Multi-Worker Safety
Redis operates atomically within a single-threaded server execution loop. This isolates commands and allows multi-worker instances to modify user session facts concurrently without race conditions.
For Celery or RQ deployments, use RedisBeliefStore — the same Redis instance can serve both your task queue and belief store.
PostgreSQL Store
The PostgreSQL backend provides full production-grade persistence with concurrent connection support, audit trails, and turn-based optimistic concurrency.
| Parameter | Type | Default | Description |
|---|---|---|---|
dsn |
str | required | PostgreSQL connection string (DSN). |
min_pool_size |
int | 2 | Minimum number of connections in the pool. |
max_pool_size |
int | 10 | Maximum number of connections in the pool. |
Features
- Turn-based upsert — uses
ON CONFLICT ... DO UPDATEwith turn comparison for optimistic concurrency. - Audit trail — every mutation is logged to a
beliefs_audittable for version history. - Binary embeddings — embeddings stored as binary BLOBs using
struct.packfor precision and space efficiency. - Connection pooling — async connection pool with configurable min/max sizes.
- Semantic search — computes cosine similarity in Python over fetched embeddings (consider pgvector extension for large datasets).
Requires the asyncpg package: pip install asyncpg.
In-Memory Store
The default in-memory store persists records inside local dictionary variables. Data resets when the application process terminates.
When to Use
- Executing unit tests and local integration flows.
- Prototyping logic and running one-off scripts.
- Testing tracking pipelines before configuring database instances.
- Never in production deployments.
LRU Eviction
To prevent memory leaks during long-running processes, the store maintains an OrderedDict and evicts older, least-recently-used beliefs once memory usage exceeds max_bytes (default 100 MB).
Thread Safety
The store uses asyncio-safe OrderedDict operations. It is safe for concurrent access within a single Python process loop, but cannot synchronize across multiple server worker processes.
Do not use InMemoryBeliefStore in production. All beliefs are lost when the process restarts.