Keel

Docs / AI Infrastructure / AI providers

AI providers

Keel's AI chat runs on the Vercel AI SDK, so the model is a small, swappable dependency rather than a hardcoded API call. Two providers ship wired up out of the box, and adding a third is a few lines.

What's wired

lib/ai/provider.ts imports both official SDK adapters and exposes one function, getChatModel():

  • Anthropic via @ai-sdk/anthropic, defaulting to claude-sonnet-4-6.
  • OpenAI via @ai-sdk/openai, defaulting to gpt-4o-mini.

Each default is overridable without touching code. Set ANTHROPIC_MODEL or OPENAI_MODEL in your env and the provider picks it up:

bash
ANTHROPIC_MODEL=claude-sonnet-4-6
OPENAI_MODEL=gpt-4o-mini

How the provider is selected

resolveProviderId() decides which one to use, in order:

  1. If AI_PROVIDER is set to anthropic or openai, that wins.
  2. Otherwise, whichever API key is present wins (ANTHROPIC_API_KEY, then OPENAI_API_KEY).
  3. If neither key is set, getChatModel() throws, and the chat route returns a clear 503 instead of crashing.

Tip, one key is enough

You don't need to pick a provider explicitly. Drop in a single API key and AI chat just works with it. AI_PROVIDER only matters when both keys are set and you want to pin one.

Adding or swapping a model

Changing the model on an existing provider is env-only (see ANTHROPIC_MODEL / OPENAI_MODEL above). Adding a whole new provider is a small edit to lib/ai/provider.ts:

  1. Install its SDK adapter, e.g. bun add @ai-sdk/google.
  2. Import it and add its id to the AiProviderId union.
  3. Add a branch in resolveProviderId() and getChatModel() that returns google(MODEL), mirroring the two existing branches.

Every adapter returns the same LanguageModel type, so nothing downstream in the streaming route changes.