Environment variables

Configuration is environment variables, never code. There is no config file to load, no Ecko.configure(...) call, and no way for a library to change your provider behind your back. A program's behaviour is a function of its source and its environment.

A project can pin its own environment in the environment block of ecko.json, which is applied before evaluation and overrides the surrounding shell - so a checkout runs the way its author intended rather than the way your terminal happens to be set up.

The global flags --key, --provider, --model, --trace and --cache are one-run overrides of the matching variable.

AI and LLM

variablemeaning
ECKO_API_KEYProvider API key. ECKO_LLM_API_KEY is also accepted. Unset means mock mode.
ECKO_AI_PROVIDERopenai (default), openrouter, ollama
ECKO_AI_MODELModel name; each provider has a default
ECKO_AI_BASE_URLOverride the provider endpoint, for a proxy or a compatible server. Must be https, or http to a loopback host, since the API key travels on it; ECKO_ALLOW_HTTP=1 overrides
ECKO_AI_EMBED_MODELEmbedding model; defaults per provider
ECKO_AI_MAX_RETRIESRetries for typed and contract calls. Default 3
ECKO_AI_MAX_CALLSHard cap on total ai calls per process. Unset means unlimited
ECKO_AI_MAX_TOOL_ROUNDSTool-call rounds per ai ... using. Default 8
ECKO_AI_TOOL_TIMEOUT_MSPer-round tool timeout. Default 30000; 0 disables
ECKO_AI_TOOL_MAX_RESULTMax bytes of one tool result fed back to the model. Default 32768; 0 disables
ECKO_AI_CACHEDirectory for the prompt cache
ECKO_TRACE1 traces to stderr; a path writes JSONL
ECKO_RETRY_BASE_MSBase backoff for retry. Default 50

ECKO_AI_MAX_CALLS is the one to set in anything unattended. It is a hard budget: the call that would exceed it fails rather than spending.

Concurrency

variablemeaning
ECKO_MAX_PARALLELConcurrent workers in pmap and tool rounds. Default: all cores
ECKO_MAX_TASKSCap on running async tasks. Default 256

HTTP and WebSocket server

variablemeaning
ECKO_HTTP_WORKERSHow many http.serve handler invocations run at once. Default 8. Worth tuning: leave it alone for handlers that compute, raise it for handlers that wait on a database, a service or ai - see sizing the pool
ECKO_MAX_STREAMSConcurrent streaming/SSE responses. Default 1024; past it a stream is refused with 503
ECKO_HTTP_REQUEST_TIMEOUT_MSPer-request handler timeout. 0 or unset means unlimited
ECKO_HTTP_MAX_BODYMax request body in bytes; a larger one is answered 413 rather than truncated. Default 10 MiB
ECKO_NET_TIMEOUT_MSRead and write deadline on a std.net socket, so a silent peer surfaces an error rather than blocking forever. 0 disables it. Default 30000
ECKO_HTTP_READ_TIMEOUT_MSThe slow-client deadline: how long a connection may take to send its request headers, and thereafter how long it may go silent mid-body before the server answers 408. Applied per body frame, so a slow but steady upload of any size completes. Default 30000
ECKO_MAX_WS_CONNSMax concurrent WebSocket connections. Default 1024

Runtime limits

variablemeaning
ECKO_MAX_DEPTHCall and recursion depth. Default 2000
ECKO_MAX_PARSE_DEPTHHow deep an expression tree may nest, by brackets or by chaining (a + b + c, `x> f> g, else if arms). Default 128`
ECKO_MAX_STEPSOpt-in loop and step budget. Unset means unlimited
ECKO_MAX_ALLOCBytes one value built from a count may hold, and the most one read from a stream may return: a string from *, repeat or the pad family, bytes from random.bytes or io.read_exact, a whole-file fs.read, a buffered HTTP body. Default 256 MiB
ECKO_ARCHIVE_MAX_UNPACKEDTotal bytes an std.archive extraction or a std.zlib decompression may produce. Default 1 GiB

These exist so that adversarial or accidental input degrades into a catchable error instead of exhausting the machine - see Resource limits.

Logging and terminal

variablemeaning
ECKO_LOGLevel filter for the default std.log sink: debug < info < warn < error. Default info
ECKO_BACKTRACEShow Rust's own panic output when the interpreter hits an internal fault. Off by default: the fault is reported as a message and exit 70 either way, and this adds the raw detail for diagnosing it.
NO_COLORAny value disables terminal colour (the convention)
CLICOLOR_FORCEForce colour on even when stdout is not a TTY

Packages

variablemeaning
ECKO_PKG_MAX_BYTESMax download size for a package. Default 50 MiB
ECKO_PKG_MAX_UNPACKEDMax unpacked size. Default 200 MiB
ECKO_ALLOW_HTTP1 or true permits plain-http package sources from non-loopback hosts
ECKO_GIT_BASEOverride the forge base URL, for a private mirror
ECKO_NET_TOKENBearer token attached to package fetches, for a private repository

The two size caps and the https default are there because fetching a package is the moment a program trusts something it did not write. ECKO_ALLOW_HTTP exists for a local registry; needing it against a real host is a warning sign.

Scaffolding

variablemeaning
ECKO_TEMPLATES_REPOWhere ecko scaffold gets templates: an owner/repo, an archive URL, or a local directory read with no network and no cache. Default ecko-lang/templates
ECKO_TEMPLATES_DIRWhere they are cached. Default: the platform cache directory

Secrets

Nothing here should hold a secret except ECKO_API_KEY and ECKO_NET_TOKEN, and neither belongs in a committed file. Put them in your shell, your CI secret store, or a secret manager. Inside a program, wrap sensitive values in secret so they cannot be printed or logged by accident, and reach for std.config when you want layered configuration with declared secret fields.