Initial commit: Agentic OS troubleshooting platform
Self-hosted, Docker-based agentic troubleshooting platform: FastAPI backend + LangGraph agent, Next.js UI, tiered LLM routing (local Ollama -> Gemini -> DeepSeek -> OpenRouter), MCP server manager, encrypted device credentials, RBAC, audit log, project-memory + Obsidian integrations, and editable troubleshooting decision rules tuned for the GeneseasX vessel stack. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
194
.env.example
Normal file
194
.env.example
Normal file
@@ -0,0 +1,194 @@
|
||||
# ======================================================================
|
||||
# Agentic OS - environment configuration
|
||||
# Copy to `.env` and fill in real values. NEVER commit the real .env.
|
||||
# ======================================================================
|
||||
|
||||
# ---- Core security ----------------------------------------------------
|
||||
# JWT signing secret (generate: openssl rand -hex 32)
|
||||
SECRET_KEY=change-me-openssl-rand-hex-32
|
||||
# Fernet key for encrypting device credentials at rest
|
||||
# generate: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
||||
CREDENTIAL_ENCRYPTION_KEY=change-me-fernet-key
|
||||
|
||||
# First admin user, created automatically on first boot
|
||||
FIRST_ADMIN_EMAIL=admin@agentic.local
|
||||
FIRST_ADMIN_PASSWORD=change-me-strong-password
|
||||
|
||||
# ---- Database / cache -------------------------------------------------
|
||||
POSTGRES_USER=agentic
|
||||
POSTGRES_PASSWORD=agentic
|
||||
POSTGRES_DB=agentic_os
|
||||
# Used by backend + worker (inside docker network)
|
||||
DATABASE_URL=postgresql+asyncpg://agentic:agentic@postgres:5432/agentic_os
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
|
||||
# ---- CORS -------------------------------------------------------------
|
||||
# Comma-separated browser origins allowed to call the API. Do NOT use "*"
|
||||
# (invalid with credentials). Add your deployed UI origin(s) here.
|
||||
CORS_ALLOW_ORIGINS=http://localhost:3000
|
||||
|
||||
# ---- LLM routing (LiteLLM gateway) -----------------------------------
|
||||
# LiteLLM listens here inside the docker network
|
||||
LITELLM_BASE_URL=http://litellm:4000
|
||||
LITELLM_MASTER_KEY=sk-litellm-master-change-me
|
||||
|
||||
# Ollama runs on the HOST (Apple Silicon Metal GPU is not available inside Docker)
|
||||
OLLAMA_BASE_URL=http://host.docker.internal:11434
|
||||
# Local triage model (must support tool/function calling)
|
||||
LOCAL_TRIAGE_MODEL=qwen2.5:7b-instruct
|
||||
|
||||
# ---- Cloud LLM API keys ----------------------------------------------
|
||||
# Google AI Studio: https://aistudio.google.com/apikey
|
||||
GEMINI_API_KEY=
|
||||
OPENROUTER_API_KEY=
|
||||
# Optional: a provisioning/management key unlocks /api/v1/credits totals
|
||||
OPENROUTER_PROVISIONING_KEY=
|
||||
DEEPSEEK_API_KEY=
|
||||
|
||||
# Default cloud model used for deep reasoning (legacy; tier routing uses LLM_* vars below)
|
||||
CLOUD_REASONING_MODEL=openrouter/deepseek/deepseek-chat
|
||||
|
||||
# ---- Tiered LLM routing (local → gemini → deepseek → openrouter) ----
|
||||
# Local Ollama model (triage + first reasoning attempt)
|
||||
LLM_LOCAL_MODEL=qwen2.5:7b-instruct
|
||||
# Economy tier — capable but inexpensive
|
||||
LLM_ECONOMY_GEMINI=gemini-2.5-flash
|
||||
LLM_ECONOMY_DEEPSEEK=deepseek-chat
|
||||
LLM_ECONOMY_OPENROUTER=deepseek/deepseek-chat
|
||||
# Premium tier — strongest models for critical/complex cases
|
||||
LLM_PREMIUM_GEMINI=gemini-2.5-pro
|
||||
LLM_PREMIUM_DEEPSEEK=deepseek-reasoner
|
||||
LLM_PREMIUM_OPENROUTER=anthropic/claude-3.5-sonnet
|
||||
# Auto-escalate from local → economy → premium when needed
|
||||
LLM_AUTO_ESCALATE=true
|
||||
# Cost cap: local | economy | premium
|
||||
LLM_MAX_TIER=premium
|
||||
# Cloud provider cascade within each tier (requires matching API key)
|
||||
LLM_CLOUD_PROVIDER_ORDER=gemini,deepseek,openrouter
|
||||
|
||||
# ---- MCP self-development (agent patches MCP source on failures) ------
|
||||
MCP_DEVELOPMENT_ENABLED=true
|
||||
# Push to Gitea automatically after patch (false = approval required on task)
|
||||
MCP_DEV_AUTO_PUSH=false
|
||||
MCP_DEV_MODEL_TIER=premium
|
||||
|
||||
# ---- Worker -----------------------------------------------------------
|
||||
# Max tasks running in parallel (1 = sequential; 2+ shares MCP sessions — avoid same vessel)
|
||||
WORKER_MAX_CONCURRENT_TASKS=1
|
||||
|
||||
# ---- Balance polling --------------------------------------------------
|
||||
BALANCE_POLL_INTERVAL_SECONDS=900
|
||||
# Block new agent runs if remaining balance (USD) is below this
|
||||
MIN_BALANCE_USD=1.0
|
||||
|
||||
# ---- Gitea (for MCP repos + Obsidian vault) --------------------------
|
||||
# Use an address reachable FROM Docker containers (internal LAN IP, not public DNS/VPN-only hostnames)
|
||||
GITEA_BASE_URL=http://10.77.30.250:3000
|
||||
GITEA_USERNAME=nearxos
|
||||
GITEA_TOKEN=
|
||||
# Comma-separated list of MCP servers to run as sidecars.
|
||||
# Names matching a folder in ./mcp-servers are launched locally (no clone);
|
||||
# others are cloned from Gitea by repo name.
|
||||
MCP_REPOS=ssh-generic-mcp,fortigate-mcp,fortiswitch-mcp,pfsense-mcp,proxmox-mcp,asterisk-mcp,vessel-orchestrator-mcp
|
||||
# Folder (inside the container) holding locally-shipped MCP servers
|
||||
MCP_LOCAL_DIR=/app/mcp-servers
|
||||
|
||||
# Allow write/config-changing tools on the new MCP servers (default read-only)
|
||||
SSH_ALLOW_WRITES=false
|
||||
FORTIGATE_ALLOW_WRITES=false
|
||||
FORTISWITCH_ALLOW_WRITES=false
|
||||
|
||||
# ---- Obsidian vault ---------------------------------------------------
|
||||
OBSIDIAN_VAULT_REPO=homelab-vault
|
||||
OBSIDIAN_TASKS_FOLDER=agentic-os-tasks
|
||||
# Auto commit+push task notes back to Gitea
|
||||
OBSIDIAN_AUTO_PUSH=true
|
||||
|
||||
# ---- Project memory MCP (HTTP, Streamable) ---------------------------
|
||||
MEMORY_MCP_URL=http://10.77.30.184:8787/mcp
|
||||
MEMORY_MCP_TOKEN=
|
||||
MEMORY_TASK_PROJECT_ID=agentic-os-task
|
||||
# Comma-separated project IDs searched at task start for related past issues
|
||||
MEMORY_SEARCH_PROJECTS=agentic-os-task,agentic-os,global
|
||||
# Obsidian folders (under vault root) searched alongside OBSIDIAN_TASKS_FOLDER
|
||||
OBSIDIAN_SEARCH_PATHS=agentic-os-tasks,Meta/Agent-Memory
|
||||
|
||||
# Troubleshooting decision rules (YAML)
|
||||
TROUBLESHOOTING_RULES_PATH=/app/rules/troubleshooting.yaml
|
||||
|
||||
# ---- Frontend ---------------------------------------------------------
|
||||
# Public URL the browser uses to reach the backend API
|
||||
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
|
||||
|
||||
# ---- Device default credentials (vessel inventory) -------------------
|
||||
# Applied automatically when creating vessel devices unless overridden in the UI.
|
||||
# Secrets are stored encrypted in the DB; values here never appear in the API.
|
||||
|
||||
# Shared SSH fallback (proxmox, docker_vm, asterisk, debian_host, tplink)
|
||||
DEVICE_SSH_USERNAME=root
|
||||
DEVICE_SSH_PASSWORD=
|
||||
|
||||
# Shared API-key fallback (pfsense, fortigate when per-device key not set)
|
||||
DEVICE_API_KEY=
|
||||
|
||||
# Per-device overrides (catalog_key → env prefix)
|
||||
# Proxmox — REST API (proxmox-mcp, tried first)
|
||||
# Blank DEVICE_PROXMOX_API_URL → auto https://<vessel-public-ip>:8006
|
||||
# Quote values containing ! (e.g. root@pam!mcp)
|
||||
# DEVICE_PROXMOX_API_URL=
|
||||
DEVICE_PROXMOX_TOKEN_ID=
|
||||
DEVICE_PROXMOX_TOKEN_SECRET=
|
||||
DEVICE_PROXMOX_VERIFY_SSL=false
|
||||
# Passed to proxmox-mcp subprocess — set false for self-signed Proxmox VE certificates
|
||||
PROXMOX_VERIFY_SSL=false
|
||||
# Proxmox — SSH fallback (ssh-generic-mcp)
|
||||
DEVICE_PROXMOX_PORT=22
|
||||
DEVICE_PROXMOX_USERNAME=
|
||||
DEVICE_PROXMOX_PASSWORD=
|
||||
|
||||
# pfSense — REST API
|
||||
DEVICE_PFSENSE_PORT=40443
|
||||
DEVICE_PFSENSE_API_KEY=
|
||||
|
||||
# GeneseasX Docker VM — SSH
|
||||
DEVICE_DOCKER_VM_PORT=22
|
||||
DEVICE_DOCKER_VM_USERNAME=
|
||||
DEVICE_DOCKER_VM_PASSWORD=
|
||||
|
||||
# Asterisk — SSH (often a dedicated forwarded port)
|
||||
# Asterisk — GeneseasX (docker voip on Docker VM, SSH port 5022)
|
||||
DEVICE_ASTERISK_GENESEASX_PORT=5022
|
||||
DEVICE_ASTERISK_GENESEASX_USERNAME=
|
||||
DEVICE_ASTERISK_GENESEASX_PASSWORD=
|
||||
DEVICE_ASTERISK_GENESEASX_CONTAINER=voip
|
||||
|
||||
# Asterisk — TMGeneseas / satbox (native on Debian 9/10, SSH port 22)
|
||||
DEVICE_ASTERISK_SATBOX_PORT=22
|
||||
DEVICE_ASTERISK_SATBOX_USERNAME=
|
||||
DEVICE_ASTERISK_SATBOX_PASSWORD=
|
||||
|
||||
# Legacy alias (same as GeneseasX)
|
||||
DEVICE_ASTERISK_PORT=5022
|
||||
DEVICE_ASTERISK_CONTAINER=voip
|
||||
DEVICE_ASTERISK_USERNAME=
|
||||
DEVICE_ASTERISK_PASSWORD=
|
||||
|
||||
# Standalone Debian — SSH
|
||||
DEVICE_DEBIAN_HOST_PORT=22
|
||||
DEVICE_DEBIAN_HOST_USERNAME=
|
||||
DEVICE_DEBIAN_HOST_PASSWORD=
|
||||
|
||||
# FortiGate — REST API
|
||||
DEVICE_FORTIGATE_PORT=443
|
||||
DEVICE_FORTIGATE_USERNAME=
|
||||
DEVICE_FORTIGATE_API_KEY=
|
||||
|
||||
# FortiSwitch — REST API (username + password)
|
||||
DEVICE_FORTISWITCH_PORT=443
|
||||
DEVICE_FORTISWITCH_USERNAME=admin
|
||||
DEVICE_FORTISWITCH_PASSWORD=
|
||||
|
||||
# TP-Link — SSH
|
||||
DEVICE_TPLINK_PORT=22
|
||||
DEVICE_TPLINK_USERNAME=
|
||||
DEVICE_TPLINK_PASSWORD=
|
||||
Reference in New Issue
Block a user