Providers and gateways
Every provider, gateway and local runtime Nib supports, how it detects them, and how it adapts to each model family.
Nib talks to models through four wire protocols. Almost every provider, gateway and local server speaks at least one of them, which is how one runtime covers so many models.
| Wire protocol | Endpoint | Used for |
|---|---|---|
| Anthropic Messages | POST {root}/v1/messages | Anthropic, and the Anthropic-compatible endpoints of Z.ai, Moonshot, MiniMax, DeepSeek, Qwen, OpenRouter, Vercel, LiteLLM, Ollama and others |
| OpenAI Responses | POST {base}/responses | OpenAI, xAI, and gateways that support it |
| OpenAI Chat Completions | POST {base}/chat/completions | Everything OpenAI-compatible: Groq, Together, Fireworks, Mistral, vLLM, LM Studio, … |
| Google Gemini | …/models/{model}:streamGenerateContent | Google AI Studio |
When a provider speaks more than one, Nib prefers the one that preserves the most: Responses for OpenAI and xAI, Messages for Anthropic, Z.ai, Moonshot and MiniMax, and generateContent for Gemini.
Providers
| Provider | Protocols | Key prefix | Environment variable | Notes |
|---|---|---|---|---|
| Anthropic | Messages | sk-ant- | ANTHROPIC_API_KEY | Prompt caching, token counting and documents fully supported |
| OpenAI | Responses, Chat | sk-proj-, sk-svcacct-, sk-admin- | OPENAI_API_KEY | Native apply_patch tool and encrypted reasoning replay on Responses |
| Google Gemini | Gemini, Chat | AIza | GEMINI_API_KEY, GOOGLE_API_KEY | Thought signatures round-tripped |
| xAI | Responses, Chat | xai- | XAI_API_KEY | Conversation id header for cache affinity |
| DeepSeek | Chat, Messages | — | DEEPSEEK_API_KEY | Reasoning content replayed as required |
| Z.ai (GLM) | Messages, Chat | — | ZAI_API_KEY, ZHIPU_API_KEY | Coding plan endpoint; api.z.ai and open.bigmodel.cn |
| Moonshot (Kimi) | Messages, Chat | — | MOONSHOT_API_KEY, KIMI_API_KEY | .ai and .cn hosts |
| Alibaba Qwen (DashScope) | Chat, Messages | sk-sp- | DASHSCOPE_API_KEY | International, US and China regions |
| MiniMax | Messages, Chat | — | MINIMAX_API_KEY | Messages is MiniMax's recommended path |
| Xiaomi MiMo | Chat, Messages | tp-, ttp- | MIMO_API_KEY | |
| Mistral | Chat | — | MISTRAL_API_KEY | Tool call ids normalized to Mistral's format |
| Groq | Chat | gsk_ | GROQ_API_KEY | |
| Cerebras | Chat | csk- | CEREBRAS_API_KEY | |
| Together AI | Chat | — | TOGETHER_API_KEY | |
| Fireworks AI | Chat, Messages | fw_ | FIREWORKS_API_KEY | |
| DeepInfra | Chat, Messages | — | DEEPINFRA_API_KEY | |
| Novita AI | Chat, Messages | — | NOVITA_API_KEY | |
| SiliconFlow | Chat, Messages | — | SILICONFLOW_API_KEY |
A dash in the key prefix column means the key format isn't distinctive. Pick the provider yourself, or paste the key as a .env line with its variable name.
Cloud platforms
Azure OpenAI, Amazon Bedrock and Google Vertex AI aren't available yet: Nib doesn't support how they authenticate (Microsoft Entra ID for Azure, AWS SigV4 request signing for Bedrock, Google Application Default Credentials for Vertex), so it doesn't offer them as providers and no model picker lists their models.
Gateways
A gateway gives you many models behind one key. Nib treats each gateway as a provider and reads its model list, so you pick models by their gateway slug.
| Gateway | Protocols | Key prefix | Environment variable | Notes |
|---|---|---|---|---|
| OpenRouter | Chat, Messages, Responses | sk-or- | OPENROUTER_API_KEY | Session id for sticky routing; reasoning details replayed; prompt caching for Claude models |
| Vercel AI Gateway | Chat, Messages, Responses | vck_ | AI_GATEWAY_API_KEY | Prompt caching for Claude models |
| LiteLLM proxy | Chat, Messages | — | — | Self-hosted; default http://localhost:4000 |
Other OpenAI-compatible gateways (Portkey, Cloudflare AI Gateway, Helicone, and so on) work as a custom endpoint: give Nib the base URL and any extra headers the gateway needs.
Local models
| Runtime | Default URL | Protocols |
|---|---|---|
| Ollama | http://localhost:11434 | Chat, Messages |
| LM Studio | http://localhost:1234 | Chat, Messages |
| vLLM | http://localhost:8000 | Chat |
| llama.cpp server, SGLang | Your server's URL | Chat |
No key is required for local runtimes. Nib lists the runtime's models and picks one the same way as for any provider (see Models and effort).
Small local models struggle with long agentic sessions. Nib gives them the edit format that suits them best (see below), but expect more retries than with a frontier model. Give the server enough context length; many runtimes default to 4k or 8k tokens, which is too short for an agent.
Auto-detection
In the app you can paste a key, a .env line or a base URL into one field. Nib works out the provider from its shape alone; nothing is sent while it does:
- Recognize. A key's prefix (
sk-ant-,sk-or-,AIza, …) names the provider; the longest matching prefix wins, and a prefix several providers share offers each of them. In a.envline such asOPENAI_API_KEY=…, the variable name decides. If Nib can't place a key, you pick the provider. - Base URLs. A base URL becomes a custom OpenAI-compatible endpoint. If its host belongs to a provider Nib knows, Nib treats it as that provider.
- Keys you already have. Provider keys set in your environment variables are offered too.
- Check. Once the key is saved, one real call checks it and tells you whether the provider answered, refused the key, is out of credit or failed.
- Models. The model list comes from the endpoint, with details from Nib's model catalog (context window, pricing, capabilities).
- Pick. Nib chooses a main model and a small model for auxiliary work, as described in Models and effort.
You can override every result. Auto-detection only fills in a configuration; nothing is hidden.
Per-model-family adapters
The protocol is only half the story. Models from different labs were trained with different tool conventions, and they behave best when the harness speaks their dialect. Nib keeps a profile per model family and adapts to it.
Edit format
| Family | Edit tool | Why |
|---|---|---|
| Claude, Gemini and most open models | Edit (str_replace: exact old text → new text) | The format these models were trained on |
| GPT-5 and later | ApplyPatch, sent as apply_patch (the V4A patch format) | OpenAI's models are trained on it; on OpenAI it is sent as the native tool |
| A few small models, picked by edit benchmarks | EditLines with hash-anchored lines | Each line in Read output carries a short content hash. The model edits by anchor (12:a3) instead of reproducing exact text, which removes the most common failure mode for small models |
Write is available to every family. Fuzzy matching for Edit goes through a ladder (exact; line endings and typographic characters folded; trailing whitespace ignored; indentation ignored; block anchored by its first and last lines) and reports which tier it used, so a near miss doesn't silently edit the wrong place.
Reasoning round-trip
Reasoning models return state that must be sent back on the next turn: Anthropic thinking signatures, OpenAI encrypted reasoning, Gemini thought signatures, and reasoning_content from DeepSeek, Kimi and GLM. Dropping it causes errors on some providers and a quiet loss of quality on others. Nib stores this state opaquely with each message and replays it byte-exact to the same model. When you switch models mid-session, it sends a safe projection instead and notes the change.
Other adaptations
- Tool names and descriptions. GPT models plan with
update_plan, current Claude models without a progress tool, and others withTodoWrite. Hooks and permission rules always see the canonical name. - Deferred tools. GPT models get every tool up front; other models load rarely needed tools with
ToolSearch. See Tools. - Strict schemas. On OpenAI, tool schemas are sent in strict mode, with optional fields made nullable and mapped back.
- Broken tool calls. Open models sometimes emit malformed JSON or tool calls embedded in text (Hermes, Qwen, GLM, MiniMax and Kimi markup). Nib repairs JSON, coerces types against the schema, and extracts text-embedded calls before giving up.
- Parallel calls. Turned off for runtimes that don't support them.
- System prompts. Dynamic context goes where each provider handles it best: a mid-conversation system message on Claude, a
developeritem on OpenAI, a system reminder elsewhere.
Caching and cost
Nib keeps the system prompt and tool list byte-stable across turns so providers can cache them. It sets the cache key each provider understands (prompt_cache_key on OpenAI, the session id on OpenRouter, a conversation header on xAI) and places Anthropic cache breakpoints automatically. Cost is computed per turn from the model's pricing, counting cache reads and writes separately. /cost in the CLI shows the running total.
Retries and fallbacks
Transient errors (rate limits, overloaded servers, dropped streams) are retried with backoff, and the UI tells you what happened: "Rate limited by Anthropic — retrying in 8 s." If a request fails because the endpoint rejects a parameter, Nib learns from the error and retries without it. You can configure a fallback model (fallbackModel in settings); Nib stays on one route as long as it works, to keep the cache warm.
Environment variables
The CLI and daemon pick up keys from these variables:
ANTHROPIC_API_KEY OPENAI_API_KEY GEMINI_API_KEY GOOGLE_API_KEY
OPENROUTER_API_KEY AI_GATEWAY_API_KEY XAI_API_KEY DEEPSEEK_API_KEY
ZAI_API_KEY ZHIPU_API_KEY MOONSHOT_API_KEY KIMI_API_KEY
MINIMAX_API_KEY DASHSCOPE_API_KEY MIMO_API_KEY MISTRAL_API_KEY
GROQ_API_KEY CEREBRAS_API_KEY TOGETHER_API_KEY FIREWORKS_API_KEY
DEEPINFRA_API_KEY NOVITA_API_KEY SILICONFLOW_API_KEYIn the desktop app, keys you paste are stored in the OS keychain instead.