Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions litellm/llms/github_copilot/responses/transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
)
from litellm.types.router import GenericLiteLLMParams
from litellm.types.utils import LlmProviders
from litellm.utils import _get_model_info_helper

from ..authenticator import Authenticator
from ..common_utils import (
Expand All @@ -38,6 +39,53 @@
LiteLLMLoggingObj = Any


def github_copilot_supports_responses_api(model: str) -> bool:
"""
Resolve whether to use the native Responses API for a github_copilot model.

Copilot's /v1/responses endpoint is per-model (only some models like
gpt-5.5, gpt-5.4, gpt-5.4-mini opt in upstream). The Responses API config
is registered for github_copilot provider-wide, so this function gates
per-model to keep /v1/responses calls from failing upstream on chat-only
Copilot models like claude-opus-4.7 or gemini-3.1-pro-preview.

The router calls ``litellm.register_model`` for every proxy deployment,
which merges the user's per-deployment ``model_info`` (e.g. ``mode: chat``
to force a chat-only override) into ``litellm.model_cost`` before any
request runs. ``_get_model_info_helper`` therefore returns merged data
with user overrides already applied.

Resolution order (first match wins):
1. ``mode == "responses"`` → True (positive opt-in; user or catalog).
2. ``mode == "chat"`` → False (explicit opt-out wins over endpoint
declarations, letting users force the bridge for dual-endpoint models).
3. ``"/v1/responses"`` in ``supported_endpoints`` → True.
4. Otherwise → False (conservative default; the bridge always works
because every Copilot model supports /chat/completions).

Catalog lookup raising (model not registered) → False (conservative).
"""
try:
info = _get_model_info_helper(model=model, custom_llm_provider="github_copilot")
except Exception as e:
verbose_logger.debug(
"github_copilot_supports_responses_api: get_model_info failed "
"for %s: %s",
model,
e,
)
return False

mode = info.get("mode")
if mode == "responses":
return True
if mode == "chat":
return False

endpoints = info.get("supported_endpoints")
return isinstance(endpoints, list) and "/v1/responses" in endpoints


class GithubCopilotResponsesAPIConfig(OpenAIResponsesAPIConfig):
"""
Configuration for GitHub Copilot's Responses API.
Expand Down
8 changes: 7 additions & 1 deletion litellm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8575,7 +8575,13 @@ def _get_python_responses_api_config(
elif litellm.LlmProviders.XAI == provider:
return litellm.XAIResponsesAPIConfig()
elif litellm.LlmProviders.GITHUB_COPILOT == provider:
return litellm.GithubCopilotResponsesAPIConfig()
from litellm.llms.github_copilot.responses.transformation import (
github_copilot_supports_responses_api,
)

if model is None or github_copilot_supports_responses_api(model=model):
return litellm.GithubCopilotResponsesAPIConfig()
return None
elif litellm.LlmProviders.CHATGPT == provider:
return litellm.ChatGPTResponsesAPIConfig()
elif litellm.LlmProviders.LITELLM_PROXY == provider:
Expand Down
Loading
Loading