# ── Model providers (at least one required) ───────────────────────────── ANTHROPIC_API_KEY= GOOGLE_API_KEY= OPENAI_API_KEY= # ── Git hosting (required only for pushing branches / opening PRs) ────── GITHUB_TOKEN= # GITHUB_API_URL=https://api.github.com # override for GitHub Enterprise # ── Long-term memory (optional) — self-hosted supermemory ─────────────── # Run `npx supermemory local` (or the docker-compose service); it prints an # sm_ API key at startup. # SUPERMEMORY_BASE_URL=http://localhost:6767 # SUPERMEMORY_API_KEY=sm_... # ── Firecrawl (optional) — JS-rendering scraper for the Resources page ── # Self-hosted instance (github.com/firecrawl/firecrawl) or cloud API. # Unset = sde-deepagent's built-in fetcher (static pages only). # FIRECRAWL_API_URL=http://localhost:3002 # self-hosted (no key needed) # FIRECRAWL_API_KEY=fc-... # or cloud: implies api.firecrawl.dev # ── Telegram intake (optional) — create a bot via @BotFather ──────────── TELEGRAM_BOT_TOKEN= # TELEGRAM_ALLOWED_CHATS=12345,67890 # required; use * only for explicit allow-all # ── Slack intake (optional) — Socket Mode app, no public URL needed ───── SLACK_BOT_TOKEN= SLACK_APP_TOKEN= # SLACK_ALLOWED_USERS=U0123,U0456 # required; use * only for explicit allow-all # ── Linear intake (optional) ──────────────────────────────────────────── # RECOMMENDED — seatless agent (no Linear seat, webhook-driven): # 1. Linear → Settings → API → create an OAuth application; enable webhooks # and tick the "Agent session events" category; point the webhook URL at # https:///webhooks/linear and copy its signing secret below. # 2. Authorize the app as the agent (actor=app), then exchange the code: # open: https://linear.app/oauth/authorize?client_id=&redirect_uri= # &response_type=code&scope=read,write,app:assignable,app:mentionable&actor=app # then: curl -X POST https://api.linear.app/oauth/token \ # -d client_id= -d client_secret= -d code= \ # -d redirect_uri= -d grant_type=authorization_code # Put the returned access_token in LINEAR_OAUTH_TOKEN (long-lived, Bearer). # 3. In Linear, assign (delegate) an issue to the app — it picks it up and # replies in the agent session. No LINEAR_API_KEY needed. LINEAR_WEBHOOK_SECRET= # webhook signing secret (enables intake) LINEAR_OAUTH_TOKEN= # OAuth app token (actor=app); seatless write-back # # LEGACY — personal key (consumes a seat); enables polling + issue comments: # LINEAR_API_KEY= # LINEAR_TRIGGER=label # "label" (default), or "assignee" (this key's user) # LINEAR_LABEL=agent # only used when LINEAR_TRIGGER=label # LINEAR_POLL_SECONDS=30 # ── LLM cost budgets (USD; unset/0 = unlimited) ───────────────────────── # TASK_BUDGET_USD=5 # abort any single task whose LLM spend exceeds this # DAILY_BUDGET_USD=50 # pause picking up new tasks once today's spend hits this # ── Runtime ────────────────────────────────────────────────────────────── # HOST=127.0.0.1 # non-loopback binds require AUTH_TOKEN # PORT=8321 # SDE_DATA_DIR=/absolute/path/to/sde-deepagent/data # required by Docker Compose # MAX_CONCURRENT_TASKS=2 # TASK_TIMEOUT_SECONDS=3600 # AUTO_FINALIZE=true # REQUIRE_APPROVAL=true # hold every task for human review before push/PR # WORKSPACE_RETENTION=10 # keep N most recent task workspaces on disk # CHECKPOINT_RESUME=true # persist agent state; resume interrupted tasks after a restart # ── API auth (recommended for any networked deployment) ───────────────── # Required for Docker/server deployments that bind beyond loopback. Generate # with: openssl rand -hex 32 # AUTH_TOKEN= # ── Per-repo container sandbox (on by default; reused across tasks) ───── # SANDBOX_DEFAULT=true # set false only to run untrusted commands on the host # SANDBOX_IMAGE=buildpack-deps:bookworm # SANDBOX_NETWORK=bridge # none | bridge — egress policy inside the sandbox # SANDBOX_MEMORY=2g # SANDBOX_CPUS=2 # SANDBOX_IDLE_HOURS=168 # remove a repo's container after this many idle hours (7 days) # ── Per-repo secrets (optional) ───────────────────────────────────────── # Repos can need credentials to run setup/tests. Two ways to supply them # (mix freely per repo); either way, values are injected only into # controller-run setup/tests — never the agent's shell — and redacted from all # output. Prefer sandbox_network: none for repos with secrets. # # (1) Enter values in the UI (Codebases → Secrets), encrypted at rest. Needs a # master key (any high-entropy string; a data key is derived from it): # SECRETS_KEY= # e.g. `openssl rand -hex 32` # # (2) Reference a host env var by name in config/repos.yaml, e.g. # secrets: { REGISTRY_TOKEN: env:NPM_TOKEN } — put the value here: # NPM_TOKEN= # BACKEND_DB_URL= # ── GitHub PR review → auto-revision (needs GITHUB_TOKEN) ─────────────── # GITHUB_REVIEW_POLLING=false # GITHUB_REVIEW_POLL_SECONDS=120 # ── Bounded growth & resilience ───────────────────────────────────────── # RETENTION_DAYS=90 # prune finished-task events + chat-spend rows older than this (0 = keep forever) # REF_CLONE_TTL_MINUTES=15 # refresh chat's read-only repo clones after this long (0 = never refresh) # REF_CLONE_RETENTION_DAYS=14 # remove ref clones not read for this many days (0 = keep forever) # USAGE_FLUSH_SECONDS=30 # persist in-flight LLM spend to the DB this often (0 = every response)