Skip to content

api_server: honor the model field in /v1/chat/completions - #24008

Closed
evangelinekamin wants to merge 1 commit into
NousResearch:mainfrom
evangelinekamin:api-server-honor-model-field
Closed

api_server: honor the model field in /v1/chat/completions#24008
evangelinekamin wants to merge 1 commit into
NousResearch:mainfrom
evangelinekamin:api-server-honor-model-field

Conversation

@evangelinekamin

Copy link
Copy Markdown

What

/v1/chat/completions reads the request's model field but only echoes it back in the response — the agent always runs on model.default regardless of what the client asked for. This makes the model field actually select the model for that request.

Why

OpenAI-compatible clients (Open WebUI, custom front-ends, etc.) generally expect model to choose the model. It's also useful to pick a model per conversation — e.g. a cheap default with an explicit escalation to a stronger model for hard turns — without restarting the gateway or running a second instance.

How

A per-request override threaded through:

  • _handle_chat_completions treats any model other than the server's advertised name (_get_advertised_model_name()) as an override; an omitted model (or one matching the advertised name) behaves exactly as before.
  • _run_agent and _create_agent gain a model_override parameter.
  • _create_agent resolves it: if it's a key in model_aliases it uses that alias's model, otherwise it's treated as a literal provider/model id, and it's passed to AIAgent(model=...) for that turn only.

Provider credentials (api_key / base_url from _resolve_runtime_agent_kwargs()) are left untouched, so this works cleanly when the override resolves to a model reachable with the configured provider — the common case (everything routed through OpenRouter, or any single-provider setup). A future change could resolve per-provider credentials for cross-provider overrides; this keeps it minimal.

/v1/runs is left as-is — it could get the same treatment if there's interest.

Testing

Against a local gateway:

  • {"model": "deepseek/deepseek-v4-pro", ...} → that turn runs on V4 Pro (confirmed via the model column on the session row in state.db).
  • {"model": "opus", ...} → resolves through model_aliases to the configured Opus model id.
  • request with no model field → still uses model.default.
  • streaming and non-streaming paths both exercised.

The OpenAI-compatible chat-completions endpoint reads the request's `model`
field but only echoes it back — the agent always runs on `model.default`.
Most OpenAI-compatible clients expect `model` to actually select the model,
and being able to pick a model per conversation (e.g. a cheap default with
an escalation lane) without restarting the gateway is handy.

Thread the requested model through as a per-request override:

- `_handle_chat_completions` treats a `model` other than the advertised name
  (`_get_advertised_model_name()`) as an override.
- `_run_agent` / `_create_agent` gain a `model_override` parameter.
- `_create_agent` resolves it against `model_aliases` (so `"opus"` works) or
  uses it as a literal provider/model id, and passes it to `AIAgent(model=...)`
  for that turn only.

When `model` is omitted or equals the advertised name, behaviour is
unchanged — `model.default` is used. Provider credentials (api_key/base_url
from `_resolve_runtime_agent_kwargs()`) are left as-is, so this works as long
as the override resolves to a model reachable with the configured provider
(the common case — e.g. everything via OpenRouter).

Tested against a local gateway: `"model": "deepseek/deepseek-v4-pro"` runs
that turn on V4 Pro (confirmed via the session row in state.db), `"model":
"opus"` resolves through `model_aliases`, and an omitted `model` still uses
`model.default`. Left `/v1/runs` alone; it could get the same treatment.
@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have labels May 11, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #10773, which implements the same per-request model field override for /v1/chat/completions. Please coordinate or close in favor of the earlier PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants