Spaces:
Paused
Paused
| # ┌─────────────────────────────────────────────────────────────────────────────┐ | |
| # │ OmniRoute — .env Contract │ | |
| # │ This file documents EVERY environment variable read by the runtime. │ | |
| # │ Copy to .env and adjust values. Lines starting with # are commented out │ | |
| # │ (optional / off-by-default). Uncomment only what you need. │ | |
| # │ Reference: docs/ENVIRONMENT.md for full details and usage scenarios. │ | |
| # └─────────────────────────────────────────────────────────────────────────────┘ | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 1. REQUIRED SECRETS — Must be set before first run! | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # These secrets are critical for security. Generate strong, unique values. | |
| # JWT signing key for dashboard session tokens. | |
| # Used by: src/lib/auth — signs/verifies all authenticated session cookies. | |
| # Generate: openssl rand -base64 48 | |
| JWT_SECRET= | |
| # Encryption key for API keys stored in the database. | |
| # Used by: src/lib/db/apiKeys.ts — encrypts API key values at rest in SQLite. | |
| # Generate: openssl rand -hex 32 | |
| API_KEY_SECRET= | |
| # Initial admin login password — CHANGE THIS before first use! | |
| # Used by: bootstrap only — sets the initial dashboard password on first boot. | |
| # After first login you can change it from Dashboard → Settings → Security. | |
| # Default: CHANGEME (insecure, for local dev only) | |
| INITIAL_PASSWORD=CHANGEME | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 2. STORAGE & DATABASE | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # OmniRoute uses SQLite for all persistence. These variables control where | |
| # data lives, encryption, and cleanup policies. | |
| # Base directory for all persistent data (SQLite DB, logs, backups). | |
| # Used by: src/lib/db/core.ts — resolves the SQLite database file path. | |
| # Default: ~/.omniroute/ | Override for Docker or custom installations. | |
| # DATA_DIR=/var/lib/omniroute | |
| # Encryption key for SQLite database encryption at rest. | |
| # Used by: src/lib/db/encryption.ts — encrypts the entire SQLite database. | |
| # Generate: openssl rand -hex 32 | Leave empty to disable DB encryption. | |
| STORAGE_ENCRYPTION_KEY= | |
| # Version tag for the encryption key — allows future key rotation. | |
| # Used by: scripts/bootstrap-env.mjs, electron/main.js — persists key version. | |
| # Default: v1 | Increment when rotating STORAGE_ENCRYPTION_KEY. | |
| STORAGE_ENCRYPTION_KEY_VERSION=v1 | |
| # Automatic SQLite backup on startup. | |
| # Used by: src/lib/db/backup.ts — creates a timestamped backup before migrations. | |
| # Default: false (backups enabled) | Set true to skip backup on every restart. | |
| DISABLE_SQLITE_AUTO_BACKUP=false | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 3. NETWORK & PORTS | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # OmniRoute can run on a single port (default) or split Dashboard/API ports. | |
| # Canonical port for both Dashboard UI and API (single-port mode). | |
| # Used by: src/lib/runtime/ports.ts — base port for the Next.js server. | |
| # Default: 20128 | |
| PORT=20128 | |
| # Split-port mode: serve Dashboard and API on separate ports for network isolation. | |
| # Used by: src/lib/runtime/ports.ts — overrides PORT for each service. | |
| # API_PORT=20129 | |
| # API_HOST=0.0.0.0 | |
| # DASHBOARD_PORT=20128 | |
| # Use Turbopack in local dev. Next 16.2.4 can fail to compile next/font/google | |
| # through the custom dev runner without this on Windows. | |
| OMNIROUTE_USE_TURBOPACK=1 | |
| # Docker production port mappings (docker-compose.prod.yml only). | |
| # These set the HOST-side published ports. Container ports use PORT/API_PORT. | |
| # PROD_DASHBOARD_PORT=20130 | |
| # PROD_API_PORT=20131 | |
| # Runtime override used by Electron and wrapped environments. | |
| # OMNIROUTE_PORT takes precedence over PORT when running inside wrappers. | |
| # Used by: src/lib/runtime/ports.ts — preserves canonical port in Electron. | |
| # OMNIROUTE_PORT=20128 | |
| # Environment mode — affects Next.js behavior, logging verbosity, and caching. | |
| # Values: production | development | Default: production | |
| NODE_ENV=production | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 4. SECURITY & AUTHENTICATION | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Salt for generating unique machine IDs (fingerprint diversification). | |
| # Used by: src/lib/auth — combined with hardware identifiers for machine-id hash. | |
| # Default: endpoint-proxy-salt | Change per-deployment for isolation. | |
| MACHINE_ID_SALT=endpoint-proxy-salt | |
| # Set true when running behind HTTPS (reverse proxy with TLS termination). | |
| # Used by: src/lib/auth — sets the Secure flag on session cookies. | |
| # Default: false | MUST be true in any non-localhost deployment. | |
| AUTH_COOKIE_SECURE=false | |
| # Require an API key for all /v1/* proxy endpoints. | |
| # Used by: API middleware — rejects unauthenticated requests to the proxy API. | |
| # Default: false | Set true for multi-user/public deployments. | |
| REQUIRE_API_KEY=false | |
| # Allow revealing full API key values in the Dashboard UI. | |
| # Used by: Dashboard providers page — controls show/hide of key values. | |
| # Default: false | Security risk if enabled on shared instances. | |
| ALLOW_API_KEY_REVEAL=false | |
| # Shared secret for the internal Codex Responses WebSocket bridge. | |
| # Used by: src/app/api/internal/codex-responses-ws/route.ts — authenticates | |
| # bridge requests between the Electron/browser WS relay and OmniRoute. | |
| # ⚠️ REQUIRED for production — if unset, all WS bridge requests are rejected. | |
| # Generate: openssl rand -base64 32 | |
| # OMNIROUTE_WS_BRIDGE_SECRET= | |
| # Comma-separated API key IDs that skip request logging (GDPR/compliance). | |
| # Used by: src/lib/compliance/index.ts — suppresses logs for specific keys. | |
| # NO_LOG_API_KEY_IDS=key_abc123,key_def456 | |
| # Maximum request body size in bytes (rejects larger payloads). | |
| # Used by: src/shared/middleware/bodySizeGuard.ts — prevents oversized uploads. | |
| # Default: 10485760 (10 MB) | |
| # MAX_BODY_SIZE_BYTES=10485760 | |
| # CORS configuration — controls which origins can call the API. | |
| # Used by: Next.js middleware — sets Access-Control-Allow-Origin header. | |
| # Default: * (all origins) | Restrict for production security. | |
| # CORS_ORIGIN=https://your-domain.com | |
| # Allow provider URLs pointing to private/local networks (localhost, 192.168.x.x, etc.). | |
| # REQUIRED for self-hosted providers: LM Studio, Ollama, vLLM, Llamafile, Triton, etc. | |
| # Used by: src/shared/network/outboundUrlGuard.ts — disables SSRF guard for provider calls. | |
| # Default: false (blocked) | Set true to enable local providers. | |
| # OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 5. INPUT SANITIZATION & PII PROTECTION (FASE-01) | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Multi-layer defense: request-side injection guard + response-side PII sanitizer. | |
| # ── Request-Side: Prompt Injection Guard ── | |
| # Scans incoming messages for prompt injection patterns before routing. | |
| # Used by: src/middleware/promptInjectionGuard.ts | |
| # INPUT_SANITIZER_ENABLED=true | |
| # INPUT_SANITIZER_MODE=warn # warn = log only | block = reject request | redact = strip patterns | |
| # Legacy alias for INPUT_SANITIZER_MODE (same effect). | |
| # INJECTION_GUARD_MODE=warn | |
| # PII detection in incoming requests (emails, phone numbers, SSNs, etc.). | |
| # Used by: src/middleware/promptInjectionGuard.ts — extends injection guard. | |
| # PII_REDACTION_ENABLED=false | |
| # ── Response-Side: PII Sanitizer ── | |
| # Scans LLM responses for leaked PII before returning to the client. | |
| # Used by: src/lib/piiSanitizer.ts | |
| # PII_RESPONSE_SANITIZATION=false | |
| # PII_RESPONSE_SANITIZATION_MODE=redact # redact = mask PII | warn = log only | block = drop response | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 6. TOOL & ROUTING POLICIES | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Tool policy mode — controls which tools LLMs can invoke via function calling. | |
| # Used by: src/lib/toolPolicy.ts — enforces allowlist/denylist on tool_choice. | |
| # Values: allowlist | denylist | disabled | Default: disabled | |
| # TOOL_POLICY_MODE=disabled | |
| # Payload manipulation rules JSON file. | |
| # Used by: open-sse/services/payloadRules.ts — injects/removes upstream payload fields per model/protocol. | |
| # Default: ./config/payloadRules.json | |
| # OMNIROUTE_PAYLOAD_RULES_PATH=./config/payloadRules.json | |
| # Reload interval for payloadRules.json mtime checks in milliseconds. | |
| # Used by: open-sse/services/payloadRules.ts — keeps file-based rules hot-reloadable without restart. | |
| # Default: 5000 | Minimum: 1000 | |
| # OMNIROUTE_PAYLOAD_RULES_RELOAD_MS=5000 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 7. URLS & CLOUD SYNC | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # URLs used for internal sync jobs, OAuth callbacks, and cloud relay. | |
| # Internal base URL — used by server-side sync jobs to call /api/sync/cloud. | |
| # Used by: src/lib/cloudSync.ts, src/lib/initCloudSync.ts | |
| # Default: http://localhost:20128 | |
| BASE_URL=http://localhost:20128 | |
| # Cloud relay URL — premium feature for remote config sync. | |
| # Used by: src/lib/cloudSync.ts — pushes/pulls settings from OmniRoute Cloud. | |
| CLOUD_URL= | |
| # Timeout for cloud sync HTTP requests in milliseconds. | |
| # Used by: src/lib/cloudSync.ts — fetchWithTimeout wrapper. | |
| # Default: 12000 (12 seconds) | |
| # CLOUD_SYNC_TIMEOUT_MS=12000 | |
| # Public-facing base URL — CRITICAL for reverse proxy / OAuth callback setups. | |
| # Used by: OAuth redirect_uri computation, Dashboard UI links, cloud/model sync. | |
| # Set to your public URL when behind nginx/Caddy (e.g., https://omniroute.example.com). | |
| # Default: http://localhost:20128 | |
| NEXT_PUBLIC_BASE_URL=http://localhost:20128 | |
| # Browser-facing OmniRoute origin for generated assets in API responses. | |
| # Used by: chatgpt-web image generation cache URLs (/v1/chatgpt-web/image/<id>). | |
| # Set this when OpenWebUI or another relay reaches OmniRoute by an internal URL | |
| # but the user's browser must fetch images from a LAN, tunnel, or public origin. | |
| # Do not include /v1; if included accidentally it will be normalized away. | |
| # OMNIROUTE_PUBLIC_BASE_URL=http://192.168.0.15:20128 | |
| # Max wait time for an async chatgpt-web image to land via the celsius | |
| # WebSocket, in milliseconds. Default 180000 (3 minutes). Increase during | |
| # upstream queue-deep windows ("Lots of people are creating images right now"). | |
| # OMNIROUTE_CGPT_WEB_IMAGE_TIMEOUT_MS=180000 | |
| # Total in-memory byte budget for the chatgpt-web image cache (used to serve | |
| # /v1/chatgpt-web/image/<id>), in megabytes. Default 256. Lower this if you | |
| # run OmniRoute on a memory-constrained host; raise it if image generation | |
| # is heavy and clients are racing the 30-minute TTL. | |
| # OMNIROUTE_CGPT_WEB_IMAGE_CACHE_MAX_MB=256 | |
| # Public cloud URL — client-side mirror of CLOUD_URL. | |
| NEXT_PUBLIC_CLOUD_URL= | |
| # Legacy alias — fallback for NEXT_PUBLIC_BASE_URL in sync schedulers. | |
| # NEXT_PUBLIC_APP_URL=http://localhost:20128 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 8. OUTBOUND PROXY (Upstream Provider Calls) | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Route upstream LLM API calls through an HTTP/SOCKS5 proxy. | |
| # Useful for corporate egress, geo-routing, or IP masking. | |
| # Enable SOCKS5 proxy support in both server and client components. | |
| # Used by: open-sse/executors — wraps fetch() calls through the proxy agent. | |
| ENABLE_SOCKS5_PROXY=true | |
| NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=true | |
| # Standard proxy variables (lowercase variants also supported). | |
| # HTTP_PROXY=http://127.0.0.1:7890 | |
| # HTTPS_PROXY=http://127.0.0.1:7890 | |
| # ALL_PROXY=socks5://127.0.0.1:7890 | |
| # NO_PROXY=localhost,127.0.0.1 | |
| # TLS fingerprint spoofing (opt-in) — mimics Chrome 124 TLS handshake via wreq-js. | |
| # Reduces risk of JA3/JA4 fingerprint-based blocking by providers (e.g., Google). | |
| # Used by: open-sse/executors — replaces Node.js default TLS fingerprint. | |
| # ENABLE_TLS_FINGERPRINT=true | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 9. CLI TOOL INTEGRATION | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Control how OmniRoute discovers and launches CLI sidecars (Claude, Codex, etc.). | |
| # Used by: src/shared/services/cliRuntime.ts | |
| # CLI discovery mode: auto = search PATH | manual = use explicit paths below. | |
| # CLI_MODE=auto | |
| # Additional PATH entries for finding CLI binaries (colon-separated). | |
| # CLI_EXTRA_PATHS=/host-cli/bin:/usr/local/bin | |
| # Home directory override for reading CLI config files (~/.claude, etc.). | |
| # CLI_CONFIG_HOME=/root | |
| # Allow OmniRoute to write CLI config files (token refresh, etc.). | |
| # CLI_ALLOW_CONFIG_WRITES=true | |
| # Override binary paths for individual CLI tools. | |
| # CLI_CLAUDE_BIN=claude | |
| # CLI_CODEX_BIN=codex | |
| # CLI_DROID_BIN=droid | |
| # CLI_OPENCLAW_BIN=openclaw | |
| # CLI_CURSOR_BIN=agent | |
| # CLI_CLINE_BIN=cline | |
| # CLI_CONTINUE_BIN=cn | |
| # CLI_QODER_BIN=qoder | |
| # CLI_QWEN_BIN=qwen | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 10. INTERNAL AGENT & MCP INTEGRATIONS | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Used by MCP server, A2A skills, and CLI sidecars to call the running instance. | |
| # Explicit base URL for MCP/A2A tools to reach OmniRoute (overrides localhost auto-detect). | |
| # For browser-visible generated image URLs, prefer OMNIROUTE_PUBLIC_BASE_URL above. | |
| # Used by: open-sse/mcp-server/server.ts, src/lib/a2a/ | |
| # OMNIROUTE_BASE_URL=http://localhost:20128 | |
| # API key for internal tool calls (MCP tools, A2A skills). | |
| # OMNIROUTE_API_KEY= | |
| # API key ID for MCP audit logging. | |
| # Used by: open-sse/mcp-server/audit.ts — tags audit events with a key identity. | |
| # OMNIROUTE_API_KEY_ID= | |
| # Legacy alias for OMNIROUTE_API_KEY. | |
| # ROUTER_API_KEY= | |
| # Enforce scope-based access control on MCP tool calls. | |
| # Used by: open-sse/mcp-server/server.ts — rejects calls outside allowed scopes. | |
| # OMNIROUTE_MCP_ENFORCE_SCOPES=false | |
| # Comma-separated scopes granted to this MCP connection. | |
| # Full list: admin, combos, health, models, routing, budget, metrics, pricing, memory, skills | |
| # OMNIROUTE_MCP_SCOPES=admin,combos,health | |
| # Model catalog sync interval in hours. | |
| # Used by: src/shared/services/modelSyncScheduler.ts — periodic model refresh. | |
| # Default: 24 | |
| # MODEL_SYNC_INTERVAL_HOURS=24 | |
| # Provider limits sync interval in minutes (rate limit windows, quotas). | |
| # Used by: src/server-init.ts — polls provider health endpoints. | |
| # Default: 70 | |
| PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES=70 | |
| # Disable all background services (sync, pricing, model refresh). | |
| # Used by: src/instrumentation-node.ts, src/lib/initCloudSync.ts | |
| # Useful for: CI builds, test environments, or resource-constrained containers. | |
| # OMNIROUTE_DISABLE_BACKGROUND_SERVICES=false | |
| # Flag set by bootstrap script after initial setup is complete. | |
| # Used by: src/app/(dashboard)/dashboard/page.tsx — shows setup wizard vs. dashboard. | |
| # OMNIROUTE_BOOTSTRAPPED=false | |
| # Allow request body to override the Antigravity project field. | |
| # Used by: open-sse/executors/antigravity.ts — escape hatch for multi-project setups. | |
| # OMNIROUTE_ALLOW_BODY_PROJECT_OVERRIDE=0 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 11. OAUTH PROVIDER CREDENTIALS | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Built-in default credentials for localhost development. | |
| # For remote/VPS deployments, register your own at each provider's developer console. | |
| # The bootstrap-env script auto-populates these in .env if missing. | |
| # Can also be overridden via data/provider-credentials.json where supported. | |
| # ── Claude Code (Anthropic) ── | |
| CLAUDE_OAUTH_CLIENT_ID=9d1c250a-e61b-44d9-88ed-5944d1962f5e | |
| # Custom redirect URI override for Claude OAuth callback. | |
| # CLAUDE_CODE_REDIRECT_URI=https://platform.claude.com/oauth/code/callback | |
| # ── Codex / OpenAI ── | |
| CODEX_OAUTH_CLIENT_ID=app_EMoamEEZ73f0CkXaXp7hrann | |
| # ── Gemini (Google) ── | |
| GEMINI_OAUTH_CLIENT_ID=681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com | |
| GEMINI_OAUTH_CLIENT_SECRET=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 | |
| # ── Gemini CLI (Google) ── | |
| GEMINI_CLI_OAUTH_CLIENT_ID=681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com | |
| GEMINI_CLI_OAUTH_CLIENT_SECRET=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 | |
| # ── Qwen (Alibaba) ── | |
| QWEN_OAUTH_CLIENT_ID=f0304373b74a44d2b584a3fb70ca9e56 | |
| # ── Kimi Coding (Moonshot) ── | |
| KIMI_CODING_OAUTH_CLIENT_ID=17e5f671-d194-4dfb-9706-5516cb48c098 | |
| # ── Antigravity (Google Cloud Code) ── | |
| ANTIGRAVITY_OAUTH_CLIENT_ID=1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com | |
| ANTIGRAVITY_OAUTH_CLIENT_SECRET=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 | |
| # ── GitHub Copilot ── | |
| GITHUB_OAUTH_CLIENT_ID=Iv1.b507a08c87ecfe98 | |
| # ── Qoder ── | |
| QODER_OAUTH_CLIENT_SECRET=4Z3YjXycVsQvyGF1etiNlIBB4RsqSDtW | |
| # ── Qoder Browser OAuth (experimental) ── | |
| # OmniRoute only enables the browser OAuth flow when ALL 5 variables below are set: | |
| # - QODER_OAUTH_AUTHORIZE_URL | |
| # - QODER_OAUTH_TOKEN_URL | |
| # - QODER_OAUTH_USERINFO_URL | |
| # - QODER_OAUTH_CLIENT_ID | |
| # - QODER_OAUTH_CLIENT_SECRET | |
| # | |
| # Redirect URI to register in the Qoder OAuth app: | |
| # - Localhost dev with PORT=20128: http://localhost:20128/callback | |
| # - LAN access (example): http://192.168.0.15:20128/callback | |
| # - Public domain (recommended): https://omniroute.example.com/callback | |
| # | |
| # Behind reverse proxy / public domain, also set NEXT_PUBLIC_BASE_URL to the same public origin. | |
| # If these values are not available, prefer QODER_PERSONAL_ACCESS_TOKEN below. | |
| # QODER_OAUTH_AUTHORIZE_URL= | |
| # QODER_OAUTH_TOKEN_URL= | |
| # QODER_OAUTH_USERINFO_URL= | |
| # QODER_OAUTH_CLIENT_ID= | |
| # QODER_OAUTH_CLIENT_SECRET= | |
| # ── Qoder Personal Access Token (direct API key fallback) ── | |
| # Used by: open-sse/executors/qoder.ts — bypasses OAuth when set. | |
| # QODER_PERSONAL_ACCESS_TOKEN= | |
| # QODER_CLI_WORKSPACE= | |
| # OMNIROUTE_QODER_WORKSPACE= | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # ⚠️ GOOGLE OAUTH (Antigravity, Gemini CLI) & OTHER PROVIDERS — REMOTE SERVERS | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # The default Client IDs above ONLY work when OmniRoute runs on localhost. | |
| # For remote/VPS hosting (including Docker containers on remote servers): | |
| # 1. By default, the browser will attempt OAuth redirects back to localhost, which will fail. | |
| # 2. Set NEXT_PUBLIC_BASE_URL=https://your-domain.com to fix the redirect URI. | |
| # 3. You MUST create your own OAuth App in each provider's developer console (Google Cloud, etc.) | |
| # and set the Authorized redirect URI to your domain (e.g., https://your-domain.com/callback). | |
| # 4. Replace the _OAUTH_CLIENT_ID and _SECRET values above with your own credentials. | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # ── OAuth sidecar/CLI bridge (internal) ── | |
| # Used by: src/lib/oauth/config/index.ts — internal CLI↔OmniRoute auth bridge. | |
| # OMNIROUTE_SERVER=http://localhost:20128 | |
| # OMNIROUTE_TOKEN= | |
| # OMNIROUTE_USER_ID=cli | |
| # CLI_TOKEN= # legacy alias for OMNIROUTE_TOKEN | |
| # CLI_USER_ID= # legacy alias for OMNIROUTE_USER_ID | |
| # SERVER_URL= # legacy alias for OMNIROUTE_SERVER | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 12. PROVIDER USER-AGENT OVERRIDES | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Customize the User-Agent header sent to each upstream provider. | |
| # Format: {PROVIDER_ID}_USER_AGENT=custom-value | |
| # Used by: open-sse/executors/base.ts — buildHeaders() dynamic lookup. | |
| # Update these when providers release new CLI versions to avoid blocks. | |
| CLAUDE_USER_AGENT=claude-cli/2.1.121 (external, cli) | |
| CODEX_USER_AGENT=codex-cli/0.125.0 (Windows 10.0.26100; x64) | |
| GITHUB_USER_AGENT=GitHubCopilotChat/0.45.1 | |
| ANTIGRAVITY_USER_AGENT=antigravity/1.107.0 darwin/arm64 | |
| KIRO_USER_AGENT=AWS-SDK-JS/3.0.0 kiro-ide/1.0.0 | |
| QODER_USER_AGENT=Qoder-Cli | |
| QWEN_USER_AGENT=QwenCode/0.15.3 (linux; x64) | |
| CURSOR_USER_AGENT=connect-es/1.6.1 | |
| GEMINI_CLI_USER_AGENT=google-api-nodejs-client/10.3.0 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 13. CLI FINGERPRINT COMPATIBILITY (Anti-Detection) | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # When enabled, OmniRoute reorders HTTP headers and JSON body fields to match | |
| # the exact signature of official CLI tools, reducing account flagging risk. | |
| # Your proxy IP is preserved — you get both stealth AND IP masking. | |
| # Used by: open-sse/config/cliFingerprints.ts, open-sse/executors/base.ts | |
| # Enable per-provider: | |
| # CLI_COMPAT_CODEX=1 | |
| # CLI_COMPAT_CLAUDE=1 | |
| # CLI_COMPAT_GITHUB=1 | |
| # CLI_COMPAT_ANTIGRAVITY=1 | |
| # CLI_COMPAT_KIRO=1 | |
| # CLI_COMPAT_CURSOR=1 | |
| # CLI_COMPAT_KIMI_CODING=1 | |
| # CLI_COMPAT_KILOCODE=1 | |
| # CLI_COMPAT_CLINE=1 | |
| # CLI_COMPAT_QWEN=1 | |
| # Or enable for all providers at once: | |
| # CLI_COMPAT_ALL=1 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 14. API KEY PROVIDERS | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # API keys for direct-authentication providers. | |
| # Preferred setup: Dashboard → Providers → Add API Key. | |
| # Setting here is an alternative for Docker/headless deployments. | |
| # DEEPSEEK_API_KEY= | |
| # GROQ_API_KEY= | |
| # XAI_API_KEY= | |
| # MISTRAL_API_KEY= | |
| # PERPLEXITY_API_KEY= | |
| # TOGETHER_API_KEY= | |
| # FIREWORKS_API_KEY= | |
| # CEREBRAS_API_KEY= | |
| # COHERE_API_KEY= | |
| # NVIDIA_API_KEY= | |
| # Embedding Providers (optional — used by /v1/embeddings) | |
| # NEBIUS_API_KEY= | |
| # Provider keys above (OpenAI, Mistral, Together, Fireworks, NVIDIA) also work for embeddings. | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 15. TIMEOUT SETTINGS | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # All timeout values are in milliseconds. | |
| # Used by: src/shared/utils/runtimeTimeouts.ts — centralized timeout resolution. | |
| # | |
| # Hierarchy: REQUEST_TIMEOUT_MS acts as a global override. | |
| # If set, it becomes the default for FETCH_TIMEOUT_MS and STREAM_IDLE_TIMEOUT_MS. | |
| # The fine-grained variables below override their respective defaults only when set. | |
| # ── Global shortcut ── | |
| # REQUEST_TIMEOUT_MS=600000 # Overrides both fetch and stream idle defaults | |
| # ── Upstream fetch (provider calls) ── | |
| # FETCH_TIMEOUT_MS=600000 # Total request timeout (default: 600000 = 10 min) | |
| # # Also drives anthropic-compatible-cc-* X-Stainless-Timeout. | |
| # FETCH_HEADERS_TIMEOUT_MS=600000 # Time to receive response headers | |
| # FETCH_BODY_TIMEOUT_MS=600000 # Time to receive full response body | |
| # FETCH_CONNECT_TIMEOUT_MS=30000 # TCP connection establishment (default: 30s) | |
| # FETCH_KEEPALIVE_TIMEOUT_MS=4000 # Keep-alive socket idle timeout (default: 4s) | |
| # ── Stream idle detection ── | |
| # STREAM_IDLE_TIMEOUT_MS=600000 # Max silence between SSE chunks (default: 600000) | |
| # # Extended-thinking models rarely pause >90s. | |
| # ── TLS client (wreq-js fingerprint proxy) ── | |
| # TLS_CLIENT_TIMEOUT_MS=600000 # Inherits from FETCH_TIMEOUT_MS by default | |
| # ── API Bridge (/v1 proxy server) ── | |
| # API_BRIDGE_PROXY_TIMEOUT_MS=30000 # Proxy hop timeout (default: 30s) | |
| # API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS=300000 # Overall server request timeout | |
| # API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS=60000 # Time to send response headers | |
| # API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS=5000 # Keep-alive idle timeout | |
| # API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS=0 # Raw socket timeout (0 = disabled) | |
| # ── Graceful shutdown ── | |
| # Time to wait for in-flight requests before force-exiting on SIGTERM/SIGINT. | |
| # Used by: src/lib/gracefulShutdown.ts | |
| # Default: 30000 (30 seconds) | |
| # SHUTDOWN_TIMEOUT_MS=30000 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 16. LOGGING | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Used by: src/lib/logEnv.ts, src/lib/logRotation.ts, src/shared/utils/logger.ts | |
| # Application log level — controls console and file log verbosity. | |
| # Values: debug | info | warn | error | Default: info | |
| # APP_LOG_LEVEL=info | |
| # Log output format. | |
| # Values: text | json | Default: text | |
| # APP_LOG_FORMAT=text | |
| # Write logs to file in addition to stdout. | |
| # Default: true | Set false to disable file logging. | |
| APP_LOG_TO_FILE=true | |
| # Path to the application log file. | |
| # Default: logs/application/app.log (relative to project root / DATA_DIR) | |
| # APP_LOG_FILE_PATH=logs/application/app.log | |
| # Maximum single log file size before rotation. | |
| # Accepts: plain bytes or suffixed (50M, 1G, 512K). Default: 50M | |
| # APP_LOG_MAX_FILE_SIZE=50M | |
| # Days to keep rotated application log files before auto-deletion. | |
| # Default: 7 | |
| # APP_LOG_RETENTION_DAYS=7 | |
| # Maximum number of rotated log file backups to keep. | |
| # Default: 20 | |
| # APP_LOG_MAX_FILES=20 | |
| # How often OmniRoute checks whether the active log file has exceeded | |
| # APP_LOG_MAX_FILE_SIZE and triggers a rotation. Set lower for very verbose | |
| # services to prevent log files from growing large between checks. | |
| # Accepts milliseconds. Default: 60000 (1 minute) | |
| # APP_LOG_ROTATION_CHECK_INTERVAL_MS=60000 | |
| # Days to keep request/call log entries in the database before auto-cleanup. | |
| # Default: 7 | |
| # CALL_LOG_RETENTION_DAYS=7 | |
| # Maximum call log entries stored in-memory buffer. | |
| # Default: 10000 | |
| # CALL_LOG_MAX_ENTRIES=10000 | |
| # Maximum rows in the call_logs SQLite table before oldest entries are pruned. | |
| # Default: 100000 | |
| # CALL_LOGS_TABLE_MAX_ROWS=100000 | |
| # Whether call log pipeline capture stores stream chunks when enabled in settings. | |
| # Only applies when call_log_pipeline_enabled=true. | |
| # Default: true | |
| # CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS=true | |
| # Maximum call log artifact size for pipeline captures, in KB. | |
| # Only applies when call_log_pipeline_enabled=true. | |
| # Default: 512 | |
| # CALL_LOG_PIPELINE_MAX_SIZE_KB=512 | |
| # Maximum rows in the proxy_logs SQLite table. | |
| # Default: 100000 | |
| # PROXY_LOGS_TABLE_MAX_ROWS=100000 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 17. MEMORY OPTIMIZATION (Low-RAM / Docker) | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Node.js V8 heap limit in MB. | |
| # Used by: Docker entrypoint — sets --max-old-space-size. | |
| # Default: 256 (Docker) | system default (npm) | |
| # OMNIROUTE_MEMORY_MB=256 | |
| # ── Prompt cache (system prompt deduplication) ── | |
| # Used by: open-sse/services — caches identical system prompts across requests. | |
| # PROMPT_CACHE_MAX_SIZE=50 # Max cached entries (default: 50) | |
| # PROMPT_CACHE_MAX_BYTES=2097152 # Max total cache size in bytes (default: 2 MB) | |
| # PROMPT_CACHE_TTL_MS=300000 # Cache entry TTL (default: 5 minutes) | |
| # ── Semantic cache (deterministic response dedup, temperature=0) ── | |
| # Used by: open-sse/services — caches identical temperature=0 responses. | |
| # SEMANTIC_CACHE_MAX_SIZE=100 # Max cached entries (default: 100) | |
| # SEMANTIC_CACHE_MAX_BYTES=4194304 # Max total cache size in bytes (default: 4 MB) | |
| # SEMANTIC_CACHE_TTL_MS=1800000 # Cache entry TTL (default: 30 minutes) | |
| # ── In-memory log buffers ── | |
| # Maximum recent stream events kept in memory for the Dashboard live view. | |
| # STREAM_HISTORY_MAX=50 | |
| # ── Context length default ── | |
| # Global fallback max context length for models without explicit config. | |
| # Used by: open-sse/services/contextManager.ts | |
| # CONTEXT_LENGTH_DEFAULT=128000 | |
| # ── Usage token buffer ── | |
| # Extra token headroom reserved when tracking usage quotas (prevents over-limit). | |
| # Used by: open-sse/utils/usageTracking.ts | |
| # USAGE_TOKEN_BUFFER=100 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 18. PRICING SYNC | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Automatic model pricing synchronization from external sources. | |
| # Used by: src/lib/pricingSync.ts | |
| # Enable periodic pricing data sync. Default: false (opt-in only). | |
| # PRICING_SYNC_ENABLED=false | |
| # Sync interval in seconds. Default: 86400 (24 hours). | |
| # PRICING_SYNC_INTERVAL=86400 | |
| # Comma-separated data sources. Default: litellm | |
| # PRICING_SYNC_SOURCES=litellm | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 19. MODEL SYNC (Dev) | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Development-time model catalog sync interval in seconds. | |
| # Used by: src/lib/modelsDevSync.ts | |
| # Default: 86400 (24 hours) | |
| # MODELS_DEV_SYNC_INTERVAL=86400 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 20. PROVIDER-SPECIFIC SETTINGS | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # ── OpenRouter ── | |
| # OpenRouter model catalog cache TTL in ms. | |
| # Used by: src/lib/catalog/openrouterCatalog.ts | |
| # Default: 86400000 (24 hours) | |
| # OPENROUTER_CATALOG_TTL_MS=86400000 | |
| # ── NanoBanana (Image Generation) ── | |
| # Polling config for async image generation jobs. | |
| # Used by: open-sse/handlers/imageGeneration.ts | |
| # NANOBANANA_POLL_TIMEOUT_MS=120000 # Max wait for job completion (default: 120s) | |
| # NANOBANANA_POLL_INTERVAL_MS=2500 # Poll frequency (default: 2.5s) | |
| # ── Cloudflare Workers AI ── | |
| # Account ID override for Cloudflare Workers AI executor. | |
| # Used by: open-sse/executors/cloudflare-ai.ts | |
| # CLOUDFLARE_ACCOUNT_ID= | |
| # ── Cloudflare Tunnel (cloudflared) ── | |
| # Custom path to cloudflared binary for tunnel management. | |
| # Used by: src/lib/cloudflaredTunnel.ts | |
| # CLOUDFLARED_BIN=/usr/local/bin/cloudflared | |
| # ── Search cache ── | |
| # TTL for search API response caching (Perplexity, Brave, etc.). | |
| # Used by: open-sse/services/searchCache.ts | |
| # Default: 300000 (5 minutes) | |
| # SEARCH_CACHE_TTL_MS=300000 | |
| # ── OpenAI-compatible multi-connection ── | |
| # Allow multiple simultaneous connections per OpenAI-compatible provider node. | |
| # Used by: src/app/api/providers/route.ts | |
| # ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE=false | |
| # ── CC-compatible provider (experimental) ── | |
| # Enable the Claude Code compatible provider endpoint. | |
| # This is only for third-party relays that accept Claude Code clients exclusively. | |
| # OmniRoute rewrites requests to pass those relays' Claude Code client validation. | |
| # If you only want to use Claude Code CLI, or you are not sure what these relays are, | |
| # keep this disabled and add a regular Anthropic-compatible provider instead. | |
| # Used by: src/shared/utils/featureFlags.ts | |
| # ENABLE_CC_COMPATIBLE_PROVIDER=false | |
| # ── CLIProxyAPI bridge (legacy) ── | |
| # Connection settings for external CLIProxyAPI instances. | |
| # Used by: open-sse/executors/cliproxyapi.ts | |
| # CLIPROXYAPI_HOST=127.0.0.1 | |
| # CLIPROXYAPI_PORT=5544 | |
| # CLIPROXYAPI_CONFIG_DIR=~/.cli-proxy-api | |
| # ── Local hostnames (Docker networking) ── | |
| # Comma-separated additional hostnames treated as "local" for provider routing. | |
| # Used by: open-sse/config/providerRegistry.ts — allows Docker service names. | |
| # LOCAL_HOSTNAMES=omlx,mlx-audio | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 21. PROXY HEALTH | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Fine-tune proxy health checking behavior. | |
| # Used by: src/lib/proxyHealth.ts | |
| # Timeout for fast-fail health checks (ms). Default: 2000 | |
| # PROXY_FAST_FAIL_TIMEOUT_MS=2000 | |
| # Health check result cache TTL (ms). Default: 30000 (30s) | |
| # PROXY_HEALTH_CACHE_TTL_MS=30000 | |
| # Rate limit maximum wait time before failing a request (ms). Default: 120000 (2 min) | |
| # Used by: open-sse/services/rateLimitManager.ts | |
| # RATE_LIMIT_MAX_WAIT_MS=120000 | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 22. DEBUGGING | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # These variables enable verbose debugging output. NEVER enable in production. | |
| # Dump Cursor protobuf decode/encode details to console. | |
| # CURSOR_PROTOBUF_DEBUG=1 | |
| # Dump raw Cursor SSE stream data to console. | |
| # CURSOR_STREAM_DEBUG=1 | |
| # Log Responses API SSE-to-JSON translation details. | |
| # DEBUG_RESPONSES_SSE_TO_JSON=true | |
| # Enable E2E test mode — relaxes auth and enables test harness hooks. | |
| # NEXT_PUBLIC_OMNIROUTE_E2E_MODE=true | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # 23. GITHUB INTEGRATION (Issue Reporting) | |
| # ═══════════════════════════════════════════════════════════════════════════════ | |
| # Allow users to report issues directly from the Dashboard to GitHub. | |
| # Used by: src/app/api/v1/issues/report/route.ts | |
| # GitHub repository in owner/repo format. | |
| # GITHUB_ISSUES_REPO=owner/repo | |
| # GitHub Personal Access Token with issues:write scope. | |
| # GITHUB_ISSUES_TOKEN=ghp_xxxx | |