# Database Configuration
DATABASE_URL=postgres://localhost/ironclaw
DATABASE_POOL_SIZE=10

# LLM Provider
# LLM_BACKEND=nearai           # default
# Possible values: nearai, ollama, openai_compatible, openai, anthropic, github_copilot, tinfoil, openai_codex, gemini_oauth
# LLM_REQUEST_TIMEOUT_SECS=120  # Increase for local LLMs (Ollama, vLLM, LM Studio)

# === Anthropic Direct ===
# Two auth modes:
#   1. API key: Set ANTHROPIC_API_KEY (from console.anthropic.com/settings/keys)
#   2. OAuth token: Set ANTHROPIC_OAUTH_TOKEN (from `claude login`)
#      OAuth tokens use Authorization: Bearer instead of x-api-key header.
# ANTHROPIC_API_KEY=sk-ant-...
# ANTHROPIC_OAUTH_TOKEN=sk-ant-oat01-...   # from `claude login` credentials
# ANTHROPIC_MODEL=claude-sonnet-4-20250514

# === OpenAI Direct ===
# OPENAI_API_KEY=sk-...
# Reuse Codex CLI auth.json instead of setting OPENAI_API_KEY manually.
# Works with both OpenAI API-key mode and Codex ChatGPT OAuth mode.
# In ChatGPT mode this uses the private `chatgpt.com/backend-api/codex` endpoint.
# LLM_USE_CODEX_AUTH=true
# CODEX_AUTH_PATH=~/.codex/auth.json

# === GitHub Copilot ===
# Uses the OAuth token from your Copilot IDE sign-in (for example
# ~/.config/github-copilot/apps.json on Linux/macOS), or run `ironclaw onboard`
# and choose the GitHub device login flow.
# LLM_BACKEND=github_copilot
# GITHUB_COPILOT_TOKEN=gho_...
# GITHUB_COPILOT_MODEL=gpt-4o
# IronClaw injects standard VS Code Copilot headers automatically.
# Optional advanced headers for custom overrides:
# GITHUB_COPILOT_EXTRA_HEADERS=Copilot-Integration-Id:vscode-chat

# === NEAR AI (Chat Completions API) ===
# Two auth modes:
#   1. Session token (default): Uses browser OAuth (GitHub/Google) on first run.
#      Session token stored in ~/.ironclaw/session.json automatically.
#      Base URL defaults to https://private.near.ai
#   2. API key: Set NEARAI_API_KEY to use API key auth from cloud.near.ai.
#      Base URL defaults to https://cloud-api.near.ai
NEARAI_MODEL=Qwen/Qwen3.5-122B-A10B
NEARAI_BASE_URL=https://private.near.ai
NEARAI_AUTH_URL=https://private.near.ai
# NEARAI_SESSION_TOKEN=sess_...                  # hosting providers: set this
# NEARAI_SESSION_PATH=~/.ironclaw/session.json   # optional, default shown
# NEARAI_API_KEY=...                             # API key from cloud.near.ai

# Local LLM Providers (Ollama, LM Studio, vLLM, LiteLLM)

# === Ollama ===
# OLLAMA_MODEL=llama3.2
# LLM_BACKEND=ollama
# OLLAMA_BASE_URL=http://localhost:11434   # default

# === OpenAI-compatible (LM Studio, vLLM, Anything-LLM) ===
# LLM_MODEL=llama-3.2-3b-instruct-q4_K_M
# LLM_BACKEND=openai_compatible
# LLM_BASE_URL=http://localhost:1234/v1
# LLM_API_KEY=sk-...                        # optional for local servers
# Custom HTTP headers for OpenAI-compatible providers
# Format: comma-separated key:value pairs
# LLM_EXTRA_HEADERS=HTTP-Referer:https://github.com/nearai/ironclaw,X-Title:ironclaw

# === OpenRouter (300+ models via OpenAI-compatible) ===
# LLM_MODEL=anthropic/claude-sonnet-4       # see openrouter.ai/models for IDs
# LLM_BACKEND=openai_compatible
# LLM_BASE_URL=https://openrouter.ai/api/v1
# LLM_API_KEY=sk-or-...

# LLM_EXTRA_HEADERS=HTTP-Referer:https://myapp.com,X-Title:MyApp


# === Together AI (via OpenAI-compatible) ===
# LLM_MODEL=meta-llama/Llama-3.3-70B-Instruct-Turbo
# LLM_BACKEND=openai_compatible
# LLM_BASE_URL=https://api.together.xyz/v1
# LLM_API_KEY=...

# === Fireworks AI (via OpenAI-compatible) ===
# LLM_MODEL=accounts/fireworks/models/llama4-maverick-instruct-basic
# LLM_BACKEND=openai_compatible
# LLM_BASE_URL=https://api.fireworks.ai/inference/v1
# LLM_API_KEY=fw_...

# === MiniMax ===
# LLM_BACKEND=minimax
# MINIMAX_API_KEY=...
# MINIMAX_MODEL=MiniMax-M2.7
# MINIMAX_BASE_URL=https://api.minimax.io/v1   # default (global); use https://api.minimaxi.com/v1 for China

# === Anthropic Direct ===
# LLM_BACKEND=anthropic
# ANTHROPIC_MODEL=claude-sonnet-4-6
# ANTHROPIC_API_KEY=sk-ant-...
# ANTHROPIC_BASE_URL=https://api.anthropic.com  # default
# Prompt cache retention — controls Anthropic server-side prompt caching:
#   none  = disabled (no cache_control injected)
#   short = 5-minute TTL, 1.25× (125%) write surcharge (default)
#   long  = 1-hour TTL, 2.0× (200%) write surcharge
# ANTHROPIC_CACHE_RETENTION=short

# === OpenAI Codex (ChatGPT subscription, OAuth) ===
# LLM_BACKEND=openai_codex
# OPENAI_CODEX_MODEL=gpt-5.3-codex              # default
# OPENAI_CODEX_CLIENT_ID=app_EMoamEEZ73f0CkXaXp7hrann  # override (rare)
# OPENAI_CODEX_AUTH_URL=https://auth.openai.com  # override (rare)
# OPENAI_CODEX_API_URL=https://chatgpt.com/backend-api/codex  # override (rare)

# === Google Gemini (OAuth, Gemini CLI compatible) ===
# LLM_BACKEND=gemini_oauth
# GEMINI_MODEL=gemini-2.5-flash                  # default
# GEMINI_CREDENTIALS_PATH=~/.gemini/oauth_creds.json  # default
# GEMINI_API_KEY=...                             # optional: use API key instead of OAuth
# GEMINI_API_KEY_AUTH_MECHANISM=query             # "query" (default) or "header"
# GEMINI_SAFETY_BLOCK_NONE=true                  # disable safety filters (default: false)
# GEMINI_CLI_CUSTOM_HEADERS=Key:Value,Key2:Value2
# GEMINI_TOP_P=0.95
# GEMINI_TOP_K=40
# GEMINI_SEED=42
# GEMINI_PRESENCE_PENALTY=0.0
# GEMINI_FREQUENCY_PENALTY=0.0
# GEMINI_RESPONSE_MIME_TYPE=application/json
# GEMINI_RESPONSE_JSON_SCHEMA={"type":"object"}
# GEMINI_CACHED_CONTENT=cachedContents/abc123

# For full provider setup guide see docs/LLM_PROVIDERS.md

# Channel Configuration
# CLI is always enabled

# Slack Bot (optional)
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
SLACK_SIGNING_SECRET=...

# Telegram Bot (optional)
TELEGRAM_BOT_TOKEN=...

# HTTP Webhook Server (optional)
HTTP_HOST=0.0.0.0
HTTP_PORT=8080
HTTP_WEBHOOK_SECRET=your-webhook-secret
# Webhook authentication uses HMAC-SHA256 signature verification.
# Callers must send an X-IronClaw-Signature header with format: sha256=<hex_digest>
# where the digest is HMAC-SHA256(HTTP_WEBHOOK_SECRET, raw_request_body) in lowercase hex.
#
# Example (bash):
#   BODY='{"content":"hello"}'
#   SIG=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$HTTP_WEBHOOK_SECRET" | cut -d' ' -f2)
#   curl -X POST http://localhost:8080/webhook \
#     -H "Content-Type: application/json" \
#     -H "X-IronClaw-Signature: sha256=$SIG" \
#     -d "$BODY"
#
# DEPRECATED: Passing "secret" in the JSON body still works but will be removed in a future release.

# Signal Channel (optional, requires signal-cli daemon --http)
# SIGNAL_HTTP_URL=http://127.0.0.1:8080
# SIGNAL_ACCOUNT=+1234567890
# SIGNAL_ALLOW_FROM=+1234567890,uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  # comma-separated, * for all, empty = deny/require pairing
# SIGNAL_ALLOW_FROM_GROUPS=                        # comma-separated group IDs, * for all, empty = deny all groups
# SIGNAL_DM_POLICY=pairing                         # open | allowlist | pairing
# SIGNAL_GROUP_POLICY=allowlist                    # allowlist | open | disabled
# SIGNAL_GROUP_ALLOW_FROM=                         # comma-separated, empty = inherit from ALLOW_FROM
# SIGNAL_IGNORE_ATTACHMENTS=false
# SIGNAL_IGNORE_STORIES=true

# Agent Settings
AGENT_NAME=ironclaw
AGENT_MAX_PARALLEL_JOBS=5
AGENT_JOB_TIMEOUT_SECS=3600
AGENT_STUCK_THRESHOLD_SECS=300
# Maximum tokens per job (0 = unlimited, also settable via settings.json agent.max_tokens_per_job)
# AGENT_MAX_TOKENS_PER_JOB=0
# Enable planning phase before tool execution (default: true)
AGENT_USE_PLANNING=true

# Self-repair settings
SELF_REPAIR_CHECK_INTERVAL_SECS=60
SELF_REPAIR_MAX_ATTEMPTS=3

# Heartbeat settings (proactive periodic execution)
# When enabled, reads HEARTBEAT.md checklist and reports findings
HEARTBEAT_ENABLED=false
HEARTBEAT_INTERVAL_SECS=1800
HEARTBEAT_NOTIFY_CHANNEL=cli
HEARTBEAT_NOTIFY_USER=default

# Memory hygiene settings (automatic cleanup of stale workspace documents)
# Runs on each heartbeat tick; identity files (IDENTITY.md, SOUL.md) are never deleted
# MEMORY_HYGIENE_ENABLED=true
# MEMORY_HYGIENE_DAILY_RETENTION_DAYS=30         # delete daily/ docs older than this many days
# MEMORY_HYGIENE_CONVERSATION_RETENTION_DAYS=7   # delete conversations/ docs older than this many days
# MEMORY_HYGIENE_CADENCE_HOURS=12                # minimum hours between cleanup passes

# Docker Sandbox
# SANDBOX_ENABLED=true
# SANDBOX_POLICY=readonly                # readonly, workspace_write, or full_access
# SANDBOX_ALLOW_FULL_ACCESS=false        # REQUIRED second opt-in for full_access policy.
#                                        # FullAccess bypasses Docker entirely and runs
#                                        # commands directly on the host. Without this
#                                        # set to "true", full_access is downgraded to
#                                        # workspace_write.
# SANDBOX_IMAGE=ironclaw-worker:latest
# SANDBOX_TIMEOUT_SECS=120
# SANDBOX_MEMORY_LIMIT_MB=2048

# Safety settings
SAFETY_MAX_OUTPUT_LENGTH=100000
SAFETY_INJECTION_CHECK_ENABLED=true

# Restart Feature (Docker containers only)
# Set IRONCLAW_IN_DOCKER=true in the container entrypoint to enable the restart feature.
# Without this, the restart tool and /restart command will be disabled.
# IRONCLAW_IN_DOCKER=false
# IRONCLAW_RESTART_DELAY=5          # default wait before exit (seconds, range: 1-30)
# IRONCLAW_MAX_FAILURES=10          # max consecutive failures before container exits

# Logging
RUST_LOG=ironclaw=debug,tower_http=debug
