* refactor: provider adapter system + 7 new search providers Architecture: - Each search backend is a small adapter implementing SearchProvider - 12 providers: custom, tavily, exa, you, jina, bing, mojeek, linkup, firecrawl, duckduckgo + native - WEB_SEARCH_PROVIDER controls selection: auto (fallback chain) or specific provider - Auth always in headers, never in query strings Bug fixes from review feedback: - Fix applyDomainFilters catch block: keep hits with malformed URLs on blocked_domains (can't confirm blocked), drop on allowed_domains (can't confirm allowed) - Add safeHostname() helper: safely extract hostname from URLs without throwing - Replace unsafe new URL(r.url).hostname in 7 providers with safeHostname() - Remove dead code: buildAllHeaders, buildAuthHeaders, parseExtraHeaders from types.ts - Fix WEB_PARMS typo: consistently use WEB_QUERY_PARAM everywhere - AbortSignal forwarded to fetch() in all 12 providers - DuckDuckGo: wrap dynamic import in try/catch for graceful error - Exa: remove double domain filtering (server-side already) - runSearch(): aggregate all provider errors instead of throwing only the last one - Retry logic: check numeric status code directly, retry 5xx/network, skip 4xx Test coverage (44 tests, all passing): - types.test.ts: safeHostname, normalizeHit, applyDomainFilters (20 tests) - index.test.ts: getProviderMode, getProviderChain, getAvailableProviders (13 tests) - custom.test.ts: extractHits flexible response parsing (11 tests) Co-authored-by: FluxLuFFy <195792511+FluxLuFFy@users.noreply.github.com> * security: add guardrails to custom search provider (Option B) - HTTPS-only by default (opt-out: WEB_CUSTOM_ALLOW_HTTP=true) - Private/localhost IPs blocked by default (opt-out: WEB_CUSTOM_ALLOW_PRIVATE=true) - Header allowlist: only known-safe headers allowed unless WEB_CUSTOM_ALLOW_ARBITRARY_HEADERS=true - Configurable timeout in seconds (WEB_CUSTOM_TIMEOUT_SEC, default 15) - Configurable POST body limit (WEB_CUSTOM_MAX_BODY_KB, default 300) - Removed max URL size restriction - Audit log warning on first custom search call - Updated .env.example and README_SEARCH_PROVIDERS.md with all new options * fix: remove custom provider from auto chain (Option 1) Remove customProvider from the auto fallback chain so it is only available when WEB_SEARCH_PROVIDER=custom is explicitly selected. Changes: - Remove customProvider from ALL_PROVIDERS array in providers/index.ts - Add 3 new tests verifying custom is excluded from auto chain - Update README_SEARCH_PROVIDERS.md: auto priority, mode table, note - Update .env.example: auto priority comment, custom mode annotation All 47 tests pass (44 existing + 3 new). Co-Authored-By: @Vasanthdev2004 * fix: address review blockers (routing, abort, config check, domain matching) 1. Native/Codex routing precedence in auto mode shouldUseAdapterProvider() now checks if native/first-party/vertex/foundry or Codex paths are available before falling back to adapter providers. Auto mode: native paths take precedence; adapter is fallback only. 2. AbortError stops provider chain immediately runSearch() now checks for AbortError/aborted signal before continuing the fallback chain. Cancelled searches don't create extra outbound requests. 3. Explicit provider mode fails fast on missing credentials runSearch() validates isConfigured() for explicit modes before attempting requests. Throws clear error: 'Search provider "X" is not configured.' 4. Domain filter exact-or-subdomain matching (fixes suffix collision) New hostMatchesDomain() helper: exact match or .subdomain match. badexample.com no longer matches example.com. 5. Tests: 56 pass (9 new) covering all 4 fixes Co-Authored-By: @Vasanthdev2004 --------- Co-authored-by: Claude Fix <fix@openclaude.local> Co-authored-by: FluxLuFFy <195792511+FluxLuFFy@users.noreply.github.com> Co-authored-by: bot <bot@openclaw.ai>
341 lines
13 KiB
Plaintext
341 lines
13 KiB
Plaintext
# =============================================================================
|
|
# OpenClaude Environment Configuration
|
|
# =============================================================================
|
|
# Copy this file to .env and fill in your values:
|
|
# cp .env.example .env
|
|
#
|
|
# Only set the variables for the provider you want to use.
|
|
# All other sections can be left commented out.
|
|
# =============================================================================
|
|
|
|
# =============================================================================
|
|
# SYSTEM-WIDE SETUP (OPTIONAL)
|
|
# =============================================================================
|
|
# Instead of using a .env file per project, you can set these variables
|
|
# system-wide so OpenClaude works from any directory on your machine.
|
|
#
|
|
# STEP 1: Pick your provider variables from the list below.
|
|
# STEP 2: Set them using the method for your OS (see further down).
|
|
#
|
|
# ── Provider variables ───────────────────────────────────────────────
|
|
#
|
|
# Option 1 — Anthropic:
|
|
# ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
# ANTHROPIC_MODEL=claude-sonnet-4-5 (optional)
|
|
# ANTHROPIC_BASE_URL=https://api.anthropic.com (optional)
|
|
#
|
|
# Option 2 — OpenAI:
|
|
# CLAUDE_CODE_USE_OPENAI=1
|
|
# OPENAI_API_KEY=sk-your-key-here
|
|
# OPENAI_MODEL=gpt-4o
|
|
# OPENAI_BASE_URL=https://api.openai.com/v1 (optional)
|
|
#
|
|
# Option 3 — Google Gemini:
|
|
# CLAUDE_CODE_USE_GEMINI=1
|
|
# GEMINI_API_KEY=your-gemini-key-here
|
|
# GEMINI_MODEL=gemini-2.0-flash
|
|
# GEMINI_BASE_URL=https://generativelanguage.googleapis.com (optional)
|
|
#
|
|
# Option 4 — GitHub Models:
|
|
# CLAUDE_CODE_USE_GITHUB=1
|
|
# GITHUB_TOKEN=ghp_your-token-here
|
|
#
|
|
# Option 5 — Ollama (local):
|
|
# CLAUDE_CODE_USE_OPENAI=1
|
|
# OPENAI_BASE_URL=http://localhost:11434/v1
|
|
# OPENAI_API_KEY=ollama
|
|
# OPENAI_MODEL=llama3.2
|
|
#
|
|
# Option 6 — LM Studio (local):
|
|
# CLAUDE_CODE_USE_OPENAI=1
|
|
# OPENAI_BASE_URL=http://localhost:1234/v1
|
|
# OPENAI_MODEL=your-model-id-here
|
|
# OPENAI_API_KEY=lmstudio (optional)
|
|
#
|
|
# Option 7 — AWS Bedrock (may also need: aws configure):
|
|
# CLAUDE_CODE_USE_BEDROCK=1
|
|
# AWS_REGION=us-east-1
|
|
# AWS_DEFAULT_REGION=us-east-1
|
|
# AWS_BEARER_TOKEN_BEDROCK=your-bearer-token-here
|
|
# ANTHROPIC_BEDROCK_BASE_URL=https://bedrock-runtime.us-east-1.amazonaws.com
|
|
#
|
|
# Option 8 — Google Vertex AI:
|
|
# CLAUDE_CODE_USE_VERTEX=1
|
|
# ANTHROPIC_VERTEX_PROJECT_ID=your-gcp-project-id
|
|
# CLOUD_ML_REGION=us-east5
|
|
# GOOGLE_CLOUD_PROJECT=your-gcp-project-id
|
|
#
|
|
# ── How to set variables on each OS ──────────────────────────────────
|
|
#
|
|
# macOS (zsh):
|
|
# 1. Open: nano ~/.zshrc
|
|
# 2. Add each variable as: export VAR_NAME=value
|
|
# 3. Save and reload: source ~/.zshrc
|
|
#
|
|
# Linux (bash):
|
|
# 1. Open: nano ~/.bashrc
|
|
# 2. Add each variable as: export VAR_NAME=value
|
|
# 3. Save and reload: source ~/.bashrc
|
|
#
|
|
# Windows (PowerShell):
|
|
# Run for each variable:
|
|
# [System.Environment]::SetEnvironmentVariable('VAR_NAME', 'value', 'User')
|
|
# Then restart your terminal.
|
|
#
|
|
# Windows (Command Prompt):
|
|
# Run for each variable:
|
|
# setx VAR_NAME value
|
|
# Then restart your terminal.
|
|
#
|
|
# Windows (GUI):
|
|
# Settings > System > About > Advanced System Settings >
|
|
# Environment Variables > under "User variables" click New,
|
|
# then add each variable.
|
|
#
|
|
# ── Important notes ──────────────────────────────────────────────────
|
|
#
|
|
# LOCAL SERVERS: If using LM Studio or Ollama, the server MUST be
|
|
# running with a model loaded before you launch OpenClaude —
|
|
# otherwise you'll get connection errors.
|
|
#
|
|
# SWITCHING PROVIDERS: To temporarily switch, unset the relevant
|
|
# variables in your current terminal session:
|
|
#
|
|
# macOS / Linux:
|
|
# unset VAR_NAME
|
|
# # e.g.: unset CLAUDE_CODE_USE_OPENAI OPENAI_BASE_URL OPENAI_MODEL
|
|
#
|
|
# Windows (PowerShell — current session only):
|
|
# Remove-Item Env:VAR_NAME
|
|
#
|
|
# To permanently remove a variable on Windows:
|
|
# [System.Environment]::SetEnvironmentVariable('VAR_NAME', $null, 'User')
|
|
#
|
|
# LOAD ORDER:
|
|
# Shell and system environment variables are inherited by the process.
|
|
# Project .env files are only used if your launcher or shell loads them
|
|
# before starting OpenClaude.
|
|
# COMPATIBILITY:
|
|
# System-wide variables work regardless of how you run OpenClaude:
|
|
# npx, global npm install, bun run, or node directly. Any process
|
|
# launched from your terminal inherits your shell's environment.
|
|
#
|
|
# REMINDER: Make sure .env is in your .gitignore to avoid committing secrets.
|
|
# =============================================================================
|
|
|
|
# =============================================================================
|
|
# PROVIDER SELECTION — uncomment ONE block below
|
|
# =============================================================================
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 1: Anthropic (default — no provider flag needed)
|
|
# -----------------------------------------------------------------------------
|
|
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
|
|
# Override the default model (optional)
|
|
# ANTHROPIC_MODEL=claude-sonnet-4-5
|
|
|
|
# Use a custom Anthropic-compatible endpoint (optional)
|
|
# ANTHROPIC_BASE_URL=https://api.anthropic.com
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 2: OpenAI
|
|
# -----------------------------------------------------------------------------
|
|
# CLAUDE_CODE_USE_OPENAI=1
|
|
# OPENAI_API_KEY=sk-your-key-here
|
|
# OPENAI_MODEL=gpt-4o
|
|
|
|
# Use a custom OpenAI-compatible endpoint (optional — defaults to api.openai.com)
|
|
# OPENAI_BASE_URL=https://api.openai.com/v1
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 3: Google Gemini
|
|
# -----------------------------------------------------------------------------
|
|
# CLAUDE_CODE_USE_GEMINI=1
|
|
# GEMINI_API_KEY=your-gemini-key-here
|
|
# GEMINI_MODEL=gemini-2.0-flash
|
|
|
|
# Use a custom Gemini endpoint (optional)
|
|
# GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 4: GitHub Models
|
|
# -----------------------------------------------------------------------------
|
|
# CLAUDE_CODE_USE_GITHUB=1
|
|
# GITHUB_TOKEN=ghp_your-token-here
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 5: Ollama (local models)
|
|
# -----------------------------------------------------------------------------
|
|
# CLAUDE_CODE_USE_OPENAI=1
|
|
# OPENAI_BASE_URL=http://localhost:11434/v1
|
|
# OPENAI_API_KEY=ollama
|
|
# OPENAI_MODEL=llama3.2
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 6: LM Studio (local models)
|
|
# -----------------------------------------------------------------------------
|
|
# LM Studio exposes an OpenAI-compatible API, so we use the OpenAI provider.
|
|
# Make sure LM Studio is running with the Developer server enabled
|
|
# (Developer tab > toggle server ON).
|
|
#
|
|
# Steps:
|
|
# 1. Download and install LM Studio from https://lmstudio.ai
|
|
# 2. Search for and download a model (e.g. any coding or instruct model)
|
|
# 3. Load the model and start the Developer server
|
|
# 4. Set OPENAI_MODEL to the model ID shown in LM Studio's Developer tab
|
|
#
|
|
# The default server URL is http://localhost:1234 — change the port below
|
|
# if you've configured a different one in LM Studio.
|
|
#
|
|
# OPENAI_API_KEY is optional — LM Studio runs locally and ignores it.
|
|
# Some clients require a non-empty value; if you get auth errors, set it
|
|
# to any dummy value (e.g. "lmstudio").
|
|
#
|
|
# CLAUDE_CODE_USE_OPENAI=1
|
|
# OPENAI_BASE_URL=http://localhost:1234/v1
|
|
# OPENAI_MODEL=your-model-id-here
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 7: AWS Bedrock
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# You may also need AWS CLI credentials configured (run: aws configure)
|
|
# or have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY set in your
|
|
# environment in addition to the variables below.
|
|
#
|
|
# CLAUDE_CODE_USE_BEDROCK=1
|
|
# AWS_REGION=us-east-1
|
|
# AWS_DEFAULT_REGION=us-east-1
|
|
# AWS_BEARER_TOKEN_BEDROCK=your-bearer-token-here
|
|
# ANTHROPIC_BEDROCK_BASE_URL=https://bedrock-runtime.us-east-1.amazonaws.com
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Option 8: Google Vertex AI
|
|
# -----------------------------------------------------------------------------
|
|
# CLAUDE_CODE_USE_VERTEX=1
|
|
# ANTHROPIC_VERTEX_PROJECT_ID=your-gcp-project-id
|
|
# CLOUD_ML_REGION=us-east5
|
|
# GOOGLE_CLOUD_PROJECT=your-gcp-project-id
|
|
|
|
|
|
# =============================================================================
|
|
# OPTIONAL TUNING
|
|
# =============================================================================
|
|
|
|
# Max number of API retries on failure (default: 10)
|
|
# CLAUDE_CODE_MAX_RETRIES=10
|
|
|
|
# Enable persistent retry mode for unattended/CI sessions
|
|
# Retries 429/529 indefinitely with smart backoff
|
|
# CLAUDE_CODE_UNATTENDED_RETRY=1
|
|
|
|
# Enable extended key reporting (Kitty keyboard protocol)
|
|
# Useful for iTerm2, WezTerm, Ghostty if modifier keys feel off
|
|
# OPENCLAUDE_ENABLE_EXTENDED_KEYS=1
|
|
|
|
# Disable "Co-authored-by" line in git commits made by OpenClaude
|
|
# OPENCLAUDE_DISABLE_CO_AUTHORED_BY=1
|
|
|
|
# Custom timeout for API requests in milliseconds (default: varies)
|
|
# API_TIMEOUT_MS=60000
|
|
|
|
# Enable debug logging
|
|
# CLAUDE_DEBUG=1
|
|
|
|
|
|
# =============================================================================
|
|
# WEB SEARCH (OPTIONAL)
|
|
# =============================================================================
|
|
# OpenClaude includes a web search tool. By default it uses DuckDuckGo (free)
|
|
# or the provider's native search (Anthropic firstParty / vertex).
|
|
#
|
|
# Set one API key below to enable a provider. That's it.
|
|
|
|
# ── Provider API keys — set ONE of these ────────────────────────────
|
|
|
|
# Tavily (AI-optimized search, recommended)
|
|
# TAVILY_API_KEY=tvly-your-key-here
|
|
|
|
# Exa (neural/semantic search)
|
|
# EXA_API_KEY=your-exa-key-here
|
|
|
|
# You.com (RAG-ready snippets)
|
|
# YOU_API_KEY=your-you-key-here
|
|
|
|
# Jina (s.jina.ai endpoint)
|
|
# JINA_API_KEY=your-jina-key-here
|
|
|
|
# Bing Web Search
|
|
# BING_API_KEY=your-bing-key-here
|
|
|
|
# Mojeek (privacy-focused)
|
|
# MOJEEK_API_KEY=your-mojeek-key-here
|
|
|
|
# Linkup
|
|
# LINKUP_API_KEY=your-linkup-key-here
|
|
|
|
# Firecrawl (premium, uses @mendable/firecrawl-js)
|
|
# FIRECRAWL_API_KEY=fc-your-key-here
|
|
|
|
# ── Provider selection mode ─────────────────────────────────────────
|
|
#
|
|
# WEB_SEARCH_PROVIDER controls fallback behavior:
|
|
#
|
|
# "auto" (default) — try all configured providers, fall through on failure
|
|
# "custom" — custom API only, throw on failure (NOT in auto chain)
|
|
# "firecrawl" — firecrawl only
|
|
# "tavily" — tavily only
|
|
# "exa" — exa only
|
|
# "you" — you.com only
|
|
# "jina" — jina only
|
|
# "bing" — bing only
|
|
# "mojeek" — mojeek only
|
|
# "linkup" — linkup only
|
|
# "ddg" — duckduckgo only
|
|
# "native" — anthropic native / codex only
|
|
#
|
|
# Auto mode priority: firecrawl → tavily → exa → you → jina → bing → mojeek →
|
|
# linkup → ddg
|
|
# Note: "custom" is NOT in the auto chain. To use the custom API provider,
|
|
# you must explicitly set WEB_SEARCH_PROVIDER=custom.
|
|
#
|
|
# WEB_SEARCH_PROVIDER=auto
|
|
|
|
# ── Built-in custom API presets ─────────────────────────────────────
|
|
#
|
|
# Use with WEB_KEY for the API key:
|
|
# WEB_PROVIDER=searxng|google|brave|serpapi
|
|
# WEB_KEY=your-api-key-here
|
|
|
|
# ── Custom API endpoint (advanced) ──────────────────────────────────
|
|
#
|
|
# WEB_SEARCH_API — base URL of your search endpoint
|
|
# WEB_QUERY_PARAM — query parameter name (default: "q")
|
|
# WEB_METHOD — GET or POST (default: GET)
|
|
# WEB_PARAMS — extra static query params as JSON: {"lang":"en","count":"10"}
|
|
# WEB_URL_TEMPLATE — URL template with {query} for path embedding
|
|
# WEB_BODY_TEMPLATE — custom POST body with {query} placeholder
|
|
# WEB_AUTH_HEADER — header name for API key (default: "Authorization")
|
|
# WEB_AUTH_SCHEME — prefix before key (default: "Bearer")
|
|
# WEB_HEADERS — extra headers as "Name: value; Name2: value2"
|
|
# WEB_JSON_PATH — dot-path to results array in response
|
|
|
|
# ── Custom API security guardrails ──────────────────────────────────
|
|
#
|
|
# The custom provider enforces security guardrails by default.
|
|
# Override these only if you understand the risks.
|
|
#
|
|
# WEB_CUSTOM_TIMEOUT_SEC=15 — request timeout in seconds (default 15)
|
|
# WEB_CUSTOM_MAX_BODY_KB=300 — max POST body size in KB (default 300)
|
|
# WEB_CUSTOM_ALLOW_ARBITRARY_HEADERS=false — set "true" to use non-standard headers
|
|
# WEB_CUSTOM_ALLOW_HTTP=false — set "true" to allow http:// URLs
|
|
# WEB_CUSTOM_ALLOW_PRIVATE=false — set "true" to target localhost/private IPs
|
|
# (needed for self-hosted SearXNG)
|