# Onboarding profile — setup/onboarding or setup/profile can detect defaults from FreeBSD locale/timezone SETUP_LOCALE=en-US DISPLAY_LOCALE=en-US ASSISTANT_LOCALE=en-US SYSTEM_LOCALE=en_US.UTF-8 TZ=UTC # Agent identity — ASSISTANT_NAME is primary; AGENT_NAME is auto-derived unless overridden # AGENT_NAME drives all system identifiers (user, service, ZFS, DB names) AGENT_NAME=clawdie ASSISTANT_NAME=Clawdie # Primary engine for fresh installs AGENT_ENGINE=pi-tui PI_TUI_BIN=pi # Profile presets: # setup, operator, status, payments, docs, cms, git, memory, local # Explicit provider/model values below override the profile defaults. PI_TUI_PROFILE=operator PI_TUI_PROVIDER=zai PI_TUI_MODEL=glm-5-turbo # Known-stable alternative primary (operator-validated 26.apr.2026): # PI_TUI_PROVIDER=openrouter # PI_TUI_MODEL=openai/o3 # Use this if zAI is over budget, you don't have a zAI key, or you've # experienced silent no-reply situations under zAI's rolling 5-hour cap. # Requires OPENROUTER_API_KEY below. # Primary API key for pi ZAI_API_KEY= # ZAI API base URL — override if the default endpoint does not match your key # pi uses https://api.z.ai/api/coding/paas/v4; litellm defaults differ # ZAI_API_BASE=https://api.z.ai/api/coding/paas/v4 # Optional alternative providers supported by pi # DEEPSEEK_API_KEY= # DEEPSEEK_BASE_URL=https://api.deepseek.com # OPENAI_API_KEY= # ANTHROPIC_API_KEY= # GEMINI_API_KEY= # OPENROUTER_API_KEY= # Ollama Cloud — free tier at ollama.com, no local hardware needed # Sign up at https://ollama.com, create API key in settings # Provides access to 30+ models including coding, reasoning, and vision # OLLAMA_API_KEY= # Provider fallback — automatically swap providers when the primary hits a # usage cap (e.g. zAI 429 "Usage limit reached"). See # docs/public/operate/provider-fallback.md for the full operator guide. # # IMPORTANT: do NOT use a free-tier model as the fallback target. Free tiers # rate-limit unpredictably and the failure mode is silent (no reply at all). # Use a paid stable OpenRouter model or another provider entirely. # LLM_FALLBACK_PROVIDER=openrouter # LLM_FALLBACK_MODEL=openai/o3 # LLM_FALLBACK_DEFAULT_COOLDOWN_SECONDS=3600 # used only when no reset stamp parsed # Local LLM runtime (optional) # LOCAL_LLM_PROVIDER=none|ollama|llama_cpp LOCAL_LLM_PROVIDER=none FEATURE_OLLAMA=NO FEATURE_LLAMA_CPP=NO FEATURE_OLLAMA_HPP=NO FEATURE_TAILSCALE=NO TAILSCALE_AUTHKEY= # Channels TELEGRAM_BOT_TOKEN= # TTS (text-to-speech) — Microsoft Edge TTS engine (free, no API key) # Auto-mode: always | inbound | tagged | off # always — every reply gets a voice message # inbound — only reply with voice when user sent a voice note # tagged — only when agent output contains [[tts]] marker # off — no voice messages TTS_AUTO_MODE=always TTS_PROVIDER=edge-cli TTS_VOICE=en-US-EmmaMultilingualNeural # Output format: audio-16khz-32kbitrate-mono-mp3 (native MP3, Telegram reads duration) TTS_OUTPUT_FORMAT=audio-16khz-32kbitrate-mono-mp3 # Max chars to synthesize (longer text is truncated, not summarized) TTS_MAX_TEXT_LENGTH=1500 # TTS rate/volume (optional, passed to edge-tts CLI) # TTS_RATE=+0% # TTS_VOLUME=+0% # Controlplane agent API auth (jail agents -> host API) # Generate: openssl rand -base64 32 CONTROLPLANE_SHARED_SECRET= # Better Auth base URL (required to avoid callback/redirect warnings) # Default is http://127.0.0.1:3100, set to your nginx/Tailscale URL if exposed. BETTER_AUTH_URL=http://127.0.0.1:3100 # Prompt/token guardrails (model context safety) # These are char/byte-based caps (fast, model-agnostic). # Increase in dev if you paste large logs; keep conservative in production. AGENT_MAX_INBOUND_CHARS=12000 AGENT_MAX_INBOUND_BYTES=64000 AGENT_MAX_BACKLOG_MESSAGES=20 AGENT_MAX_BACKLOG_CHARS=25000 AGENT_MAX_PROMPT_CHARS=60000 # Budget-aware chat policy (soft-degrade + pause) # When budget accounting is unavailable (controlplane down), default state # Options: normal | low_budget # Per-chat daily token limit (0 = disabled, no per-chat quota tracking). # When set, each chat gets its own daily budget independent of the global limit. # Chats exceeding their quota enter low_budget/paused states just like global budget. # Session files exceeding this size trigger compaction (or fresh session if # compaction is disabled). Prevents model context_window_exceeded errors. AGENT_SESSION_MAX_BYTES=200000 # Session compaction — when a session grows past the byte limit, old turns are # summarized into a compaction header and the summary is stored in memory DB. # The last N turns are kept at full fidelity. AGENT_SESSION_COMPACT_ENABLED=YES AGENT_SESSION_COMPACT_KEEP_TURNS=20 AGENT_SESSION_COMPACT_MIN_ENTRIES=30 # Crowdin — Translation management for multi-language docs # Free for open source: https://crowdin.com/open-source # Create token at: https://crowdin.com/settings#api-key CROWDIN_PERSONAL_TOKEN= # SSH (optional) — used by Ansible when enabling sshd inside jails # Also deployed to the git jail's git user authorized_keys automatically. # Example: SSH_PUBLIC_KEY="ssh-ed25519 AAAA... you@host" SSH_PUBLIC_KEY= # Private key path for git-admin agent (public key auto-derived for git jail) # GIT_SSH_KEY_PATH=/home/clawdie/.ssh/id_ed25519 # Stripe is built into the default Clawdie runtime. # Leave blank to skip for now, or set a Restricted key from # Stripe Dashboard -> Developers -> API Keys -> Restricted Keys. STRIPE_SECRET_KEY= STRIPE_ENABLE_REFUNDS=NO # Domain split: # AGENT_DOMAIN -> public-facing site/API domain. Leave blank until # you have a real public DNS name configured. # AGENT_INTERNAL_DOMAIN -> internal jail/service names written into /etc/hosts # # Use home.arpa for internal-only names. .local is reserved for mDNS and can # create resolver ambiguity on the local link. # This example internal value matches the default AGENT_NAME above; replace it # if you rename the agent. AGENT_DOMAIN= AGENT_INTERNAL_DOMAIN=clawdie.home.arpa # Local code hosting defaults # Current main provisions a dedicated git jail by default. CODE_HOSTING_MODE=git REMOTE_GIT_URL=https://codeberg.org/Clawdie/Clawdie-AI.git # Local git jail — primary push target for agents (no Codeberg keys needed) GIT_LOCAL_URL=git@10.0.1.6:/srv/git/Clawdie-AI.git FEATURE_GIT=YES FEATURE_GITEA=NO # Optional: isolate git-admin agent edits to a dedicated working tree # (mounted into the git-worker jail at /opt/repo). If unset, the git-admin # worker may mount the project root as its repo. # AGENT_REPO_DIR=/home///data/worktrees/git-admin # Warden jail network — choose your private subnet at bootstrap. # AGENT_SUBNET_BASE sets the default subnet; WARDEN_* can pin individual addresses. # Code defaults to 10.0.0.x if these are not set. # Common choices: 192.168.100.x, 10.0.0.x, 172.16.50.x # # Reserved IPs (lower = more foundational to agent runtime): # .1 Gateway — bridge interface # .2 Reserved — do not use for new runtime # .3 Database — PostgreSQL (skills + memory) # .4 CMS — Astro/Strapi content (if enabled) # .5 Local LLM — Ollama or llama-cpp (if enabled) # .6 Git — local bare repositories # .101+ Worker — jailed agent execution # .150 Browser VM — reserved browser automation profile AGENT_SUBNET_BASE=10.0.0 WARDEN_SUBNET_BASE=10.0.0 WARDEN_SUBNET=10.0.0.0/24 WARDEN_GATEWAY=10.0.0.1 # There is no active controlplane jail; keep this slot unused. WARDEN_CONTROLPLANE_IP=10.0.0.2 WARDEN_DB_IP=10.0.0.3 WARDEN_CMS_IP=10.0.0.4 WARDEN_OLLAMA_IP=10.0.0.5 WARDEN_LLAMA_CPP_IP=10.0.0.5 WARDEN_GIT_IP=10.0.0.6 # PostgreSQL runtime: host (default) or jail. # Host runs PostgreSQL directly on FreeBSD; jails connect via warden0 # (DB_HOST defaults to ${AGENT_SUBNET_BASE}.1). Jail mode is available for # operators who intentionally want PostgreSQL isolated from the host service. DB_RUNTIME=host DB_HOST= # Max wait during Clawdie startup for host PostgreSQL to become query-ready. HOST_DB_READINESS_TIMEOUT_MS=60000 # ZFS dataset compression for host-based PostgreSQL (lz4 default, zstd optional). DB_COMPRESSION=lz4 # PostgreSQL — split-brain architecture (three databases, host PostgreSQL by default) # Skills DB: ships with repo, restored from dump, read-only at runtime # Memory DB: user data, grows with conversations, needs backups # Ops DB: operational data (chats, messages, tasks, sessions, routing) # setup/onboarding and setup/db will generate these if missing and keep the # URLs below in sync with AGENT_NAME, subnet, and passwords. # PostgreSQL identifiers use the fixed platform namespace on root installs: # Root/platform install -> system_skills / system_brain / system_ops / system_git / system_web POSTGRES_ADMIN_PASSWORD= SKILLS_DB_PASSWORD= MEMORY_DB_PASSWORD= OPS_DB_PASSWORD= FORGEJO_DB_PASSWORD= SKILLS_DB_URL= MEMORY_DB_URL= OPS_DB_URL= # Embeddings (pgvector) — used by memory search. Defaults: # - If OPENROUTER_API_KEY is set: OpenRouter embeddings endpoint # - Otherwise: local llama-server at http://localhost:8080/v1 # Disable embeddings entirely (FTS-only) by setting EMBED_BASE_URL to empty: # EMBED_BASE_URL= # OpenRouter default (when OPENROUTER_API_KEY is set): # EMBED_BASE_URL=https://openrouter.ai/api/v1 # EMBED_API_KEY= # defaults to OPENROUTER_API_KEY when base_url is openrouter # Model must match DB vector dimensions (default vector(1024)): # EMBED_MODEL=BAAI/bge-m3 # EMBED_DIMENSIONS=1024 FORGEJO_DB_URL= # Strapi secrets are generated automatically by onboarding/db/cms if missing. # They back the internal Strapi app in the cms jail and should not be exposed. STRAPI_DB_PASSWORD= STRAPI_APP_KEYS= STRAPI_API_TOKEN_SALT= STRAPI_ADMIN_JWT_SECRET= STRAPI_TRANSFER_TOKEN_SALT= STRAPI_JWT_SECRET= CMS_ENABLE=NO CMS_ADMIN_UI=NO GIT_JAIL_NAME= GIT_JAIL_IP= GIT_STORAGE_ROOT= GIT_DEFAULT_REPO_NAME= # Multi-agent note: if you run multiple agents on one host, set explicit jail # names so service jails do not collide. CMS_JAIL_NAME= OLLAMA_JAIL_NAME= LLAMA_CPP_JAIL_NAME= # CMS_JAIL_NAME defaults to "cms". # CMS_JAIL_IP defaults to ${AGENT_SUBNET_BASE}.4 when setup --step cms runs. # CMS_WEBROOT defaults to /usr/local/www/clawdie and serves docs/tenant output # CMS_DOCS_SITE_PATH defaults to /home/clawdie/clawdie-docs # CMS_LANDING_SITE_PATH defaults to /home/clawdie/clawdie-si # CMS_LANDING_WEBROOT defaults to /usr/local/www/clawdie-si # CMS_STRAPI_PATH defaults to /home/clawdie/strapi # CMS_STRAPI_URL defaults to http://cms..home.arpa:1337/api # CMS_STRAPI_ADMIN_URL defaults to http://cms..home.arpa:1337/admin # CMS_ASTRO_MODE=strapi-seed # Protected screenshots auth (generated by onboarding/cms if missing) SCREENSHOTS_USER=clawdie SCREENSHOTS_PASSWORD= # Control Plane (multi-agent orchestration) CONTROLPLANE_NAME=clawdie CONTROLPLANE_DAILY_TOKENS=100000 CONTROLPLANE_PORT=3100 CONTROLPLANE_BIND_HOST=0.0.0.0 # IP address that jailed agents use to reach the host API (default: 10.0.1.1). # CONTROLPLANE_HOST_IP=10.0.1.1 CONTROLPLANE_AUTH_MODE=local_trusted # Shared secret for agent-to-API Bearer token auth (required for agent subprocesses). # Generate with: openssl rand -base64 32 # CONTROLPLANE_SHARED_SECRET= # CONTROLPLANE_RUNNER=pi # Options: pi | aider | codex # CONTROLPLANE_CODEX_BIN=codex # CONTROLPLANE_CODEX_MODEL=gpt-5.2 # CONTROLPLANE_AIDER_BIN=aider # CONTROLPLANE_AIDER_FLAGS=--no-check-update --no-gitignore # CONTROLPLANE_AIDER_TMUX_SESSION=clawdie-controlplane # CONTROLPLANE_AIDER_LOG_DIR=/home/clawdie/clawdie-ai/tmp/controlplane/aider # BETTER_AUTH_SECRET — required when CONTROLPLANE_AUTH_MODE=authenticated # BETTER_AUTH_URL defaults to http://127.0.0.1: # CONTROLPLANE_OPERATOR_EMAIL defaults to @ CONTROLPLANE_DASHBOARD_DIR=/usr/local/www/clawdie/controlplane # Generate with: openssl rand -base64 32 BETTER_AUTH_SECRET= # CONTROLPLANE_OPERATOR_EMAIL= OPERATOR_PASSWORD= # Vision fallback (optional) — OCR Telegram screenshots via OpenRouter. # Requires OPENROUTER_API_KEY. # VISION_PROVIDER=openrouter # VISION_MODEL=nvidia/nemotron-nano-12b-v2-vl:free # VISION_MAX_IMAGES=1 # STT (optional) — transcribe Telegram voice notes. # Default implementation supports OpenAI Whisper, or attempts OpenRouter with an OpenAI-compatible endpoint. # STT_PROVIDER=openrouter # STT_MODEL=openai/whisper-1 # Telegram admin user IDs (comma-separated). # In group chats, admin-only commands (/tts, /stop, /new, /activation) require sender ID in this list. # Example: TELEGRAM_ADMIN_IDS=85126311,123456789 TELEGRAM_ADMIN_IDS= # Ops group chat ID — receives startup reports and system notifications. # This chat is exempt from budget-aware pausing (never paused, only degraded). # Example: TELEGRAM_OPS_CHAT_ID=-5148108067 TELEGRAM_OPS_CHAT_ID= # Compaction provider/model — controls which LLM summarizes old session turns. # # Default behavior (both unset): compaction follows the chat runtime. If # provider fallback is active (see LLM_FALLBACK_* above), compaction also # uses the fallback. Simplest, no extra cost surface, no separate API key. # # Pinning compaction to a specific provider decouples it from the chat # runtime — chat can fall over to a fallback while compaction stays on a # stable secondary. Useful if you want compaction to keep using a cheap # model when chat swaps to a more expensive one, or vice versa. Requires # the pinned provider's API key. # # Operator note (26.apr.2026): leaving these unset is the validated default. # Pin only when you have a deliberate cost or stability reason. # HEARTBEAT_PROVIDER=deepseek # HEARTBEAT_MODEL=deepseek-v4-flash # AGENT_COMPACTION_PROVIDER=zai # AGENT_COMPACTION_MODEL=glm-4.6 # Idle maintenance interval for heartbeat-enabled agents in ms (default: 7200000 = 2h). # Controls how often agents with no pending tasks receive a maintenance idle prompt. # Separate from the 30s task pickup tick. # AGENT_HEARTBEAT_IDLE_INTERVAL_MS=7200000