Skip to content

fix(api_server): respect per-request model override in all API paths - #19939

Closed
mssteuer wants to merge 1 commit into
NousResearch:mainfrom
mssteuer:fix/api-server-model-override
Closed

mssteuer wants to merge 1 commit into
NousResearch:mainfrom
mssteuer:fix/api-server-model-override

Conversation

@mssteuer

@mssteuer mssteuer commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

When API consumers (e.g. CCC task dispatcher, external UIs) pass a model field in their request body, the API server adapter now correctly routes to that model instead of silently falling back to the gateway configured default.

Problem

The model field was extracted from request bodies but never passed through to _create_agent(). All API-spawned sessions used the gateway default — in our case claude-opus-4-6 — regardless of what was requested. This silently burned expensive Opus tokens on mechanical work that should route to cheaper/different models.

Impact observed: CCC task dispatcher was correctly requesting openrouter/openai/gpt-5.5 for coding agents, but every session was recorded as claude-opus-4-6. This consumed ~257K Opus tokens/day unnecessarily.

Changes

  • _create_agent() accepts a new model_override parameter
  • When the override contains a known provider prefix (openrouter/, litellm-), provider credentials and base URL are resolved from config
  • Wired into all 3 API paths:
    • Chat Completions (streaming + non-streaming)
    • Responses API (streaming + non-streaming)
    • Spawn/Run endpoint
  • If the request model matches the gateway advertised model name, it is treated as "use default" (not an override)

Tests

7 new tests in tests/gateway/test_api_server_model_override.py:

  • Override passed through to agent
  • No override when model matches gateway default
  • OpenRouter prefix resolves credentials
  • LiteLLM prefix sets correct base_url
  • All 3 API paths covered

All 166 existing API server tests continue to pass.

Related Issues

Closes #16216 — Honor per-request model override from API server adapter
Related: #15789, #14974 (delegate_task model overrides — different scope but same symptom)
Related: #12467 (model field override behavior)

CI Notes

The Contributor Attribution and Docs Site checks are pre-existing failures unrelated to this change (unmapped contributor emails from other PRs, and an ASCII box linter threshold).

@mssteuer
mssteuer force-pushed the fix/api-server-model-override branch from 6842163 to dafec84 Compare May 4, 2026 23:08
…paths

When API consumers (e.g. CCC task dispatcher) pass a 'model' field in
their request body, the API server now correctly uses that model instead
of falling back to the gateway's default.

Previously, the model field was extracted from the request body but never
passed through to _create_agent(). This caused all API-spawned sessions
to use the gateway default (claude-opus-4-6) regardless of what model
was requested — silently burning expensive Opus tokens on mechanical
coding work that should route to cheaper models.

Changes:
- _create_agent() now accepts model_override parameter
- When override contains 'openrouter/' prefix: resolves OpenRouter
  credentials from providers config
- When override contains 'litellm-' or 'litellm/' prefix: routes to
  LiteLLM proxy
- Chat completions (streaming + non-streaming) passes body.model as
  model_override
- Responses API (streaming + non-streaming) passes body.model as
  model_override
- Spawn/run endpoint passes body.model as model_override
- Added regression tests covering all override paths

Fixes the issue where CCC sends model='openrouter/openai/gpt-5.5' but
agents were created with claude-opus-4-6, causing ~24% of weekly Claude
quota to be wasted on mechanical tasks.
@mssteuer
mssteuer force-pushed the fix/api-server-model-override branch from dafec84 to 41a633d Compare May 4, 2026 23:14
@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 4, 2026
@mssteuer

Copy link
Copy Markdown
Contributor Author

Superseded by #22825 — same fix, rebased fresh on current main with updated tests. This branch was 685 commits behind and the conflicts aren't worth resolving when the replacement PR is already green.

@mssteuer mssteuer closed this May 10, 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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Honor per-request model override from API server adapter (X-Router-Model header or request body)

2 participants