Add support for GPT-Image-2.5 (#181735)

This commit is contained in:
Denis Shulyaka
2026-09-09 13:21:47 +02:00
committed by GitHub
parent 5b742807ba
commit 2089f53b38
5 changed files with 61 additions and 13 deletions
@@ -553,6 +553,8 @@ class OpenAISubentryFlowHandler(ConfigSubentryFlow):
] = SelectSelector(
SelectSelectorConfig(
options=[
"gpt-image-2.5-sunburst",
"gpt-image-2.5-flare",
"gpt-image-2",
"gpt-image-1.5",
"gpt-image-1",
@@ -40,7 +40,7 @@ CONF_WEB_SEARCH_TIMEZONE = "timezone"
CONF_WEB_SEARCH_INLINE_CITATIONS = "inline_citations"
RECOMMENDED_CODE_INTERPRETER = False
RECOMMENDED_CHAT_MODEL = "gpt-4o-mini"
RECOMMENDED_IMAGE_MODEL = "gpt-image-2"
RECOMMENDED_IMAGE_MODEL = "gpt-image-2.5-flare"
RECOMMENDED_MAX_TOKENS = 3000
RECOMMENDED_PRO_MODE = False
RECOMMENDED_REASONING_EFFORT = "low"
@@ -630,7 +630,7 @@ class OpenAIBaseLLMEntity(Entity):
model=image_model,
output_format="png",
)
if image_model not in ("gpt-image-1-mini", "gpt-image-2"):
if image_model in ("gpt-image-1", "gpt-image-1.5"):
image_tool["input_fidelity"] = "high"
tools.append(image_tool)
# Keep image state on OpenAI so follow-up prompts can continue by
@@ -10,7 +10,10 @@ import voluptuous as vol
from homeassistant.components import ai_task, media_source
from homeassistant.components.openai_conversation import DOMAIN
from homeassistant.components.openai_conversation.const import CONF_STORE_RESPONSES
from homeassistant.components.openai_conversation.const import (
CONF_IMAGE_MODEL,
CONF_STORE_RESPONSES,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er, issue_registry as ir, selector
@@ -229,12 +232,31 @@ async def test_generate_data_with_attachments(
@pytest.mark.freeze_time("2025-06-14 22:59:00")
@pytest.mark.parametrize("configured_store", [False, True])
@pytest.mark.parametrize(
("image_model", "input_fidelity_present"),
("image_options", "image_model", "input_fidelity_options"),
[
("gpt-image-2", False),
("gpt-image-1.5", True),
("gpt-image-1", True),
("gpt-image-1-mini", False),
({}, "gpt-image-2.5-flare", {}),
(
{CONF_IMAGE_MODEL: "gpt-image-2.5-sunburst"},
"gpt-image-2.5-sunburst",
{},
),
(
{CONF_IMAGE_MODEL: "gpt-image-2.5-flare"},
"gpt-image-2.5-flare",
{},
),
({CONF_IMAGE_MODEL: "gpt-image-2"}, "gpt-image-2", {}),
(
{CONF_IMAGE_MODEL: "gpt-image-1.5"},
"gpt-image-1.5",
{"input_fidelity": "high"},
),
(
{CONF_IMAGE_MODEL: "gpt-image-1"},
"gpt-image-1",
{"input_fidelity": "high"},
),
({CONF_IMAGE_MODEL: "gpt-image-1-mini"}, "gpt-image-1-mini", {}),
],
)
async def test_generate_image(
@@ -243,8 +265,9 @@ async def test_generate_image(
mock_create_stream: AsyncMock,
entity_registry: er.EntityRegistry,
issue_registry: ir.IssueRegistry,
image_options: dict[str, str],
image_model: str,
input_fidelity_present: bool,
input_fidelity_options: dict[str, str],
configured_store: bool,
) -> None:
"""Test AI Task image generation."""
@@ -264,7 +287,7 @@ async def test_generate_image(
ai_task_entry,
data={
**ai_task_entry.data,
"image_model": image_model,
**image_options,
CONF_STORE_RESPONSES: configured_store,
},
)
@@ -314,7 +337,12 @@ async def test_generate_image(
if tool["type"] == "image_generation"
),
)
assert ("input_fidelity" in image_tool) == input_fidelity_present
assert image_tool == {
"type": "image_generation",
"model": image_model,
"output_format": "png",
**input_fidelity_options,
}
image_data = mock_upload_media.call_args[0][1]
assert image_data.file.getvalue() == b"A"
assert image_data.content_type == "image/png"
@@ -1352,10 +1352,27 @@ async def test_ai_task_subentry_not_loaded(
assert result.get("reason") == "entry_not_loaded"
@pytest.mark.usefixtures("mock_init_component")
@pytest.mark.parametrize(
("image_options", "image_model"),
[
({}, "gpt-image-2.5-flare"),
(
{CONF_IMAGE_MODEL: "gpt-image-2.5-sunburst"},
"gpt-image-2.5-sunburst",
),
(
{CONF_IMAGE_MODEL: "gpt-image-2.5-flare"},
"gpt-image-2.5-flare",
),
({CONF_IMAGE_MODEL: "gpt-image-2"}, "gpt-image-2"),
],
)
async def test_creating_ai_task_subentry_additional(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_init_component,
image_options: dict[str, str],
image_model: str,
) -> None:
"""Test creating an AI task subentry with additional settings."""
result = await hass.config_entries.subentries.async_init(
@@ -1398,6 +1415,7 @@ async def test_creating_ai_task_subentry_additional(
result["flow_id"],
{
CONF_CODE_INTERPRETER: False,
**image_options,
},
)
@@ -1406,7 +1424,7 @@ async def test_creating_ai_task_subentry_additional(
assert result4.get("data") == {
CONF_RECOMMENDED: False,
CONF_CHAT_MODEL: "gpt-4o",
CONF_IMAGE_MODEL: "gpt-image-2",
CONF_IMAGE_MODEL: image_model,
CONF_MAX_TOKENS: 200,
CONF_STORE_RESPONSES: True,
CONF_TEMPERATURE: 0.5,