mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-19 00:01:29 +00:00
[Bug Fix] xai/ translation fix - ensure finish_reason includes tool calls when xai responses with tool calls (#12545)
* Helper to fix finish_reason for tool calls when XAI API returns empty string * use llm http handler for Groq
This commit is contained in:
parent
858c756d47
commit
6bc926e04b
2 changed files with 90 additions and 1 deletions
|
|
@ -1,5 +1,7 @@
|
|||
from typing import List, Optional, Tuple
|
||||
|
||||
import httpx
|
||||
|
||||
import litellm
|
||||
from litellm._logging import verbose_logger
|
||||
from litellm.litellm_core_utils.prompt_templates.common_utils import (
|
||||
|
|
@ -8,6 +10,7 @@ from litellm.litellm_core_utils.prompt_templates.common_utils import (
|
|||
)
|
||||
from litellm.secret_managers.main import get_secret_str
|
||||
from litellm.types.llms.openai import AllMessageValues
|
||||
from litellm.types.utils import Choices, ModelResponse
|
||||
|
||||
from ...openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||
|
||||
|
|
@ -100,3 +103,60 @@ class XAIChatConfig(OpenAIGPTConfig):
|
|||
return super().transform_request(
|
||||
model, messages, optional_params, litellm_params, headers
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _fix_choice_finish_reason_for_tool_calls(choice: Choices) -> None:
|
||||
"""
|
||||
Helper to fix finish_reason for tool calls when XAI API returns empty string.
|
||||
|
||||
XAI API returns empty string for finish_reason when using tools,
|
||||
so we need to set it to "tool_calls" when tool_calls are present.
|
||||
"""
|
||||
if (choice.finish_reason == "" and
|
||||
choice.message.tool_calls and
|
||||
len(choice.message.tool_calls) > 0):
|
||||
choice.finish_reason = "tool_calls"
|
||||
|
||||
def transform_response(
|
||||
self,
|
||||
model: str,
|
||||
raw_response: httpx.Response,
|
||||
model_response: ModelResponse,
|
||||
logging_obj,
|
||||
request_data: dict,
|
||||
messages: List[AllMessageValues],
|
||||
optional_params: dict,
|
||||
litellm_params: dict,
|
||||
encoding,
|
||||
api_key: Optional[str] = None,
|
||||
json_mode: Optional[bool] = None,
|
||||
) -> ModelResponse:
|
||||
"""
|
||||
Transform the response from the XAI API.
|
||||
|
||||
XAI API returns empty string for finish_reason when using tools,
|
||||
so we need to fix this after the standard OpenAI transformation.
|
||||
"""
|
||||
|
||||
# First, let the parent class handle the standard transformation
|
||||
response = super().transform_response(
|
||||
model=model,
|
||||
raw_response=raw_response,
|
||||
model_response=model_response,
|
||||
logging_obj=logging_obj,
|
||||
request_data=request_data,
|
||||
messages=messages,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
encoding=encoding,
|
||||
api_key=api_key,
|
||||
json_mode=json_mode,
|
||||
)
|
||||
|
||||
# Fix finish_reason for tool calls across all choices
|
||||
if response.choices:
|
||||
for choice in response.choices:
|
||||
if isinstance(choice, Choices):
|
||||
self._fix_choice_finish_reason_for_tool_calls(choice)
|
||||
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -1766,7 +1766,36 @@ def completion( # type: ignore # noqa: PLR0915
|
|||
additional_args={"headers": headers},
|
||||
)
|
||||
raise e
|
||||
|
||||
elif custom_llm_provider == "xai":
|
||||
## COMPLETION CALL
|
||||
try:
|
||||
response = base_llm_http_handler.completion(
|
||||
model=model,
|
||||
messages=messages,
|
||||
headers=headers,
|
||||
model_response=model_response,
|
||||
api_key=api_key,
|
||||
api_base=api_base,
|
||||
acompletion=acompletion,
|
||||
logging_obj=logging,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
timeout=timeout, # type: ignore
|
||||
client=client,
|
||||
custom_llm_provider=custom_llm_provider,
|
||||
encoding=encoding,
|
||||
stream=stream,
|
||||
provider_config=provider_config,
|
||||
)
|
||||
except Exception as e:
|
||||
## LOGGING - log the original exception returned
|
||||
logging.post_call(
|
||||
input=messages,
|
||||
api_key=api_key,
|
||||
original_response=str(e),
|
||||
additional_args={"headers": headers},
|
||||
)
|
||||
raise e
|
||||
elif custom_llm_provider == "groq":
|
||||
api_base = (
|
||||
api_base # for deepinfra/perplexity/anyscale/groq/friendliai we check in get_llm_provider and pass in the api base from there
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue