From 791356405f8eaa80db25b96a002579c9a5ae0f43 Mon Sep 17 00:00:00 2001 From: burtenshaw Date: Thu, 19 Jun 2025 12:21:19 +0200 Subject: [PATCH 1/2] remove tool_calls from requests for groq --- .../inference/_providers/groq.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/huggingface_hub/inference/_providers/groq.py b/src/huggingface_hub/inference/_providers/groq.py index 11e677504e..757dba99fd 100644 --- a/src/huggingface_hub/inference/_providers/groq.py +++ b/src/huggingface_hub/inference/_providers/groq.py @@ -1,3 +1,6 @@ +from typing import Any, Dict, Optional + +from huggingface_hub.hf_api import InferenceProviderMapping from ._common import BaseConversationalTask @@ -7,3 +10,26 @@ def __init__(self): def _prepare_route(self, mapped_model: str, api_key: str) -> str: return "/openai/v1/chat/completions" + + def _prepare_payload_as_dict( + self, + inputs: Any, + parameters: Dict, + provider_mapping_info: InferenceProviderMapping, + ) -> Optional[Dict]: + payload = super()._prepare_payload_as_dict( + inputs, parameters, provider_mapping_info + ) + + # Fix tool messages for Groq compatibility + if payload is not None and "messages" in payload: + messages = payload.get("messages") + if messages is not None: + for message in messages: + is_dict = isinstance(message, dict) + is_tool_role = message.get("role") == "tool" + if is_dict and is_tool_role: + # Remove tool_calls field from tool messages + message.pop("tool_calls", None) + + return payload if payload is not None else {} From 87c65d3b7415dac30b7d435bd1c70286542a3fbb Mon Sep 17 00:00:00 2001 From: Celina Hanouti Date: Thu, 19 Jun 2025 15:26:51 +0100 Subject: [PATCH 2/2] fix input messages types instead --- .../_generated/types/chat_completion.py | 17 ++++++++++++ .../inference/_providers/groq.py | 26 ------------------- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/huggingface_hub/inference/_generated/types/chat_completion.py b/src/huggingface_hub/inference/_generated/types/chat_completion.py index 5b3b50f320..4c4c59243a 100644 --- a/src/huggingface_hub/inference/_generated/types/chat_completion.py +++ b/src/huggingface_hub/inference/_generated/types/chat_completion.py @@ -43,6 +43,23 @@ class ChatCompletionInputMessage(BaseInferenceType): content: Optional[Union[List[ChatCompletionInputMessageChunk], str]] = None name: Optional[str] = None tool_calls: Optional[List[ChatCompletionInputToolCall]] = None + tool_call_id: Optional[str] = None + refusal: Optional[str] = None + + def __post_init__(self) -> None: + super().__post_init__() + valid_fields_by_role = { + "developer": {"role", "content", "name"}, + "system": {"role", "content", "name"}, + "user": {"role", "content", "name"}, + "assistant": {"role", "content", "name", "refusal", "tool_calls", "function_call", "audio"}, + "tool": {"role", "content", "tool_call_id"}, + } + valid_fields = valid_fields_by_role.get(self.role, set()) + for field_name in ["content", "name", "tool_calls", "tool_call_id", "refusal"]: + if field_name not in valid_fields and field_name in self: + self.pop(field_name, None) + setattr(self, field_name, None) @dataclass_with_extra diff --git a/src/huggingface_hub/inference/_providers/groq.py b/src/huggingface_hub/inference/_providers/groq.py index 757dba99fd..11e677504e 100644 --- a/src/huggingface_hub/inference/_providers/groq.py +++ b/src/huggingface_hub/inference/_providers/groq.py @@ -1,6 +1,3 @@ -from typing import Any, Dict, Optional - -from huggingface_hub.hf_api import InferenceProviderMapping from ._common import BaseConversationalTask @@ -10,26 +7,3 @@ def __init__(self): def _prepare_route(self, mapped_model: str, api_key: str) -> str: return "/openai/v1/chat/completions" - - def _prepare_payload_as_dict( - self, - inputs: Any, - parameters: Dict, - provider_mapping_info: InferenceProviderMapping, - ) -> Optional[Dict]: - payload = super()._prepare_payload_as_dict( - inputs, parameters, provider_mapping_info - ) - - # Fix tool messages for Groq compatibility - if payload is not None and "messages" in payload: - messages = payload.get("messages") - if messages is not None: - for message in messages: - is_dict = isinstance(message, dict) - is_tool_role = message.get("role") == "tool" - if is_dict and is_tool_role: - # Remove tool_calls field from tool messages - message.pop("tool_calls", None) - - return payload if payload is not None else {}