Skip to content

[CRITICAL] LiteLLM discovery: resolveLiteLLMApi routes every OpenAI-tagged model group to /v1/responses; LiteLLM only guarantees /v1/chat/completions #9306

Description

@AincradBot

[CRITICAL] LiteLLM provider discovery misroutes models to OpenAI Responses API (/v1/responses)

Description

Since 17.4.1 (introduced by merged PR #9085 fix(catalog): route LiteLLM OpenAI models through Responses), the LiteLLM discovery path assigns the client wire API from the model's upstream provider type. Any LiteLLM-discovered model whose rich metadata reports providers: ["openai"] (or litellm_params.custom_llm_provider == "openai", or a backend model/base_model prefixed openai/) is mapped to api: "openai-responses", so OMP sends requests to {baseUrl}/v1/responses.

LiteLLM is a Chat-Completions-compatible gateway: its documented OpenAI-compatible surface is /v1/chat/completions (it transcodes OpenAI-format requests to whatever the upstream speaks). A standard LiteLLM proxy does not guarantee a working /v1/responses endpoint for these models, so affected models fail on every request.

Verified against main (packages/catalog/src/provider-models/openai-compat.ts):

// classifyLiteLLMApiRoute (entry from /model_group/info, /v2/model/info, ...)
if (providers) {
    return providers.every(provider => provider === "openai") ? "openai" : "other";
}
// ...

export function resolveLiteLLMApi(entry, id, fallbackApi = "openai-completions"): Api {
    return classifyLiteLLMApiRoute(entry, id) === "openai" ? "openai-responses" : fallbackApi;
}

Used in the model builder at

api: options.resolveApi?.(entry, id) ?? options.api,   // mapLiteLLMRichEntry

and wired into both discovery paths (litellmModelManagerOptions and discoverLiteLLMModels in packages/coding-agent/src/config/model-discovery.ts).

Why this is wrong: the providers field in LiteLLM's /model_group/info (and custom_llm_provider in litellm_params) describes which upstream provider type LiteLLM uses internally to reach the backend (OpenAI SDK / openai-family integration) — it says nothing about which wire API a client of the proxy should use. This specifically includes model: openai/<anything> pointing at a custom api_base (any OpenAI-compatible server, incl. local/self-hosted and non-Responses backends): LiteLLM still classifies those with the OpenAI provider, so providers == ["openai"] matches far more deployments than "native api.openai.com models". Every LiteLLM model group backed by the openai upstream type is misrouted — potentially a large share of typical LiteLLM deployments — regardless of whether a Responses-capable endpoint exists behind the gateway. (PR review discussion already touched adjacent mixed-backend hazards; the fundamental issue is that the heuristic treats upstream driver as client wire API.)

The unknown-route fallback in the same function (/v1/models fallback path, mapLiteLLMOpenAICompatibleModelresolveLiteLLMApi(undefined, model.id)) additionally promotes well-known OpenAI model IDs served by any OpenAI-compatible gateway to openai-responses based on the ID alone.

Steps to Reproduce

  1. Run a LiteLLM proxy with any OpenAI-upstream model, e.g. config:

    model_list:
      - model_name: gpt-5.6-sol          # or any model
        litellm_params:
          model: openai/gpt-5.6-sol      # custom_llm_provider resolves to "openai"

    (or any gateway exposing /model_group/info where entries carry providers: ["openai"], including openai/… models pointed at a custom api_base).

  2. Use omp 17.4.1+ with the litellm provider (LITELLM_API_KEY/stored auth) or a models.yml provider with discovery.type: "litellm".

  3. Select the discovered model and send any prompt.

Expected Behavior

LiteLLM-discovered models default to the provider-level API (openai-completions/{base}/v1/chat/completions), because that is the guaranteed contract of a LiteLLM gateway. The Responses API must not be inferred from the providers/custom_llm_provider field; upstream provider type does not determine the client wire API. If per-model Responses routing is desired for LiteLLM at all, it needs positive evidence that this specific proxy serves /v1/responses (e.g. an explicit config flag such as api: openai-responses, or a capability probe), never a default derived from upstream tags.

Error Output

Every chat request to an affected model is sent to POST {baseUrl}/v1/responses instead of {baseUrl}/v1/chat/completions and fails — 404/Cannot POST /v1/responses on older LiteLLM proxies and non-Responses OpenAI-compatible backends; on proxies that partially implement /responses, downstream errors depending on upstream support. On 17.4.0 the identical deployment works.

Environment

  • Platform: any (observed on Windows native; platform-independent)
  • omp version: ≥ 17.4.1 (regression from 17.4.0; still present on main and in latest release line 17.4.4)
  • Provider: LiteLLM (litellm discovery, and models.yml providers with discovery.type: "litellm")

Workaround (temporary)

  • Downgrade to 17.4.0, or
  • For each affected model, set modelOverrides in models.yml with an explicit api: openai-completions (impractical with many discovered models).

Suggested direction

Revert resolveLiteLLMApi's promotion of providers == ["openai"] to openai-responses for LiteLLM discovery (both the built-in litellm descriptor and the configured discovery.type: "litellm" path, incl. the /v1/models ID-based fallback), or gate Responses routing behind explicit, opt-in evidence that the proxy actually serves the Responses API. Reasoning-summary support for OpenAI models behind LiteLLM should be handled without breaking the chat-completions default for every other deployment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    provider:litellmProvider-specific issues for litellmprovidersLLM provider-specific issuestriagedwontfixThis will not be worked on

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions