Skip to content

fix(api-server): honor chat completions request model - #25552

Open
lld1995 wants to merge 2 commits into
NousResearch:mainfrom
lld1995:fix/api-server-chat-model-routing
Open

fix(api-server): honor chat completions request model#25552
lld1995 wants to merge 2 commits into
NousResearch:mainfrom
lld1995:fix/api-server-chat-model-routing

Conversation

@lld1995

@lld1995 lld1995 commented May 14, 2026

Copy link
Copy Markdown

Summary

  • route /v1/chat/completions request model into the server-side AIAgent
  • keep the advertised API-server model name as an alias for the configured default model
  • add regression coverage for request-model propagation

Tests

  • venv/bin/python -m py_compile gateway/platforms/api_server.py tests/gateway/test_api_server.py
  • venv/bin/python -m pytest tests/gateway/test_api_server.py -q

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery labels May 14, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #10773 (same feature, same approach). #24008 was already closed as duplicate of #10773. See also #16403, #18549, #5862 for competing implementations.

When a routing gateway (e.g. an alias like "high-accuracy" that fans
out to "high-accuracy-m1/m2/m3") is configured as the inference
backend, clients had no way to tell which concrete model actually served
a given request — the response.model field always echoed the alias the
client sent.

Capture response.model from every successful upstream API call on
AIAgent (_last_response_model) and surface it through run_conversation()
so the api_server adapter can put the concrete backend id into the
chat.completion response. Falls back to the client-supplied name when
the upstream omits a model field, preserving the existing behavior for
non-routing providers.

Adds a regression test that verifies the alias is still used for
provider selection (requested_model kwarg) while the response advertises
the upstream-reported concrete backend.
Codename-11 added a commit to Codename-11/hermes-agent that referenced this pull request Jun 17, 2026
Desktop/external clients that send a model field in the session chat or
chat/stream request body can now override the gateway default for that
turn. _create_agent() and _run_agent() accept requested_model, which
takes priority over _resolve_gateway_model() when present.

Wired through:
- POST /api/sessions/{id}/chat
- POST /api/sessions/{id}/chat/stream

This enables the desktop composer model picker to hot-swap the model
mid-session without requiring a config.yaml write + gateway restart.

Upstream PRs NousResearch#22825, NousResearch#25552, and NousResearch#36110 address similar gaps on /v1/*
paths; this patch is scoped to the /api/sessions/* surface only.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the API-server routing work. Current main now has a provider-aware request-model contract, but this PR still represents a different behavior rather than a redundant patch.

Problems

  • gateway/platforms/api_server.py:1299-1324 resolves provider-specific runtime credentials for configured model_routes. The PR's raw requested_model assignment at gateway/platforms/api_server.py:833 changes only the model value, so it bypasses that provider/runtime resolution path.
  • Current main applies request model routing to chat completions, responses, and runs (gateway/platforms/api_server.py:2194-2201, 3285-3287, 4285-4298); this PR covers only chat completions.

Suggested changes

  • Define the contract for arbitrary request model strings versus configured model_routes, including session /model precedence.
  • If arbitrary selection is intended, integrate it with provider credential/runtime resolution and cover all API-server endpoints and streaming paths.

Automated hermes-sweeper review.

runtime_model = runtime_kwargs.pop("model", None)
model = requested_model or runtime_model or _resolve_gateway_model()

user_config = _load_gateway_config()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current main's model_routes path resolves provider-specific runtime credentials before changing the model (gateway/platforms/api_server.py:1299-1324). Selecting a raw request model here leaves the global provider/API key/base URL intact, so cross-provider model strings need a provider-resolution contract rather than only this precedence change.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
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 P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants