Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Environment variables, complete

Every variable the runtime reads, grouped by subsystem. The dozen an operator actually sets are on Environment variables; this page is the exhaustive list, derived from current code paths in:

  • packages/coding-agent/src/**
  • packages/ai/src/** (provider/auth resolution used by coding-agent)
  • packages/utils/src/** and packages/tui/src/** where those vars directly affect coding-agent runtime

It documents only active behavior.

Resolution model and precedence

Most runtime lookups use $env from @veyyon/utils (packages/utils/src/env.ts).

$env precedence, high to low:

  1. Existing process environment (Bun.env)
  2. Project .env ($PWD/.env) for keys not already set
  3. Agent .env (~/.veyyon/profiles/default/agent/.env, respecting VEYYON_CONFIG_DIR / VEYYON_CODING_AGENT_DIR) for keys not already set
  4. Config-root .env (~/.veyyon/profiles/default/.env, respecting VEYYON_CONFIG_DIR and the active profile) for keys not already set
  5. Home .env (~/.env) for keys not already set

Precedence is not the same as load order, and the difference matters if you are reading the source. Part of the home .env is applied FIRST, by packages/utils/src/dotenv-home.ts, because a VEYYON_CODING_AGENT_DIR or XDG_CONFIG_HOME set there sets where layers 3 and 4 are. packages/utils/src/dirs.ts imports that module before it resolves anything, so a directory is never computed from a pre-.env environment. env.ts then applies all four layers in full, overriding the values home contributed and nothing else, and refreshes the directory resolver. The result is the precedence listed above, whichever module a program imported.

That early phase applies only the variables that decide where a directory is: VEYYON_CODING_AGENT_DIR, VEYYON_CONFIG_DIR, and the four XDG_* bases. Everything else in your home .env, including every API key, waits for env.ts. The reason is that whatever is in the environment that early is inherited by every process veyyon spawns, and the sandboxed evaluator that runs your eval code is one of them: it should not receive your credentials.

Two variables are deliberately not read from a .env file at all. VEYYON_PROFILE selects the profile, and the profile sets where layers 3 and 4 are, so reading it out of one of them would be circular; set it in your shell or pass --profile. PATH is read only after env.ts has run, which is when binary lookup happens anyway, so extending PATH in a .env works as it always has.


1) Model/provider authentication

These are consumed via getEnvApiKey() (packages/ai/src/env-api-key.ts) unless noted otherwise.

Core provider credentials

The provider-first projection of this map lives in Providers; the two tables are two views of one source.

VariableUsed forRequired whenNotes / precedence
OPENAI_CODEX_OAUTH_TOKENOpenAI Codex OAuth authUsing openai-codex provider
BASETEN_API_KEYBaseten authUsing baseten provider
CMD_API_KEYCommand Code authUsing command-code providerPreferred key alias; endpoint https://api.commandcode.ai/provider/v1, default moonshotai/Kimi-K2.7-Code
COMMAND_CODE_API_KEYCommand Code authUsing command-code provider without CMD_API_KEYFallback after CMD_API_KEY; keys are issued at https://commandcode.ai/studio/provider
NOUS_API_KEYNous Research explicit/headless authUsing nous-research without a /loginEither login is preferred: nous-research (device flow) or nous-research-api-key (pasted key); endpoint https://inference-api.nousresearch.com/v1, default anthropic/claude-sonnet-4.6
COREWEAVE_API_KEYCoreWeave authUsing coreweave providerTakes precedence over WANDB_API_KEY
WANDB_API_KEYCoreWeave authUsing coreweave providerFallback after COREWEAVE_API_KEY
DEVIN_API_KEYDevin authUsing devin provider
SAKANA_API_KEYSakana authUsing sakana providerTakes precedence over FUGU_API_KEY
FUGU_API_KEYSakana authUsing sakana providerFallback after SAKANA_API_KEY
ANTHROPIC_OAUTH_TOKENAnthropic API authUsing Anthropic with OAuth token authTakes precedence over ANTHROPIC_API_KEY for provider auth resolution
ANTHROPIC_API_KEYAnthropic API authUsing Anthropic without OAuth tokenFallback after ANTHROPIC_OAUTH_TOKEN
ANTHROPIC_FOUNDRY_API_KEYAnthropic via Azure Foundry / enterprise gatewayCLAUDE_CODE_USE_FOUNDRY enabledTakes precedence over ANTHROPIC_OAUTH_TOKEN and ANTHROPIC_API_KEY when Foundry mode is enabled
OPENAI_API_KEYOpenAI authUsing OpenAI-family providers without explicit apiKey argumentUsed by OpenAI Completions/Responses providers
GEMINI_API_KEYGoogle Gemini authUsing google provider modelsPrimary key for Gemini provider mapping
GOOGLE_API_KEYGemini image tool auth fallbackUsing gemini_image tool without GEMINI_API_KEYUsed by coding-agent image tool fallback path
GROQ_API_KEYGroq authUsing Groq models
CEREBRAS_API_KEYCerebras authUsing Cerebras models
FIREWORKS_API_KEYFireworks authUsing Fireworks models
FIREPASS_API_KEYFire Pass authUsing Fire Pass models
TOGETHER_API_KEYTogether authUsing together provider
AIMLAPI_API_KEYAIML API authUsing aimlapi providerOpenAI-compatible AIML API endpoint at https://api.aimlapi.com/v1
HUGGINGFACE_HUB_TOKENHugging Face authUsing huggingface providerPrimary Hugging Face token env var
HF_TOKENHugging Face authUsing huggingface providerFallback when HUGGINGFACE_HUB_TOKEN is unset
SYNTHETIC_API_KEYSynthetic authUsing Synthetic models
NVIDIA_API_KEYNVIDIA authUsing nvidia provider
NANO_GPT_API_KEYNanoGPT authUsing nanogpt provider
NOVITA_API_KEYNovita authUsing novita provider
VENICE_API_KEYVenice authUsing venice provider
LITELLM_API_KEYLiteLLM authUsing litellm providerOpenAI-compatible LiteLLM proxy key
LM_STUDIO_API_KEYLM Studio auth (optional)Using lm-studio provider with authenticated hostsLocal LM Studio usually runs without auth; any non-empty token works when a key is required
OLLAMA_API_KEYOllama auth (optional)Using ollama provider with authenticated hostsLocal Ollama usually runs without auth; any non-empty token works when a key is required
LLAMA_CPP_API_KEYllama.cpp auth (optional)Using llama.cpp provider with authenticated hostsLocal llama.cpp usually runs without auth; any non-empty token works when a key is configured
XIAOMI_API_KEYXiaomi MiMo authUsing xiaomi provider
XIAOMI_TOKEN_PLAN_AMS_API_KEYXiaomi MiMo Token Plan auth (AMS)Using xiaomi-token-plan-ams provider
XIAOMI_TOKEN_PLAN_CN_API_KEYXiaomi MiMo Token Plan auth (CN)Using xiaomi-token-plan-cn provider
XIAOMI_TOKEN_PLAN_SGP_API_KEYXiaomi MiMo Token Plan auth (SGP)Using xiaomi-token-plan-sgp provider
MOONSHOT_API_KEYMoonshot authUsing moonshot provider
XAI_API_KEYxAI authUsing xAI models or as fallback for xai-oauth
XAI_OAUTH_TOKENxAI OAuth/SuperGrok authUsing xai-oauth providerTakes precedence over XAI_API_KEY for xai-oauth
OPENROUTER_API_KEYOpenRouter authUsing OpenRouter modelsAlso used by image tool when preferred/auto provider is OpenRouter
MISTRAL_API_KEYMistral authUsing Mistral models
ZAI_API_KEYz.ai authUsing z.ai modelsAlso used by z.ai web search provider
ZHIPU_API_KEYZhipu Coding Plan authUsing zhipu-coding-plan provider
UMANS_AI_CODING_PLAN_API_KEYUmans AI Coding Plan authUsing umans provider
MINIMAX_API_KEYMiniMax authUsing minimax provider
MINIMAX_CODE_API_KEYMiniMax Code authUsing minimax-code provider
MINIMAX_CODE_CN_API_KEYMiniMax Code CN authUsing minimax-code-cn provider
OPENCODE_API_KEYOpenCode authUsing opencode-go / opencode-zen models
QIANFAN_API_KEYQianfan authUsing qianfan provider
QWEN_OAUTH_TOKENQwen Portal authUsing qwen-portal with OAuth tokenTakes precedence over QWEN_PORTAL_API_KEY
QWEN_PORTAL_API_KEYQwen Portal authUsing qwen-portal with API keyFallback after QWEN_OAUTH_TOKEN
ZENMUX_API_KEYZenMux authUsing zenmux providerUsed for ZenMux OpenAI and Anthropic-compatible routes
VLLM_API_KEYvLLM auth/discovery opt-inUsing vllm provider (local OpenAI-compatible servers)Any non-empty value works for no-auth local servers
CURSOR_ACCESS_TOKENCursor provider authUsing Cursor provider
AI_GATEWAY_API_KEYVercel AI Gateway authUsing vercel-ai-gateway provider
CLOUDFLARE_AI_GATEWAY_API_KEYCloudflare AI Gateway authUsing cloudflare-ai-gateway providerBase URL must be configured as https://gateway.ai.cloudflare.com/v1/<account>/<gateway>/anthropic
ALIBABA_CODING_PLAN_API_KEYAlibaba Coding Plan authUsing alibaba-coding-plan provider
DEEPSEEK_API_KEYDeepSeek authUsing DeepSeek models
KILO_API_KEYKilo authUsing Kilo models
OLLAMA_CLOUD_API_KEYOllama Cloud authUsing ollama-cloud provider
WAFER_SERVERLESS_API_KEYWafer Serverless authUsing wafer-serverless providerPay-as-you-go Wafer SKU; validated against https://pass.wafer.ai/v1/models
GITLAB_TOKENGitLab Duo authUsing gitlab-duo provider

/login nous-research stores the Portal refresh token and supplies refreshed short-lived inference access tokens to requests and model discovery. When no stored OAuth credential is selected, NOUS_API_KEY supplies the headless fallback.

GitHub/Copilot tokens

VariableUsed forNotes
COPILOT_GITHUB_TOKENGitHub Copilot provider authGeneric GitHub tokens are not used here
GH_TOKENGitHub API auth in web scraperWeb scraper fallback after GITHUB_TOKEN
GITHUB_TOKENGitHub API auth in web scraperWeb scraper checks this before GH_TOKEN

Auth broker / auth gateway (remote credential vault)

When the broker is enabled, the local SQLite credential store is bypassed and all OAuth refresh / access tokens live on the broker host. See auth-broker-gateway.md for the full protocol, CLI surface, and 5-min/15-s usage cache layering.

VariableUsed forRequired whenNotes / precedence
VEYYON_AUTH_BROKER_URLBase URL of the remote auth-broker (e.g. https://broker.tailnet:8765); selects broker modeResolving credentials through a broker; also required by veyyon auth-gateway serve (the gateway is itself a broker client)Wins over auth.broker.url in config.yml. When set with no resolvable token, resolveAuthBrokerConfig() hard-errors instead of falling back to local SQLite.
VEYYON_AUTH_BROKER_TOKENBearer token sent on every broker endpoint except /v1/healthzVEYYON_AUTH_BROKER_URL is set and no token is available from auth.broker.token or <config-dir>/auth-broker.tokenResolution: this env → auth.broker.token ($ENV_NAME indirection supported) → <config-dir>/auth-broker.token (mode 0600). <config-dir> is ~/.veyyon/ (respecting VEYYON_CONFIG_DIR).
VEYYON_AUTH_BROKER_SNAPSHOT_TTL_MSFreshness window for the encrypted local broker snapshot cacheOptional in broker modeDefault 3600000 (1 h). Freshness is based on broker snapshot.generatedAt; 0 disables cache reads/writes and forces the old blocking fetch every startup.
VEYYON_AUTH_BROKER_SNAPSHOT_CACHEPath to the encrypted local broker snapshot cacheOptional in broker modeDefaults to ~/.veyyon/profiles/<profile>/cache/auth-broker-snapshot.enc (or XDG cache equivalent). Useful for tests, ephemeral hosts, or relocating the 0600 cache file.

The gateway has no dedicated env vars, it inherits VEYYON_AUTH_BROKER_*. Its own inbound bearer token lives at <config-dir>/auth-gateway.token and is managed via veyyon auth-gateway token.


2) Provider-specific runtime configuration

Anthropic Foundry Gateway (Azure / enterprise proxy)

When CLAUDE_CODE_USE_FOUNDRY is enabled, Anthropic requests switch to Foundry mode:

  • Base URL resolves from FOUNDRY_BASE_URL (fallback remains model/default base URL if unset).

  • API key resolution for provider anthropic becomes: ANTHROPIC_FOUNDRY_API_KEYANTHROPIC_OAUTH_TOKENANTHROPIC_API_KEY.

  • ANTHROPIC_CUSTOM_HEADERS is parsed as comma/newline-separated key: value pairs and merged into request headers. They are also forwarded when ANTHROPIC_BASE_URL points to a non-Anthropic host (e.g. a corporate API gateway), so enterprise gateways requiring proprietary auth headers work without enabling Foundry mode.

  • TLS client/server material can be injected from env values: NODE_EXTRA_CA_CERTS, CLAUDE_CODE_CLIENT_CERT, CLAUDE_CODE_CLIENT_KEY. Each accepts either:

    • a filesystem path to PEM content, or
    • inline PEM (including escaped \n sequences).

    NODE_EXTRA_CA_CERTS is honoured for every provider fetch (OpenAI-compatible, Codex, Ollama, Azure Responses, Google, Anthropic), not just Foundry, Bun’s fetch does not consume the env var natively, so the bundle is merged into RequestInit.tls.ca alongside the system root store. The CLAUDE_CODE_* mTLS material remains Anthropic-Foundry-specific.

VariableValue typeBehavior
CLAUDE_CODE_USE_FOUNDRYBoolean-like string (1, true, yes, on)Enables Foundry mode for Anthropic provider
FOUNDRY_BASE_URLURL stringAnthropic endpoint base URL in Foundry mode
ANTHROPIC_FOUNDRY_API_KEYToken stringUsed for Authorization: Bearer <token>
ANTHROPIC_CUSTOM_HEADERSHeader list stringExtra headers; format header-a: value, header-b: value or newline-separated. Also forwarded outside Foundry whenever ANTHROPIC_BASE_URL is non-Anthropic.
NODE_EXTRA_CA_CERTSPEM path or inline PEMExtra CA chain for server certificate validation
CLAUDE_CODE_CLIENT_CERTPEM path or inline PEMmTLS client certificate
CLAUDE_CODE_CLIENT_KEYPEM path or inline PEMmTLS client private key (must be paired with cert)

Amazon Bedrock

VariableDefault / behavior
AWS_REGIONPrimary region source
AWS_DEFAULT_REGIONFallback if AWS_REGION unset
AWS_PROFILEEnables named profile auth path
AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEYEnables IAM key auth path
AWS_BEARER_TOKEN_BEDROCKHighest-precedence bearer token auth path; skips AWS profile/credential-chain lookup when set
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI / AWS_CONTAINER_CREDENTIALS_FULL_URIMarks Bedrock as available in provider detection (credential resolution itself covers env keys, profiles/SSO/credential_process, then IMDSv2)
AWS_WEB_IDENTITY_TOKEN_FILE + AWS_ROLE_ARNMarks Bedrock as available in provider detection (same caveat as the ECS variables above)
AWS_BEDROCK_SKIP_AUTHIf 1, injects dummy credentials (proxy/non-auth scenarios)
HTTPS_PROXY / HTTP_PROXYHonored via Bun’s native fetch proxy support (the provider no longer ships an AWS SDK / proxy-agent transport)
NO_PROXYExcludes matching hosts from Bun’s native proxy routing

Region fallback in provider code: options.regionAWS_REGIONAWS_DEFAULT_REGIONus-east-1.

Azure OpenAI Responses

VariableDefault / behavior
AZURE_OPENAI_API_KEYRequired unless API key passed as option
AZURE_OPENAI_API_VERSIONDefault v1
AZURE_OPENAI_BASE_URLDirect base URL override
AZURE_OPENAI_RESOURCE_NAMEUsed to construct base URL: https://<resource>.openai.azure.com/openai/v1
AZURE_OPENAI_DEPLOYMENT_NAME_MAPOptional mapping string: modelId=deploymentName,model2=deployment2

Base URL resolution: option azureBaseUrl → env AZURE_OPENAI_BASE_URL → option/env resource name → the model row’s baseUrl in models.yml.

Google Vertex AI

VariableRequired?Notes
GOOGLE_CLOUD_PROJECTYes (unless passed in options)Primary project ID source
GCP_PROJECTFallbackAlternate project ID source
GCLOUD_PROJECTFallbackAlternate project ID source
GOOGLE_CLOUD_PROJECT_IDOAuth login helper onlyUsed by Gemini CLI OAuth project discovery
GOOGLE_VERTEX_LOCATIONYes (unless passed in options)Primary Vertex location source
GOOGLE_CLOUD_LOCATIONFallbackAlternate Vertex location source
VERTEX_LOCATIONFallbackAlternate Vertex location source
GOOGLE_CLOUD_API_KEYConditionalDirect Vertex API-key auth; otherwise ADC fallback can authenticate when project and location are set
GOOGLE_APPLICATION_CREDENTIALSConditionalIf set, file must exist; otherwise ADC fallback path is checked (~/.config/gcloud/application_default_credentials.json)

Kimi

VariableDefault / behavior
KIMI_CODE_OAUTH_HOSTPrimary OAuth host override
KIMI_OAUTH_HOSTFallback OAuth host override
KIMI_CODE_BASE_URLOverrides Kimi usage endpoint base URL (usage/kimi.ts)

OAuth host chain: KIMI_CODE_OAUTH_HOSTKIMI_OAUTH_HOSThttps://auth.kimi.com.

Gemini CLI compatibility

VariableDefault / behavior
VEYYON_AI_GEMINI_CLI_VERSIONOverrides the Gemini CLI user-agent version tag (0.46.0 if unset)
VEYYON_AI_ANTIGRAVITY_VERSIONOverrides the Antigravity / Cloud Code Assist user-agent version tag (2.1.4 if unset)

OpenAI Codex responses (feature/debug controls)

VariableBehavior
VEYYON_CODEX_DEBUG1/true enables Codex provider debug logging
VEYYON_CODEX_WEBSOCKET1/true enables websocket transport preference
VEYYON_OPENAI_STATEFULOverrides the stateful-chaining default for the platform OpenAI Responses API (previous_response_id, forces store: true): on by default against api.openai.com, off elsewhere
VEYYON_CODEX_WEBSOCKET_IDLE_TIMEOUT_MSPositive integer override (default 300000)
VEYYON_CODEX_WEBSOCKET_RETRY_BUDGETNon-negative integer override (default 5)
VEYYON_CODEX_WEBSOCKET_RETRY_DELAY_MSPositive integer base backoff override (default 500)
VEYYON_CODEX_WEBSOCKET_FIRST_EVENT_TIMEOUT_MSPositive integer wait for the first websocket event before falling back to SSE (default 60000). Switches transport rather than failing the request
VEYYON_CODEX_WEBSOCKET_MAX_IDLE_REUSE_MSLongest quiet period a reused socket is trusted for before a fresh handshake (default 30000); 0 disables the ceiling
VEYYON_CODEX_WEBSOCKET_PING_INTERVAL_MSPositive integer keepalive ping interval (default 10000)
VEYYON_CODEX_WEBSOCKET_PONG_TIMEOUT_MSPositive integer wait for a pong before the socket is treated as dead (default 60000)
VEYYON_CODEX_WEBSOCKET_MESSAGE_QUEUE_CAPACITYPositive integer inbound frame queue capacity (default 4096)
VEYYON_OPENAI_STREAM_FIRST_EVENT_TIMEOUT_MSPositive integer OpenAI first-event timeout override; 0 disables. veyyon config set providers.streamFirstEventTimeoutSeconds <seconds> provides the persisted config equivalent
VEYYON_OPENAI_STREAM_IDLE_TIMEOUT_MSPositive integer OpenAI stream idle timeout override; 0 disables. veyyon config set providers.streamIdleTimeoutSeconds <seconds> provides the persisted config equivalent

Cursor provider debug

VariableBehavior
DEBUG_CURSOREnables provider debug logs; 2/verbose for detailed payload snippets
DEBUG_CURSOR_LOGOptional file path for JSONL debug log output

Transport selection (OpenRouter, Perplexity)

Both providers can be reached over two different HTTP APIs, and these pick which one.

VariableBehavior
VEYYON_OPENROUTER_RESPONSESOpenRouter uses the Responses API unless this is exactly 0, which selects chat completions. Any other value leaves the default in place
VEYYON_PERPLEXITY_RESPONSESPerplexity web search uses the Responses API only when this is exactly 1

Prompt cache controls

VariableBehavior
VEYYON_CACHE_RETENTIONIf long, enables long retention where supported (anthropic, openai-responses, Bedrock retention resolution)
VEYYON_CACHE_ENFORCEMENTWhat happens when a request’s cache markers demonstrably did not take effect: off, warn (default), or error. error aborts the turn. Anthropic only. Overridden by an explicit per-request level, and the cache.blockOnRejection setting selects error through the same resolver. See prompt caching.

3) Web search subsystem

Search provider credentials

VariableUsed by
EXA_API_KEYExa search provider and Exa MCP tools
BRAVE_API_KEYBrave search provider
PERPLEXITY_API_KEYPerplexity search provider API-key mode
PERPLEXITY_COOKIESPerplexity cookie-auth search mode
TAVILY_API_KEYTavily search provider
ZAI_API_KEYz.ai search provider (also checks stored OAuth in agent.db)
OPENAI_API_KEY / Codex OAuth in DBCodex search provider availability/auth
VEYYON_CODEX_WEB_SEARCH_MODELCodex search provider model override
MOONSHOT_SEARCH_API_KEY / KIMI_SEARCH_API_KEYKimi/Moonshot search provider env auth
MOONSHOT_SEARCH_BASE_URL / KIMI_SEARCH_BASE_URLKimi/Moonshot search endpoint override
KAGI_API_KEYKagi search provider
JINA_API_KEYJina search provider
PARALLEL_API_KEYParallel search provider
SEARXNG_ENDPOINT, SEARXNG_TOKENSearXNG endpoint and optional bearer token
SEARXNG_BASIC_USERNAME, SEARXNG_BASIC_PASSWORDSearXNG HTTP Basic Auth credentials

SearXNG also reads the equivalent searxng.endpoint, searxng.token, searxng.basicUsername, and searxng.basicPassword settings from ~/.veyyon/profiles/default/agent/config.yml; environment variables are fallbacks.

Anthropic web search auth chain

searchAnthropic() resolves credentials in this order:

  1. ANTHROPIC_SEARCH_API_KEY
  2. authStorage.getApiKey("anthropic") fallback credentials (runtime/config overrides, stored API-key credentials, stored OAuth credentials, then generic Anthropic env fallback: ANTHROPIC_FOUNDRY_API_KEY in Foundry mode, otherwise ANTHROPIC_OAUTH_TOKEN / ANTHROPIC_API_KEY)

For either credential path, base URL resolution is:

  1. ANTHROPIC_SEARCH_BASE_URL
  2. FOUNDRY_BASE_URL when CLAUDE_CODE_USE_FOUNDRY is enabled
  3. ANTHROPIC_BASE_URL
  4. https://api.anthropic.com

Related vars:

VariableDefault / behavior
ANTHROPIC_SEARCH_API_KEYAPI key used exclusively for the Anthropic web search provider. Highest-priority search auth; overrides ANTHROPIC_API_KEY / OAuth / Foundry for search calls without affecting chat completions.
ANTHROPIC_SEARCH_BASE_URLBase URL used exclusively for the Anthropic web search provider. Applied to either ANTHROPIC_SEARCH_API_KEY or fallback Anthropic credentials; overrides ANTHROPIC_BASE_URL (and FOUNDRY_BASE_URL in Foundry mode) for search calls.
ANTHROPIC_SEARCH_MODELSearch model override. Defaults to claude-haiku-4-5.
ANTHROPIC_BASE_URLGeneric fallback base URL for Anthropic requests when no search-specific base URL is set.

Use ANTHROPIC_SEARCH_BASE_URL (optionally with ANTHROPIC_SEARCH_API_KEY) to keep chat routed through an enterprise gateway (ANTHROPIC_BASE_URL or CLAUDE_CODE_USE_FOUNDRY=true) while pointing web search at a direct Anthropic endpoint, or vice versa.

Perplexity OAuth flow behavior flag

VariableBehavior
VEYYON_AUTH_NO_BORROWIf set, disables macOS native-app token borrowing path in Perplexity login flow

4) Python tooling and kernel runtime

VariableDefault / behavior
VEYYON_PYBoolean-like override for the Python eval backend: truthy (1/true/yes/on) enables, any other value disables; unset defers to the eval.py setting (default enabled)
VEYYON_JSSame boolean-like override for the JavaScript eval backend; unset defers to the eval.js setting (default enabled)
VEYYON_PYTHON_SKIP_CHECKIf 1, skips Python interpreter availability checks (subprocess runner still starts on demand)
VEYYON_PYTHON_INTEGRATIONIf 1, opts gated integration tests in (e.g. python-runner-integration.test.ts) into running against real Python
VEYYON_PYTHON_IPC_TRACEIf 1, logs NDJSON frames exchanged with the Python runner subprocess
VEYYON_RUBY_IPC_TRACESame, for the Ruby runner subprocess
VEYYON_JULIA_IPC_TRACESame, for the Julia runner subprocess
VIRTUAL_ENVHighest-priority venv path for Python runtime resolution

Extra conditional behavior:

  • If BUN_ENV=test or NODE_ENV=test, Python availability checks are treated as OK and warming is skipped.
  • Python env filtering denies common API keys and allows safe base vars + LC_, XDG_, VEYYON_ prefixes.
  • Every eval kernel spells its IPC trace variable VEYYON_<LANGUAGE>_IPC_TRACE, with the language spelled out in full (PYTHON, RUBY, JULIA), not abbreviated the way the source directories are. A language added later follows the same convention: it comes from one helper in packages/coding-agent/src/eval/kernel-base.ts rather than from each kernel formatting its own name.

5) Agent/runtime behavior toggles

VariableDefault / behavior
VEYYON_SMOL_MODELEphemeral model-role override for smol (CLI --smol takes precedence)
VEYYON_STREAM_FRAME_MAX_BYTESBytes one frame of a streamed protocol may occupy before the reader rejects it and cancels the source: a line, a JSONL record, or an SSE event ending at a blank line. Default 67108864 (64 MiB). Covers provider response streams, MCP server stdout and session files. A value that is not a positive integer keeps the default, so a typo cannot remove the bound. The refusal is terminal and never retried.
VEYYON_SLOW_MODELEphemeral model-role override for slow (CLI --slow takes precedence)
VEYYON_PLAN_MODELEphemeral model-role override for plan (CLI --plan takes precedence)
VEYYON_NO_TITLEIf set (any non-empty value), disables auto session title generation on first user message
VEYYON_SKIP_SETUPIf set to any value other than empty/0/false/no (case-insensitive), skips the first-run setup wizard (no setup scenes are shown).
VEYYON_TINY_DEVICEONNX execution provider for local tiny models; overrides the providers.tinyModelDevice setting (setting default: default, which selects CPU-only inference; also supports cpu, gpu, metal/webgpu, auto, cuda, dml, coreml, wasm, webnn, webnn-gpu, webnn-cpu, webnn-npu)
VEYYON_TINY_DTYPEONNX quantization/precision for local tiny models; overrides the providers.tinyModelDtype setting (setting default: default, which selects each model’s shipped dtype, currently q4; also supports auto, fp32, fp16, q8, int8, uint8, q4, bnb4, q4f16, q2, q2f16, q1, q1f16)
VEYYON_NO_INTERLEAVED_THINKINGIf 1, disables Anthropic interleaved thinking budget behavior and uses output-token inflation for older thinking mode
VEYYON_NO_INTENTIf 1, tool schemas ship without the injected i intent parameter, so the model stops stating what each call is for. Tools that already opt out are unaffected
NULL_PROMPTIf true, system prompt builder returns empty string
VEYYON_BLOCKED_AGENTSelf-recursion prevention: read once from the process env when the task tool is constructed, and any spawn whose agent type equals it is rejected with Cannot spawn <name> agent from within itself (recursion prevention). The comparison is against the name the caller wrote, before retired-name resolution, so it must be spelled the way the spawn spells it (deep, not the retired task, unless the caller itself writes task). Nothing in the product sets it; it is a harness/debug knob.
VEYYON_SUBPROCESS_CMDOverrides subagent spawn command (veyyon / veyyon.cmd resolution bypass)
VEYYON_TASK_MAX_OUTPUT_BYTESMax captured output bytes per subagent (default 500000)
VEYYON_TASK_MAX_OUTPUT_LINESMax captured output lines per subagent (default 5000)
VEYYON_TIMINGIf set (any non-empty value), prints a hierarchical timing-span tree to stderr via logger.printTimings(). In interactive mode the tree prints once the agent is ready (before the TUI starts); in print mode it prints after the whole prompt batch completes. Print-mode prompts are wrapped in print:prompt:initial / print:prompt:next spans so each user message shows up as its own row. VEYYON_TIMING=x exits the process with code 0 right after printing in interactive mode (use to measure cold startup only). VEYYON_TIMING=full lists every module-load entry instead of just the top N.
VEYYON_DEBUG_STARTUPIf set (any non-empty value), streams one synchronous [startup] <phase>:start / :done marker line to stderr as each startup phase begins/ends, including command-module imports (cli:load:<name>) and the native addon extraction/dlopen (native:*). Unlike VEYYON_TIMING (which prints only once startup completes), the markers survive a hard hang: the last line on stderr states the phase the process is stuck in. Combine with VEYYON_TIMING freely; markers and the span tree share the same phase names.
VEYYON_PACKAGE_DIROverrides package asset base dir resolution (docs, examples, and CHANGELOG assets)
VEYYON_REPAIR_DISABLEIf 1/true/yes, disables malformed-tool-call schema repair (calls fail instead of being repaired)
VEYYON_DISABLE_LSPMUXIf 1, disables lspmux detection/integration and forces direct LSP server spawning
VEYYON_RPC_EMIT_TITLEBoolean-like flag enabling title events in RPC mode
SMITHERY_URLSmithery web URL override (default https://smithery.ai)
SMITHERY_API_URLSmithery API base URL override (default https://api.smithery.ai)
SMITHERY_API_KEYSmithery API key for managed MCP auth lookup
PUPPETEER_EXECUTABLE_PATHBrowser tool Chromium executable override
LITELLM_BASE_URLLiteLLM proxy base URL fallback (http://localhost:4000/v1 if unset); an explicit baseUrl on the litellm provider in models.yml wins
LM_STUDIO_BASE_URLDefault implicit LM Studio discovery base URL override (http://127.0.0.1:1234/v1 if unset)
OLLAMA_BASE_URLDefault implicit Ollama discovery base URL override (OLLAMA_HOST if unset, then http://127.0.0.1:11434)
OLLAMA_HOSTOllama host used for implicit Ollama discovery when OLLAMA_BASE_URL is unset; accepts Ollama-style values such as 127.0.0.1:11434 or http://host:11434
OLLAMA_CONTEXT_LENGTHPositive integer context-window override for implicit Ollama discovery; affects Veyyon context budgeting only and does not change Ollama’s runtime num_ctx
LLAMA_CPP_BASE_URLDefault implicit Llama.cpp discovery base URL override (http://127.0.0.1:8080 if unset)
VEYYON_EDIT_VARIANTForces edit tool variant when valid (patch, replace, hashline, apply_patch)
VEYYON_STRICT_EDIT_MODEIf 1, suppresses the built-in per-model fallback that turns a hashline default into another mode for models known to do badly with it (today: any model id containing kimi falls back to replace). It does not affect the two overrides that outrank edit.mode anyway: an edit.modelVariants pattern that matches the active model wins first, then VEYYON_EDIT_VARIANT, then edit.mode
VEYYON_FORCE_IMAGE_PROTOCOLForces supported image protocol (kitty, iterm2/iterm, sixel, none) where used
VEYYON_ALLOW_SIXEL_PASSTHROUGHAllows SIXEL passthrough when VEYYON_FORCE_IMAGE_PROTOCOL=sixel
VEYYON_NO_WEBPIf 1 or true (case-insensitive), excludes WebP from image encoding so images are sent as PNG/JPEG only (llama.cpp/Ollama STB decoders cannot read WebP). Read per call, so it takes effect at runtime.
VEYYON_NO_PTYIf 1, disables interactive PTY path for bash tool
VEYYON_DIALECTForce-enables owned (in-band) tool calling with the named dialect when no configured dialect wins: glm, hermes, kimi, xml, anthropic, deepseek, harmony, qwen3, gemini, gemma, minimax, pi-native; 1/true mean glm. Unrecognized values are ignored. Same set as the tools.format setting.
VEYYON_HARMONY_DEBUGDebug. If 1, includes the full removed text as removedBlob in each harmony-leak audit event (the onHarmonyLeak hook); otherwise only a redacted length/hash/preview is emitted. Use to inspect what harmony-leak scrubbing removed.
VEYYON_MCP_TIMEOUT_MSOverrides MCP client request timeout (ms) for every MCP server. 0 disables client-side timeouts (AbortSignal never fires). Invalid (negative or non-numeric) values are ignored with a warning and the per-server config or default (30000) is used
VEYYON_PIPED_STDIN_WAIT_MSHow long veyyon -p "prompt" waits for the FIRST byte of piped stdin when the prompt is already on the command line (default 10000). It bounds only the wait before anything arrives, so a slow or large piped document is still read in full; 0 waits indefinitely, which is what happens when the pipe is your only input. It exists because a parent process that spawns Veyyon with an inherited pipe it never writes to and never closes sends no EOF, and the run would otherwise block forever.
VEYYON_STACKIf 1, fatal CLI errors print the full inspected error (stack + source context) instead of the default concise message + cause chain report
VEYYON_EDIT_FUZZYtrue/1 or false/0 forces fuzzy matching in the edit tool on or off; auto (the default) reads the edit.fuzzyMatch setting. Any other value fails the call
VEYYON_EDIT_FUZZY_THRESHOLDSimilarity floor for fuzzy matching, 0-1. auto (the default) reads the edit.fuzzyThreshold setting. A value outside the range, or not a number, fails the call
VEYYON_STREAM_FIRST_EVENT_TIMEOUT_MSCross-provider first-event watchdog in ms; 0 disables it. A per-request streamFirstEventTimeoutMs wins, and OpenAI-family transports prefer VEYYON_OPENAI_STREAM_FIRST_EVENT_TIMEOUT_MS. Default 100000
VEYYON_STREAM_IDLE_TIMEOUT_MSCross-provider maximum idle gap between streamed events in ms, applied once the first event has arrived; 0 disables it. A per-request streamIdleTimeoutMs wins, and VEYYON_OPENAI_STREAM_IDLE_TIMEOUT_MS is the OpenAI-family alias. Default 120000
VEYYON_NO_THINKING_LOOP_GUARDIf 1, disables the repeated-thinking-block loop detector for the models it normally guards
VEYYON_MAX_AST_FILESPositive integer cap on how many files one ast_edit call may rewrite (default 1000)
VEYYON_TOKENIZER_ACCURATEIf 1, uses the accurate tokenizer instead of the fast estimate. Ignored under NODE_ENV=test
VEYYON_REQ_DEBUGIf 1, dumps every provider HTTP request and its response stream to rr-session-<n>.json and rr-session-<n>.res.log in the process working directory, mode 0600. The dumps include request headers, so they contain credentials. A dump that cannot be written is logged and the request proceeds
VEYYON_PROXYEgress proxy URL for every provider request. VEYYON_PROXY_<PROVIDER> (the provider id uppercased with non-alphanumerics as _, e.g. VEYYON_PROXY_GITHUB_COPILOT) overrides it for one provider. Localhost, RFC1918, link-local and cloud metadata hosts always bypass the proxy, as do NO_PROXY/no_proxy matches
VEYYON_EVAL_SYSTEM_PROMPT_SECTIONSBenchmark instrumentation, not an operator knob. A JSON object of section name to replacement text. When set, the benchmark payload becomes the only source of prompt sections and the run logs that the override is active. Invalid JSON fails the build
VEYYON_EVAL_SYSTEM_PROMPT_STATEMENTSThe statement-level counterpart to the section override, same benchmark-only status. See system prompt architecture

VEYYON_NO_PTY is also set internally when CLI --no-pty is used.


6) Storage and config root paths

These are consumed via @veyyon/utils/dirs and affect where coding-agent stores data.

VariableDefault / behavior
VEYYON_CONFIG_DIRConfig root dirname under home (default .veyyon). A name, not a path: an absolute value is rejected at startup.
VEYYON_PROFILEActivate a named profile (relocates the user base to ~/.veyyon/profiles/<name>)
VEYYON_WORKTREE_DIRBase directory for task-isolation worktrees (default ~/.veyyon/profiles/<name>/wt)
VEYYON_GITHUB_CACHE_DBPath override for the GitHub tool cache database
VEYYON_AUTORESEARCH_DB_DIRDirectory override for the autoresearch database
VEYYON_CODING_AGENT_DIRFull override for the agent directory (default ~/<config dir>/profiles/<active-or-default>/agent)
PWDUsed when matching canonical current working directory in path helpers

7) Shell/tool execution environment

(From packages/utils/src/procmgr.ts and coding-agent bash tool integration.)

VariableBehavior
VEYYON_BASH_NO_CISuppresses automatic CI=true injection into spawned shell env
CLAUDE_BASH_NO_CILegacy alias fallback for VEYYON_BASH_NO_CI
VEYYON_BASH_NO_LOGINDisables login-shell mode; shell args become ['-c'] instead of ['-l','-c']
CLAUDE_BASH_NO_LOGINLegacy alias fallback for VEYYON_BASH_NO_LOGIN
VEYYON_SHELL_PREFIXOptional command prefix wrapper
CLAUDE_CODE_SHELL_PREFIXLegacy alias fallback for VEYYON_SHELL_PREFIX
VISUALPreferred external editor command
EDITORFallback external editor command

Current implementation: VEYYON_BASH_NO_LOGIN/CLAUDE_BASH_NO_LOGIN are active; when either is set, getShellArgs() returns ['-c'].


8) UI/theme/session detection (auto-detected env)

These are read as runtime signals; they are usually set by the terminal/OS rather than manually configured.

VariableUsed for
COLORTERM, TERM, WT_SESSIONColor capability detection (theme color mode)
COLORFGBGTerminal background light/dark auto-detection
TERM_PROGRAM, TERM_PROGRAM_VERSION, TERMINAL_EMULATORTerminal identity in system prompt/context
TMUX_PANE, CMUX_SURFACE_ID, KITTY_WINDOW_ID, TERM_SESSION_ID, WT_SESSIONStable per-terminal session breadcrumb IDs
SHELL, ComSpec, TERM_PROGRAM, TERMSystem info diagnostics
APPDATA, XDG_CONFIG_HOMElspmux config path resolution
HOMEPath shortening in MCP command UI

9) TUI runtime flags (shared package, affects coding-agent UX)

VariableBehavior
VEYYON_NOTIFICATIONSoff / 0 / false suppress desktop notifications
VEYYON_TUI_WRITE_LOGIf set, logs TUI writes to file
VEYYON_HARDWARE_CURSORIf 1, enables hardware cursor mode
VEYYON_NO_SYNC_OUTPUTIf set (any non-empty value), disables DEC 2026 synchronized-output wrappers while keeping TUI autowrap guards
VEYYON_TUI_SYNC_OUTPUT0 disables synchronized output, 1 forces it on. It shares one override tier with VEYYON_NO_SYNC_OUTPUT and VEYYON_FORCE_SYNC_OUTPUT, and an opt-out always beats a force-on. With no override the default comes from TERM_FEATURES, WT_SESSION, a terminal allowlist, and then a runtime DECRQM probe
VEYYON_FORCE_SYNC_OUTPUT1 forces synchronized output on, unless an opt-out is also set
VEYYON_TUI_SCROLL_TRANSPORTalt-arrows releases the mouse grab and moves the transcript to the alternate screen with Alternate Scroll Mode, so the terminal keeps native selection and sends wheel ticks as cursor keys. Any other value keeps the default mouse transport
VEYYON_NO_DECCARAIf set (truthy), disables Kitty DECCARA rectangular-SGR background fills (forces padded-string rendering)
VEYYON_DEBUG_REDRAWIf 1, enables redraw debug logging
VEYYON_FORCE_IMAGE_PROTOCOLForces terminal image protocol detection (kitty, iterm2/iterm, sixel, none)
VEYYON_TUI_RESIZE_IN_PLACE1/true force in-place resize (no alt-screen borrow, no ED3 rewrap); 0/false force the alt-screen fast path. Default-on for Warp, which re-reports its size on alt-screen toggles

10) Commit generation controls

VariableBehavior
VEYYON_COMMIT_TEST_FALLBACKIf true (case-insensitive), force commit fallback generation path
VEYYON_COMMIT_NO_FALLBACKIf true, disables fallback when agent returns no proposal
VEYYON_COMMIT_MAP_REDUCEIf false, disables map-reduce commit analysis path
DEBUGIf set, commit agent error stack traces are printed

Security-sensitive variables

Treat these as secrets; do not log or commit them:

  • Provider/API keys and OAuth/bearer credentials (all *_API_KEY, *_TOKEN, OAuth access/refresh tokens)
  • Cloud credentials (AWS_*, GOOGLE_APPLICATION_CREDENTIALS path may expose service-account material)
  • Search/provider auth vars (EXA_API_KEY, BRAVE_API_KEY, PERPLEXITY_API_KEY, Anthropic search keys)
  • Foundry mTLS material (CLAUDE_CODE_CLIENT_CERT, CLAUDE_CODE_CLIENT_KEY, NODE_EXTRA_CA_CERTS when it points to private CA bundles)
  • VEYYON_REQ_DEBUG is not a secret itself, but the rr-session-*.json dumps it writes into the working directory record request headers verbatim, so a dump carries whatever credential authenticated the request. Delete the files or keep them out of the repository

Python runtime also explicitly strips many common key vars before spawning kernel subprocesses (packages/coding-agent/src/eval/py/runtime.ts).