Agent models
How an agent chooses its models: the main model that runs the conversation, optional additional models, and how selection works at run time.
Every agent has one main model. It answers when nobody asks for anything else, and every agent has one. On top of that an agent can offer additional models that a caller may pick for a run: a fast one for quick questions, a stronger one for hard ones, a regional one for data that must stay in the region.
Available from the next Console release
Additional models, the agent_model field, the model list on the agent, the portal model switch and the model picker arrive with the next Console release. The main model works as it always has.
Set the models
Open Build → Agents → your agent → Build, in the model section of the Configuration card.
| Field | What it does |
|---|---|
| Model | The main model. Required for a native agent. Must be a chat (LLM) model of the agent's project |
| Additional models | "Models a caller may pick instead of the main one (up to 10)." Add models from the project's list |
| Label (per additional model) | The name shown in a picker. Placeholder: "Name shown in the picker". Defaults to the model's name |
| Description (per additional model) | "When to choose this model (optional)". Shown next to the label so people and programs can choose well |
Rules the editor and the API enforce when you save:
- At most 10 additional models, each listed once, and none of them the main model.
- Every model must exist in the agent's project and be a chat model (not an embedding, rerank or speech model). Anything else is a validation error.
- A model that cannot call tools, while the agent has tools or a Knowledge Engine, or that cannot read images, while the agent accepts attachments, saves with a warning, not an error. A Dynamic LLM is never warned about, because it routes by its own rules.
An additional model can be a Dynamic LLM. Offer one called auto next to two fixed models and callers get "let the router decide" as a choice.
In the API these are config.modelKey and config.additionalModels, a list of { modelKey, label?, description? }.
Who can pick, and what it needs
There is no separate permission for choosing a model. Whoever may run the agent may use any model on its list. The checks happen when the author saves the list: each model goes through the same checks as the main model, including the project boundary (it must exist in the agent's project). The list is the allow-list: a model that is not on it is refused at run time.
If you need only some people to reach an expensive model, do not put it on the shared agent's list. Offer it on a second agent, or on a portal that only those people can open. See Portal access.
How a caller picks a model
| Surface | How |
|---|---|
Client API, POST /api/client/v1/agents/responses (and the draft POST /api/client/v1/responses) | Body field agent_model, or the X-Cognipeer-Agent-Model header. model names the agent here, never the model. The body wins over the header |
OpenAI-compatible chat, POST /api/client/v1/chat/completions | model names the agent (agent:<key> or the bare key). Add agent_model; with the OpenAI SDKs send it in extra_body. The header works too |
| Studio and portals | A model picker in the chat, when the agent offers more than one model. Studio remembers the model a session used |
curl -X POST "$BASE/api/client/v1/agents/responses" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "model": "support", "input": "Summarise this contract", "agent_model": "claude-deep" }'client.chat.completions.create(
model="agent:support",
messages=[{"role": "user", "content": "Summarise this contract"}],
extra_body={"agent_model": "claude-deep"},
)Which model answers
- The caller asked for a model. It must be the main model or on the list, otherwise the call fails with
400and codemodel_not_allowed("The model "…" is not offered by this agent"). - Nothing was asked. The model the session last used (it is sticky). It is checked against the list again; if it was removed meanwhile, the run quietly goes back to the main model.
- Otherwise the agent's main model.
The choice is stored on the session (metadata.activeModel, with the reason requested, session or default) so a follow-up message keeps the model, and a background run starts with the model its request was authorized for. It is also recorded on the run's session events and trace tags. A run always executes the published configuration (or the version you pin); a draft run uses the draft's list.
What the answer tells you
- The answer says which model produced it: in
POST /agents/responsesand in chat completions the object carriescognipeer.agent_model, the key of the model that answered. Themodelfield of the response stays the agent. - Agent lookups list the choices.
GET /api/client/v1/agents/{agentKey}returnsmodelswhen the agent offers more than one: the main model first withdefault: true, then each additional model as{ key, label, description?, default: false }. Send akeyasagent_model. The field is absent when the agent has a single model.
In a portal
Enterprise module
Portals are an enterprise module. See Portals.
In the portal's Chat features tab, an agent that offers additional models has a switch Let people choose the model: "Shows a model picker in the chat with the agent's main model and its additional models." On (the default), people see the picker. Off, the agent always uses its main model.
Chat UI and Agent Server
The picker is the ModelPicker of @cognipeer/chat-ui (0.5.0 and later). Chat shows it next to the composer when the agent's info lists two or more models, keeps the choice per conversation (a new conversation starts on the default) and sends it as model with each message. Under each answer it shows "Answered with …" (showAnsweredWith, on by default), and a divider marks a change of model inside a conversation.
@cognipeer/agent-server (0.4.0 and later) carries the list as AgentInfo.models ({ key, label, description?, default }) and accepts model on message, regenerate and edit requests; a model that is not in the list is refused with 400 model_not_allowed. Agents that do not run on Console can declare a static models list and a selectModel hook. See the model choice use case for a runnable app.
Models and cost
Each run is priced and logged on the model that actually answered, so cost, tracing and usage reports separate the models of one agent. Pricing must be set on a model for a cost limit to work: saving an agent with a cost limit and a priceless model is refused.
Who can do this
Editing an agent's models is a change to the agent: agents.write (or agent.update on the agent). Running the agent with any listed model needs only the right to run it. See the Permissions reference.

