refactor(gpt_transformation.py): refactor out json schema converstion to base config

keeps logic consistent across providers
This commit is contained in:
Krrish Dholakia 2025-02-05 15:30:23 -08:00
parent 6f01d22d73
commit efc2a886ee
2 changed files with 47 additions and 43 deletions

View file

@ -175,46 +175,17 @@ class AzureOpenAIConfig(BaseConfig):
else:
optional_params["tool_choice"] = value
elif param == "response_format" and isinstance(value, dict):
json_schema: Optional[dict] = None
if "response_schema" in value:
json_schema = value["response_schema"]
elif "json_schema" in value:
json_schema = value["json_schema"]["schema"]
"""
Follow similar approach to anthropic - translate to a single tool call.
When using tools in this way: - https://docs.anthropic.com/en/docs/build-with-claude/tool-use#json-mode
- You usually want to provide a single tool
- You should set tool_choice (see Forcing tool use) to instruct the model to explicitly use that tool
- Remember that the model will pass the input to the tool, so the name of the tool and description should be from the model’s perspective.
"""
_is_response_format_supported_model = (
self._is_response_format_supported_model(model)
)
if json_schema is not None and (
(api_version_year <= "2024" and api_version_month < "08")
or not _is_response_format_supported_model
): # azure api version "2024-08-01-preview" onwards supports 'json_schema' only for gpt-4o/3.5 models
_tool_choice = ChatCompletionToolChoiceObjectParam(
type="function",
function=ChatCompletionToolChoiceFunctionParam(
name=RESPONSE_FORMAT_TOOL_NAME
),
)
_tool = ChatCompletionToolParam(
type="function",
function=ChatCompletionToolParamFunctionChunk(
name=RESPONSE_FORMAT_TOOL_NAME, parameters=json_schema
),
)
optional_params = self._add_response_format_to_tools(
optional_params, _tool, _tool_choice
)
else:
optional_params["response_format"] = value
should_convert_response_format_to_tool = (
api_version_year <= "2024" and api_version_month < "08"
) or not _is_response_format_supported_model
optional_params = self._add_response_format_to_tools(
optional_params=optional_params,
value=value,
should_convert_response_format_to_tool=should_convert_response_format_to_tool,
)
elif param == "tools" and isinstance(value, list):
optional_params.setdefault("tools", [])
optional_params["tools"].extend(value)

View file

@ -19,10 +19,13 @@ import httpx
from pydantic import BaseModel
from litellm._logging import verbose_logger
from litellm.constants import RESPONSE_FORMAT_TOOL_NAME
from litellm.types.llms.openai import (
AllMessageValues,
ChatCompletionToolChoiceFunctionParam,
ChatCompletionToolChoiceObjectParam,
ChatCompletionToolParam,
ChatCompletionToolParamFunctionChunk,
)
from litellm.types.utils import ModelResponse
@ -155,18 +158,48 @@ class BaseConfig(ABC):
def _add_response_format_to_tools(
self,
optional_params: dict,
_tool: ChatCompletionToolParam,
_tool_choice: ChatCompletionToolChoiceObjectParam,
value: dict,
should_convert_response_format_to_tool: bool,
) -> dict:
"""
Follow similar approach to anthropic - translate to a single tool call.
When using tools in this way: - https://docs.anthropic.com/en/docs/build-with-claude/tool-use#json-mode
- You usually want to provide a single tool
- You should set tool_choice (see Forcing tool use) to instruct the model to explicitly use that tool
- Remember that the model will pass the input to the tool, so the name of the tool and description should be from the model’s perspective.
Add response format to tools
This is used to translate response_format to a tool call, for models/APIs that don't support response_format directly.
"""
optional_params.setdefault("tools", [])
optional_params["tools"].append(_tool)
optional_params["tool_choice"] = _tool_choice
optional_params["json_mode"] = True
json_schema: Optional[dict] = None
if "response_schema" in value:
json_schema = value["response_schema"]
elif "json_schema" in value:
json_schema = value["json_schema"]["schema"]
if json_schema and should_convert_response_format_to_tool:
_tool_choice = ChatCompletionToolChoiceObjectParam(
type="function",
function=ChatCompletionToolChoiceFunctionParam(
name=RESPONSE_FORMAT_TOOL_NAME
),
)
_tool = ChatCompletionToolParam(
type="function",
function=ChatCompletionToolParamFunctionChunk(
name=RESPONSE_FORMAT_TOOL_NAME, parameters=json_schema
),
)
optional_params.setdefault("tools", [])
optional_params["tools"].append(_tool)
optional_params["tool_choice"] = _tool_choice
optional_params["json_mode"] = True
else:
optional_params["response_format"] = value
return optional_params
@abstractmethod