From 4b675ccab3e91fbd0decf1be58753f0fc0f6f698 Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Sat, 11 Oct 2025 09:45:57 -0700 Subject: [PATCH] fix: _handle_raw_dict_response_item --- .../transformation.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/litellm/completion_extras/litellm_responses_transformation/transformation.py b/litellm/completion_extras/litellm_responses_transformation/transformation.py index 5f732fc521..bf7f7a5dd1 100644 --- a/litellm/completion_extras/litellm_responses_transformation/transformation.py +++ b/litellm/completion_extras/litellm_responses_transformation/transformation.py @@ -50,6 +50,47 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): def __init__(self): pass + def _handle_raw_dict_response_item( + self, item: Dict[str, Any], index: int + ) -> Tuple[Optional[Any], int]: + """ + Handle raw dict response items from Responses API (e.g., GPT-5 Codex format). + + Args: + item: Raw dict response item with 'type' field + index: Current choice index + + Returns: + Tuple of (Choice object or None, updated index) + """ + from litellm.types.utils import Choices, Message + + item_type = item.get("type") + + # Ignore reasoning items for now + if item_type == "reasoning": + return None, index + + # Handle message items with output_text content + if item_type == "message": + content_list = item.get("content", []) + for content_item in content_list: + if isinstance(content_item, dict): + content_type = content_item.get("type") + if content_type == "output_text": + response_text = content_item.get("text", "") + msg = Message( + role=item.get("role", "assistant"), + content=response_text if response_text else "" + ) + choice = Choices( + message=msg, finish_reason="stop", index=index + ) + return choice, index + 1 + + # Unknown or unsupported type + return None, index + def convert_chat_completion_messages_to_responses_api( self, messages: List["AllMessageValues"] ) -> Tuple[List[Any], Optional[str]]: @@ -273,6 +314,11 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge): Choices(message=msg, finish_reason="tool_calls", index=index) ) index += 1 + elif isinstance(item, dict): + # Handle raw dict responses (e.g., from GPT-5 Codex) + choice, index = self._handle_raw_dict_response_item(item=item, index=index) + if choice is not None: + choices.append(choice) else: pass # don't fail request if item in list is not supported