Batteries-included memory for voice bots—FAISS + SQLite + embeddings + encryption in one pip install
Project description
brainfart
Batteries-included memory for voice bots. One pip install, one env var, done.
FAISS vector search + SQLite storage + sentence-transformers embeddings + Gemini extraction + at-rest encryption—all bundled and ready to use.
Quick Start
Installation
pip install brainfart
Set your Gemini API key
export GOOGLE_API_KEY="your-gemini-api-key"
Add to your Pipecat bot
from pipecat.pipeline.pipeline import Pipeline
from brainfart import MemoryProcessor
# That's it—zero configuration needed
memory = MemoryProcessor(user_id="user123")
pipeline = Pipeline([
transport.input(),
stt_service,
memory, # <- Add memory here
llm_service,
tts_service,
transport.output(),
])
What you get
- Vector similarity search with FAISS (no external database)
- Persistent storage in SQLite (survives restarts)
- Automatic embeddings using all-MiniLM-L6-v2 (fast, ~90MB)
- Smart extraction with Gemini Flash (extracts what's worth remembering)
- At-rest encryption with Fernet (crash-safe, optional)
How it works
The memory system has two modes:
-
Extraction: As the user speaks, the processor buffers messages and periodically uses Gemini to extract memorable facts (identity, preferences, relationships, etc.)
-
Retrieval: Before each LLM response, relevant memories are retrieved using semantic search and injected into the context.
User speaks → Buffer → Extract (Gemini) → Store (FAISS + SQLite)
↓
Retrieve → Inject → LLM
Configuration
Everything works with defaults, but you can customize:
Environment Variables
| Variable | Default | Description |
|---|---|---|
GOOGLE_API_KEY |
Required | Gemini API key for extraction |
BRAINFART_TOP_K |
5 |
Memories to retrieve per query |
BRAINFART_DATA_DIR |
~/.cache/brainfart |
Storage location |
BRAINFART_EMBEDDING_MODEL |
all-MiniLM-L6-v2 |
Embedding model |
BRAINFART_ENCRYPTION_KEY |
None | Enable encryption with this key |
Constructor Parameters
memory = MemoryProcessor(
user_id="user123", # Required: user identifier
agent_id="my-bot", # Optional: for multi-agent isolation
gemini_api_key="your-key", # Optional: override env var
top_k=10, # Optional: more memories
embedding_model="all-mpnet-base-v2", # Optional: larger model
encryption_key="secret", # Optional: enable encryption
inject_memories=True, # Optional: inject into LLM context
extract_memories=True, # Optional: extract from conversation
extraction_interval=5, # Optional: extract every N messages
)
Encryption
Enable at-rest encryption for security:
export BRAINFART_ENCRYPTION_KEY="your-secret-passphrase"
Or pass directly:
memory = MemoryProcessor(
user_id="user123",
encryption_key="your-secret-passphrase",
)
Data is encrypted on disk, decrypted only in memory. Crash-safe—if the process dies, data remains encrypted.
Multi-Agent Isolation
Different agents maintain separate memories for the same user:
# Sales bot memories
sales_memory = MemoryProcessor(user_id="user123", agent_id="sales-bot")
# Support bot memories (separate store)
support_memory = MemoryProcessor(user_id="user123", agent_id="support-bot")
Storage structure:
~/.cache/brainfart/
├── sales-bot/
│ └── user123.index
│ └── user123.db
└── support-bot/
└── user123.index
└── user123.db
Direct API Usage
Use the memory system without Pipecat:
from brainfart import LocalMemory, MemorySettings
settings = MemorySettings(
data_dir="/path/to/data",
encryption_key="secret",
)
memory = LocalMemory(settings, user_id="user123")
await memory.load()
# Store
await memory.store("User lives in SF", category="identity", importance=5)
# Retrieve
results = await memory.retrieve("Where does the user live?")
for r in results:
print(f"[{r.category}] {r.content} (similarity: {r.similarity:.2f})")
await memory.close()
Memory Categories
Memories are categorized for better retrieval:
| Category | Description | Example |
|---|---|---|
identity |
Core facts about who the user is | "User lives in San Francisco" |
preference |
Likes, dislikes, communication style | "User prefers concise answers" |
context |
Current projects, ongoing situations | "User is working on a Python project" |
relationship |
Emotional moments, shared experiences | "User was excited about promotion" |
surprise |
Unusual or noteworthy facts | "User has visited 50 countries" |
Performance
- First import: 5-15 seconds (model loading)
- Subsequent imports: <1 second (cached)
- Embedding: ~7-8ms per text
- Retrieval: ~1-2ms (excluding embedding)
- Install size: ~500MB (mostly sentence-transformers/PyTorch)
Docker
Pre-download models during build for faster cold starts:
FROM python:3.11-slim
RUN pip install brainfart
# Pre-download embedding model
RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2')"
# Set cache location
ENV HF_HOME=/app/.cache
Full Example
See examples/bot.py for a complete working bot.
Known Issues
- Redundant memories: The extraction process may create duplicate or near-duplicate memories. Deduplication is not yet implemented.
License
BSD-2-Clause (same as Pipecat)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file brainfart-0.2.0.tar.gz.
File metadata
- Download URL: brainfart-0.2.0.tar.gz
- Upload date:
- Size: 25.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27eeb1e6b74621ba86c18c35464c236955917102e8009c85933c112a575e89f7
|
|
| MD5 |
1f25810d9949d870a27194166e0de79a
|
|
| BLAKE2b-256 |
9daef523a1000d46c12d4599b08392d1ab5586d003892796caef2097e6a25e44
|
File details
Details for the file brainfart-0.2.0-py3-none-any.whl.
File metadata
- Download URL: brainfart-0.2.0-py3-none-any.whl
- Upload date:
- Size: 24.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a34e329be4e604bdfdc63112644ddd6dcf30c3bec7792b85c4753e1ae51a13f7
|
|
| MD5 |
ca9fde12dc5d40b844ec44c8eed89206
|
|
| BLAKE2b-256 |
2703fb808f158bd4e431aa96d3d549dda2f46c59124e0904a1912af680c5ee58
|