Nova is a privacy-first, multi-tenant AI agent workspace built around a persistent terminal-style runtime.
The product includes a desktop-first workspace, a mobile-friendly conversation UI, dedicated settings for providers, capabilities, and managed connections, plus an execution details view for understanding what happened during a run.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
git clone https://github.com/AMairesse/Nova.git
cd Nova/docker
cp .env.example .env
docker compose up -dOpen http://localhost:8080.
Default credentials:
- Username:
admin - Password:
changeme
Optional services are enabled through COMPOSE_FILE in docker/.env.
Then configure your providers, capabilities/connections, and agents: README-agents.md.
- A terminal-first agent runtime with a very small model tool surface:
terminal(command: str)delegate_to_agent(...)ask_user(...)
- Built-in capabilities such as Browser, Memory, WebApp, and Date/Time available by default
- Configurable connections and backends only where they are actually needed
- Persistent thread-scoped files plus runtime mounts such as
/inbox,/history,/memory, and/webdav - User-scoped long-term memory stored as Markdown documents and searched via chunks/embeddings
- Email, CalDAV, WebDAV, web search, browsing, MCP, and custom API integrations
- Continuous discussion mode with day summaries and history search/get commands
- Live thread-scoped static web apps published from normal workspace files
- Provider-aware model configuration, metadata refresh, and active verification
- Execution details with a readable overview, timeline, and technical drill-down
- A responsive UI that remains usable on mobile as well as desktop
- Scheduled tasks, email polling, and maintenance flows
Nova agents work through a persistent terminal-style mental model:
- normal file operations (
ls,cat,find,tee,mv,rm, ...) - current-message inputs under
/inboxand earlier live-message attachments under/history - specialized command families (
mail,calendar,memory search,webapp,mcp,api, ...) - delegated sub-agents that exchange files through
/subagents/... - blocking clarifications through
ask_user
- Thread files are stored as
UserFile /memoryis a user-scoped virtual Markdown workspace backed by:MemoryDirectoryMemoryDocumentMemoryChunkMemoryChunkEmbedding
- Semantic lookup is done on chunks with
memory search
Nova supports:
- classic thread conversations
- one user-scoped continuous conversation with day segmentation, summaries, and recall
Continuous mode relies on stored messages, summaries, and embeddings.
Nova supports:
- built-in capabilities exposed through internal plugins
- backend-backed capabilities for search and Python, with deployment defaults when the matching deployment modules are enabled
- optional custom user backends for search
- MCP servers with optional managed OAuth
- custom API services defined through
APIToolOperation - optional deployment services such as SearXNG,
exec-runner, Ollama, and llama.cpp when enabled in Docker
Agents can publish live static apps from normal files:
- create/edit files in the workspace
- run
webapp expose <source_dir> - Nova serves the app under
/apps/<slug>/
In production, configure WEBAPP_PUBLIC_ORIGIN to serve these apps from a separate origin. Webapp URLs are capability-style slugs: anyone with the slug can open the published app, but the app is sandboxed away from the authenticated Nova origin.
Tenant-configured outbound integrations are subject to a shared egress policy. Private/internal targets are blocked by default unless an administrator explicitly allows them with NOVA_EGRESS_ALLOWLIST.
Local LLM and embeddings endpoints keep working with Nova's built-in local allowances: user-configured custom embeddings support localhost, 127.0.0.1, ::1, host.docker.internal, and docker.internal, while admin-configured system providers can also target explicit internal Docker Compose hostnames such as llamacpp-embeddings.
Nova exposes a minimal authenticated API:
GET /api/GET /api/ask/POST /api/ask/
POST /api/ask/ runs your default agent through the same runtime on an ephemeral thread, then returns only the final answer.
Authentication uses DRF token auth:
curl -H "Authorization: Token YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
--data '{"question":"Who are you and what can you do?"}' \
http://localhost:8080/api/ask/Nova
├─ docker/ # Docker stacks and runtime configuration
├─ nova/
│ ├─ api/ # REST API endpoints
│ ├─ continuous/ # Continuous-mode context, summaries, recall
│ ├─ models/ # One model per file
│ ├─ plugins/ # Internal plugin registry and builtin descriptors
│ ├─ providers/ # Provider adapters and capability logic
│ ├─ runtime/ # Nova runtime
│ ├─ tasks/ # Celery tasks and task templates
│ ├─ views/ # Django views
│ ├─ web/ # Search, browser, and download services
│ └─ webapp/ # Webapp publishing/serving
├─ user_settings/ # User configuration app
├─ plans/ # Current architecture and product notes
├─ README-agents.md # Agent setup guide
└─ README-dev.md # Development guide
- docker/README.md: Docker stacks and environment configuration
- README-agents.md: provider/capability/connection/agent setup
- README-dev.md: repository structure and runtime internals
- plans/react_terminal.md: runtime architecture
- plans/memory.md: long-term memory model
- plans/continuous_discussion.md: continuous mode behavior
- plans/task_engine.md: task execution model
Nova is released under the MIT License. See LICENSE.
- Port conflicts: ensure
HOST_PORT(default8080) is free - Stack mismatch: after changing
COMPOSE_FILE, rundocker compose up -d --remove-orphans - No superuser: ensure
DJANGO_SUPERUSER_*is set indocker/.env - Optional service missing in UI: check
COMPOSE_FILEand related env vars - Ollama connectivity: use
host.docker.internalon Docker Desktop or your host IP on Linux - LM Studio embeddings connectivity: use
host.docker.internalon Docker Desktop or your host IP on Linux for custom user endpoints; use the system embeddings provider for Docker Compose-only hostnames such asllamacpp-embeddings - Internal integration blocked: add an explicit admin entry to
NOVA_EGRESS_ALLOWLISTinstead of relying on user-provided private URLs







