lobs-memory is a persistent semantic search service for the Lobs agent system. It provides hybrid search (BM25 keyword + vector embeddings) over memory files and project docs, with neural reranking for result quality.
It runs as a separate service (typically on port 7420) and is called by lobs-core via the Librarian service for cross-session memory search.
lobs-core (Librarian service) ──search──> lobs-memory (port 7420)
│
├── BM25 (SQLite FTS5)
├── Vector search (sqlite-vec)
├── Neural reranker (node-llama-cpp)
└── File watcher (chokidar)
Key server modules (server/):
index.ts— HTTP server, routes/search,/health,/status,/indexdb.ts— SQLite with FTS5 + sqlite-vec for full-text and vector searchembedder.ts— LM Studio embedding clientreranker.ts— Cross-encoder reranking via node-llama-cppsearch.ts— Full search pipeline (BM25 → vector → rerank → MMR → decay)indexer.ts— File indexing and watchingchunker.ts— Markdown chunking
cd ~/lobs/lobs-memory
# Install (Bun)
bun install
# Start server
bun run start
# Development (auto-reload)
bun run dev
# Run tests
bun testExternal dependencies:
- LM Studio on
localhost:1234withtext-embedding-qwen3-embedding-4bloaded - Reranker GGUF (optional, degrades gracefully if missing):
~/.cache/qmd/models/hf_ggml-org_qwen3-reranker-0.6b-q8_0.gguf
Edit config.json or set environment variables:
| Env var | Default | Description |
|---|---|---|
PORT |
7420 | Server port |
LMSTUDIO_URL |
http://localhost:1234/v1 |
LM Studio base URL |
EMBEDDING_MODEL |
text-embedding-qwen3-embedding-4b |
Embedding model |
RERANKER_MODEL |
path to GGUF | Reranker model path |
- Tech stack: Bun runtime, TypeScript, SQLite (FTS5 + sqlite-vec), node-llama-cpp
- File collections are defined in
config.jsonundercollections[]. Each collection has aname,path, andpatternglobs - Chunking: Markdown files are split into chunks (with citation line ranges) before embedding
- Caching: Embeddings are cached in SQLite — unchanged files skip re-embedding on restart
- Graceful degradation: Server works without reranker (just skips that step)
- Background indexing: On startup, indexing runs in background — server is responsive immediately
- File watching:
chokidarwatches collection paths and re-indexes changed files automatically
index.db(SQLite) — FTS5 full-text index + sqlite-vec vector store + embedding cachememory.db— secondary database (per README)- Indexed files — Markdown files matching collection patterns (e.g.,
MEMORY.md,memory/**/*.md)
Data lives in ~/.lobs/plugins/lobs-memory/ by default.
curl -X POST http://localhost:7420/search \
-H "Content-Type: application/json" \
-d '{"query": "github issues", "maxResults": 5}'Response includes results[] with path, startLine, endLine, score, snippet, source, and citation.
Other endpoints:
GET /health— health checkGET /status— index status, document countsPOST /index— trigger manual re-index