Providers & configuration

Three providers, one program. Switching is an environment variable, not a code change.

export ECKO_API_KEY=sk-...
export ECKO_AI_PROVIDER=openai        # or anthropic, ollama
export ECKO_AI_MODEL=gpt-4o-mini      # optional; each provider has a default

Or per run:

ecko report.ecko --provider anthropic --model claude-sonnet-4-5

The providers

providernotes
openaiThe default.
anthropicClaude models.
ollamaLocal models. No key needed; runs against your own machine.

ECKO_AI_BASE_URL overrides the endpoint, which is how you point at a proxy, a gateway, or an OpenAI-compatible server.

What the runtime normalizes

The differences between providers are real - message shapes, tool-call serialization, streaming frame formats, image encodings, error bodies - and all of them are handled underneath. One ai expression with tools and a session works across all three, and a provider swap does not touch your source.

Errors are parsed per provider, so a failure reports what the provider actually said rather than an empty string.

Configuration is never code

There is no configure() call and no config file the runtime reads. A program's behaviour is a function of its source and its environment, which means a library cannot change your provider behind your back and a code review shows you everything the program decides.

For a project-level default, use the environment block in ecko.json - applied before evaluation and overriding the shell, so a checkout runs the way its author intended:

{ "environment": { "ECKO_AI_PROVIDER": "ollama", "ECKO_AI_MODEL": "llama3" } }

Never put a key in it. That file is committed.

Local models

ollama is the zero-cost, zero-egress option, and worth reaching for when the data should not leave the machine. Quality differs from a frontier model, so it is a real choice rather than a drop-in - but the code is identical, so trying it costs one variable.

No key at all

Everything still runs. See Mock mode.

The full list

Every setting is in Environment variables.