Copy .env.example to .env and edit it. This is the complete file for v0.7.5; lines starting with # are optional examples.
Copy this file to .env and add your own Gemini API key. RagLeap Core is bring-your-own-key only — there is no system-provided key. Get a free Gemini API key at: https://aistudio.google.com/apikey
GEMINI_API_KEY=your-gemini-api-key-here
GEMINI_EMBEDDING_MODEL=models/gemini-embedding-001
EMBEDDING_DIMENSIONS=3072
GEMINI_CHAT_MODEL=gemini-3.5-flash
Knowledge Graph (Neo4j) — optional, degrades gracefully if unset
NEO4J_URI=bolt://neo4j:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=
Comma-separated domain-specific terms to boost entity extraction, e.g. DOMAIN_TERMS=API,SDK,RAG
DOMAIN_TERMS=
Language Detection (langdetect) — optional, defaults shown below
DEFAULT_LANGUAGE=en
LANGUAGE_DETECTION_CONFIDENCE_THRESHOLD=0.7
Comma-separated list of language codes to restrict detection to (blank = unrestricted)
LANGUAGE_DETECTION_SUPPORTED_LANGUAGES=
Integrations — Fernet key for encrypting stored connection strings/API keys. Generate one with:
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
ADDON_ENCRYPTION_KEY=
Provider fallback chain — comma-separated provider names to try, in order, if LLM_PROVIDER fails (rate limit, outage, bad key). Each needs its own API key configured normally (e.g. ANTHROPIC_API_KEY). Optional — leave blank to disable fallback entirely.
LLM_FALLBACK_PROVIDERS=
Generation output length and defaults
MAX_OUTPUT_TOKENS=1024
DEFAULT_TEMPERATURE=0.3
Token/context optimization — retrieved chunks are trimmed (lowest- ranked dropped first) once their combined character count exceeds this budget, before being sent to the LLM. ~4 chars/token is a rough English-text approximation, not an exact tokenizer count. Set to 0 to disable trimming entirely.
MAX_CONTEXT_CHARS=12000
Outbound actions (autonomy gate; nothing sends unless configured)
Webhook targets are NAMES the AI can pick, never raw URLs. https only.
# WEBHOOK_TARGETS=n8n=https://your-n8n.example.com/webhook/abc,crm=https://crm.example.com/hook
# SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
Email: recipients must be listed (addresses or @domain). Empty = nothing sends.
# SMTP_HOST=smtp.gmail.com
# SMTP_PORT=587
# [email protected]
# SMTP_PASSWORD=app-password
# [email protected]
# [email protected],@yourcompany.com
Sensitive-domain roles created at runtime (PATCH /employees/{role})
A runtime role whose name, display name or skill tags contain a marker word (legal, medical, tax, immigration, insurance, compliance, ...) is treated as sensitive: forced semi/off autonomy, reasoning mode and the grounding check. Built-in sensitive roles can never be exempted.
# SENSITIVE_ROLES_EXTRA=my_custom_role,another_role
# SENSITIVE_ROLES_REVIEWED_SAFE=tax_reminder_bot
Token budgets (all off by default; 0 or unset = unlimited; UTC days/months)
Every LLM call is recorded in the llm_usage table; providers that report no token counts (e.g. Ollama) are ESTIMATED at ~4 characters per token. At a cap, answers return a short "usage limit reached" message without calling the provider.
# BUDGET_DAILY_TOKENS=200000
# BUDGET_MONTHLY_TOKENS=3000000
# BUDGET_ROLE_DAILY_TOKENS=50000
# BUDGET_ROLE_MONTHLY_TOKENS=800000
# BUDGET_ROLE_DAILY_OVERRIDES=support=100000,legal_intake=20000
# BUDGET_ROLE_MONTHLY_OVERRIDES=
# USAGE_LEDGER=off
Docker Compose security defaults
Postgres password for the db, app, voice and worker containers. It only applies when the database volume is first created; to change an existing database also run ALTER USER ragleap WITH PASSWORD '...'. Use letters and digits only (it goes into a URL).
# POSTGRES_PASSWORD=
The API is published on 127.0.0.1 by default. Use 0.0.0.0 only behind a firewall or reverse proxy that adds authentication: the API has no login of its own yet.
# APP_BIND=127.0.0.1
Webhook and approval hardening
Telegram: set a secret and register the SAME value as secret_token when calling setWebhook. Without it, webhook requests are now rejected (403).
# TELEGRAM_WEBHOOK_SECRET=
WhatsApp (Twilio): requests without a valid X-Twilio-Signature are rejected (needs TWILIO_AUTH_TOKEN). Local testing only - accept unsigned webhook requests (logs a warning each time):
# TELEGRAM_ALLOW_UNSIGNED=true
# WHATSAPP_ALLOW_UNSIGNED=true
YES/NO approvals are accepted ONLY from the configured owner: the sender must match approval_channel + approval_target set via POST /autonomy.
Optional API-key auth for core/api.py
Unset by default: the API has NO authentication (fine for 127.0.0.1-only access, dangerous if this port is ever reachable beyond localhost). When set, every endpoint except /health and /webhook/* (which verify platform signatures themselves) requires header: X-API-Key: <this value>
# RAGLEAP_API_KEY=