One database. No Elasticsearch to sync. No Neo4j to maintain. No vector DB sidecar. pgvector, tsvector, and recursive CTEs handle everything.
Data flow
Connectors
Gmail, Drive, Slack, Fireflies, IMAP, Postgres, MySQL
Ingestion
Extract content · Chunk + embed · Extract graph · Extract memory
Storage
graph_nodes · graph_edges · rag_chunks · observations · connections
Query
Chat (SSE) · REST API · Graph UI
Connectors layer
Each connector is a Python adapter inbackend/sources/ that implements three operations:
Sync
Incremental fetch by cursor (message ID, file modification time, thread timestamp). Each connector persists its own cursor so runs only pull deltas.
| Source | Auth | Sync granularity |
|---|---|---|
| Gmail | OAuth 2.0 | Per message / thread |
| Google Drive | OAuth 2.0 | Per file modification time |
| Slack | OAuth 2.0 | Per channel timestamp |
| Fireflies | OAuth 2.0 | Per transcript ID |
| IMAP | Credentials (encrypted) | Per message UID |
| PostgreSQL / MySQL | Credentials (encrypted) | On-demand (schema + query exec) |
Ingestion pipeline
- Content extraction
- Entity + relationship extraction
- Chunking + embedding
- Memory extraction
Strip formatting, unwrap HTML, handle attachments, normalize to plain text.The content adapter produces a
SourceItem per content unit with stable IDs for deduplication across syncs.Storage layer
One Postgres database. Extensions:pgvector for embeddings, built-in tsvector for full-text search.
| Table | Role | Key indexes |
|---|---|---|
graph_nodes | Typed entities extracted from content | HNSW(embedding), GIN(search_vector), btree(source_date) |
graph_edges | Typed relationships with weight + timestamp | btree(source_id), btree(target_id), btree(relation) |
rag_chunks | Text chunks for retrieval | HNSW(embedding), GIN(search_vector) |
observations | Typed memory facts with importance decay | HNSW(embedding), GIN(search_vector), btree(importance) |
connections | Per-tenant connector credentials (AES-256) | btree(tenant_id) |
chat_sessions | Conversation history + SDK session mapping | btree(tenant_id, updated_at) |
Query layer
Chat
A Claude Agent SDK session with a tool surface —
search_knowledge, follow_edges, query_database, http_request, and more. Streams as SSE with per-token deltas, tool calls, and cost accounting.REST API
72+ endpoints in 10 modules. FastAPI auto-generates OpenAPI docs at
/docs (Swagger) and /redoc. Bearer token auth; API keys for programmatic access.Graph Explorer
React SPA that renders
graph_nodes and graph_edges via force-directed layout. Debug extraction, audit relationships, explore what Fabric has learned.Event-driven processing
Heavy work — sync, extraction, embedding, agent execution — runs in Celery workers. The API never blocks on long operations.- Sync tasks fire on Celery Beat schedules configured per connection.
- Extraction and embedding chain per item so they can be scaled and retried independently.
- Agent runs execute SDK sessions inside worker processes with session persistence on a workspace filesystem.
Observability
Langfuse traces every LLM call, embedding operation, and tool invocation. Per-query cost surfaces in the chat UI. Structured logs with
tenant_id + project_id context. Prometheus-compatible metrics at /metrics.Deployment
- Local / Docker Compose
- AWS ECS Fargate
How It Works
The engineering behind each layer.
Knowledge Graph
Typed edges, multi-hop traversal, SQL you can run directly.