LLM Providers
Nine provider slots. Switching is a settings change; the graph is provider-agnostic.
Supported providers
Section titled “Supported providers”| Provider | LangChain wrapper | Default model | Notes |
|---|---|---|---|
| Anthropic | ChatAnthropic | claude-sonnet-4-5 | Native SDK |
| OpenAI | ChatOpenAI | gpt-4o | Native SDK |
| Google Gemini | ChatGoogleGenerativeAI | gemini-2.5-pro | Native SDK |
| Groq | ChatGroq | llama-3.1-70b-versatile | Native SDK |
| xAI Grok | ChatOpenAI | model per grok.model | OpenAI-compatible, base URL x.ai |
| DeepSeek | ChatOpenAI | deepseek-chat | OpenAI-compatible |
| Qwen | ChatOpenAI | qwen-max | OpenAI-compatible (DashScope) |
| GLM (Zhipu AI) | ChatOpenAI | glm-4 | OpenAI-compatible |
| Local | ChatOpenAI | user-set | OpenAI-compatible localhost — Ollama, LM Studio, Docker, OpenRouter |
Anything that speaks OpenAI’s API works via the Local slot — set local.baseUrl to point at it.
On xAI Grok: it’s a selectable provider option (
generativeAi.option: "XGrok") and key resolution routes it tohttps://api.x.ai/, but under the hood the canonicalPROVIDER_REGISTRYaliases Grok to the Anthropic webview provider rather than giving it a first-class agent-mode entry. Treat the other eight slots as the fully independent ones.
Selection
Section titled “Selection”Resolution order: SecretStorage (keychain) → settings.json → credential-proxy indirection if enabled. Placeholder strings ("apiKey", "YOUR_API_KEY_HERE", "not-needed") are rejected before the SDK sees them.
Two factory paths
Section titled “Two factory paths”| Mode | Factory | Output |
|---|---|---|
| Agent | buildChatModel() → LangChain wrapper | Fed into the deepagents pipeline via AgentFactory |
| Inline completion | CompletionProviderFactory.getProvider() | Returns ICodeCompleter — GroqLLM, QwenLLM, GeminiLLM, LocalLLM |
Automatic failover
Section titled “Automatic failover”ProviderFailoverService monitors provider health, classifies errors, and switches to a backup on failure.
Error classes:
| Reason | Triggers | Cooldown |
|---|---|---|
auth | HTTP 401, 403 | 10 min |
rate_limit | HTTP 429 | 1 min |
billing | Billing / quota errors | 30 min |
timeout | Request timeout | 30 s |
overloaded | HTTP 503, 529 | 2 min |
model_not_found | HTTP 404 | 1 hr |
format | Schema / format errors | — |
unknown | Everything else | — |
Health state machine: healthy → degraded → down → healthy. A probe recovery attempt fires 30 s before cooldown expires, restoring the provider without waiting out the full timer.
Failover resolution: resolveProvider(primary) checks the primary → walks candidate list respecting cooldowns → returns first with valid creds. The response carries an isFallback flag so callers know a switch happened. Emits provider_switch, health_update, probe_recovery events.
Settings:
| Setting | Default | Purpose |
|---|---|---|
codebuddy.failover.enabled | true | Enable automatic failover |
codebuddy.failover.providers | [] | Ordered fallback list; empty = auto-detect from configured keys |
Cost tracking
Section titled “Cost tracking”CostTrackingService records per-provider token usage against per-model pricing tables (30+ models, separate input / output / cache-read / cache-creation rates). See Cost Tracking.
Provider settings
Section titled “Provider settings”Full setting list at Settings Reference. Common shape:
| Setting | Purpose |
|---|---|
generativeAi.option | Active provider — Anthropic, OpenAI, Gemini, Groq, XGrok, Deepseek, Qwen, GLM, Local |
{provider}.apiKey | API key (typically anthropic.apiKey, openai.apiKey, google.gemini.apiKeys, etc.) |
{provider}.model | Model name for that provider |
local.baseUrl | Endpoint for the Local slot |