@@ -168,6 +168,58 @@ def _convert_content_to_param(
168168 return messages
169169
170170
171+ async def _async_prepare_message_attachments (
172+ hass : HomeAssistant ,
173+ chat_content : Iterable [conversation .Content ],
174+ messages : ResponseInputParam ,
175+ ) -> None :
176+ """Attach files to all matching user messages."""
177+ message_index = 0
178+
179+ for content in chat_content :
180+ if isinstance (content , conversation .ToolResultContent ):
181+ message_index += 1
182+ continue
183+
184+ if (
185+ isinstance (content , conversation .AssistantContent )
186+ and isinstance (content .native , dict )
187+ and content .native .get ("type" )
188+ ):
189+ message_index += 1
190+ continue
191+
192+ if content .content or (
193+ isinstance (content , conversation .UserContent ) and content .attachments
194+ ):
195+ if isinstance (content , conversation .UserContent ) and content .attachments :
196+ files = await async_prepare_files_for_prompt (
197+ hass ,
198+ [
199+ (attachment .path , attachment .mime_type )
200+ for attachment in content .attachments
201+ ],
202+ )
203+ message = messages [message_index ]
204+ assert (
205+ message ["type" ] == "message"
206+ and message ["role" ] == "user"
207+ and isinstance (message ["content" ], str )
208+ )
209+ message_content : ResponseInputMessageContentListParam = []
210+ if message ["content" ]:
211+ message_content .append (
212+ {"type" : "input_text" , "text" : message ["content" ]}
213+ )
214+ message_content .extend (files )
215+ message ["content" ] = message_content
216+
217+ message_index += 1
218+
219+ if isinstance (content , conversation .AssistantContent ) and content .tool_calls :
220+ message_index += len (content .tool_calls )
221+
222+
171223async def _transform_stream (
172224 chat_log : conversation .ChatLog ,
173225 stream : AsyncIterable [dict [str , Any ]],
@@ -307,7 +359,9 @@ async def _async_handle_chat_log(
307359 ) -> None :
308360 """Generate an answer for the chat log."""
309361 options = self .subentry .data
310- messages = _convert_content_to_param (chat_log .content )
362+ chat_content = list (chat_log .content )
363+ messages = _convert_content_to_param (chat_content )
364+ await _async_prepare_message_attachments (self .hass , chat_content , messages )
311365
312366 model_args : dict [str , Any ] = {
313367 "model" : options .get (CONF_MODEL , self .entry .data [CONF_MODEL ]),
@@ -329,26 +383,6 @@ async def _async_handle_chat_log(
329383 if tools :
330384 model_args ["tools" ] = tools
331385
332- last_content = chat_log .content [- 1 ]
333- if last_content .role == "user" and last_content .attachments :
334- files = await async_prepare_files_for_prompt (
335- self .hass ,
336- [(a .path , a .mime_type ) for a in last_content .attachments ],
337- )
338- last_message = messages [- 1 ]
339- assert (
340- last_message ["type" ] == "message"
341- and last_message ["role" ] == "user"
342- and isinstance (last_message ["content" ], str )
343- )
344- last_message_content : ResponseInputMessageContentListParam = []
345- if last_message ["content" ]:
346- last_message_content .append (
347- {"type" : "input_text" , "text" : last_message ["content" ]}
348- )
349- last_message_content .extend (files )
350- last_message ["content" ] = last_message_content
351-
352386 if structure and structure_name :
353387 model_args ["text" ] = {
354388 "format" : {
0 commit comments