From e1b2d9de3c85bdeb8b38dab33fcef28ec42ecac5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:45:23 +0000 Subject: [PATCH 1/3] fix(images): forward gpt-image supported params like background to OpenAI and Azure Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/types/utils.py | 1 + litellm/utils.py | 11 ++++--- tests/test_litellm/test_utils.py | 31 ++++++++++++++++++++ tests/test_litellm/types/test_types_utils.py | 9 ++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 569fce4f7b8..0bdbb83fbb4 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -2543,6 +2543,7 @@ class ImageResponse(OpenAIImageResponse, BaseLiteLLMOpenAIResponseObject): ) super().__init__(created=created, data=_data, usage=_usage) + self.background = kwargs.get("background", None) self.quality = kwargs.get("quality", None) self.output_format = kwargs.get("output_format", None) self.size = kwargs.get("size", None) diff --git a/litellm/utils.py b/litellm/utils.py index ba456fc353b..239673a20d9 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -3338,6 +3338,9 @@ def get_optional_params_image_gen( continue passed_params[k] = v + provider_supported_params: Final[tuple[str, ...]] = ( + tuple(provider_config.get_supported_openai_params(model=model or "")) if provider_config is not None else () + ) default_params: Final = { "n": None, "quality": None, @@ -3348,6 +3351,7 @@ def get_optional_params_image_gen( "imageConfig": None, "tools": None, "web_search_options": None, + **{k: None for k in provider_supported_params}, } non_default_params: Final = _get_non_default_params( @@ -3407,10 +3411,9 @@ def get_optional_params_image_gen( if size is not None: optional_params["aspectRatio"] = _map_openai_size_to_vertex_ai_aspect_ratio(size) - openai_params: list[str] = list(default_params.keys()) - if provider_config is not None: - supported_params = provider_config.get_supported_openai_params(model=model or "") - openai_params = list(supported_params) + openai_params: Final[list[str]] = ( + list(provider_supported_params) if provider_config is not None else list(default_params.keys()) + ) optional_params = add_provider_specific_params_to_optional_params( optional_params=optional_params, diff --git a/tests/test_litellm/test_utils.py b/tests/test_litellm/test_utils.py index 200cfd02197..99c69d6bc31 100644 --- a/tests/test_litellm/test_utils.py +++ b/tests/test_litellm/test_utils.py @@ -330,6 +330,37 @@ def test_get_optional_params_image_gen(): assert optional_params["n"] == 3 +@pytest.mark.parametrize("custom_llm_provider", ["openai", "azure"]) +def test_get_optional_params_image_gen_keeps_gpt_image_supported_params(custom_llm_provider): + """https://github.com/BerriAI/litellm/issues/38649""" + from litellm.types.utils import LlmProviders + + provider_config = ProviderConfigManager.get_provider_image_generation_config( + model="gpt-image-2", provider=LlmProviders(custom_llm_provider) + ) + optional_params = get_optional_params_image_gen( + model="gpt-image-2", + n=1, + size="1024x1024", + custom_llm_provider=custom_llm_provider, + provider_config=provider_config, + background="transparent", + output_format="png", + moderation="low", + output_compression=50, + unknown_param="kept-in-extra-body", + ) + assert optional_params == { + "n": 1, + "size": "1024x1024", + "background": "transparent", + "output_format": "png", + "moderation": "low", + "output_compression": 50, + "extra_body": {"unknown_param": "kept-in-extra-body"}, + } + + def test_get_optional_params_image_gen_vertex_ai_size(): """Test that Vertex AI image generation properly handles size parameter and maps it to aspectRatio""" # Test with various size parameters diff --git a/tests/test_litellm/types/test_types_utils.py b/tests/test_litellm/types/test_types_utils.py index c081b9e8e0d..554604ab200 100644 --- a/tests/test_litellm/types/test_types_utils.py +++ b/tests/test_litellm/types/test_types_utils.py @@ -759,3 +759,12 @@ def test_delta_function_tool_call_unchanged_by_custom_support(): delta = Delta(tool_calls=[{"index": 0, "id": "c2", "type": "function", "function": {"name": "g", "arguments": ""}}]) assert isinstance(delta.tool_calls[0], ChatCompletionDeltaToolCall) assert "custom" not in delta.model_dump()["tool_calls"][0] + + +def test_image_response_keeps_background(): + """https://github.com/BerriAI/litellm/issues/38649""" + from litellm.types.utils import ImageResponse + + response = ImageResponse(created=1, data=[{"b64_json": "aGk="}], background="transparent", output_format="png") + assert response.background == "transparent" + assert response.model_dump()["background"] == "transparent" From 4d3c1998affa9249fbfdcd0c8157acaa991f9186 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 3 Sep 2026 10:50:23 -0700 Subject: [PATCH 2/3] fix(image_gen): report the requested output_format on gpt-image responses --- .../image_generation/gpt_transformation.py | 2 +- .../test_gpt_transformation.py | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py diff --git a/litellm/llms/openai/image_generation/gpt_transformation.py b/litellm/llms/openai/image_generation/gpt_transformation.py index 05494c497ca..64244cfaeda 100644 --- a/litellm/llms/openai/image_generation/gpt_transformation.py +++ b/litellm/llms/openai/image_generation/gpt_transformation.py @@ -84,6 +84,6 @@ class GPTImageGenerationConfig(BaseImageGenerationConfig): # set optional params image_response.size = optional_params.get("size", "1024x1024") # default is always 1024x1024 image_response.quality = optional_params.get("quality", "high") # always hd for dall-e-3 - image_response.output_format = optional_params.get("response_format", "png") # always png for dall-e-3 + image_response.output_format = optional_params.get("output_format", "png") return image_response diff --git a/tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py b/tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py new file mode 100644 index 00000000000..de54713a570 --- /dev/null +++ b/tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py @@ -0,0 +1,38 @@ +from unittest.mock import MagicMock + +import httpx +import pytest + +from litellm.llms.azure.image_generation.gpt_transformation import AzureGPTImageGenerationConfig +from litellm.llms.openai.image_generation.gpt_transformation import GPTImageGenerationConfig +from litellm.types.utils import ImageResponse + + +@pytest.mark.parametrize("config", [GPTImageGenerationConfig(), AzureGPTImageGenerationConfig()]) +def test_transform_image_generation_response_reports_requested_output_format(config): + raw_response = httpx.Response( + status_code=200, + json={ + "created": 1788457009, + "data": [{"b64_json": "/9j/4AAQSkZJRg=="}], + "output_format": "jpeg", + "background": "opaque", + "quality": "low", + "size": "1024x1024", + }, + request=httpx.Request("POST", "https://api.openai.com/v1/images/generations"), + ) + + image_response = config.transform_image_generation_response( + model="gpt-image-2", + raw_response=raw_response, + model_response=ImageResponse(), + logging_obj=MagicMock(), + request_data={"prompt": "a red apple", "output_format": "jpeg"}, + optional_params={"output_format": "jpeg"}, + litellm_params={}, + encoding=None, + ) + + assert image_response.output_format == "jpeg" + assert image_response.background == "opaque" From ec2e35b6796b75231f8ff54686baa1604e7f3697 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 3 Sep 2026 11:07:08 -0700 Subject: [PATCH 3/3] fix(image_gen): keep the provider's echoed size, quality, and output_format on gpt-image responses --- litellm/llms/openai/image_generation/gpt_transformation.py | 6 +++--- .../llms/openai/image_generation/test_gpt_transformation.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/litellm/llms/openai/image_generation/gpt_transformation.py b/litellm/llms/openai/image_generation/gpt_transformation.py index 64244cfaeda..090b2eba387 100644 --- a/litellm/llms/openai/image_generation/gpt_transformation.py +++ b/litellm/llms/openai/image_generation/gpt_transformation.py @@ -82,8 +82,8 @@ class GPTImageGenerationConfig(BaseImageGenerationConfig): ) # set optional params - image_response.size = optional_params.get("size", "1024x1024") # default is always 1024x1024 - image_response.quality = optional_params.get("quality", "high") # always hd for dall-e-3 - image_response.output_format = optional_params.get("output_format", "png") + image_response.size = image_response.size or optional_params.get("size", "1024x1024") + image_response.quality = image_response.quality or optional_params.get("quality", "high") + image_response.output_format = image_response.output_format or optional_params.get("output_format", "png") return image_response diff --git a/tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py b/tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py index de54713a570..d9b87627b58 100644 --- a/tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py +++ b/tests/test_litellm/llms/openai/image_generation/test_gpt_transformation.py @@ -9,7 +9,7 @@ from litellm.types.utils import ImageResponse @pytest.mark.parametrize("config", [GPTImageGenerationConfig(), AzureGPTImageGenerationConfig()]) -def test_transform_image_generation_response_reports_requested_output_format(config): +def test_transform_image_generation_response_keeps_provider_echo(config): raw_response = httpx.Response( status_code=200, json={ @@ -35,4 +35,5 @@ def test_transform_image_generation_response_reports_requested_output_format(con ) assert image_response.output_format == "jpeg" + assert image_response.quality == "low" assert image_response.background == "opaque"