Skip to main content

Choosing a model — Anthropic, OpenAI, and Gemini on your own key

Kiwi is bring-your-own-key. Workers run on your provider account, and Kiwi supports three providers as equals: Anthropic, OpenAI, and Gemini — plus any endpoint compatible with one of them.

The model id selects the provider

You never pick a provider. You pick a model, and the daemon routes it:

Model idProviderCredential
gemini-* (e.g. gemini-flash-latest)GeminiGEMINI_API_KEY
gpt-*, o1*, o3*, o4*, chatgpt-* (e.g. gpt-5-mini)OpenAIOPENAI_API_KEY
anything else (e.g. claude-opus-4-8)AnthropicANTHROPIC_API_KEY

The OpenAI arm matches the prefixes gpt-, gpt3, gpt4, o1, o3, o4, chatgpt and text-embedding-3. It is a prefix list rather than a bare o because o alone would swallow too much — a future opus-…, or an org's own alias — and a wrong match routes a task to a provider whose key you may never have connected.

Adaptive Thinking: Anthropic's adaptive thinking is requested automatically for supported models (Claude 4.6+). Older models bypass this request so tasks do not fail on unsupported features.

That rule is one function (provider.ProviderOf in pkg/provider/naming.go), not a convention repeated per component. The same call decides:

  • which stored credential the daemon unseals to run the worker,
  • which credential the Planner uses for the planning model,
  • how the call is priced for the per-job budget cap and the Spend page, and
  • which provider the signed execution record names for the run.

A model attributed to one provider for billing and another in the record would be a false attestation, so the tables are held identical by test — including the dashboard's copy of the rule, which is what tells you which key to connect before the daemon decides which key the task needs.

Connecting a key

In the dashboard, connect keys under Integrations. From the CLI:

kiwi creds set anthropic "sk-ant-..."
kiwi creds set openai "sk-..."
kiwi creds set gemini "AI..."
kiwi creds set git "github_pat_..."

Each alias expands to the credential name in the table above and is stored with kind llm. Model keys are validated against the provider when you save them, so a typo is caught at that moment rather than as a mysterious task failure later; a network blip fails open rather than blocking the save.

Keys are stored sealed to a daemon's public key and are only ever plaintext inside the daemon process that runs the task. They are never placed in the sandbox environment — see Sandbox & isolation.

If a task fails because a key is missing, invalid, or out of credits, that reason is surfaced on the job rather than reported as a generic failure.

Models you can pick

Four model ids are built in — claude-opus-4-8, claude-haiku-4-5-20251001, gemini-2.0-flash, gpt-5-mini — and the dashboard's Models page offers a recommended set for one-click add:

ProviderModel
Anthropicclaude-opus-4-8Most capable
Anthropicclaude-sonnet-5Balanced
Anthropicclaude-haiku-4-5-20251001Fast & cheap
OpenAIgpt-5Most capable
OpenAIgpt-5-miniBalanced
OpenAIgpt-4.1-miniFast & cheap
Geminigemini-flash-latestFast & cheap
Geminigemini-2.0-flash

You can also enter any model id your keys can reach — the routing rule is a prefix match, not an allow-list. Models are gated on your connected keys: a model whose provider you have not connected shows as needing that key instead of being offered as runnable, because picking it would produce a job that fails minutes later on the daemon.

Compatible endpoints

Set KIWI_OPENAI_BASE_URL on the daemon to point the OpenAI provider at a compatible endpoint — Azure, a gateway, or a self-hosted server — instead of api.openai.com. No code change or separate provider is involved; routing and credential lookup are unchanged.

The Actor's output ceiling is KIWI_COMPLETION_MAX_TOKENS (default 16000), because the right value is a property of the model rather than of Kiwi. When a reply hits it, the provider reports a truncation error instead of returning the partial text as though it were whole.

Planner and worker models

The model that decomposes the task and the model that edits the code are chosen separately, and both run on your key. See The Planner for how the two interact — and why the model you submit always wins over the one the decomposition suggested.