Providers

Switch between Claude, GPT-4o, and Gemini

Tutti ships with four built-in LLM providers. They all implement the same LLMProvider interface, so you can swap them with a single line change.

Anthropic (Claude)

import { AnthropicProvider } from "@tuttiai/core";

const provider = new AnthropicProvider();
// or with explicit key:
const provider = new AnthropicProvider({ api_key: "sk-ant-..." });
OptionDefaultDescription
api_keyANTHROPIC_API_KEY env varAPI key

Models: claude-sonnet-4-20250514, claude-opus-4-20250514, claude-haiku-4-20250514

OpenAI (GPT)

import { OpenAIProvider } from "@tuttiai/core";

const provider = new OpenAIProvider();
// or with custom config:
const provider = new OpenAIProvider({
  api_key: "sk-...",
  base_url: "https://your-azure-endpoint.openai.azure.com",
});
OptionDefaultDescription
api_keyOPENAI_API_KEY env varAPI key
base_urlOpenAI defaultCustom endpoint (Azure, proxies)

Models: gpt-4o, gpt-4o-mini, or any model your endpoint supports.

Google Gemini

import { GeminiProvider } from "@tuttiai/core";

const provider = new GeminiProvider();
// or with explicit key:
const provider = new GeminiProvider({ api_key: "AIza..." });
OptionDefaultDescription
api_keyGEMINI_API_KEY env varAPI key

Models: gemini-2.0-flash (default), gemini-2.0-pro

:::caution Gemini requires an API key — it will throw at construction time if neither api_key nor GEMINI_API_KEY is set. :::

OpenRouter (300+ models, one API key)

OpenRouter is an OpenAI-compatible aggregator that routes requests to 300+ models across providers (Anthropic, OpenAI, Google, Meta, Mistral, …) through a single API key. Use it when you want to try many models without juggling provider-specific keys, or when you want OpenRouter’s cross-provider failover.

import { OpenRouterProvider } from "@tuttiai/core";

const provider = new OpenRouterProvider();
// or with explicit options:
const provider = new OpenRouterProvider({
  api_key: "sk-or-...",
  http_referer: "https://example.com",  // opt-in attribution for openrouter.ai/rankings
  x_title: "My App",                     // opt-in attribution for openrouter.ai/rankings
  route: "fallback",                     // retry against backup providers on error
  models: ["anthropic/claude-sonnet-4", "openai/gpt-4o"], // ordered fallback list
});
OptionDefaultDescription
api_keyOPENROUTER_API_KEY env varAPI key
base_urlhttps://openrouter.ai/api/v1Override for self-hosted OpenRouter forks
http_refererunsetOpt-in HTTP-Referer attribution header
x_titleunsetOpt-in X-Title attribution header
routeunset'fallback' enables OpenRouter’s cross-provider retry
modelsunsetOrdered list of fallback model ids

Models: namespaced — e.g. anthropic/claude-sonnet-4, openai/gpt-4o, google/gemini-2.0-flash, meta-llama/llama-3.3-70b-instruct. See openrouter.ai/models for the live catalogue.

Cost reporting: OpenRouter returns per-call USD cost inline via its usage: { include: true } extension. The cost is surfaced on ChatResponse.usage.cost_usd and StreamChunk.usage.cost_usd — no second /generation round trip required. Your RunCostStore-backed daily/monthly budgets work identically to the native providers.

Errors: 401 → AuthenticationError, 429 → RateLimitError (with Retry-After parsing), other HTTP errors → ProviderError with status preserved. Same shape as the other providers, so retry/backoff policy is unchanged.

Switching providers

Just change the provider in your score:

import { OpenAIProvider, defineScore } from "@tuttiai/core";

export default defineScore({
  provider: new OpenAIProvider(),
  default_model: "gpt-4o",
  agents: {
    assistant: {
      name: "assistant",
      system_prompt: "You are helpful.",
      voices: [],
    },
  },
});

Per-agent model overrides

The default_model in the score applies to all agents. Individual agents can override it:

agents: {
  fast: {
    name: "Fast Agent",
    model: "claude-haiku-4-20250514",  // cheap and fast
    system_prompt: "Quick answers only.",
    voices: [],
  },
  smart: {
    name: "Smart Agent",
    model: "claude-opus-4-20250514",   // expensive and thorough
    system_prompt: "Think deeply.",
    voices: [],
  },
}

Token budget by model

Different models have different pricing. The TokenBudget knows about each model’s rates:

ModelInput $/M tokensOutput $/M tokens
claude-sonnet-4-20250514$3.00$15.00
claude-opus-4-20250514$15.00$75.00
claude-haiku-4-20250514$0.25$1.25
gpt-4o$2.50$10.00
gemini-2.0-flash$0.10$0.40
{
  assistant: {
    model: "claude-sonnet-4-20250514",
    budget: { max_cost_usd: 0.50 },  // Stop at 50 cents
    // ...
  },
}

Routing between providers

For agent systems where different turns benefit from different models, see the Smart Routing guide. The SmartProvider from @tuttiai/router wraps any of the providers above and picks the cheapest one that can handle each call.

Edit this page on GitHub →