diff --git a/litellm/llms/gemini/image_generation/transformation.py b/litellm/llms/gemini/image_generation/transformation.py index 63b835df9d0..46cbf6ae877 100644 --- a/litellm/llms/gemini/image_generation/transformation.py +++ b/litellm/llms/gemini/image_generation/transformation.py @@ -258,6 +258,7 @@ class GoogleImageGenConfig(BaseImageGenerationConfig): model_response.data.append(ImageObject( b64_json=inline_data["data"], url=None, + thought_signature=part.get("thoughtSignature"), )) # Extract usage metadata for Gemini models diff --git a/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py b/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py index 89ed9f1a8a5..f266f860712 100644 --- a/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py +++ b/litellm/llms/vertex_ai/image_generation/vertex_gemini_transformation.py @@ -298,6 +298,7 @@ class VertexAIGeminiImageGenerationConfig(BaseImageGenerationConfig, VertexLLM): model_response.data.append(ImageObject( b64_json=inline_data["data"], url=None, + thought_signature=part.get("thoughtSignature"), )) if usage_metadata := response_data.get("usageMetadata", None): diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 6c330d0f83c..077277f4830 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -2129,6 +2129,7 @@ class ImageObject(OpenAIImage): b64_json: The base64-encoded JSON of the generated image, if response_format is b64_json. url: The URL of the generated image, if response_format is url (default). revised_prompt: The prompt that was used to generate the image, if there was any revision to the prompt. + thought_signature: The thought signature returned by Gemini image generation models (used for interactive image editing). https://platform.openai.com/docs/api-reference/images/object """ @@ -2136,9 +2137,11 @@ class ImageObject(OpenAIImage): b64_json: Optional[str] = None url: Optional[str] = None revised_prompt: Optional[str] = None + thought_signature: Optional[str] = None - def __init__(self, b64_json=None, url=None, revised_prompt=None, **kwargs): + def __init__(self, b64_json=None, url=None, revised_prompt=None, thought_signature=None, **kwargs): super().__init__(b64_json=b64_json, url=url, revised_prompt=revised_prompt) # type: ignore + self.thought_signature = thought_signature def __contains__(self, key): # Define custom behavior for the 'in' operator diff --git a/tests/test_litellm/llms/vertex_ai/image_generation/test_vertex_ai_image_generation_transformation.py b/tests/test_litellm/llms/vertex_ai/image_generation/test_vertex_ai_image_generation_transformation.py index b91438b3cac..b4f5053955e 100644 --- a/tests/test_litellm/llms/vertex_ai/image_generation/test_vertex_ai_image_generation_transformation.py +++ b/tests/test_litellm/llms/vertex_ai/image_generation/test_vertex_ai_image_generation_transformation.py @@ -230,6 +230,47 @@ class TestVertexAIGeminiImageGenerationConfig: assert result.data[0].b64_json == "image1" assert result.data[1].b64_json == "image2" + def test_transform_image_generation_response_signature(self): + """Test response transformation includes thoughtSignature for Gemini 3 Pro""" + mock_response = MagicMock(spec=httpx.Response) + mock_response.status_code = 200 + mock_response.json.return_value = { + "candidates": [ + { + "content": { + "parts": [ + { + "inlineData": { + "mimeType": "image/png", + "data": "base64_encoded_image_data", + }, + "thoughtSignature": "test_signature_abc123", + } + ] + } + } + ] + } + mock_response.headers = {} + + from litellm.types.utils import ImageResponse + + model_response = ImageResponse() + result = self.config.transform_image_generation_response( + model="gemini-3-pro-image-preview", + raw_response=mock_response, + model_response=model_response, + logging_obj=MagicMock(), + request_data={}, + optional_params={}, + litellm_params={}, + encoding=None, + ) + + assert len(result.data) == 1 + assert result.data[0].b64_json == "base64_encoded_image_data" + assert result.data[0].thought_signature == "test_signature_abc123" + class TestVertexAIImagenImageGenerationConfig: def setup_method(self):