mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-13 08:52:02 +00:00
fix(databricks): bridge GPT-5.4+ function tools to the Responses API
Databricks forwards its OpenAI GPT endpoints (databricks-gpt-5-4, -5-6-sol, ...) to OpenAI, whose Chat Completions rejects function tools while reasoning is on. The version check never matched the hyphenated Databricks names, so these requests were sent to /chat/completions and failed.
This commit is contained in:
parent
e0e3523246
commit
250a694864
1 changed files with 22 additions and 3 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import re
|
||||
from collections.abc import Mapping, Sequence
|
||||
from typing import Final, cast # noqa: TID251 # moved unchanged from litellm/main.py
|
||||
from urllib.parse import urlsplit
|
||||
|
|
@ -15,6 +16,15 @@ from litellm.utils import get_model_info_helper
|
|||
|
||||
_OPENAI_DEFAULT_API_BASE: Final = "https://api.openai.com/v1"
|
||||
_OPENAI_API_HOST: Final = "api.openai.com"
|
||||
# Databricks serves OpenAI GPT models as e.g. ``databricks-gpt-5-6-sol``: the minor version is
|
||||
# hyphenated, so the OpenAI version parser does not recognise it.
|
||||
_DATABRICKS_GPT_NAME: Final = re.compile(r"^databricks-gpt-(\d+)-(\d+)(?=-|$)")
|
||||
|
||||
|
||||
def _openai_name_for_databricks_model(model: str) -> str:
|
||||
"""``databricks-gpt-5-6-sol`` -> ``gpt-5.6-sol``; other names are returned unchanged."""
|
||||
model_name: Final = model.split("/")[-1]
|
||||
return _DATABRICKS_GPT_NAME.sub(r"gpt-\1.\2", model_name)
|
||||
|
||||
|
||||
def _is_openai_backed_api_base(api_base: str) -> bool:
|
||||
|
|
@ -122,8 +132,15 @@ def responses_api_bridge_check(
|
|||
on_foundry_openai_endpoint: Final = custom_llm_provider == "azure_ai" and azure_ai_supports_native_responses(
|
||||
model, api_base
|
||||
)
|
||||
# Databricks proxies OpenAI GPT models to the real OpenAI backend, which enforces the
|
||||
# reasoning+tools constraint, and serves them on its own /responses route as well.
|
||||
on_databricks_gpt_endpoint: Final = custom_llm_provider == "databricks" and OpenAIGPT5Config.is_model_gpt_5_model(
|
||||
model
|
||||
)
|
||||
on_constraint_enforcing_endpoint: Final = (
|
||||
custom_llm_provider == "azure" or resolved_api_base == "" or _is_openai_backed_api_base(resolved_api_base)
|
||||
custom_llm_provider in ("azure", "databricks")
|
||||
or resolved_api_base == ""
|
||||
or _is_openai_backed_api_base(resolved_api_base)
|
||||
)
|
||||
chat_rejects_function_tools: Final = (
|
||||
has_function_tool
|
||||
|
|
@ -132,7 +149,9 @@ def responses_api_bridge_check(
|
|||
foundry_chat_rejects_function_tools_while_reasoning(model, reasoning_effort)
|
||||
if on_foundry_openai_endpoint
|
||||
else (
|
||||
OpenAIGPT5Config.is_model_gpt_5_4_plus_model(model)
|
||||
OpenAIGPT5Config.is_model_gpt_5_4_plus_model(
|
||||
_openai_name_for_databricks_model(model) if on_databricks_gpt_endpoint else model
|
||||
)
|
||||
and (reasoning_effort is not None or on_constraint_enforcing_endpoint)
|
||||
)
|
||||
)
|
||||
|
|
@ -143,7 +162,7 @@ def responses_api_bridge_check(
|
|||
and OpenAIGPT5Config.is_model_gpt_5_model(model)
|
||||
and not OpenAIGPT5Config.is_model_gpt_5_search_model(model)
|
||||
and ((reasoning_effort is not None and reasoning_summary is not None) or chat_rejects_function_tools)
|
||||
):
|
||||
) or (on_databricks_gpt_endpoint and model_info.get("mode") != "responses" and chat_rejects_function_tools):
|
||||
model_info["mode"] = "responses"
|
||||
model = model.replace("responses/", "")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue