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 cloud providers, hide secrets and configure price, context window and retries.
1 Providers and models
Both blocks are defined in eonyx.json: the provider describes API access, the model binds a specific id to a provider, and you can switch models right inside a session.
1.1 Provider
There is only 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 can reference environment variables ($OPENAI_API_KEY) — they are expanded after the config layers are merged. That way the key never ends up in a file committed to the repository. The same applies to 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 are only needed for the cost indicator in the TUI header ($…); they do not affect behavior. context_window matters more: without it auto-summarization does not work.
1.3 Switching the model on the fly
- In the TUI —
Ctrl+Nor/model: a list of configured models, the current one is marked. - In headless mode — the
-m/--modelflag:
eonyx run -m deepseek-v4-pro "fix the failing test"It is convenient to keep several models in the config: a cheap fast one for rough work and a powerful one for hard tasks.
2 Reliability and verification
How EONYX retries transient failures and how to make sure the config was read without errors.
2.1 Retries and timeouts
The retry block configures how the provider retries transient failures and how long it waits 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 — long token streams must not be cut off by a timeout.
2.2 Checking the configuration
eonyx config # providers (keys hidden), models, default, limits
eonyx info # where the config, data, cache and project root live3 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)