Skip to content

fix(providers): route Responses-only models on custom OpenAI providers#2985

Merged
Sayt-0 merged 1 commit into
mainfrom
fix/2303-copilot-custom-provider-responses
Jun 3, 2026
Merged

fix(providers): route Responses-only models on custom OpenAI providers#2985
Sayt-0 merged 1 commit into
mainfrom
fix/2303-copilot-custom-provider-responses

Conversation

@Sayt-0

@Sayt-0 Sayt-0 commented Jun 3, 2026

Copy link
Copy Markdown
Member

Problem

Custom OpenAI-compatible providers declared in the providers: section without
an explicit api_type were hard-defaulted to openai_chatcompletions. Models
that are only served via the Responses API (gpt-4.1, the o-series, gpt-5, Codex)
were therefore sent to /chat/completions and rejected with
400 unsupported_api_for_model — e.g. a github-copilot endpoint declared as a
custom provider running gpt-5.3-codex.

Fixes #2303

Fix

pkg/model/provider/defaults.go

  • Added defaultOpenAIAPIType(model): returns openai_responses when
    modelinfo.SupportsResponsesAPI(model) is true, otherwise
    openai_chatcompletions.
  • mergeFromProviderConfig now uses defaultOpenAIAPIType(dst.Model) for the
    OpenAI-compatible fallback instead of always setting openai_chatcompletions,
    reusing the same predicate as the built-in routing.

Tests

pkg/model/provider/custom_provider_test.go

  • TestApplyProviderDefaults_DefaultsResponsesAPIForNewerModels: a custom
    provider with no api_type routes gpt-5.3-codex, gpt-5, o3-mini to
    openai_responses, while gpt-4o stays on openai_chatcompletions.
  • TestApplyProviderDefaults_ExplicitAPITypeWinsOverModel: an explicit
    provider-level api_type is honored even for a Responses-default model.

Custom OpenAI-compatible providers (providers: section) without an explicit
api_type were hard-defaulted to openai_chatcompletions, disabling the
per-request endpoint auto-detection that the built-in openai/github-copilot
providers rely on. Models served only via the Responses API (gpt-4.1,
o-series, gpt-5, Codex) were therefore sent to /chat/completions and rejected
with 400 unsupported_api_for_model — e.g. a github-copilot endpoint defined as
a custom provider running gpt-5.3-codex.

Default the api_type from the same modelinfo.SupportsResponsesAPI predicate so
both paths stay consistent. An explicit provider- or model-level api_type
still wins.

Fixes #2303
@Sayt-0 Sayt-0 requested a review from a team as a code owner June 3, 2026 09:22

@docker-agent docker-agent left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Assessment: 🟡 NEEDS ATTENTION

One medium-severity behavioral regression was confirmed in the changed code.

Summary of findings:

  • 🟡 MEDIUM pkg/model/provider/defaults.go:47 — Model-name-based api_type defaulting silently breaks non-OpenAI custom providers whose model names match OpenAI patterns

// modelinfo.SupportsResponsesAPI predicate keeps both paths consistent so a
// provider pointed at the OpenAI/Copilot API works without a manual
// api_type override. See https://github.com/docker/docker-agent/issues/2303.
func defaultOpenAIAPIType(model string) string {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MEDIUM] Model-name-based api_type defaulting silently breaks non-OpenAI custom providers

defaultOpenAIAPIType now routes any model whose name matches SupportsResponsesAPI prefixes (gpt-4.1*, gpt-5*, codex*, o-series) to openai_responses. This is correct for providers actually pointing at the OpenAI or Copilot API — but the gate that triggers this logic (isOpenAICompatibleProvider(resolveEffectiveProvider(src))) is too broad:

  • A custom provider declared with only a base_url and no explicit Provider field resolves its effective type to "openai" (via resolveEffectiveProvider), which makes isOpenAICompatibleProvider return true.
  • This means any URL-based third-party gateway (a local vLLM instance, LiteLLM proxy, Azure relay, etc.) that names its model gpt-5-local, o3-preview, or codex-custom will silently have requests routed to /responses instead of /chat/completions, causing 404 or 400 errors.

Before this PR: all custom providers defaulted to openai_chatcompletions — a safe universal default.
After this PR: the default is model-name–driven, and any pattern match sends traffic to /responses.

The workaround exists (api_type: openai_chatcompletions in the provider config), but users have no way to know they need it unless they read the source code.

Suggested mitigation: consider narrowing the condition — e.g., only apply defaultOpenAIAPIType when src.BaseURL contains openai.com or githubcopilot.com, or add a first-class boolean flag (responses_api_routing: true) that operators must opt into for custom providers.

@Sayt-0 Sayt-0 merged commit 61020cf into main Jun 3, 2026
12 of 13 checks passed
@Sayt-0 Sayt-0 deleted the fix/2303-copilot-custom-provider-responses branch June 3, 2026 09:44
aheritier added a commit that referenced this pull request Jun 4, 2026
Updates docs/providers/custom/index.md to reflect that `api_type` is
now auto-detected based on the model name for custom OpenAI-compatible
providers. Newer models (gpt-4.1, o-series, gpt-5, Codex) default to
`openai_responses`; others default to `openai_chatcompletions`.

Previously the docs showed a hardcoded default of `openai_chatcompletions`
which was incorrect post-merge.

Source PR: #2985
@aheritier aheritier added area/providers For features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.) area/providers/openai For features/issues/fixes related to the usage of OpenAI models kind/fix PR fixes a bug (maps to fix: commit prefix) labels Jun 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/providers/openai For features/issues/fixes related to the usage of OpenAI models area/providers For features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.) kind/fix PR fixes a bug (maps to fix: commit prefix)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

copilot: unsupported_api_for_model

4 participants