Skip to content

Architecture

Nova runs as a multi-service Docker Compose stack. Each service has a single responsibility and communicates over HTTP.

ServicePortRole
orchestrator8000Agent lifecycle, task queue, pipeline execution, MCP tool dispatch, DB migrations
llm-gateway8001Multi-provider model routing via LiteLLM (Anthropic, OpenAI, Ollama, Groq, Gemini, Cerebras, OpenRouter, GitHub, Claude/ChatGPT subscription providers)
memory-service8002Embedding + hybrid semantic/keyword retrieval via pgvector
chat-api8080WebSocket streaming bridge for external clients
dashboard3000 / 5173React admin UI (nginx in production, Vite dev server in development)
postgres5432pgvector-enabled PostgreSQL 16
redis6379State, task queue (BRPOP), rate limiting, session memory
recovery8888Backup/restore, factory reset, service management, inference backend lifecycle. Depends on postgres and Redis (db 7).
chat-bridge8090Multi-platform chat integration (Telegram, Slack). Opt-in via bridges profile.
cortex8100Autonomous brain: thinking loop, goals, drives, budget tracking
intel-worker8110AI ecosystem feed poller (RSS, Reddit JSON, GitHub trending/releases). Health-only HTTP server; pushes to Redis queues.
knowledge-worker8120Autonomous personal-knowledge crawler (LLM-guided web crawl, GitHub API). Opt-in via knowledge profile.
voice-service8130STT/TTS provider proxy (OpenAI Whisper, Deepgram, ElevenLabs). Opt-in via voice profile.
ollama11434Bundled local model serving (only active when NOVA_INFERENCE_MODE=hybrid or local-only).

All communication between services is HTTP. Here’s who calls who:

dashboard ──proxy──▶ orchestrator (/api)
──proxy──▶ llm-gateway (/v1)
──proxy──▶ recovery (/recovery-api)
──proxy──▶ cortex (/cortex-api)
──proxy──▶ voice-service (/voice-api)
chat-api ──────────▶ orchestrator (streaming endpoint)
chat-bridge ───────▶ orchestrator (streaming endpoint, agent API)
───────▶ redis (session mapping, db 4)
orchestrator ──────▶ llm-gateway (/complete, /stream, /embed)
──────▶ memory-service (/api/v1/memories/*)
──────▶ redis (task queue, state)
recovery ──────────▶ postgres (backup/restore)
──────────▶ Docker API (service management, inference containers)
──────────▶ redis (system state db 7, reads config db 1)

The dashboard depends only on the recovery service at startup. It shows a startup screen while other services come online, so users always have visibility into system state.

LayerTechnology
BackendPython, FastAPI, asyncpg, asyncio
FrontendVite, React, TypeScript, Tailwind CSS, TanStack Query
DatabasePostgreSQL 16 + pgvector
QueueRedis (BRPOP task dispatch)
ContainersDocker Compose with hot reload (watch mode)
Model routingLiteLLM (multi-provider abstraction)

The nova-contracts/ package defines the API contract between services using Pydantic models (chat, LLM, memory, orchestrator). Any service satisfying these models is a drop-in replacement. This is a Pydantic-only package with no runtime dependencies on any service.

Nova uses two different database access patterns:

ServiceAccess layerReason
orchestratorRaw asyncpg queriesPerformance-critical task queue operations, no ORM overhead
memory-serviceSQLAlchemy asyncComplex vector queries benefit from ORM expressiveness

Migrations run automatically at orchestrator startup from orchestrator/app/migrations/*.sql. These are pure versioned SQL files that run idempotently — no Alembic.

All tables use UUID primary keys, TIMESTAMPTZ for timestamps, and JSONB for flexible fields.

Each service uses a dedicated Redis database to avoid key collisions:

Redis DBService
0memory-service
1llm-gateway
2orchestrator
3chat-api
4chat-bridge
5cortex
6intel-worker
7recovery
8knowledge-worker
9voice-service
  • Raw JSON responses (no { data: ... } wrapper)
  • Admin auth: X-Admin-Secret header
  • API key auth: Authorization: Bearer sk-nova-<hash> or X-API-Key
  • Streaming: Server-Sent Events (SSE) with JSON lines
  • Auto-generated API docs at /docs on each FastAPI service