Skip to main content

Provider Selection

Two LLM providers. One dispatcher.

Providers​

ProviderUseSource
AnthropicDefault. Haiku 4.5 for intent/chat/fan-out, Sonnet 4.6 for the tool loop.functions/pivotAiAgent/providers/anthropic.ts
OpenRouterFallback / enterprise routing to GPT, Llama, Mistral, etc. via the OpenAI-compatible API.functions/pivotAiAgent/providers/openrouter.ts

Dispatcher​

Single entry point: functions/pivotAiAgent/providers/index.ts.

export async function callLlm(req: LlmRequest): Promise<LlmResponse> {
switch (req.provider) {
case 'anthropic': return callAnthropicProvider(req)
case 'openrouter': return callOpenRouterProvider(req)
default: throw new Error(`Unknown LLM provider: ${req.provider}`)
}
}

Provider is set per-request in LlmRequest.provider. Resolution happens in ai-config.ts (per-company or per-env override). When no override is set, defaults to Anthropic.

Model routing inside Anthropic​

PhaseModelWhy
Intent classificationHaiku 4.5Fast, cheap, small task.
Chat path responseHaiku 4.5Fast streaming.
Tool loop (data path)Sonnet 4.6Needs the better reasoning for tool selection / multi-hop queries.
Fan-out: answer, widgets, suggestionsHaiku 4.5 × 3 (parallel)The hard work was the tool loop; these are templated transformations of structured data.

Anthropic API key rotation​

functions/pivotAiAgent/providers/anthropic.ts rotates between multiple Anthropic keys (per-user profile) to distribute rate-limit pressure across keys. Configured via env / Secret Manager.

Fallback behavior​

Today, the dispatcher does not automatically fall back from Anthropic to OpenRouter mid-request. A failed Anthropic call surfaces as an error to the user. See Reference: TODOs for the open item to add per-request fallback retry.

Caching​

Anthropic's prompt cache is used for the long system prompts (tool definitions, persona, company memory). Cache reads/writes are recorded separately in LlmUsage so cost accounting reflects the actual cache-hit price. See Token & Cost Tracking.