---
title: "Models and providers"
description: "The four model providers Chickpea can use, where their keys live, and how one turn resolves to one model."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.chickpea.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Models and providers

A **model provider** is the service that runs the model behind an Agent's replies: Anthropic, OpenAI, OpenRouter, or Cloudflare Workers AI. Where a connection gives an Agent an outside account to act on, a provider supplies the model that writes the answer. This page covers the four providers, where their keys live, how one turn resolves to one model, and the catalog behind the model picker.

## The providers

Every model is written `<provider>/<model>`. Four providers ship with Chickpea, and the onboarding wizard offers all four.

| Provider | Example specifier | What it needs |
|---|---|---|
| Anthropic | `anthropic/claude-sonnet-5` | `ANTHROPIC_API_KEY`, or a key saved in Admin |
| OpenAI | `openai/gpt-5.6-terra` | `OPENAI_API_KEY`, or a key saved in Admin |
| OpenRouter | `openrouter/anthropic/claude-sonnet-5` | `OPENROUTER_API_KEY`, or a key saved in Admin |
| Cloudflare Workers AI | `cloudflare/@cf/zai-org/glm-5.3-flash` | Nothing on Cloudflare, where the Worker's AI binding serves it |

OpenAI uses Platform API keys only. An installation that once selected a ChatGPT subscription is normalized back to the API key lane on the next read, and the API that switched lanes now answers `410` with `OpenAI now uses Platform API keys only.`

The model field accepts free text, so a specifier no provider here serves will still save. Admin flags both cases as you type: a provider it cannot detect, and a known provider with no key.

## Where keys live

Two places, and the environment wins.

- **Environment variables are read first.** Chickpea reads `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `OPENROUTER_API_KEY` and only falls back to a stored key when the variable is empty. A provider configured this way shows in Admin as `Environment managed`, and its card has no Change key and no Remove key.
- **Keys saved in Admin.** In **Settings → Model providers**, each provider is a card with **Add key**. Chickpea validates the key once before storing it, with `GET /v1/models` for Anthropic and OpenAI and `GET /auth/key` for OpenRouter. A key the provider rejects is not stored.

A key saved in the browser reaches a running Agent within five seconds, the cache lifetime on stored keys. Removing a stored key names the damage first: the Agents pinned to that provider, and, when the workspace default uses it, Chickpea and every active Agent inheriting it. An environment variable of the same name stays in force.

## How a turn resolves to one model

Two settings, read in order.

1. **The Agent's pin.** An Agent's **Model** tab holds one specifier. While it is set, that Agent stays on that model.
2. **The workspace default.** An Agent with no pin follows **Default model** in Settings → Model providers, described there as the shared model for Chickpea and every Agent that is not pinned.

`@Chickpea` is never pinned. It always runs on the workspace default, and a pin stored on it is rejected with `Chickpea cannot use a pinned model. Repair Workspace default.` With no pin and no workspace default, the turn fails with `Workspace default is not ready. Choose a model in Settings > Model providers.`

The two settings differ in when a change lands. Admin says a pin change applies to new threads, while a workspace default change applies to the next admitted message, including replies in existing threads.

What the picker offers depends on the provider. Anthropic and OpenAI show the provider's own live model list, with catalog models added where the list omits them. OpenRouter and Workers AI show only the models you star in Settings. Workers AI starts with four starred: `@cf/zai-org/glm-5.3-flash`, `@cf/moonshotai/kimi-k2.7-code`, `@cf/openai/gpt-oss-120b`, and `@cf/meta/llama-4-scout-17b-16e-instruct`.

## The model catalog

The **model catalog** is the reviewed list of Anthropic and OpenAI models Chickpea knows how to call. Each entry carries release metadata only: the canonical id, a display name, the auth lane, and optional context window and max token values that may shrink a ceiling but never raise it. How a model is actually called lives in compiled profiles inside the release, which no catalog document can supply.

The catalog runs in one of two modes.

- **Hosted**, the default. Every six hours, plus or minus up to thirty minutes of jitter, the deployment fetches `https://raw.githubusercontent.com/pejmanjohn/chickpea/main/catalog/current.json`.
- **Bundled.** The deployment pins to the list shipped with its release, nine entries in the current build.

The fetch is guarded. HTTPS only, redirects rejected rather than followed, a five-second deadline, at most 128 KiB and 64 entries, and a revision that may not go backwards. A document that reuses a revision with different bytes is rejected as equivocation. A failed refresh keeps the last good document, or the bundled list when there is none. A model call never triggers a refresh: runtime admission activates only state that is already stored and validated.

Admin shows this in Settings → Model providers as a `Compatibility rules` line with a **Refresh** button.

## On Cloudflare

The Worker's AI binding provides a keyless provider whose id is `cloudflare`. A deployment made with the Deploy to Cloudflare button seeds the workspace default with `cloudflare/@cf/zai-org/glm-4.7-flash`, a model Workers AI serves on the Workers Free plan, so `@Chickpea` answers before any key exists. Provider keys stay optional and are added afterwards, either in Settings or with `npx wrangler secret put`.

Chickpea registers the binding with the AI Gateway turned off. Flue would otherwise supply a default gateway whose logs retain request and response payloads.

A toggle on the Workers AI card removes `cloudflare/*` models from every model picker without changing any pin already saved.

A second Workers AI provider, `cloudflare-workers-ai`, reaches the same models over REST. It never appears in the picker, and on Cloudflare it counts as configured only with its own `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID`, so it never stands in for the keyless default.

## On Node

There is no keyless provider. The Node app never imports the binding module and never registers a `cloudflare/*` provider, and the Workers AI card in Settings is marked Cloudflare only.

A fresh Node install seeds no workspace default, so choosing a model during setup is not optional there. The REST `cloudflare-workers-ai` provider is available with `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID`, but the picker never lists its specifiers; type one if you want it.

## Limits

| Limit | Value | Scope |
|---|---|---|
| Catalog document | 128 KiB, 64 entries | hosted refresh |
| Catalog fetch deadline | 5 seconds | hosted refresh |
| Catalog refresh interval | 6 hours, plus or minus 30 minutes | per deployment |
| Provider model list cache | 1 hour | per provider |
| Provider request deadline | 8 seconds | key validation and model lists |
| Stored key cache | 5 seconds | per running isolate |
| Workers AI reply ceiling | 2,048 tokens | `@cf/zai-org/glm-5.3-flash`, binding and REST |
| Workers AI context window | 32,768 tokens | the same model |

One limit carries no number. The first time a deployment resolves any `cloudflare/<model>` id it logs a warning: the binding-backed provider declares no context window, Flue therefore treats it as zero and never compacts on a threshold, and a long direct-message transcript grows without bound. The REST provider declares the 32,768 floor and is not affected.

## Why it works this way

**An operator's key outranks an editor's.** A key set as a Worker secret or a host environment variable resolves first and is read-only in the browser. Someone with Admin access can add a key the deployment lacks, but cannot replace or delete one the operator set.

**One default, many exceptions.** Chickpea and every unpinned Agent share the workspace default, so switching provider is a single edit. Pin only the Agent that needs something else: a cheap fast model for triage, a stronger one for the Agent that writes.

**The catalog carries data, not behavior.** Compiled profiles in the release hold every behavioral field, and a catalog value may only shrink a ceiling. A document fetched from the internet cannot change how your deployment calls a model, only which models it offers.

## What is not covered

- **Chickpea resells nothing.** It is Apache 2.0, with no per-seat pricing and no metering. You pay your model provider directly for API usage.
- **The catalog covers Anthropic and OpenAI only.** OpenRouter and Workers AI models are not routed through it.
- **A custom provider registered in code advertises no models.** The picker offers none for it rather than a specifier the provider may not serve, so you type the specifier yourself.
- **Provider choice is not isolation.** Two Agents on the same provider still keep separate connections, memory, and channel grants.

## Next steps

- [Agents](/agents): the rest of an Agent's profile, including instructions, connections, and memory.
- [Get started on Cloudflare](/start/get-started-cloudflare): deploy, then choose a provider and a model in the setup wizard.
- [A tour of Admin](/admin/tour): the browser app that holds Settings and the provider cards.
- [Security model](/security/security-model): what leaves your deployment on a model call, and what never does.

Source: https://docs.chickpea.co/agents/models-and-providers/index.mdx
