From c8485c4120b0b959950eced3a72a9233c06ba3e0 Mon Sep 17 00:00:00 2001 From: Utsab Dahal Date: Sun, 12 Apr 2026 14:46:52 +0545 Subject: [PATCH] chore(groq): cleanup diff for GHAS and patch coverage --- litellm/llms/groq/chat/transformation.py | 17 ++++--- tests/llm_translation/test_groq.py | 56 ++++++++---------------- 2 files changed, 27 insertions(+), 46 deletions(-) diff --git a/litellm/llms/groq/chat/transformation.py b/litellm/llms/groq/chat/transformation.py index 5603aaf9611..178053df1c2 100644 --- a/litellm/llms/groq/chat/transformation.py +++ b/litellm/llms/groq/chat/transformation.py @@ -1,7 +1,6 @@ """ Translate from OpenAI's `/v1/chat/completions` to Groq's `/v1/chat/completions` """ - from typing import ( Any, Coroutine, @@ -116,7 +115,8 @@ class GroqChatConfig(OpenAILikeChatConfig): @overload def _transform_messages( self, messages: List[AllMessageValues], model: str, is_async: Literal[True] - ) -> Coroutine[Any, Any, List[AllMessageValues]]: ... + ) -> Coroutine[Any, Any, List[AllMessageValues]]: + ... @overload def _transform_messages( @@ -124,7 +124,8 @@ class GroqChatConfig(OpenAILikeChatConfig): messages: List[AllMessageValues], model: str, is_async: Literal[False] = False, - ) -> List[AllMessageValues]: ... + ) -> List[AllMessageValues]: + ... def _transform_messages( self, messages: List[AllMessageValues], model: str, is_async: bool = False @@ -132,8 +133,6 @@ class GroqChatConfig(OpenAILikeChatConfig): for idx, message in enumerate(messages): """ 1. Don't pass 'null' function_call assistant message to groq - https://github.com/BerriAI/litellm/issues/5839 - 2. Strip LiteLLM-internal provider_specific_fields from assistant history - before sending to Groq, which rejects unknown assistant properties. """ if isinstance(message, BaseModel): _message = message.model_dump() @@ -296,10 +295,10 @@ class GroqChatConfig(OpenAILikeChatConfig): json_mode=json_mode, ) - mapped_service_tier: Literal["auto", "default", "flex"] = ( - self._map_groq_service_tier( - original_service_tier=getattr(model_response, "service_tier") - ) + mapped_service_tier: Literal[ + "auto", "default", "flex" + ] = self._map_groq_service_tier( + original_service_tier=getattr(model_response, "service_tier") ) setattr(model_response, "service_tier", mapped_service_tier) return model_response diff --git a/tests/llm_translation/test_groq.py b/tests/llm_translation/test_groq.py index f6ee9c65f67..d04fe9b14bf 100644 --- a/tests/llm_translation/test_groq.py +++ b/tests/llm_translation/test_groq.py @@ -18,7 +18,6 @@ from litellm.llms.groq.chat.transformation import ( ) from litellm.types.llms.openai import AllMessageValues - class TestGroq(BaseLLMChatTest): def get_base_completion_call_args(self) -> dict: return { @@ -32,10 +31,7 @@ class TestGroq(BaseLLMChatTest): def test_tool_call_with_empty_enum_property(self): pass - @pytest.mark.parametrize( - "model", - ["groq/qwen/qwen3-32b", "groq/openai/gpt-oss-20b", "groq/openai/gpt-oss-120b"], - ) + @pytest.mark.parametrize("model", ["groq/qwen/qwen3-32b", "groq/openai/gpt-oss-20b", "groq/openai/gpt-oss-120b"]) def test_reasoning_effort_in_supported_params(self, model): """Test that reasoning_effort is in the list of supported parameters for Groq""" supported_params = GroqChatConfig().get_supported_openai_params(model=model) @@ -98,19 +94,19 @@ class TestGroqStructuredOutputs: "schema": { "type": "object", "properties": {"name": {"type": "string"}}, - "required": ["name"], - }, - }, + "required": ["name"] + } + } }, "tools": [ { "type": "function", "function": { "name": "get_weather", - "parameters": {"type": "object", "properties": {}}, - }, + "parameters": {"type": "object", "properties": {}} + } } - ], + ] } with pytest.raises(litellm.BadRequestError) as exc_info: @@ -124,9 +120,7 @@ class TestGroqStructuredOutputs: assert "does not support native structured outputs" in str(exc_info.value) assert "incompatible with user-provided tools" in str(exc_info.value) - def test_structured_output_without_tools_uses_workaround_for_non_native_models( - self, - ): + def test_structured_output_without_tools_uses_workaround_for_non_native_models(self): """ Test that structured outputs without tools works using the json_tool_call workaround for models that don't support native json_schema. @@ -143,9 +137,9 @@ class TestGroqStructuredOutputs: "schema": { "type": "object", "properties": {"name": {"type": "string"}}, - "required": ["name"], - }, - }, + "required": ["name"] + } + } } } @@ -181,9 +175,9 @@ class TestGroqStructuredOutputs: "schema": { "type": "object", "properties": {"name": {"type": "string"}}, - "required": ["name"], - }, - }, + "required": ["name"] + } + } } } @@ -206,7 +200,7 @@ class TestGroqStructuredOutputs: class TestGroqReasoning: """ Tests for Groq reasoning field mapping. - + Groq returns 'reasoning' field in delta, but LiteLLM expects 'reasoning_content'. """ @@ -241,10 +235,7 @@ class TestGroqReasoning: parsed_chunk = handler.chunk_parser(groq_chunk) # Verify that reasoning was mapped to reasoning_content - assert ( - parsed_chunk.choices[0].delta.reasoning_content - == "This is reasoning content" - ) + assert parsed_chunk.choices[0].delta.reasoning_content == "This is reasoning content" # Verify that the original 'reasoning' field was removed assert not hasattr(parsed_chunk.choices[0].delta, "reasoning") @@ -305,10 +296,7 @@ class TestGroqReasoning: { "index": 0, "id": "call_123", - "function": { - "name": "test_function", - "arguments": "{}", - }, + "function": {"name": "test_function", "arguments": "{}"}, "type": "function", } ], @@ -323,14 +311,8 @@ class TestGroqReasoning: parsed_chunk = handler.chunk_parser(groq_chunk) # Verify that reasoning was mapped to reasoning_content - assert ( - parsed_chunk.choices[0].delta.reasoning_content - == "Reasoning before tool call" - ) + assert parsed_chunk.choices[0].delta.reasoning_content == "Reasoning before tool call" # Verify tool_calls are still present assert parsed_chunk.choices[0].delta.tool_calls is not None assert len(parsed_chunk.choices[0].delta.tool_calls) == 1 - assert ( - parsed_chunk.choices[0].delta.tool_calls[0]["function"]["name"] - == "test_function" - ) + assert parsed_chunk.choices[0].delta.tool_calls[0]["function"]["name"] == "test_function"