Providers & auth
Three wires, every provider
Section titled “Three wires, every provider”ka does not integrate providers one by one: it speaks three wire protocols, which between them cover essentially every endpoint:
| Wire | Covers |
|---|---|
anthropic_messages |
Anthropic |
openai_chat |
OpenAI and every OpenAI-compatible endpoint: Ollama, vLLM, LM Studio, gateways, DeepSeek, Groq, Mistral, Together, … |
openai_responses |
OpenAI’s Responses API for reasoning models: item-based history, flat tool definitions, reasoning.effort, streamed reasoning summaries |
All three are vendored (reqwest + rustls + hand-rolled SSE): no provider SDKs, no extra weight. Per-model quirks live in a dialect profile (a data table, not code): context window, supported efforts, cache mode, char-per-token ratio, flags like replay_reasoning for byte-exact <think> re-emission on Ollama.
The catalog
Section titled “The catalog”- A curated registry of vendors works selector-only:
openai,anthropic,google,zai,zai-plan,deepseek,mistral,groq,cerebras,qwen,moonshot,xai,nvidia,openrouter,together,fireworks,ollama,lmstudio,llamacpp,vllm. - On top, a generated overlay seeded from models.dev adds 500+ models across 27 vendors, with context windows and published pricing, including subscription coding plans (
zai-coding-plan/glm-5.3and friends) as unpricedplanrows. ka modelslists everything;--no-discoveryskips probing local endpoints.
Local discovery
Section titled “Local discovery”On startup (unless disabled), ka probes well-known local endpoints (Ollama, LM Studio, vLLM, llama.cpp) and converts what it finds into ephemeral catalog rows. Explicit config always wins over discovery.
Provider-native web search
Section titled “Provider-native web search”Some providers run web search on their own servers. With the server_search dialect flag on a model:
[dialects."anthropic/claude-sonnet-5".flags]server_search = truethe wire injects the provider’s own search tool (Anthropic and OpenAI Responses support it) and drops ka’s client-side web_search hand for that model, so no [[search]] API key is needed. The streamed query and sources surface as visible text; failed searches surface as errors, never as silence. Injection honors the web feature toggle: disable web and native search goes with it, fail-closed like every toggle. openai_chat refuses the flag with an instructive error.
The auth ladder
Section titled “The auth ladder”Keys are never written into config files. ka resolves each provider’s key through, in order:
- the environment (
ANTHROPIC_API_KEY, …) ./.envin the project~/.config/ka/.env(created0600)- the OS keyring (via
/key) !cmdindirection: the key is the stdout of a shell command (for vault setups)
# in .envANTHROPIC_API_KEY=sk-ant-…
# or in ka.toml contexts that take a command:# api_key = "!pass show anthropic"ka providers shows every vendor with its key env var and whether it is set.
Fallback chains
Section titled “Fallback chains”When a turn fails on the active model with a provider/auth error after retries are exhausted, ka re-dispatches the same messages on the next entry of your fallback chain (at most 2 hops per turn):
[fallback]models = [ "anthropic/claude-sonnet-5", "openai/gpt-5.1", "ollama/qwen3.5:9b",]