Models and providers
nimlet talks to one provider at a time. A provider is where requests go and which key signs them; a model is the id you ask for there. Everything else - your config, your sessions, your instructions - stays the same when you switch.
The wired providers
Section titled “The wired providers”| Provider | Default model | Key variable | Endpoint |
|---|---|---|---|
anthropic |
claude-sonnet-4-6 |
ANTHROPIC_API_KEY |
https://api.anthropic.com/v1/messages |
codex |
gpt-5 |
Codex App Server login | Local Codex App Server |
google |
gemini-3.5-flash-lite |
GEMINI_API_KEY |
https://generativelanguage.googleapis.com/v1beta |
hyper |
deepseek-v4-flash |
HYPER_API_KEY |
https://hyper.charm.land/v1/chat/completions |
mistral |
mistral-vibe-cli-with-tools |
MISTRAL_API_KEY |
https://api.mistral.ai/v1/chat/completions |
openai |
gpt-5 |
OPENAI_API_KEY |
https://api.openai.com/v1/responses |
opencode |
deepseek-v4.1-flash |
OPENCODE_API_KEY |
https://opencode.ai/zen/go/v1/chat/completions |
opencodezen |
deepseek-v4-flash |
OPENCODE_API_KEY |
https://opencode.ai/zen/v1/chat/completions |
openrouter |
deepseek/deepseek-v4-flash-0731 |
OPENROUTER_API_KEY |
https://openrouter.ai/api/v1/chat/completions |
codex connects to the codex app-server command on your PATH. Use /login
to sign in through ChatGPT, then /provider codex. /models refresh asks the
App Server for its available models.
google is the Gemini API - the key-based service you get from Google AI Studio
(generativelanguage.googleapis.com). It is not Vertex AI, which is a different
host, a different path (projects/<project>/locations/<location>/…), and
different auth (a service account, not an API key); supporting it would be a
provider of its own. The env var is GEMINI_API_KEY, and GOOGLE_API_KEY and
GOOGLE_GENERATIVE_AI_API_KEY are accepted as well, so whichever one you already
export works.
opencode and opencodezen use OPENCODE_API_KEY. Nimlet routes those models
using their models.dev catalog entry and falls back to Chat Completions when the
catalog does not specify another wire format. Zen Gemini models can use hosted
search when the catalog identifies the model as a Google model and the gateway
endpoint can be mapped to the native Google request.
Those are the defaults when your config says nothing: with the matching
environment variable set, nimlet starts against OpenRouter and
deepseek/deepseek-v4-flash-0731.
/provider anthropicswitches provider, and picks that provider’s last model - the one you used before,
remembered in providers.anthropic.last_model. Switching back and forth therefore
costs one command, not two. /provider alone prints the active name, and
switching saves the provider, current model, and remembered model choices in your
config.
--provider NAME does the same for one run, without saving.
Choosing a model
Section titled “Choosing a model”/model prints the current id/model claude-opus-4-6 switches, and saves itTyping /model opens alphabetized suggestions for the active provider,
including your current and default model, up to 50 entries, each
showing the provider and its context size. The filter starts at two characters,
so /model claude gives you the Claude models the catalog knows about.
A model id is whatever the provider calls it. On OpenRouter that is usually
vendor/model; on the first-party providers it is the bare id. nimlet does not
translate ids between providers, and it will not stop you from typing one that
does not exist - the first request is what tells you.
--model ID overrides for a single run. --api-key KEY and --thinking LEVEL
do the same for their settings.
Resuming a session restores the provider and model that session was using, so picking up old work asks the same model again. That restore does not change your saved defaults.
The model catalog
Section titled “The model catalog”nimlet keeps a copy of the public models.dev catalog at
~/.nimlet/models-dev.json and reads it from disk. A missing or stale copy is
refreshed in the background at startup, so no lookup ever blocks on the network
and a failed fetch cannot stop you working.
The catalog is what tells nimlet:
- the context window, used for the
ctx 42%footer gauge and for deciding when to compact - which thinking levels the model actually supports
- whether the model accepts images
- prices, which is where the cost figures in
/statscome from
/models refreshfetches the catalog (20 second timeout) and replaces the cache atomically. If the
fetch fails you get Could not refresh model metadata; using existing cache. and
the old file stays. The same fetch runs by itself at startup whenever the cache is
missing or older than a day; until it lands, lookups use the older copy or their
built-in fallbacks.
Lookups fail open. For a model the catalog does not have, nimlet falls back: the context window comes from a per-family estimate (1M for Gemini, GPT-5, and GPT-4.1; 200k for Claude and GPT-4o-class models; 128k otherwise), images are assumed to be supported, the full thinking ladder is offered, and no prices are shown.
Thinking levels
Section titled “Thinking levels”The ladder is none, minimal, low, medium, high, xhigh, max. What a
level does depends entirely on the model, so nimlet asks the catalog and adapts:
/thinking prints the active level, e.g. "off" or "high"/thinking high sets it for later turns, and saves it/thinking none turns reasoning off- The menu you see while typing
/thinkinglists only the levels that model has. - If you ask for a level the model does not offer, nimlet snaps to the nearest one
it does; a tie goes to the higher effort, and
nonenever snaps upward. - On a model with no reasoning support at all, setting a level reports
(unsupported by model)and nothing is sent. - With no setting anywhere, the level is
(provider default): yourreasoningblocks in provider options pass through untouched.
Two wires exist behind those levels, chosen by the model:
- Effort-based (current models). Anthropic’s known families take
low/medium/high/max, and the newest takelow/medium/high/xhigh/max.minimalis folded intolow, andxhighfalls back tomaxwhere it is not offered. These use adaptive thinking with a summarized display, soagent.max_tokensis the combined cap on thinking plus answer. - Budget-based reasoning (older models). Nimlet maps the selected level to the provider’s supported token-budget format. That budget is added once to the answer allowance for the request. The exact budget is provider-specific.
Two details worth knowing:
- Setting
agent.thinkingor running/thinkingreplaces anyreasoning,reasoning_effort, orthinkingblock andoutput_config.effortin your provider options. Other options are left alone. This avoids two sources of truth fighting over the same field. NIMLET_THINKING=high nimletoverrides the config for one run, which is handy when you want to try a level without saving it.
A model can also require thinking. On those, /thinking none resolves to
low (thinking required) rather than sending an invalid request.
Hosted web search
Section titled “Hosted web search”/web onturns on the provider’s own search tool. It is hosted, not local: the provider searches the public web as part of the same request, so there is no nimlet-side fetching, nothing new to approve, and no extra tool output in your transcript.
It works on anthropic, google, and openai, and on Zen’s Gemini models,
which nimlet sends to the provider’s native Google endpoint. Anywhere else,
/web reports:
on (this provider or model has no hosted search)Hosted search is per model, not just per provider: switching to a Zen model that is served on the gateway’s OpenAI-compatible path turns it off again.
Hosted search is only offered to the model in act mode, and when it is active the
model is told to use it for current docs, APIs, and facts that are not in the
repository. The setting is saved as agent.web_search.
Images and attachments
Section titled “Images and attachments”When you attach an image with @ or by pasting an image file path, nimlet checks
the catalog before sending it. Models that accept image input get the image;
models that do not have images dropped from the request rather than failing the
turn. Unknown models are assumed to accept them.
Costs in /stats
Section titled “Costs in /stats”Prices come from the catalog, per million tokens, including separate cache read and
write rates. nimlet estimates the cost of each response and adds them up for the
session, so /stats can show:
Latest: ↑1204 ↓356 R980 CH81.4%Context: 42120 / 200000 (21%)Latest cost: $0.0042Session: ↑18904 ↓4210Session cost: $0.0731These are estimates from published prices, not billing. A provider’s own dashboard is the authority, and models missing from the catalog show no cost at all.
Where choices are saved
Section titled “Where choices are saved”/model, /provider, /thinking, /web, and /theme write to your config
immediately - the project config if the project is trusted and has a .nimlet
directory, otherwise the global one. That is why a model you picked last week is
already selected today.
Startup flags (--provider, --model, --thinking, --api-key, --tools) are
deliberately the opposite: they apply to one process and are never written back.
Where to go next
Section titled “Where to go next”- Configuration for the config keys behind all of this
- Context and compaction for how the context window is resolved and used
- Commands and shortcuts for
/doctor, which prints the endpoint and key status without revealing a key