HuggingClaw / .env.example
Anurag
Fix OpenClaw abort accounting and provider timeout
347107f
Raw
History Blame Contribute Delete
20.1 kB
# ════════════════════════════════════════════════════════════════
# 🦞 HuggingClaw β€” OpenClaw Gateway for HuggingFace Spaces
# ════════════════════════════════════════════════════════════════
# Copy this file to .env and fill in your values.
# For local development: cp .env.example .env && nano .env
# ── REQUIRED: Core Configuration ──
# [REQUIRED] Primary LLM provider API key (for the provider in LLM_MODEL)
# - Anthropic: sk-ant-v0-...
# - OpenAI: sk-...
# - Google: AIzaSy...
# - OpenRouter: sk-or-v1-... (300+ models via single key)
LLM_API_KEY=your_api_key_here
# [REQUIRED] LLM model to use (format: provider/model-name)
# Auto-detects provider from prefix β€” any provider is supported!
# Provider IDs from OpenClaw docs: docs.openclaw.ai/concepts/model-providers
#
# ── Core Providers ──
#
# Anthropic (ANTHROPIC_API_KEY):
# - anthropic/claude-opus-4-6
# - anthropic/claude-sonnet-4-6
# - anthropic/claude-sonnet-4-5
# - anthropic/claude-haiku-4-5
#
# OpenAI (OPENAI_API_KEY):
# - openai/gpt-5.4-pro
# - openai/gpt-5.4
# - openai/gpt-5.4-mini
# - openai/gpt-5.4-nano
# - openai/gpt-4.1
# - openai/gpt-4.1-mini
#
# Google Gemini (GEMINI_API_KEY):
# - google/gemini-3.1-pro-preview
# - google/gemini-3-flash-preview
# - google/gemini-2.5-pro
# - google/gemini-2.5-flash
#
# DeepSeek (DEEPSEEK_API_KEY):
# - deepseek/deepseek-v3.2
# - deepseek/deepseek-r1-0528
# - deepseek/deepseek-r1
#
# ── OpenCode Providers ──
#
# OpenCode Zen β€” tested & verified models (OPENCODE_API_KEY):
# - opencode/claude-opus-4-6
# - opencode/gpt-5.4
# Get key from: https://opencode.ai/auth
#
# OpenCode Go β€” low-cost open models (OPENCODE_API_KEY):
# - opencode-go/kimi-k2.5
#
# ── Gateway/Router Providers ──
#
# OpenRouter β€” 300+ models via single API key (OPENROUTER_API_KEY):
# - openrouter/anthropic/claude-sonnet-4-6
# - openrouter/openai/gpt-5.4
# - openrouter/deepseek/deepseek-v3.2
# - openrouter/meta-llama/llama-3.3-70b-instruct:free
# Get key from: https://openrouter.ai
#
# Kilo Gateway (KILOCODE_API_KEY):
# - kilocode/anthropic/claude-opus-4.6
#
# ── Chinese/Asian Providers ──
#
# Z.ai / GLM (ZAI_API_KEY) β€” OpenClaw normalizes z-ai/z.ai β†’ zai:
# - zai/glm-5
# - zai/glm-5-turbo
# - zai/glm-4.7
# - zai/glm-4.7-flash
#
# Moonshot / Kimi (MOONSHOT_API_KEY):
# - moonshot/kimi-k2.5
# - moonshot/kimi-k2-thinking
#
# MiniMax (MINIMAX_API_KEY):
# - minimax/minimax-m2.7
# - minimax/minimax-m2.5
#
# Xiaomi / MiMo (XIAOMI_API_KEY):
# - xiaomi/mimo-v2-pro
# - xiaomi/mimo-v2-omni
#
# Volcengine / Doubao (VOLCANO_ENGINE_API_KEY):
# - volcengine/doubao-seed-1-8-251228
# - volcengine/kimi-k2-5-260127
#
# BytePlus β€” international (BYTEPLUS_API_KEY):
# - byteplus/seed-1-8-251228
#
# ── Western Providers ──
#
# Mistral (MISTRAL_API_KEY):
# - mistral/mistral-large-latest
# - mistral/mistral-small-2603
# - mistral/devstral-medium
#
# xAI / Grok (XAI_API_KEY):
# - xai/grok-4.20-beta
# - xai/grok-4
#
# NVIDIA (NVIDIA_API_KEY):
# - nvidia/nemotron-3-super-120b-a12b
# - nvidia/deepseek-ai/deepseek-v4-flash
# - nvidia/qwen/qwen3-coder-480b-a35b-instruct
# - nvidia/moonshotai/kimi-k2.6
# - nvidia/stepfun-ai/step-3.7-flash
#
# Groq (GROQ_API_KEY):
# - groq/mixtral-8x7b-32768
#
# Cohere (COHERE_API_KEY):
# - cohere/command-a
#
# Together (TOGETHER_API_KEY):
# - together/meta-llama/llama-3.3-70b-instruct
#
# Cerebras (CEREBRAS_API_KEY):
# - cerebras/zai-glm-4.7
#
# HuggingFace Inference (HUGGINGFACE_HUB_TOKEN):
# - huggingface/deepseek-ai/DeepSeek-R1
#
# Or any other OpenClaw-supported provider (format: provider/model-name)
LLM_MODEL=anthropic/claude-sonnet-4-5
# ════════════════════════════════════════════════════════════════
# πŸ”‘ API KEY ROTATION (per-provider key pools)
# ════════════════════════════════════════════════════════════════
# Every provider supports a comma-separated key pool.
# Gemini is sticky by default: each model starts on the first healthy key and
# reuses it until that key fails/exhausts, then the next key takes over.
# Other providers keep normal round-robin for new task windows unless added to
# KEY_STICKY_PROVIDERS. Short, bounded multi-request bursts can reuse the same
# healthy key for KEY_TASK_AFFINITY_MS so one message/tool loop does not burn
# multiple keys unnecessarily.
#
# Smart backoff: when a key gets retryable failures (429/402, common 5xx,
# timeout/network transient errors), it is temporarily suspended so other
# keys handle traffic.
# Strike 1 β†’ suspended for KEY_BLACKLIST_COOLDOWN_MS (default 60 s)
# Strike 2 β†’ suspended for KEY_BLACKLIST_COOLDOWN_MS Γ— 4 (default 4 min)
# Strike 3 β†’ suspended for KEY_PERM_SUSPEND_MS (max 16 h cap)
# A successful response resets the strike counter for that key.
#
# Pattern: <PROVIDER>_API_KEYS=key1,key2,key3
# Fallback order: plural pool β†’ singular key β†’ LLM_API_KEY (optional)
# Set false only if you want to disable global LLM_API_KEY fallback
# across providers.
LLM_API_KEY_FALLBACK_ENABLED=true
#
# Base backoff duration (ms) after the first 429 on a key (default: 60 s).
# Increases exponentially on repeated failures.
# KEY_BLACKLIST_COOLDOWN_MS=60000
#
# Randomize backoff window (percent) to avoid many keys re-entering at once.
# 0 disables jitter. Recommended: 10-25
# KEY_BLACKLIST_JITTER_PCT=15
#
# Number of consecutive 429/quota errors before a key enters long suspend.
# KEY_MAX_STRIKES=3
#
# Long suspend duration in ms for exhausted/auth-invalid keys.
# NOTE: hard-capped to 16h internally.
# KEY_PERM_SUSPEND_MS=57600000
#
# De-prioritize keys that failed very recently, even after cooldown expired.
# Value in milliseconds (default 15 min).
# KEY_FAILURE_DECAY_MS=900000
#
# Soft cap for concurrent requests per key (default: 3). Helps avoid
# overloading one key when many requests arrive in parallel.
# KEY_MAX_INFLIGHT_PER_KEY=3
#
# Provider-level OpenClaw timeoutSeconds injected into generated model providers
# (default: 300s). Raises the ~120s idle abort window for slow preview/thinking
# models such as Gemini Flash previews. Set 0 to leave OpenClaw defaults.
# OPENCLAW_PROVIDER_TIMEOUT_SECONDS=300
#
# Safety lease for in-flight counters (default: 30s). If a picked key gets no
# provider headers/completion/error before this, only the bookkeeping lease is
# cleaned up; the key is not treated as failed just because a task/stream is long.
# KEY_INFLIGHT_TTL_MS=30000
#
# Same-task key affinity window (ms) for non-sticky providers. Sequential
# requests for the same provider/model bucket can reuse the last healthy key
# during this short idle window. Set 0 to disable and use pure per-request
# round-robin for non-sticky providers.
# KEY_TASK_AFFINITY_MS=30000
#
# Max extra same-key reuses per affinity burst (default: 3). After this many
# reuses, normal round-robin resumes even if the idle window has not expired.
# Set higher only if your single task commonly fans out into more sub-requests.
# KEY_TASK_AFFINITY_MAX_REUSES=3
#
# Max request-body bytes to inspect for model names on streaming
# OpenAI-compatible Gemini calls (default: 256 KiB).
# KEY_MODEL_SNIFF_MAX_BYTES=262144
#
# Max error-response bytes to inspect before classifying provider failures
# (default: 64 KiB). Lets 403/400 provider quota bodies stay model-scoped
# instead of being treated as permanent auth failures.
# KEY_ERROR_BODY_SNIFF_MAX_BYTES=65536
#
# Sticky mode keeps one provider/model bucket on a single key until that key
# fails or exhausts. Default is enabled for Gemini because Google quotas are
# model-scoped and per-request round-robin can burn 2-3 keys for one chat turn.
# KEY_STICKY_UNTIL_FAILURE=true
# KEY_STICKY_PROVIDERS=gemini
# KEY_STICKY_SCOPE=auto # auto = per-model for Gemini, provider-level for others
#
# Optional auto-retry count for fetch requests on retryable errors/statuses.
# Default 0 means one upstream attempt per caller request; set 1-2 to opt in.
# Total attempts = 1 + retries (GET/HEAD/OPTIONS/POST).
# KEY_FETCH_MAX_RETRIES=0
#
# Base delay (ms) between auto-retries. Exponential per attempt; also respects
# upstream Retry-After header when provided. Capped to 10s internally.
# KEY_FETCH_RETRY_BASE_DELAY_MS=250
#
# Optional diagnostics guard: warn if one caller fetch produces more than one
# upstream provider attempt. Useful when experimenting with opt-in retries.
# KEY_ROTATOR_ASSERT_NO_EXTRA_CALLS=false
#
# Optional local-only dashboard probe. Requires SYNTHETIC_API_KEYS and emits
# synthetic events without sending any upstream provider request.
# KEY_ROTATOR_EMIT_SYNTHETIC_EVENTS=false
#
# When all keys are suspended, default behavior is best-effort: reuse the
# soonest-recovering suspended key so requests keep flowing.
# Set false if you prefer strict withholding until cooldown expiry.
# KEY_USE_SUSPENDED_AS_LAST_RESORT=true
#
#
# Optional diagnostics log snapshot for key pools (default: off).
# KEY_ROTATOR_DIAGNOSTICS=true
# KEY_ROTATOR_DIAGNOSTICS_INTERVAL_MS=60000
#
# Log verbosity controls for rotator internals.
# KEY_ROTATOR_LOG_LEVEL=info
# KEY_ROTATOR_VERBOSE_PICKS=false
#
# Note: This rotator does not re-send the same failed request automatically.
# It blacklists/penalizes the failed key so the *next* request prefers
# healthier keys.
#
# Note: KIMI_API_KEYS and MOONSHOT_API_KEYS share the same API endpoint
# (api.moonshot.cn) and are combined into one rotation pool automatically.
#
# Uncomment and fill in only the providers you use:
#
# ANTHROPIC_API_KEYS=sk-ant-key1,sk-ant-key2,sk-ant-key3
# OPENAI_API_KEYS=sk-key1,sk-key2,sk-key3
# GEMINI_API_KEYS=AIzaSy-key1,AIzaSy-key2
# DEEPSEEK_API_KEYS=key1,key2
# OPENROUTER_API_KEYS=sk-or-key1,sk-or-key2
# KILOCODE_API_KEYS=key1,key2
# OPENCODE_API_KEYS=key1,key2
# ZAI_API_KEYS=key1,key2 # aliases: ZHIPU_API_KEYS, BIGMODEL_API_KEYS
# MOONSHOT_API_KEYS=key1,key2 # combines with KIMI_API_KEYS
# KIMI_API_KEYS=key1,key2 # combines with MOONSHOT_API_KEYS
# MINIMAX_API_KEYS=key1,key2
# XIAOMI_API_KEYS=key1,key2
# VOLCANO_ENGINE_API_KEYS=key1,key2 # aliases: VOLCENGINE_API_KEYS, ARK_API_KEYS
# BYTEPLUS_API_KEYS=key1,key2
# MISTRAL_API_KEYS=key1,key2
# XAI_API_KEYS=key1,key2
# NVIDIA_API_KEYS=key1,key2,key3
# GROQ_API_KEYS=gsk-key1,gsk-key2,gsk-key3
# COHERE_API_KEYS=key1,key2
# TOGETHER_API_KEYS=key1,key2
# CEREBRAS_API_KEYS=key1,key2
# HUGGINGFACE_HUB_TOKENS=hf_key1,hf_key2 # aliases: HUGGINGFACE_API_KEYS, HF_TOKEN_POOL
# MODELSTUDIO_API_KEYS=key1,key2 # aliases: DASHSCOPE_API_KEYS, QWEN_API_KEYS
# COPILOT_GITHUB_TOKENS=key1,key2 # aliases: GITHUB_COPILOT_TOKENS, GITHUB_COPILOT_API_KEYS
# AI_GATEWAY_API_KEYS=key1,key2 # aliases: VERCEL_AI_GATEWAY_API_KEYS
#
# ════════════════════════════════════════════════════════════════
# 🌐 MULTI-PROVIDER SETUP (use multiple models simultaneously)
# ════════════════════════════════════════════════════════════════
# LLM_MODEL sets your DEFAULT model. But you can activate multiple
# providers at once β€” OpenClaw auto-discovers any provider whose
# API key is present in the environment.
#
# HOW IT WORKS:
# 1. LLM_MODEL + LLM_API_KEY β†’ sets your default model & exports
# the matching provider key automatically (e.g. ANTHROPIC_API_KEY)
# 2. Any additional provider key you set directly (e.g. OPENAI_API_KEY)
# is also picked up by OpenClaw β†’ that provider's models become
# available in the Control UI for manual selection.
# 3. Rotation pools (*_API_KEYS) work for every active provider
#
# Optional: explicitly pin model lists per provider for Control UI visibility
# when provider keys are configured.
# Format: comma-separated provider-local model IDs. For NVIDIA, keep NVIDIA-owned
# API IDs as nvidia/... and third-party hosted IDs as their API owner/id; do not
# add an extra outer OpenClaw provider prefix in NVIDIA_MODELS.
# NVIDIA_MODELS=nvidia/nemotron-3-super-120b-a12b,deepseek-ai/deepseek-v4-flash,qwen/qwen3-coder-480b-a35b-instruct,moonshotai/kimi-k2.6,stepfun-ai/step-3.7-flash
# OPENAI_MODELS=gpt-4o-mini,gpt-4.1
# GROQ_MODELS=llama-3.3-70b-versatile,deepseek-r1-distill-llama-70b
# independently and in parallel.
#
# EXAMPLE β€” default Anthropic, also use OpenAI and Groq:
#
# LLM_MODEL=anthropic/claude-sonnet-4-6 # default
# LLM_API_KEY=sk-ant-xxx # β†’ auto-sets ANTHROPIC_API_KEY
#
# OPENAI_API_KEY=sk-oai-xxx # activates OpenAI models
# OPENAI_API_KEYS=sk-oai-k1,sk-oai-k2 # optional: rotation pool
#
# GROQ_API_KEY=gsk-xxx # activates Groq models
# GROQ_API_KEYS=gsk-k1,gsk-k2,gsk-k3 # optional: rotation pool
#
# EXAMPLE β€” OpenRouter only (easiest: one key, 300+ models):
#
# LLM_MODEL=openrouter/anthropic/claude-sonnet-4-6
# LLM_API_KEY=sk-or-v1-xxx
# # Switch between any of 300+ models in Control UI β€” no extra keys needed
#
# Set any of these directly as HF Space Secrets (not via LLM_API_KEY):
# ANTHROPIC_API_KEY=sk-ant-xxx
# OPENAI_API_KEY=sk-oai-xxx
# GEMINI_API_KEY=AIzaSy-xxx
# DEEPSEEK_API_KEY=xxx
# GROQ_API_KEY=gsk-xxx
# MISTRAL_API_KEY=xxx
# XAI_API_KEY=xxx
# NVIDIA_API_KEY=nvapi-xxx
# COHERE_API_KEY=xxx
# TOGETHER_API_KEY=xxx
# CEREBRAS_API_KEY=xxx
# MOONSHOT_API_KEY=xxx
# OPENROUTER_API_KEY=sk-or-v1-xxx
# HUGGINGFACE_HUB_TOKEN=hf_xxx
# ════════════════════════════════════════════════════════════════
# Optional: custom OpenAI-compatible provider
# Only use this if you want to register your own endpoint at startup.
# Leave all of these empty unless you need a custom provider.
#
# Example:
# CUSTOM_PROVIDER_NAME=modal
# CUSTOM_BASE_URL=https://api.us-west-2.modal.direct/v1
# CUSTOM_MODEL_ID=zai-org/GLM-5.1-FP8
# LLM_MODEL=modal/zai-org/GLM-5.1-FP8
#
# Notes:
# - CUSTOM_BASE_URL should be the API base URL, not /chat/completions
# - CUSTOM_PROVIDER_NAME must not reuse a built-in provider name
# - Uses LLM_API_KEY by default; set CUSTOM_API_KEY only if different
#
# CUSTOM_PROVIDER_NAME=modal
# CUSTOM_BASE_URL=https://your-openai-compatible-endpoint/v1
# CUSTOM_MODEL_ID=your-model-id
# CUSTOM_MODEL_NAME=Friendly Model Name
# CUSTOM_API_KEY=your_custom_api_key_here
# CUSTOM_API_TYPE=openai-completions
# CUSTOM_CONTEXT_WINDOW=128000
# CUSTOM_MAX_TOKENS=500
# [REQUIRED] Gateway authentication token
# Generate: openssl rand -hex 32
GATEWAY_TOKEN=your_gateway_token_here
# [OPTIONAL] JupyterLab terminal token for /terminal/
# Set a strong token for private deployments. Must NOT be "huggingface".
JUPYTER_TOKEN=run: openssl rand -hex 32
# (Optional) Password auth β€” simpler alternative to token for casual users
# If set, users can log in with this password instead of the token
# OPENCLAW_PASSWORD=your_password_here
# ── OPTIONAL: Chat Integrations ──
# Enable WhatsApp pairing flow.
# When true, startup verifies/downloads the official @openclaw/whatsapp plugin
# using OpenClaw's ClawHub install path and preserves saved WhatsApp config.
WHATSAPP_ENABLED=false
# Get bot token from: https://t.me/BotFather
TELEGRAM_BOT_TOKEN=your_bot_token_here
# Allowed Telegram User IDs (comma-separated numeric IDs)
# TELEGRAM_ALLOWED_USERS=123456789,987654321
# ── OPTIONAL: Cloudflare Outbound Proxy ──
# Automatically bypass platform network blocks for Telegram/WhatsApp/Google/etc.
# Get a Cloudflare API Token with Account: Workers Scripts: Edit permissions.
# CLOUDFLARE_WORKERS_TOKEN=your_cloudflare_api_token_here
# Alternatively, if you already have a worker deployed:
# CLOUDFLARE_PROXY_URL=https://your-proxy.workers.dev
# CLOUDFLARE_PROXY_SECRET=your_proxy_secret_here
# Extra domains to proxy, merged with built-in defaults (Telegram, Discord, WhatsApp,
# Facebook, Google). Comma-separated. Set to "*" to proxy ALL external traffic.
# Leave unset to proxy only the built-in default domains.
# CLOUDFLARE_PROXY_DOMAINS=api.sendgrid.com,slack.com
# ── OPTIONAL: Workspace Backup to HF Dataset ──
HF_USERNAME=your_hf_username
HF_TOKEN=hf_your_token_here
# Backup dataset name (auto-created if missing)
# Default: huggingclaw-backup
BACKUP_DATASET_NAME=huggingclaw-backup
# ── OPTIONAL: Background Services ──
# Workspace auto-sync interval (seconds). Default: 180.
SYNC_INTERVAL=180
# Check openclaw.json for settings changes this often (seconds). Default: 1.
OPENCLAW_CONFIG_WATCH_INTERVAL=1
# Wait for openclaw.json to stay valid and unchanged before syncing. Default: 3.
OPENCLAW_CONFIG_SETTLE_SECONDS=3
# Minimum gap between sessions-triggered immediate syncs (seconds). Default: 30.
SESSIONS_MIN_SYNC_GAP=30
# Max seconds a one-off sync waits for another sync process to release its lock.
# Startup background sync still keeps retrying; this mainly prevents shutdown or
# gateway-restart saves from hanging forever behind a stuck upload. Default: 20.
SYNC_LOCK_TIMEOUT=20
# Max seconds one HF upload call may run before the sync process marks it failed,
# releases the lock, and retries on the next pass. This prevents Backup from
# staying stuck at SYNCING forever. Set to 0 to disable this watchdog. Default: 180.
SYNC_UPLOAD_TIMEOUT=180
# Upload implementation. Default `folder` uses a normal commit upload and is
# safest for HuggingClaw's small/medium snapshots. Set `large_folder` only if you
# explicitly need Hugging Face's resumable large-folder uploader.
SYNC_UPLOAD_STRATEGY=folder
# Shutdown/restart one-shot sync upload budgets. These are intentionally much
# larger than SYNC_LOCK_TIMEOUT so 40-50 MB files are not killed mid-upload just
# because another sync lock check needed to be bounded. Set to 0 to disable the
# outer command timeout completely. Defaults: 120 seconds each.
SYNC_SETTLED_TIMEOUT=120
SYNC_FINAL_TIMEOUT=120
# Lock wait used only by shutdown/restart one-shot syncs. Keep this short
# because start.sh stops the background sync loop before these commands run.
SYNC_ONE_SHOT_LOCK_TIMEOUT=5
# Webhooks: Standard POST notifications for lifecycle events
# WEBHOOK_URL=https://your-webhook-endpoint.com/log
# Cloudflare proxy & keep-alive: add your Cloudflare API token.
# A Worker is created automatically at boot for both outbound proxying and keep-alive.
# CLOUDFLARE_WORKERS_TOKEN=your_cloudflare_token_here
# Trusted proxies (comma-separated IPs)
# Fixes "Proxy headers detected from untrusted address" behind reverse proxies
# Only set if you see pairing/auth errors. Find IPs in Space logs (remote=x.x.x.x)
# TRUSTED_PROXIES=10.20.31.87,10.20.26.157
# Allowed origins for Control UI (comma-separated URLs)
# Locks down the web UI to only these origins
# ALLOWED_ORIGINS=https://your-space.hf.space
# ════════════════════════════════════════════════════════════════
# QUICK START: Only 3 secrets required!
# 1. LLM_API_KEY β†’ From your LLM provider
# 2. LLM_MODEL β†’ Pick a model above
# 3. GATEWAY_TOKEN β†’ Run: openssl rand -hex 32
# ════════════════════════════════════════════════════════════════