Home → Providers
Providers & models
Six providers behind one streaming interface. You keep your keys, you pick the model, and nothing is proxied through anyone else.
| Provider | Key | Notes |
|---|---|---|
| OpenAI | OPENAI_API_KEY | Includes the /v1/responses transport — see below |
| Anthropic | ANTHROPIC_API_KEY | Explicit cache_control for ~90% input savings |
| OpenRouter | OPENROUTER_API_KEY | Routes any model; sticky session routing keeps the cache warm |
| Google Gemini | GEMINI_API_KEY | Via the OpenAI-compatible endpoint |
| Z.AI (GLM) | ZAI_API_KEY | Implicit caching; Coding Plan endpoint supported |
| Ollama | none | Local, free, private |
The model name decides the provider, overriding any configured
default. aico -m glm-4.6 goes to Z.AI even if your default is
OpenRouter — so switching model never means also remembering to switch provider.
Where to put your key
aico provider add writes to ~/.aico/settings.json, which
works from any directory. That is the one to use.
A .env file also works, but dotenv reads it from the
current working directory. A key in your project's .env will
not be found when you run aico anywhere else. This is the single most common
setup surprise.
Configuring one
~/.aico/settings.json is the global file; .aico/settings.json
in a project merges over it, so a repo can pin its own model without touching your
defaults.
{
"model": "gpt-5.6-terra",
"providers": {
"openai": {
"reasoningEffort": "high", // none | low | medium | high | xhigh | max
"maxOutputTokens": 32000 // reasoning shares this budget with output
},
"anthropic": {
"thinking": "adaptive",
"maxTokens": 32000
}
}
}
gpt-5.6 needs the Responses API
The gpt-5.6 family (luna, terra, sol) cannot be
driven agentically through Chat Completions at all. It rejects
max_tokens, and refuses function tools whenever any reasoning effort is
set:
Function tools with reasoning_effort are not supported … use /v1/responses
or set reasoning_effort to 'none'.
Setting none "works" but disables the reasoning you are paying for. aico
detects these models and speaks /v1/responses instead, where tools and
reasoning coexist. Nothing to configure. Older gpt-5.x models stay on Chat
Completions, which is correct for them.
Prompt caching
This is where the event log earns its keep. Because the prompt prefix only ever grows, the cacheable part of a request is stable across turns — so caching actually hits instead of being invalidated by a reshuffled history.
- Anthropic — explicit
cache_controlbreakpoints, roughly 90% off repeat input. - OpenAI, OpenRouter, Gemini, Z.AI — server-side caching that aico reports hit rates from rather than guesses at.
- OpenRouter — sticky session routing, so repeat turns land on a machine that already holds the prefix.
Measured across real coding sessions: 79–91% of input tokens served
from cache. /cost reports it per session.
Switch it off with "promptCaching": { "enabled": false } if you are
debugging something and want every request built fresh.
Switching mid-session
/model # list what is configured
/model claude-opus-5 # switch, keeping the session
/cost # what it has spent so far
The session survives the switch, because the transcript is a log rather than a provider-shaped payload. The new model gets the same history, rendered the way it expects.
Spending limits
Checked before every model call, so a breach stops the turn rather than reporting it afterwards. Sub-agent spend counts toward the parent's ceiling.
{
"safetyLimits": {
"maxCostPerSession": 5.00,
"maxTokensPerSession": 2000000
}
}
Both are off unless set — no default can be guessed honestly.