Skip to content

LLM Providers

Nine provider slots. Switching is a settings change; the graph is provider-agnostic.

ProviderLangChain wrapperDefault modelNotes
AnthropicChatAnthropicclaude-sonnet-4-5Native SDK
OpenAIChatOpenAIgpt-4oNative SDK
Google GeminiChatGoogleGenerativeAIgemini-2.5-proNative SDK
GroqChatGroqllama-3.1-70b-versatileNative SDK
xAI GrokChatOpenAImodel per grok.modelOpenAI-compatible, base URL x.ai
DeepSeekChatOpenAIdeepseek-chatOpenAI-compatible
QwenChatOpenAIqwen-maxOpenAI-compatible (DashScope)
GLM (Zhipu AI)ChatOpenAIglm-4OpenAI-compatible
LocalChatOpenAIuser-setOpenAI-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 to https://api.x.ai/, but under the hood the canonical PROVIDER_REGISTRY aliases 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.

sequenceDiagram participant Settings participant KM as getAPIKeyAndModel() participant SS as SecretStorage participant Proxy as CredentialProxy participant BC as buildChatModel() Settings->>KM: generativeAi.option = "Anthropic" KM->>SS: Check OS keychain alt Found SS-->>KM: apiKey else Miss KM->>Settings: settings.json fallback end KM->>KM: Reject placeholder keys<br/>("apiKey", "YOUR_API_KEY_HERE") opt Proxy enabled KM->>Proxy: Route via localhost proxy end KM-->>BC: {apiKey, model, baseUrl?, proxyToken?} BC-->>Settings: LangChain ChatModel

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.

ModeFactoryOutput
AgentbuildChatModel() → LangChain wrapperFed into the deepagents pipeline via AgentFactory
Inline completionCompletionProviderFactory.getProvider()Returns ICodeCompleterGroqLLM, QwenLLM, GeminiLLM, LocalLLM

ProviderFailoverService monitors provider health, classifies errors, and switches to a backup on failure.

Error classes:

ReasonTriggersCooldown
authHTTP 401, 40310 min
rate_limitHTTP 4291 min
billingBilling / quota errors30 min
timeoutRequest timeout30 s
overloadedHTTP 503, 5292 min
model_not_foundHTTP 4041 hr
formatSchema / format errors
unknownEverything 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:

SettingDefaultPurpose
codebuddy.failover.enabledtrueEnable automatic failover
codebuddy.failover.providers[]Ordered fallback list; empty = auto-detect from configured keys

CostTrackingService records per-provider token usage against per-model pricing tables (30+ models, separate input / output / cache-read / cache-creation rates). See Cost Tracking.

Full setting list at Settings Reference. Common shape:

SettingPurpose
generativeAi.optionActive provider — Anthropic, OpenAI, Gemini, Groq, XGrok, Deepseek, Qwen, GLM, Local
{provider}.apiKeyAPI key (typically anthropic.apiKey, openai.apiKey, google.gemini.apiKeys, etc.)
{provider}.modelModel name for that provider
local.baseUrlEndpoint for the Local slot