> ## Documentation Index
> Fetch the complete documentation index at: https://comis-feature-matrix-channel.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Models

> Configuring AI providers, model selection, and automatic failover

**What it does.** Picks which AI model answers each message — globally,
per-agent, or per-task — and falls back to a backup model if the primary
provider has a hiccup.

**Who it is for.** Anyone setting up an agent. The plain-language section
covers picking a default; the reference section covers per-agent overrides,
fallback chains, and key rotation.

Comis ships with native support for **every provider in the [`@earendil-works/pi-ai`](https://www.npmjs.com/package/@earendil-works/pi-ai) catalog** — currently 35 hosted providers (Anthropic, OpenAI, Google, Mistral, Groq, OpenRouter, DeepSeek, xAI, Cerebras, Amazon Bedrock, Azure OpenAI Responses, Vercel AI Gateway, Cloudflare AI Gateway / Workers AI, GitHub Copilot, Hugging Face, Fireworks, Together (via OpenRouter), Moonshot, Minimax, Z.ai, Kimi, OpenCode, and more). The catalog is queried at runtime — adding a new provider to pi-ai automatically lights it up across the daemon, web wizard, CLI wizard, and `comis models list` with **zero comis code changes**.

Plus you can register custom OpenAI-compatible endpoints (any HTTP service that speaks the OpenAI chat-completions API) for proxies and self-hosted gateways.

You can set a default model for all agents, override it per agent, and configure automatic failover so your agents keep working even if one provider goes down.

## Discovering available providers and models

The catalog is dynamic. Two CLI commands surface it:

```bash theme={null}
# List all providers with model counts and key status
comis providers list

# Browse the full model catalog
comis models list

# Filter to one provider
comis models list --provider openrouter

# Machine-readable
comis providers list --format json
comis models list --format json
```

Each command tries the daemon's `models.list_providers` / `models.list` RPC first, and falls back to the local pi-ai static catalog when the daemon isn't running (so the wizard still works pre-init).

In the web dashboard, the same catalog drives:

* **Setup Wizard › Provider step** — provider grid populated from `models.list_providers`
* **Setup Wizard › Model dropdown** — per-provider model list from `models.list`
* **Models view › Catalog tab** — full searchable model catalog
* **Agents view › Edit agent** — provider and model dropdowns

There is no hardcoded provider/model list in comis source. The pi-ai catalog is the single source of truth, accessed via `getProviders()` and `getModels(provider)` from `@earendil-works/pi-ai`.

## Custom providers (proxies and self-hosted)

For any endpoint not in the pi-ai catalog — your own gateway, a private deployment, an OpenAI-compatible proxy — register a custom provider entry under `providers.entries.<id>` with `type: "openai"` and your custom `baseUrl`. The daemon's built-in-provider guard rejects redundant entries that try to re-create a built-in provider with the catalog's default URL (those should use the built-in path: env\_set + agent provider/model directly).

## Choosing a model

You set a default AI model globally, and every agent uses that model unless you
override it. The default is Claude Sonnet from Anthropic, but you can switch to
any supported provider at any time.

You can also create **model aliases** -- friendly shorthand names that map to
specific provider and model combinations. Instead of typing a long model ID
every time, you can just use a name like `claude` or `gpt4`.

## Three levels of configuration

Comis gives you three levels of control over which model your agents use.
Each level overrides the one above it:

### Level 1: Global defaults

Set the default model and provider for all agents. This is the simplest way to
get started -- configure it once and every agent uses it.

| Option                   | Type    | Default                                           | What it does                                   |
| ------------------------ | ------- | ------------------------------------------------- | ---------------------------------------------- |
| `models.defaultModel`    | string  | `""` (falls back to `claude-sonnet-4-5-20250929`) | Default model for all agents                   |
| `models.defaultProvider` | string  | `""` (falls back to `anthropic`)                  | Default provider for all agents                |
| `models.aliases`         | array   | `[]`                                              | Friendly names for model/provider pairs        |
| `models.scanOnStartup`   | boolean | `false`                                           | Scan providers for available models on startup |

```yaml title="~/.comis/config.yaml" theme={null}
models:
  defaultModel: "claude-sonnet-4-5-20250929"
  defaultProvider: "anthropic"
  aliases:
    - alias: "claude"
      provider: "anthropic"
      modelId: "claude-sonnet-4-5-20250929"
    - alias: "gpt4"
      provider: "openai"
      modelId: "gpt-4o"
    - alias: "gemini"
      provider: "google"
      modelId: "gemini-2.0-flash"
```

With aliases configured, you can reference models by their short name anywhere
in the configuration. For example, setting an agent's model to `claude` would
use `anthropic/claude-sonnet-4-5-20250929`.

### Level 2: Per-agent override

Override the global default for specific agents. This is useful when different
agents have different needs -- your main conversational agent might use Claude,
while a code-focused agent uses GPT-4o, a fast triage agent uses Groq, and a
local-only agent uses Ollama.

| Option              | Type   | Default     | What it does                                           |
| ------------------- | ------ | ----------- | ------------------------------------------------------ |
| `agents.*.model`    | string | `"default"` | Model for this agent (or `"default"` to use global)    |
| `agents.*.provider` | string | `"default"` | Provider for this agent (or `"default"` to use global) |

```yaml title="~/.comis/config.yaml" theme={null}
models:
  defaultModel: "claude-sonnet-4-5-20250929"
  defaultProvider: "anthropic"

agents:
  default:
    model: "default"                       # Global default (Claude Sonnet)
    provider: "default"

  code-helper:
    model: "gpt-4o"                        # Long-context coding agent
    provider: "openai"

  quick-lookup:
    model: "gemini-2.5-flash"              # Speed for quick answers
    provider: "google"

  triage:
    model: "llama-3.3-70b"                 # Cerebras for sub-second classification
    provider: "cerebras"

  private-notes:
    model: "llama3.1:8b"                   # Local Ollama, no key required
    provider: "ollama"
```

A single Comis instance can mix all five at once — each agent picks
independently, and key resolution is handled by the
[Secret Manager](/reference/secret-manager).

### Level 3: Per-task routes

For advanced use cases, you can route specific tasks to different models. For
example, use a cheaper model for summarization and your primary model for
everything else.

```yaml title="~/.comis/config.yaml" theme={null}
agents:
  default:
    model: "claude-sonnet-4-5-20250929"
    provider: "anthropic"
    modelRoutes:
      summarization: "gemini-2.0-flash"
      classification: "gpt-4o-mini"
```

Task routes are optional and most users do not need them. They are available for
specific optimization scenarios where different tasks benefit from different
models.

## Automatic failover

What happens when your AI provider goes down or returns errors? Comis can
automatically try backup models so your agents keep working.

### Fallback models

You can specify an ordered list of backup models. If the primary model fails,
Comis tries the next one in the list, and so on until one succeeds or all
options are exhausted.

### Auth profiles

You can configure multiple API keys per provider. Comis rotates between them
automatically, which is useful for:

* **Rate limit management** -- If one key hits its rate limit, Comis switches
  to another.
* **Redundancy** -- If one key is revoked or expired, others keep working.

Comis supports three key selection strategies that it manages internally:
explicit ordering, round-robin rotation, and last-known-good preference.

### Cooldown behavior

After a model fails, Comis waits before trying it again. The wait time
increases with each failure using exponential backoff:

* First failure: 1 minute cooldown
* Second failure: 5 minutes
* Third failure: 25 minutes
* Maximum: 1 hour cap

This prevents your agent from hammering a broken provider and racking up
error counts.

### Failover configuration

| Option                             | Type   | Default   | What it does                                      |
| ---------------------------------- | ------ | --------- | ------------------------------------------------- |
| `modelFailover.fallbackModels`     | array  | `[]`      | Ordered list of backup models to try              |
| `modelFailover.authProfiles`       | array  | `[]`      | API key profiles for rotation                     |
| `modelFailover.allowedModels`      | array  | `[]`      | Model allowlist (empty = allow all)               |
| `modelFailover.maxAttempts`        | number | `6`       | Maximum total attempts across all models and keys |
| `modelFailover.cooldownInitialMs`  | number | `60000`   | Initial cooldown after failure (1 minute)         |
| `modelFailover.cooldownMultiplier` | number | `5`       | Cooldown multiplier for exponential backoff       |
| `modelFailover.cooldownCapMs`      | number | `3600000` | Maximum cooldown duration (1 hour)                |

```yaml title="~/.comis/config.yaml" theme={null}
agents:
  default:
    model: "claude-sonnet-4-5-20250929"
    provider: "anthropic"

    modelFailover:
      fallbackModels:
        - provider: "openai"
          modelId: "gpt-4o"
        - provider: "google"
          modelId: "gemini-2.0-flash"

      authProfiles:
        - keyName: "ANTHROPIC_API_KEY"
          provider: "anthropic"
        - keyName: "ANTHROPIC_API_KEY_2"
          provider: "anthropic"
        - keyName: "OPENAI_API_KEY"
          provider: "openai"

      maxAttempts: 6
      cooldownInitialMs: 60000
      cooldownMultiplier: 5
      cooldownCapMs: 3600000
```

In this example, if the primary Claude model fails, Comis tries GPT-4o next,
then Gemini Flash. It also has two Anthropic API keys and rotates between them
if one hits a rate limit.

## Model capability matrix

Different model families support different features. The capability matrix
governs how Comis builds the request body for each provider.

| Family                                   | Context window (typical) | Prompt cache                | Tool use             | Vision            | Reasoning blocks  |
| ---------------------------------------- | ------------------------ | --------------------------- | -------------------- | ----------------- | ----------------- |
| Anthropic Claude (Sonnet/Opus/Haiku 4.x) | 200K                     | Ephemeral 5m / 1h           | Yes                  | Yes               | Yes               |
| OpenAI GPT-4o family                     | 128K                     | Implicit (provider-managed) | Yes                  | Yes               | No                |
| OpenAI GPT-5.4 family                    | 200K+                    | Implicit                    | Yes                  | Yes               | Optional          |
| Google Gemini 2.5 / 3                    | 1M                       | Explicit `CachedContent`    | Yes                  | Yes               | No                |
| Mistral Large / Codestral                | 128K                     | None                        | Yes (strict ID mode) | Pixtral only      | No                |
| Groq (Llama / Mixtral)                   | 128K                     | None                        | Yes                  | No                | No                |
| Ollama (local)                           | Varies by model          | None                        | If model supports    | If model supports | If model supports |
| OpenRouter                               | Per upstream             | Per upstream                | Per upstream         | Per upstream      | Per upstream      |
| Cerebras (Llama)                         | 128K                     | None                        | Yes                  | No                | No                |
| xAI Grok                                 | 128K                     | None                        | Yes                  | Limited           | No                |
| DeepSeek                                 | 64K-128K                 | None                        | Yes                  | No                | No                |

The exact context window per concrete model is resolved at runtime from
the pi-ai catalog (`getModels(provider)`). To see the live catalog: `comis
models list` (or filter to one provider with `comis models list --provider <id>`). The capability matrix above is a reference summary — concrete
per-model capabilities (cost, max tokens, vision support, reasoning) are
queryable directly via `comis models list --format json` or the
`models.list` RPC.

## Key rotation

You can configure multiple API keys per provider to spread usage across
accounts or handle key expiration gracefully. When a key hits a rate limit or
returns an authentication error, Comis automatically switches to the next
available key.

Keys are managed through the [Secret Manager](/reference/secret-manager). Each
`authProfile` entry maps a secret name to a provider, and Comis handles the
rotation logic automatically.

<Tip>
  Start with a single model and no failover. Add fallback models and key
  rotation only when you need higher availability or are hitting rate limits
  regularly.
</Tip>

<CardGroup cols={2}>
  <Card title="Safety" icon="shield-check" href="/agents/safety">
    Budget protection, circuit breakers, and cost controls.
  </Card>

  <Card title="Routing" icon="route" href="/agents/routing">
    How messages are directed to specific agents.
  </Card>
</CardGroup>
