11"""AI Task integration for Open Responses."""
22
3- import base64
43from json import JSONDecodeError
54import logging
65from typing import TYPE_CHECKING
76
8- from openai .types .responses .response_output_item import ImageGenerationCall
9-
107from homeassistant .components import ai_task , conversation
118from homeassistant .core import HomeAssistant
129from homeassistant .exceptions import HomeAssistantError
1310from homeassistant .helpers .entity_platform import AddConfigEntryEntitiesCallback
1411from homeassistant .util .json import json_loads
1512
16- from .const import (
17- CONF_CHAT_MODEL ,
18- CONF_IMAGE_MODEL ,
19- RECOMMENDED_CHAT_MODEL ,
20- RECOMMENDED_IMAGE_MODEL ,
21- UNSUPPORTED_IMAGE_MODELS ,
22- )
23- from .entity import OpenAIBaseLLMEntity
13+ from .entity import OpenResponsesEntity
2414
2515if TYPE_CHECKING :
2616 from homeassistant .config_entries import ConfigSubentry
2717
28- from . import OpenAIConfigEntry
18+ from . import OpenResponsesConfigEntry
2919
3020_LOGGER = logging .getLogger (__name__ )
3121
3222
3323async def async_setup_entry (
3424 hass : HomeAssistant ,
35- config_entry : OpenAIConfigEntry ,
25+ config_entry : OpenResponsesConfigEntry ,
3626 async_add_entities : AddConfigEntryEntitiesCallback ,
3727) -> None :
3828 """Set up AI Task entities."""
@@ -41,27 +31,26 @@ async def async_setup_entry(
4131 continue
4232
4333 async_add_entities (
44- [OpenAITaskEntity (config_entry , subentry )],
34+ [OpenResponsesTaskEntity (config_entry , subentry )],
4535 config_subentry_id = subentry .subentry_id ,
4636 )
4737
4838
49- class OpenAITaskEntity (
39+ class OpenResponsesTaskEntity (
5040 ai_task .AITaskEntity ,
51- OpenAIBaseLLMEntity ,
41+ OpenResponsesEntity ,
5242):
5343 """Open Responses AI Task entity."""
5444
55- def __init__ (self , entry : OpenAIConfigEntry , subentry : ConfigSubentry ) -> None :
45+ def __init__ (
46+ self , entry : OpenResponsesConfigEntry , subentry : ConfigSubentry
47+ ) -> None :
5648 """Initialize the entity."""
5749 super ().__init__ (entry , subentry )
5850 self ._attr_supported_features = (
5951 ai_task .AITaskEntityFeature .GENERATE_DATA
6052 | ai_task .AITaskEntityFeature .SUPPORT_ATTACHMENTS
6153 )
62- model = self .subentry .data .get (CONF_CHAT_MODEL , RECOMMENDED_CHAT_MODEL )
63- if not model .startswith (tuple (UNSUPPORTED_IMAGE_MODELS )):
64- self ._attr_supported_features |= ai_task .AITaskEntityFeature .GENERATE_IMAGE
6554
6655 async def _async_generate_data (
6756 self ,
@@ -101,56 +90,3 @@ async def _async_generate_data(
10190 conversation_id = chat_log .conversation_id ,
10291 data = data ,
10392 )
104-
105- async def _async_generate_image (
106- self ,
107- task : ai_task .GenImageTask ,
108- chat_log : conversation .ChatLog ,
109- ) -> ai_task .GenImageTaskResult :
110- """Handle a generate image task."""
111- await self ._async_handle_chat_log (chat_log , task .name , force_image = True )
112-
113- if not isinstance (chat_log .content [- 1 ], conversation .AssistantContent ):
114- raise HomeAssistantError (
115- "Last content in chat log is not an AssistantContent"
116- )
117-
118- image_call : ImageGenerationCall | None = None
119- for content in reversed (chat_log .content ):
120- if not isinstance (content , conversation .AssistantContent ):
121- break
122- if isinstance (content .native , ImageGenerationCall ):
123- if image_call is None or image_call .result is None :
124- image_call = content .native
125- else : # Remove image data from chat log to save memory
126- content .native .result = None
127-
128- if image_call is None or image_call .result is None :
129- raise HomeAssistantError ("No image returned" )
130-
131- image_data = base64 .b64decode (image_call .result )
132- image_call .result = None
133-
134- if hasattr (image_call , "output_format" ) and (
135- output_format := image_call .output_format
136- ):
137- mime_type = f"image/{ output_format } "
138- else :
139- mime_type = "image/png"
140-
141- if hasattr (image_call , "size" ) and (size := image_call .size ):
142- width , height = tuple (size .split ("x" ))
143- else :
144- width , height = None , None
145-
146- return ai_task .GenImageTaskResult (
147- image_data = image_data ,
148- conversation_id = chat_log .conversation_id ,
149- mime_type = mime_type ,
150- width = int (width ) if width else None ,
151- height = int (height ) if height else None ,
152- model = self .subentry .data .get (CONF_IMAGE_MODEL , RECOMMENDED_IMAGE_MODEL ),
153- revised_prompt = image_call .revised_prompt
154- if hasattr (image_call , "revised_prompt" )
155- else None ,
156- )
0 commit comments