Home → Providers
Providers & models
Eight 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 |
| Moonshot Kimi | MOONSHOT_API_KEY | Kimi K3, K2.7 Code, K2.6; reasoning replayed as reasoning_content; automatic caching |
| DeepSeek | DEEPSEEK_API_KEY | First-party V4; deepseek-flash at its full 1M window; cache hits at ~1/50th of a miss |
| 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.
Moonshot Kimi
Three models, read from Moonshot's own documentation: kimi-k3
(1M context, the flagship), kimi-k2.7-code (256K, the coding model
and aico's default for this provider) and kimi-k2.6 (256K, general).
Every one of them reasons, and the chain of thought comes back as its own
channel — aico shows it, and sends it back on later turns as the platform asks.
Reasoning is controlled the way each model wants: an effort level on K3, an
on/off switch on K2.6, and nothing at all on K2.7 Code, which thinks always.
Caching is automatic and the cache-hit price is a tenth to a sixth of a miss,
so the cost meter uses the published rates rather than a guess. Temperature is
never sent; the platform fixes it.
Reasoning effort
The Think control beside the model picker offers only the levels the current model accepts — Claude's five, DeepSeek's four, a single rung on Kimi K2.7 Code, which cannot be told anything — and Auto says what the provider does when nothing is sent. Switch to a model that lacks the level you picked and the button shows the one that will actually go out. What Auto means for each provider is set on its card in Settings → Models.
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 and gpt-6 need 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. The gpt-6 family (luna, sol, astra, with a
1.05M window) refuses them the same way:
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. Tool definitions and the system prompt are cached for an hour and the conversation for five minutes, so a pause over five minutes no longer re-writes the whole prefix. One-hour writes are costed at their real 2x. - OpenAI, OpenRouter, Gemini, Z.AI — server-side caching that aico reports hit rates from rather than guesses at. OpenAI requests carry a
prompt_cache_keyon both Chat Completions and Responses, and on the Responses API each step's volatile note stays where it was sent, so every request contains the previous one whole — OpenAI's cache then grows with the conversation instead of stopping at the system prompt (measured: the cached share of each step went from a flat ~14K to the entire previous prompt). - 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. Anthropic's prefix
lifetime is "promptCaching": { "prefixTtl": "1h" } by default;
"5m" uses the shorter one.
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. Spend is costed
at each provider's published rates; the gpt-5.6, gpt-6, deepseek-flash and
deepseek-v4-pro rates were
checked against the published pages on 2026-09-28.