Skip to content

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.

FieldWhat it does
ModelThe 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 ​

SurfaceHow
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/completionsmodel 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 portalsA model picker in the chat, when the agent offers more than one model. Studio remembers the model a session used
bash
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" }'
python
client.chat.completions.create(
    model="agent:support",
    messages=[{"role": "user", "content": "Summarise this contract"}],
    extra_body={"agent_model": "claude-deep"},
)

Which model answers ​

  1. The caller asked for a model. It must be the main model or on the list, otherwise the call fails with 400 and code model_not_allowed ("The model "…" is not offered by this agent").
  2. 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.
  3. 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/responses and in chat completions the object carries cognipeer.agent_model, the key of the model that answered. The model field of the response stays the agent.
  • Agent lookups list the choices. GET /api/client/v1/agents/{agentKey} returns models when the agent offers more than one: the main model first with default: true, then each additional model as { key, label, description?, default: false }. Send a key as agent_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.

Reasoning effort and visibility ​

Available from the next Console release

Per-model reasoning effort, Show reasoning and the reasoning request fields arrive with the next Console release.

Reasoning models think before they answer. An agent controls two things about it: how hard each of its models thinks, and whether the thinking text is shown.

Effort beside each model ​

In the Build tab, the main model and every additional model have a Reasoning control. Its first option is Model default; the other options follow the model's provider (for example none, minimal, low, medium, high for OpenAI, and none, low, medium, high plus an optional Thinking budget (tokens) for Claude and Gemini). A pick made here "wins over the Model Hub default and over an API request".

For each model the run uses the first value it finds:

  1. The agent's pick for that model.
  2. The Model Hub default of the model.
  3. The API request (reasoning_effort, or reasoning: { effort }).
  4. Nothing: the provider's own default applies.

This is decided per model, so the main model, a model the caller chose, and a sub-agent's model each resolve their own. If a Dynamic LLM routes the call, the agent's pick still outranks the routed model's Model Hub default. Titles are generated with effort none. The old Advanced reasoning block is gone except the reflection setting; existing values are migrated when an agent is read or saved. Full rules and provider details: Reasoning.

In the API, the main model's pick is config.reasoningEffort (and reasoningBudgetTokens for engines that think in tokens), and each additional model entry carries its own reasoningEffort and reasoningBudgetTokens. Unset means Model default.

Ask for a level per request ​

The agent endpoints (POST /api/client/v1/agents/responses, the draft POST /api/client/v1/responses, the agent chat-completions bridge and dashboard chat) accept reasoning_effort or reasoning: { effort }, with none, minimal, low, medium, high, xhigh or max. A level the model does not take is moved to the nearest lower one it takes. When both are sent the object wins. Anything else is 400 invalid_reasoning. A request's value is the lowest rung of the order above, so it never overrides an author's pick, and background runs ignore it.

bash
curl -X POST "$BASE/api/client/v1/agents/responses" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{ "model": "support", "input": "Compare these two contracts", "reasoning": { "effort": "high" } }'

Show or hide the thinking text ​

The agent's Show reasoning switch (config.showReasoning, default on) decides whether the thinking text is shown.

Switch stateWhat callers get
OnThe reasoning appears as a reasoning output item in /agents/responses (summary text), in session messages, in the portal and in Studio chat
OffThe text is left out of API responses, session events and stored messages, portal and Studio chat. The operator's own playground view can still show it

A request can narrow what the agent allows with include_reasoning: false (or reasoning.exclude on /responses), but cannot show what the agent or the Model Hub hid. If the Model Hub model has Return reasoning to callers off, the agent path hides the text too. Hiding changes nothing about cost: the model still thinks, and the tokens are counted and billed. Clients such as Agent Server and Chat UI honour the switch: Agent Server publishes it as AgentInfo.showReasoning, and the Chat UI shows a Thinking block only when it is on.

When the model runs out of output tokens ​

A model that thinks a lot can spend its whole output limit before it writes an answer. An agent turn handles this without failing:

  1. The call is retried once with a raised limit. The new limit is bounded by the model's declared maximum output tokens and by what is left of the run's output-token budget.
  2. If the model still cannot answer, the turn ends with a notice instead of an error: "The model reached its output token limit before it could answer. Raise the model's maximum output tokens or lower its reasoning effort, then try again." The run is reported as incomplete with stop reason max_output_tokens.

To fix it, raise the model's maximum output tokens in the Model Hub or lower its reasoning effort. Direct calls to /chat/completions do not get this softening: they keep the error, see Chat completions errors.

How the model calls are made ​

Every model call of an agent goes through the same gateway as a direct API call, so the Model Hub settings apply to agents too. See How agents call models.

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.

Studio · Pulse · Console · Agent SDK and more — the Cognipeer documentation hub