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.

ProviderKeyNotes
OpenAIOPENAI_API_KEYIncludes the /v1/responses transport — see below
AnthropicANTHROPIC_API_KEYExplicit cache_control for ~90% input savings
OpenRouterOPENROUTER_API_KEYRoutes any model; sticky session routing keeps the cache warm
Google GeminiGEMINI_API_KEYVia the OpenAI-compatible endpoint
Moonshot KimiMOONSHOT_API_KEYKimi K3, K2.7 Code, K2.6; reasoning replayed as reasoning_content; automatic caching
DeepSeekDEEPSEEK_API_KEYFirst-party V4; deepseek-flash at its full 1M window; cache hits at ~1/50th of a miss
Z.AI (GLM)ZAI_API_KEYImplicit caching; Coding Plan endpoint supported
OllamanoneLocal, 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.

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.