# ============================================================================= # Decepticon — Environment Variables # ============================================================================= # The installer copies this file to ~/.decepticon/.env # Run `decepticon onboard` to (re)configure interactively. # --- LLM API Keys (configure at least one credential below) --- # Each entry corresponds to one AuthMethod. The onboard wizard rewrites # the keys you select; unselected keys keep their placeholder values and # are ignored at runtime. ANTHROPIC_API_KEY=your-anthropic-key-here OPENAI_API_KEY=your-openai-key-here GEMINI_API_KEY=your-gemini-key-here MINIMAX_API_KEY=your-minimax-key-here OPENROUTER_API_KEY=your-openrouter-key-here NVIDIA_API_KEY=your-nvidia-key-here DEEPSEEK_API_KEY=your-deepseek-key-here XAI_API_KEY=your-xai-key-here MISTRAL_API_KEY=your-mistral-key-here # Voyage AI — embeddings for skillogy hybrid retrieval (ADR-0011). Anthropic's # official embedding partner, so an Anthropic-key deployment can power skillogy # semantics with this alone (set DECEPTICON_SKILLOGY_EMBED_MODEL=voyage/voyage-3). VOYAGE_API_KEY=your-voyage-key-here # --- Cloud Gateways (added in the OpenClaude provider migration) --- # All routed through LiteLLM's native provider implementations. The # onboard wizard rewrites only the keys you explicitly select; placeholder # values are skipped at credentials-resolution time. GROQ_API_KEY=your-groq-key-here TOGETHER_API_KEY=your-together-key-here FIREWORKS_API_KEY=your-fireworks-key-here COHERE_API_KEY=your-cohere-key-here MOONSHOT_API_KEY=your-moonshot-key-here # Kimi for Coding (api.kimi.com/coding), K3 / K2.7. Separate platform # from the legacy Moonshot API above; keys start with sk-kimi-. KIMI_API_KEY=your-kimi-key-here ZAI_API_KEY=your-zai-key-here DASHSCOPE_API_KEY=your-dashscope-key-here # Optional current-model routes mirrored from the production LiteLLM catalog. # The proxy registers each route only when its provider key is configured. CEREBRAS_API_KEY=your-cerebras-key-here CHUTES_API_KEY=your-chutes-key-here DEEPINFRA_API_KEY=your-deepinfra-key-here NEBIUS_API_KEY=your-nebius-key-here NOVITA_API_KEY=your-novita-key-here SAMBANOVA_API_KEY=your-sambanova-key-here SILICONFLOW_API_KEY=your-siliconflow-key-here UPSTAGE_API_KEY=your-upstage-key-here REQUESTY_API_KEY=your-requesty-key-here KILO_API_KEY=your-kilo-key-here OLLAMA_CLOUD_API_KEY=your-ollama-cloud-key-here # RUNYOUR_API_BASE=https://your-runyour-endpoint/v1 RUNYOUR_API_KEY=your-runyour-key-here # GitHub Models — fine-grained PAT with the 'models' permission scope. # Generate at github.com/settings/personal-access-tokens. GITHUB_TOKEN=your-github-token-here # --- OpenAI-compatible gateways / aggregators (oh-my-pi parity) --- # Each routes through LiteLLM's openai/ provider with a fixed api_base # override (see config/litellm.yaml). Set only the gateways you use; a # placeholder key is skipped at credentials-resolution time. Order in the # default fallback chain follows _DEFAULT_AUTH_PRIORITY (factory.py). OPENCODE_API_KEY=your-opencode-zen-key-here # opencode.ai/zen # Vercel names this AI_GATEWAY_API_KEY; the Decepticon-namespaced alias is # passed explicitly to LiteLLM, so set THIS var (not Vercel's bare name). VERCEL_AI_GATEWAY_API_KEY=your-vercel-ai-gateway-key-here # vercel.com/ai-gateway HF_TOKEN=your-hf-token-here # huggingface.co/settings/tokens VENICE_API_KEY=your-venice-key-here # venice.ai/settings/api NANOGPT_API_KEY=your-nanogpt-key-here # nano-gpt.com SYNTHETIC_API_KEY=your-synthetic-key-here # synthetic.new ZENMUX_API_KEY=your-zenmux-key-here # zenmux.ai QIANFAN_API_KEY=your-qianfan-key-here # qianfan.baidubce.com (Baidu ERNIE) # Cloudflare AI Gateway is per-account: set BOTH the key and the # OpenAI-compat base URL (the gateway's `…/compat` path). A key without # the base URL 404s at call time. CLOUDFLARE_AI_GATEWAY_API_KEY=your-cloudflare-ai-gateway-key-here # CLOUDFLARE_AI_GATEWAY_API_BASE=https://gateway.ai.cloudflare.com/v1///compat CHEAPER_INFERENCE_API_KEY=your-cheaper-inference-key-here # cheaperinference.com (keys start ci_live_) # --- Generic OpenAI-compatible gateway (opt-in, DEFAULT OFF) --- # Point at ANY OpenAI-compatible /v1 endpoint. No vendor is hardcoded. # Requires base URL + real key + at least one model. Uncomment to enable. # See issue #989 (vendor-neutral alternative to a named third-party entry). # OPENAI_COMPAT_GATEWAY_API_BASE=https://gateway.example.com/v1 # OPENAI_COMPAT_GATEWAY_API_KEY= # OPENAI_COMPAT_GATEWAY_MODEL=gpt-4o-mini # Optional per-tier overrides (fall back to OPENAI_COMPAT_GATEWAY_MODEL): # OPENAI_COMPAT_GATEWAY_MODEL_HIGH= # OPENAI_COMPAT_GATEWAY_MODEL_MID= # OPENAI_COMPAT_GATEWAY_MODEL_LOW= # --- AWS Bedrock --- # IAM access key + secret + region. The region must have your chosen # Anthropic models enabled (us-east-1 / us-west-2 are typical). # AWS_ACCESS_KEY_ID=AKIA... # AWS_SECRET_ACCESS_KEY=... # AWS_REGION=us-east-1 # --- GCP Vertex AI --- # Service-account JSON path + project + region. Download a key from # IAM & Admin → Service Accounts. Project + location must match where # Anthropic / Gemini models are enabled. # GOOGLE_APPLICATION_CREDENTIALS=/abs/path/to/service-account.json # VERTEXAI_PROJECT=my-gcp-project-id # VERTEXAI_LOCATION=us-central1 # --- Azure OpenAI Service --- # Deployment endpoint + key + API version. Deployment names default to # the model id (gpt-5.5/gpt-5.4/gpt-5-nano); override per role via # DECEPTICON_MODEL_ if your Azure deployment names differ. # AZURE_API_KEY=... # AZURE_API_BASE=https://.openai.azure.com # AZURE_API_VERSION=2024-08-01-preview # --- LM Studio (local OpenAI-compatible) --- # LM Studio runs a local OpenAI-compatible server on port 1234. # Launch the LM Studio app → Developer tab → Start Server. # LMSTUDIO_API_BASE=http://host.docker.internal:1234/v1 # LMSTUDIO_MODEL=qwen2.5-coder-7b-instruct # LMSTUDIO_API_KEY=lm-studio # accepts any string; sentinel for the shim # --- llama.cpp (local OpenAI-compatible) --- # llama.cpp's `llama-server` exposes an OpenAI-compatible REST API # (default http://localhost:8080/v1). Run a GGUF model with: # llama-server -m /path/to/model.gguf --port 8080 # The route prefix is `llamacpp/` and remaps to LiteLLM's openai- # compatible path with LLAMACPP_API_BASE. See issue #151. # LLAMACPP_API_BASE=http://host.docker.internal:8080/v1 # LLAMACPP_MODEL=qwen2.5-coder-7b-instruct-q4_k_m # LLAMACPP_API_KEY=llama-cpp # accepts any string; sentinel for the shim # --- Custom OpenAI-compatible Endpoint --- # Bring-your-own gateway (vLLM, internal LiteLLM, third-party hub, etc.). # CUSTOM_OPENAI_API_BASE=https://gateway.example.com/v1 # CUSTOM_OPENAI_API_KEY=... # CUSTOM_OPENAI_MODEL=gpt-4o-mini # --- Self-hosted LLM (vLLM) --- # For running your own model on your own GPU. Set both and the proxy # registers hosted_vllm/ at startup — the same shape as OLLAMA_MODEL # below, so you don't need to know the LiteLLM provider prefix. # # VLLM_MODEL must match the server's --served-model-name, NOT the HuggingFace # repo. vLLM answers on the served name only, and a mismatch 404s in a way # that reads like a routing bug rather than a typo. # VLLM_API_BASE=http://host.docker.internal:8000/v1 # VLLM_MODEL=qwen3-coder-30b # VLLM_API_KEY= # only if you started vLLM with --api-key # # Serving notes, learned the hard way on a rented Ampere GPU: # # --enable-auto-tool-choice --tool-call-parser is mandatory. # Without the right parser vLLM returns tool calls as plain text, the # agent calls nothing, and the run fails with no error anywhere. Pick the # parser by reading the model's chat_template: a {"name":...} # JSON body is `hermes`, while XML is # `qwen3_coder` / `qwen3_xml`. Guessing costs a full model load to find out. # # Prefer a pure-transformer model. vLLM disables automatic prefix caching on # Mamba/linear-attention hybrids, and this agent resends a large prompt # every turn — losing the cache costs far more than the architecture wins. # Check the startup log for `enable_prefix_caching=True`. # # MoE beats dense at equal VRAM. A 30B-A3B (3B active) measured ~4x the # generation speed of a 27B dense on the same card, and its smaller weights # leave several times more room for KV cache. # # VLLM_USE_FLASHINFER_SAMPLER=0 on hosts with the NVIDIA driver but no CUDA # toolkit. The flashinfer sampler JIT-compiles at startup and dies with # "Could not find nvcc"; attention is unaffected, so disabling just the # sampler is cheaper than installing the toolkit. # --- Local LLM (Ollama) --- # Set both to run Decepticon against a local Ollama model. The # launcher's onboard wizard writes these when you pick "Local LLM". # OLLAMA_MODEL is any tag you pulled (`ollama pull qwen3-coder:30b`); # the proxy registers ollama_chat/ at startup, routing through # Ollama's /api/chat endpoint so tool calling keeps working. # # OLLAMA_API_BASE points the LiteLLM container at your Ollama server. # The right URL depends on where Ollama runs: # - macOS / Docker Desktop on Windows / Linux Docker: # http://host.docker.internal:11434 # (the litellm service has extra_hosts: host.docker.internal:host-gateway) # - WSL2 with Ollama installed on the Windows host: # http://host.docker.internal:11434 (Docker Desktop wires this up) # - WSL2 with Ollama installed inside the WSL distro itself: # http://localhost:11434 # (or http://:11434 from `ip addr` inside WSL if Docker # runs natively in WSL without Docker Desktop) # - Remote Ollama on another host: # http://:11434 # OLLAMA_API_BASE=http://host.docker.internal:11434 # OLLAMA_MODEL=qwen3-coder:30b # --- LiteLLM Proxy --- # WARNING: the values below are dev fallbacks. `decepticon onboard` replaces # them with strong random values; `decepticon start` refuses to use them. # To generate values manually: # openssl rand -hex 32 | sed 's/^/sk-/' # LITELLM_MASTER_KEY # openssl rand -hex 24 # POSTGRES_PASSWORD LITELLM_MASTER_KEY=sk-decepticon-master LITELLM_SALT_KEY=sk-decepticon-salt-change-me # --- PostgreSQL --- POSTGRES_PASSWORD=decepticon # --- Neo4j (Attack Chain Graph DB) --- # Used when DECEPTICON_KG_BACKEND=neo4j. # # SECURITY: Neo4j is dual-homed across sandbox-net and decepticon-net. # The default password below is PUBLIC KNOWLEDGE and MUST be changed # for any deployment that isn't a single-operator dev box on loopback. # Generate a strong one with `openssl rand -base64 32`. See # docs/security/neo4j-hardening.md for the full hardening posture. NEO4J_PASSWORD=decepticon-graph # Skillogy hybrid retrieval (ADR-0011) embedding model, routed through litellm. # Default is openai/text-embedding-3-small (needs OPENAI_API_KEY). Switch to # voyage/voyage-3 (VOYAGE_API_KEY) or gemini/gemini-embedding-001 (GEMINI_API_KEY) # for non-OpenAI deployments. With the default OpenAI model and no # OPENAI_API_KEY, Skillogy skips vector ingest and uses lexical search # immediately; it no longer retries unusable embedding requests. A valid # OpenAI key retains semantic search. Explicit Voyage/Gemini/custom model # settings keep their existing proxy routing and fallback behavior. # DECEPTICON_SKILLOGY_EMBED_MODEL=openai/text-embedding-3-small # --- Model Profile --- # eco = per-agent tier (production default) # max = every agent on HIGH (high-value targets) # test = every agent on LOW (development / CI) DECEPTICON_MODEL_PROFILE=eco # --- Auth Method Priority --- # Comma-separated list of AuthMethods, ordered by user preference. The # first method supplies primary models for every tier; the rest are # fallbacks. Methods whose credential isn't configured (placeholder key # or DECEPTICON_AUTH_CLAUDE_CODE=false) are skipped at runtime. # # Valid methods: anthropic_api, anthropic_oauth, openai_api, openai_oauth, # google_api, google_oauth, minimax_api, deepseek_api, xai_api, # mistral_api, openrouter_api, nvidia_api, copilot_oauth, grok_oauth, # perplexity_oauth, bedrock_api, vertex_api, azure_api, groq_api, # together_api, fireworks_api, cohere_api, moonshot_api, zai_api, # dashscope_api, github_models_api, lmstudio_local, ollama_local, # ollama_cloud, custom_openai_api # Empty value → factory walks _DEFAULT_AUTH_PRIORITY in priority order, # keeping only methods whose credential is actually configured. DECEPTICON_AUTH_PRIORITY= # --- Claude Code OAuth (subscription) --- # Set true to route Anthropic models through the Claude Code OAuth handler # (auth/* in LiteLLM) instead of the x-api-key path. Requires a valid # ~/.claude/.credentials.json from `claude` CLI auth. DECEPTICON_AUTH_CLAUDE_CODE=false # --- ChatGPT OAuth (subscription) --- # Set true to route OpenAI models through the ChatGPT subscription handler # (auth/gpt-* in LiteLLM) instead of the API-key path. Requires one of: # - CHATGPT_SESSION_TOKEN below (browser cookie), OR # - CHATGPT_ACCESS_TOKEN env var (pre-extracted Bearer), OR # - ~/.config/chatgpt/tokens.json file DECEPTICON_AUTH_CHATGPT=false # Session token from a signed-in chatgpt.com browser session: # 1. Open chatgpt.com and sign in # 2. DevTools → Application → Cookies → chatgpt.com # 3. Copy the value of `__Secure-next-auth.session-token` # The onboard wizard prompts for this when ChatGPT OAuth is selected. CHATGPT_SESSION_TOKEN= # --- Other OAuth subscriptions (set true + provide one credential each) --- # All are selectable from the onboard wizard. Each handler walks the same # resolution order at runtime: _ACCESS_TOKEN → _SESSION_TOKEN / # _SESSION_COOKIES / _REFRESH_TOKEN → ~/.config//tokens.json. # Gemini Advanced (Google One AI Premium) — gemini-sub/* models # DECEPTICON_AUTH_GEMINI=false # GEMINI_SESSION_COOKIES= # NID + __Secure-1PSID + __Secure-1PSIDTS # GEMINI_ACCESS_TOKEN= # alternative: pre-extracted Bearer # SuperGrok (X Premium+) — grok-sub/* models # DECEPTICON_AUTH_GROK=false # GROK_SESSION_TOKEN= # auth_token cookie from grok.com # GROK_ACCESS_TOKEN= # alternative: pre-extracted Bearer # GitHub Copilot Pro — copilot/* models # DECEPTICON_AUTH_COPILOT=false # COPILOT_REFRESH_TOKEN= # ghu_... or ghr_... refresh token # COPILOT_ACCESS_TOKEN= # alternative: pre-extracted Bearer # Perplexity Pro — pplx-sub/* models # DECEPTICON_AUTH_PERPLEXITY=false # PERPLEXITY_SESSION_TOKEN= # next-auth.session-token cookie # PERPLEXITY_ACCESS_TOKEN= # alternative: pre-extracted Bearer # --- Benchmark Mode --- # Set to 1 to switch the LangGraph orchestrator into BENCHMARK MODE for the # XBOW / CTF benchmark harness. Activates Rule-8/9 suspension and accepts # challenge context (target_url, vulnerability tags, flag format, mission # brief) via state — used by `make benchmark`. Leave empty for normal # engagement work. Restart the LangGraph container after toggling. BENCHMARK_MODE= # --- LangSmith Tracing (optional) --- # Set LANGSMITH_TRACING=true AND fill LANGSMITH_API_KEY to enable. # The onboard wizard handles both when you opt in. # # LANGSMITH_API_KEY is intentionally left unset (commented out) — leaving # a placeholder value here causes the LangChain SDK to attempt metadata # uploads to api.smith.langchain.com and spam the langgraph container # logs with 403 Forbidden, even when LANGSMITH_TRACING=false. LANGSMITH_TRACING=false # LANGSMITH_API_KEY= LANGSMITH_PROJECT=decepticon # --- Ports (optional) --- # On a confirmed bind conflict, start tries port + 1 and saves the free port. # Override host-side ports when running multiple Decepticon stacks # side by side, or when one of the defaults clashes with another # service on your host. Container-internal ports are unchanged. # LANGGRAPH_PORT=2024 # LITELLM_PORT=4000 # POSTGRES_PORT=5432 # WEB_PORT=3000 # TERMINAL_PORT=3003 # NEO4J_HTTP_PORT=7474 # NEO4J_BOLT_PORT=7687 # SKILLOGY_REST_PORT=9100 # --- LangGraph dev-mode strictness --- # By default langgraph dev runs with --allow-blocking so a sync I/O # call in a third-party dep (e.g. deepagents' subagents.py atask path) # downgrades blockbuster's BlockingError to a non-fatal warning. # Set this to 1 to remove --allow-blocking and reinstate the fatal- # on-sync behavior (useful when debugging async issues in your own code). # LANGGRAPH_STRICT_ASYNC=1 # --- C2 Framework / Specialist workloads --- # ADR-0006 (v1.1.8+): specialist workloads (c2-sliver, c2-havoc, ad, # reversing, …) come up on demand through the opscontrol daemon — # the orchestrator agent calls `ops_start("c2-sliver")` after gaining # a foothold, `ops_start("ad")` once recon identifies a Windows # domain, and so on. Default `decepticon start` keeps every # specialist plane cold to minimize idle cost + attack surface. # # Override only when you need every profile up by hand (e.g. CI # regression of every workload at once): # COMPOSE_PROFILES=cli,c2-sliver,ad,reversing # --- Paths --- # Install directory (used for workspace bind mount into containers). # - Production: The installer sets this to ~/.decepticon automatically. # - Development: `decepticon` (Python entry point) sets this to the repo root automatically. # Do not use ~ (tilde) — Docker Compose cannot expand it. # DECEPTICON_HOME=/home/youruser/.decepticon # --- Advanced (optional) --- # Startup checks for a newer release and offers Update now / Skip on a TTY. # Skip is selected by default. Non-interactive launches only show a notice. # Legacy AUTO_UPDATE=true/1/yes/on also require approval; no silent updates. # AUTO_UPDATE=false # air-gapped / version-pinned deploys # AUTO_UPDATE=prompt # same as the default # AUTO_UPDATE=false # # Update channel — which release stream `update` / startup checks track. # Defaults to latest. Both channels are final-only (Claude-Code-style soak # model); the difference is a bake delay. See docs/update-channels.md. # stable — newest final release baked >= the soak window (default 7d). # Opt in to the delayed channel (GHCR :stable). # latest — newest final release, immediately (GHCR :latest). Default. # DECEPTICON_CHANNEL=stable # Soak window (days) the stable channel waits before adopting a release: # DECEPTICON_STABLE_SOAK_DAYS=7 # DECEPTICON_DEBUG=true # Multi-stack container naming (PR #216). Unset/empty keeps the default # `decepticon-*` names. Set to e.g. `stack2` to get `decepticon-stack2-*` # so two stacks can coexist on the same Docker host. The declaration here # (even when blank) silences the compose "variable is not set" WARN. DECEPTICON_STACK_NAME= # --- Language --- # Pin agent output language to an ISO 639-1 code. All agent prose output # (menus, questions, summaries, errors) renders in this language. # Default: en (English). Presets: # # en English no Norwegian da Danish # sv Swedish fi Finnish is Icelandic # ko Korean ja Japanese zh Chinese # zh-cn Simplified Chinese zh-tw Traditional Chinese # es Spanish pt Portuguese pt-br Brazilian Portuguese # de German fr French nl Dutch # it Italian ca Catalan el Greek # pl Polish cs Czech sk Slovak # uk Ukrainian ro Romanian hr Croatian # bg Bulgarian sr Serbian sl Slovenian # hu Hungarian ru Russian et Estonian # lv Latvian lt Lithuanian # tr Turkish ar Arabic fa Persian # he Hebrew hi Hindi bn Bengali # ta Tamil te Telugu th Thai # vi Vietnamese id Indonesian ms Malay # tl Filipino sw Swahili af Afrikaans # # Country-code aliases (auto-resolved): # dk → Danish se → Swedish jp → Japanese cn → Chinese # br → Brazilian Portuguese tw → Traditional Chinese # # Special: # wenyan 文言文 Classical Chinese prose + English technical terms # --- Reverse Engineering --- # REA 6.3.0 and Ghidra 12.1.4 run in the optional reversing sidecar. # The orchestrator starts it when native analysis is needed; for manual startup, # use COMPOSE_PROFILES=reversing. DECEPTICON_LANGUAGE=en # --- LLM client timeout --- # Seconds to wait for a single LLM completion before raising # APITimeoutError / LLMTimeoutError. Default 120s (httpx transport) # and 600s (whole-coroutine guard in decepticon.llm.factory) are too # short for long Opus generations with max_tokens=128000 — generations # routinely exceed 120s mid-stream while LiteLLM proxy keeps returning # 200 OK upstream. 600s (10min) covers worst-case extended-thinking + # large tool_use payloads. # # This single knob drives both the httpx transport timeout # (``LLMConfig.timeout`` via pydantic-settings nested env) AND the # whole-coroutine guard (``_resolve_llm_timeout_seconds`` alias). For # tests or one-off overrides, ``DECEPTICON_LLM_TIMEOUT_SECONDS`` takes # precedence over this for the coroutine guard only. DECEPTICON_LLM__TIMEOUT=600 # --- Telemetry (opt-in) --- # Off by default. Set to `research` (masked reasoning corpus) or `basic` # (structural stats only) to share anonymous usage with the maintainers. # See TELEMETRY.md for exactly what is collected. DO_NOT_TRACK=1 forces off. DECEPTICON_TELEMETRY=off # Terminal presentation (interactive TTYs; /tui and /mouse change the current session). # --no-alt-screen and --no-mouse override these settings. Non-TTY/dumb terminals use inline. DECEPTICON_TUI=fullscreen DECEPTICON_MOUSE=1 # Optional per-session CLI runtime controls (flags override environment/.env). # Persisted in the selected thread; omitted settings survive resume. # DECEPTICON_LLM__FALLBACK_MODELS=["openai/gpt-5.5"] # auto/configured chain; none disables # DECEPTICON_LLM__EFFORT=auto # low|medium|high|max; provider support required # DECEPTICON_LLM__AUTOCOMPACT=auto # or 1024–10000000 token threshold