Configuring providers and models in EONYX
EONYX talks to any OpenAI-compatible API.
A provider is the way to reach a backend.
A model binds an id to a provider.
Here is how to connect one, hide the secrets and set price, window and retries.
1 🔧 Providers and models
1.1 Provider
There is one type so far: "openai".
It covers any OpenAI-compatible endpoint.base_url is required.
"providers": {
"openai": { "type": "openai", "base_url": "https://api.openai.com/v1", "api_key": "$OPENAI_API_KEY" },
"openrouter": { "type": "openai", "base_url": "https://openrouter.ai/api/v1", "api_key": "$OPENROUTER_API_KEY" },
"deepseek": { "type": "openai", "base_url": "https://api.deepseek.com", "api_key": "$DEEPSEEK_API_KEY" },
"moonshot": { "type": "openai", "base_url": "https://api.moonshot.cn/v1", "api_key": "$MOONSHOT_API_KEY" }
}api_key and base_url may reference variables such as $OPENAI_API_KEY.They are expanded after the config layers merge.
So the key never lands in a committed file.
The same holds for
report.database_url and MCP headers.1.2 Model
A model links an id, as the API understands it, to a provider:
"models": [
{ "id": "gpt-5", "provider": "openai", "context_window": 400000, "input_price": 1.25, "output_price": 10 },
{ "id": "deepseek-v4-pro", "provider": "deepseek", "context_window": 1000000, "input_price": 0.435, "output_price": 0.87 }
],
"default_model": "deepseek-v4-pro"| Field | Purpose |
|---|---|
id | the model name at the provider |
provider | a key from the providers block |
context_window | window size in tokens — enables history auto-summarization |
input_price | price per 1M input tokens (USD) — for the cost counter |
output_price | price per 1M output tokens (USD) |
Prices only feed the cost indicator in the TUI header.
They change no behaviour.context_window matters more: without it there is no auto-summarization.
1.3 Switching the model on the fly
- In the TUI, press
Ctrl+Nor type/model. The configured models are listed, the current one marked. - Headless, pass
-m/--model:
eonyx run -m deepseek-v4-pro "fix the failing test"Keeping several models around pays off.
A cheap fast one for rough work.
A strong one for the hard problems.
2 🛡️ Reliability and verification
2.1 Retries and timeouts
The retry block controls transient failures and the wait for the first response:
"retry": {
"max_retries": 3,
"base_delay_ms": 500,
"response_header_timeout_sec": 60
}| Field | Default | Meaning |
|---|---|---|
max_retries | 3 | extra attempts on 429/5xx and transport errors (0 disables them) |
base_delay_ms | 500 | the first backoff step; it doubles, capped at 30s; honors Retry-After |
response_header_timeout_sec | 60 | how long to wait for the first response header before streaming starts |
There is deliberately no global Client.Timeout.
A long token stream must never be cut off by a clock.
2.2 Checking the configuration
eonyx config # providers (keys hidden), models, default, limits
eonyx info # where the config, data, cache and project root liveAn unknown field, a wrong type or broken JSON is fatal at startup.
For an unknown field you get its name and line number.
EONYX would rather not start than quietly swallow a typo.
3 📋 Summary
- Provider
type: "openai"+base_url- covers OpenAI, OpenRouter, DeepSeek, Moonshot and local servers
- Secrets
- via
$ENVreferences inapi_key/base_url - expanded after merging
- via
- Model
id+providercontext_windowenables summarization, prices drive the cost counter
- Switching
Ctrl+N//modelin the TUI or-min headless mode
retrymax_retries(3),base_delay_ms(500),response_header_timeout_sec(60)