---
title: Auto model choice
description: With model "auto", the Gateway judges task difficulty and picks a model your workspace allows. Named models are never swapped; responses name their model.
url: https://agentlab.cresclab.com/docs/en/gateway/auto
language: en
updated: 2026-10-30
---

# Auto model choice

With model "auto", the Gateway judges task difficulty and picks a model your workspace allows. Named models are never swapped; responses name their model.

## Name a model or use auto

The `model` field takes either a model name from `GET /v1/models` or `auto`:

| `model`                         | What happens                                                              |
| ------------------------------- | ------------------------------------------------------------------------- |
| `auto`                          | The Gateway picks a model your workspace allows, by how hard the task is. |
| A model name                    | Only that model answers. It is never replaced by another.                 |
| `agentlab/…`                    | Refused with 400 `invalid_model`; the message lists the valid values.     |
| A name the Gateway doesn't know | Refused with 404 `model_not_found`; the message lists the valid values.   |
| A model your workspace excludes | Refused with 403 `model_not_enabled`.                                     |

`/v1/chat/completions` and `/v1/responses` choose among every allowed model, whichever company makes it. `/v1/messages` only uses Claude models, and a Responses request that only an OpenAI model can serve (for example one with the `code_interpreter` tool) only uses OpenAI models.

Claude Code and Codex check the model name before they send, so they cannot send `auto`. They keep a real model name in the request and add the header `X-AgentLab-Routing: auto`, which makes the Gateway choose. The header must be exactly `auto` and sent once; anything else is refused with 400.

## How auto picks

1. **Judge the task** The cheapest allowed model that can return structured output reads a short excerpt of the request (the start of the system prompt, the first and the latest user message and the tool names, at most 8 KiB; never the whole conversation) and says what kind of task it is and whether it takes several steps.
2. **Pick the model** Multi-step work gets a stronger model. Routine analysis, coding and planning get the standard model. Routine extraction, rewriting and conversation get the cheapest allowed model.
3. **Keep the turn together** Later steps of the same tool loop reuse the first step's model, so encrypted reasoning, thinking signatures and the prompt cache stay valid.

When the judgement fails, times out (after 6 seconds) or is unsure, the standard model answers. Auto never picks a cheaper model when it can't tell.

When less than 20% of the workspace's monthly spend limit is left, work judged multi-step gets the standard model instead of the stronger one.

The judgement is a model call of its own. It is recorded and charged under the same key and linked to the request it was for.

## Use only some providers

To keep a request on some companies' models, send `provider.only` with Chat Completions or Responses, in the shape OpenRouter uses:

```json
{
  "model": "auto",
  "provider": { "only": ["anthropic"] },
  "messages": [{ "role": "user", "content": "Hello" }]
}
```

- A provider is the company that makes the model, as the console's model list shows it: `anthropic`, `openai`, `google`, `meta`, `xai`, `deepseek`, `moonshot`, `mistral`, `zhipu`, `qwen`, `minimax`, `amazon`, `microsoft`, `cohere` or `black-forest-labs`. `anthropic` includes Claude on Amazon Bedrock and Google Vertex AI.
- auto, its judgement, its retries and the `auto` entries of `models` only use those providers' models. The workspace's model settings still apply.
- A model you name outside the list, an unknown provider, or any other `provider` option is refused with 400 and `param` `provider.only` (or the option's name). When none of the listed providers' models can serve the request, it is refused with 400 and the message lists the providers that can.
- `provider` is read by the Gateway and never sent to the model.

## See what auto chose

Every answered request carries:

| Header                  | Value                                                                                                                                                                              |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Agentlab-Model`      | The model that answered.                                                                                                                                                           |
| `X-Agentlab-Decision`   | Why: `requested_model` for a named model; with auto, `auto_assessed`, `auto_reused`, `auto_uncertain`, `auto_assessment_failed`, `auto_assessment_timeout` or `auto_budget_guard`. |
| `X-Agentlab-Assessment` | With auto, the judgement, such as `analysis/multi_step`, or `unavailable` when there was none.                                                                                     |
| `X-Request-Id`          | The request's id, as shown on the usage page and in the export.                                                                                                                    |

Chat Completions also returns the model that answered in `model` and the reason in `agentlab_decision.reason` (`auto` or `requested_model`).
