Configuration
All configuration is loaded from .env via pydantic-settings (navi/config.py). The global settings object is imported everywhere as from navi.config import settings.
LLM
| Variable |
Type |
Default |
Description |
|
OLLAMA_HOST |
str |
http://localhost:11434 |
Ollama server URL (used when OLLAMA_BACKENDS_FILE is not set) |
|
OLLAMA_API_KEY |
str |
"" |
Ollama Cloud API key (used when OLLAMA_BACKENDS_FILE is not set) |
|
OLLAMA_DEFAULT_MODEL |
str |
gemma4:31b-cloud |
Default model (can be overridden per profile) |
|
OLLAMA_NUM_CTX |
int |
65536 |
Context window size in tokens |
|
OLLAMA_THINK |
bool |
true |
Enable extended reasoning (thinking) |
|
OLLAMA_BACKENDS_FILE |
str |
"" |
Path to JSON file with multi-server config (see below). When set, overrides OLLAMA_HOST/OLLAMA_API_KEY. |
|
OLLAMA_REQUEST_TIMEOUT |
int |
30 |
Seconds before Ollama request times out (affects fallback speed) |
|
EMBEDDING_OLLAMA_HOST |
str |
"" |
Ollama server for embedding model (falls back to OLLAMA_HOST if empty) |
|
EMBEDDING_OLLAMA_API_KEY |
str |
"" |
API key for embedding Ollama server |
|
EMBEDDING_MODEL |
str |
nomic-embed-text:latest |
Embedding model for memory vector search |
|
EMBEDDING_DIMENSIONS |
int |
768 |
Vector dimensionality for embeddings |
|
OPENAI_API_KEY |
str |
"" |
OpenAI API key (if using OpenAI backend) |
|
OPENAI_MODEL |
str |
"gpt-4" |
Default model for OpenAI backend |
|
OPENAI_BASE_URL |
str \ |
None |
None |
Custom base URL for OpenAI-compatible endpoints (e.g. vLLM, LM Studio) |
ANTHROPIC_API_KEY |
str |
"" |
Reserved — no Anthropic backend implemented yet |
|
For direct Ollama Cloud access without fallback: set OLLAMA_HOST=https://ollama.com and OLLAMA_API_KEY=<key>.
Web Search
| Variable |
Type |
Default |
Description |
BRAVE_SEARCH_API_KEY |
str |
"" |
Brave Search API key (free tier: 2000 req/month). Used when DuckDuckGo returns no results. |
SEARXNG_URL |
str |
"" |
Self-hosted SearXNG meta-search URL, e.g. http://localhost:8888 |
Multi-server fallback (OLLAMA_BACKENDS_FILE)
When OLLAMA_BACKENDS_FILE points to a JSON file, Navi uses FallbackOllamaBackend instead of the single-server backend. The file contains an ordered list of servers:
[
{ "host": "https://ollama.com", "api_key": "ollama_..." },
{ "host": "http://localhost:11434" }
]
Each profile's model field is also a priority list (see docs/profiles.md). The fallback algorithm tries all combinations in a nested loop:
for each server (in order):
for each model (in order):
try → success: use this server+model
LLMConnectionError → blacklist server, skip remaining models, try next server
LLMModelNotFoundError → blacklist (server, model) pair, try next model
raise if all exhausted
Blacklisting is in-memory (module-level sets in navi/llm/fallback.py) and persists until server restart. A dead server or missing model is only probed once per process lifetime, avoiding latency spikes from repeated retries.
For streaming calls, the first chunk is awaited before yielding, so connection/model errors are caught before any output is sent to the client — clean retry with no partial response.
LLM Timeouts
| Variable |
Type |
Default |
Description |
LLM_COMPLETE_TIMEOUT |
int |
120 |
Seconds before a non-streaming complete() call times out |
LLM_STREAM_FIRST_CHUNK_TIMEOUT |
int |
180 |
Seconds to wait for the first token of a streaming call (prefill phase) |
LLM_STREAM_CHUNK_TIMEOUT |
int |
60 |
Max seconds between consecutive tokens in a streaming call |
Large contexts can take 60–90 s to prefill; LLM_STREAM_FIRST_CHUNK_TIMEOUT=180 is a safe upper bound for local Ollama. Reduce if using a fast cloud endpoint.
Security / Sandboxing
| Variable |
Type |
Default |
Description |
FS_ALLOWED_PATHS |
str |
"*" |
Comma-separated paths the filesystem tool can access. "*" = no restriction |
TERMINAL_ALLOWED_COMMANDS |
str |
"*" |
Comma-separated allowed executables for terminal. "*" = allow all |
SSH_HOSTS_FILE |
str |
ssh_hosts.json |
Path to JSON file with named SSH connections |
settings.fs_allowed_paths_list and settings.terminal_allowed_commands_list are computed properties that parse the comma-separated strings into lists.
| Variable |
Type |
Default |
Description |
TERMINAL_USER_ALLOWED_COMMANDS |
str |
long allowlist |
Comma-separated allowed executables for non-admin users. Admin bypasses this restriction. |
settings.terminal_user_allowed_commands_list — computed property parsed from the comma-separated string.
Database
| Variable |
Type |
Default |
Description |
DATABASE_URL |
str |
"" |
PostgreSQL URL (postgresql://user:pass@host:port/db). Required — Navi requires PostgreSQL 15+ with pgvector extension. |
Logging
| Variable |
Type |
Default |
Description |
LOG_LEVEL |
str |
INFO |
Python logging level (DEBUG, INFO, WARNING, ERROR) |
| Variable |
Type |
Default |
Description |
TOOLS_DIR |
str |
tools |
Directory for user-defined tools (auto-discovered at startup) |
CONTEXT_PROVIDERS_DIR |
str |
context_providers |
Directory for user-defined context providers (auto-discovered at startup) |
Session files
| Variable |
Type |
Default |
Description |
SESSION_FILES_DIR |
str |
session_files |
Directory for uploaded session files |
SESSION_FILES_MAX_SIZE_MB |
int |
200 |
Max upload size per file in megabytes |
SHARE_FILE_MAX_SIZE_MB |
int |
1024 |
Max file size share_file may copy into session files, in megabytes |
SESSION_MESSAGES_WINDOW |
int |
1000 |
Max hot (non-archived) messages per session |
WS_REPLAY_BUFFER_SIZE |
int |
500 |
Max events retained per WebSocket turn for reconnect replay |
Public URL
| Variable |
Type |
Default |
Description |
PUBLIC_URL |
str |
http://localhost:8000 |
Base URL used by share_file to build download links. Set this when behind a reverse proxy. |
Context compression
| Variable |
Type |
Default |
Description |
CONTEXT_COMPRESSION_ENABLED |
bool |
true |
Enable/disable automatic context compression |
CONTEXT_COMPRESSION_THRESHOLD |
float |
0.70 |
Trigger compression at this fraction of OLLAMA_NUM_CTX |
CONTEXT_KEEP_RECENT |
int |
8 |
Number of recent conversation turns to keep verbatim |
CONTEXT_SUMMARY_TEMPERATURE |
float |
0.3 |
Temperature for the summarization LLM call |
CONTEXT_SUMMARY_MAX_TOKENS |
int |
3000 |
Max output tokens for the summary LLM call |
OUTPUT_RESERVE_TOKENS |
int |
2048 |
Headroom reserved for model response in context size checks |
Gmail
| Variable |
Type |
Default |
Description |
GMAIL_ADDRESS |
str |
"" |
Gmail address for the email_manager tool (IMAP/SMTP with App Password) |
GMAIL_APP_PASSWORD |
str |
"" |
Gmail App Password (not the account password — generate at myaccount.google.com) |
Authentication (gnexus-auth OAuth)
| Variable |
Type |
Default |
Description |
GNAUTH_BASE_URL |
str |
http://gnexus-auth.local |
gnexus-auth server base URL |
GNAUTH_CLIENT_ID |
str |
"" |
OAuth client ID |
GNAUTH_CLIENT_SECRET |
str |
"" |
OAuth client secret |
GNAUTH_REDIRECT_URI |
str |
http://localhost:8000/auth/callback |
Must match redirect URI registered in gnexus-auth |
GNAUTH_ADMIN_ROLE_SLUG |
str |
navi_admin |
Role slug that maps to Navi admin role |
GNAUTH_USER_ROLE_SLUG |
str |
navi_user |
Role slug that maps to Navi user role |
GNAUTH_PROFILE_PATH |
str |
/account/profile |
Path appended to gnauth_base_url for profile links |
NAVI_AUTH_ENCRYPTION_KEY |
str |
"" |
Fernet key (base64, 32 bytes). Generate once with python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())". Never change after first launch. |
NAVI_AUTH_COOKIE_NAME |
str |
navi_auth_session |
Session cookie name |
NAVI_AUTH_COOKIE_SECURE |
bool |
False |
Set True behind HTTPS |
NAVI_AUTH_COOKIE_SAMESITE |
str |
lax |
SameSite policy |
NAVI_AUTH_COOKIE_MAX_AGE_DAYS |
int |
30 |
Cookie lifetime |
Full auth setup guide: docs/auth.md.
Persona
| Variable |
Type |
Default |
Description |
NAVI_PERSONA |
str |
"" |
Global personality prompt prepended to every profile's system prompt |
NAVI_PERSONA_FILE |
str |
"" |
Path to a .txt file containing the persona (preferred over inline NAVI_PERSONA) |
Recommended: use NAVI_PERSONA_FILE=persona.txt rather than inlining the persona in .env, because multi-line values don't parse reliably in .env files.
The _load_persona_from_file validator reads the file on startup if NAVI_PERSONA is empty and NAVI_PERSONA_FILE is set.
Example .env
# LLM — Ollama (primary)
OLLAMA_HOST=http://localhost:11434
OLLAMA_API_KEY=
OLLAMA_DEFAULT_MODEL=gemma4:31b-cloud
OLLAMA_NUM_CTX=65536
OLLAMA_THINK=true
OLLAMA_REQUEST_TIMEOUT=30
# Multi-server fallback mode (overrides OLLAMA_HOST/API_KEY):
# OLLAMA_BACKENDS_FILE=ollama_backends.json
# LLM — OpenAI (optional)
# OPENAI_API_KEY=sk-...
# OPENAI_MODEL=gpt-4
# OPENAI_BASE_URL=https://api.openai.com/v1
# Database (PostgreSQL 15+ with pgvector)
DATABASE_URL=postgresql://user:pass@localhost:5432/navidb
# Security / sandboxing
FS_ALLOWED_PATHS=*
TERMINAL_ALLOWED_COMMANDS=*
# Misc
LOG_LEVEL=INFO
TOOLS_DIR=tools
SHARE_FILE_MAX_SIZE_MB=1024
SESSION_MESSAGES_WINDOW=1000
WS_REPLAY_BUFFER_SIZE=500
# Context compression
CONTEXT_COMPRESSION_ENABLED=true
CONTEXT_COMPRESSION_THRESHOLD=0.70
CONTEXT_KEEP_RECENT=8
# Persona
NAVI_PERSONA_FILE=persona.txt