- Postgres, pgvector
- Memories, their versions, entities, relationships, evidence, conflicts, Space membership and the vectors are one database. A memory and its embedding in two systems with no transaction between them drift apart, and nothing notices until an answer cites something that no longer says that.
- Redis
- The job queue and the shared rate-limit counters. Without a shared store the configured limit is silently multiplied by however many processes are running, and nobody can say what the real one is.
- Eight job kinds
- Ingest, OCR, extract, consolidate, embed, event, maintenance and video — each with its own timeout and its own concurrency, because what a job contends for differs per kind and is invisible from the queue. A kind is added when a handler exists to run it, never before; video is the newest, and the one whose answer resumes a waiting plan.
- Several model providers
- No call site names a vendor. Every call asks the router for a capability — chat, tool calling, reasoning, extraction, vision, transcription — and one map says which models serve each, in what order: Groq leads text and tool rounds with NVIDIA, Cloudflare and OpenRouter rotated beside it, NVIDIA leads reasoning, and OpenAI is held back as the paid last resort. Calls rotate across accounts within a vendor, and the fallback reaches every vendor in the chain before the paid tier, so one vendor being unavailable is a slower answer rather than an outage. Retrieval intent is classified deterministically; the planner that turns a job into steps is a reasoning call, and a planner that fails hands the message to the ordinary loop rather than to nobody.
- Blob storage
- Original files. References travel through the queue as keys and never as signed URLs, because a URL with a grant baked into it outlives the grant once it is sitting in a dead-letter row.