diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 82346043b4..0cb0f2b6d9 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -3487,6 +3487,8 @@ async def drain_approved_tool_calls(request, form_data, user, model, metadata) - output_parts.append({'type': 'input_image', 'image_url': image_url}) else: display_files.append(file_item) + if file_item.get('type') == 'image' and file_item.get('url'): + output_parts.append({'type': 'input_image', 'image_url': file_item['url']}) output.append( { @@ -5858,7 +5860,7 @@ async def streaming_chat_response_handler(response, ctx): frontend_output = [] for item in full_output() if snapshot else full_output()[output_start:]: if item.get('type') == 'function_call_output': - # input_image parts are base64 data URIs only for the LLM, via convert_output_to_messages + # input_image parts are for the LLM only, via convert_output_to_messages item = { **item, 'output': [ @@ -6127,8 +6129,7 @@ async def streaming_chat_response_handler(response, ctx): ) result_status_by_call_id[result.get('tool_call_id', '')] = local_output_status - # Separate image data URIs (for LLM via input_image) from - # other files (for frontend display via files attribute). + # Data-URI images: LLM only. File-URL images: LLM and frontend. Other files: frontend. display_files = [] for file_item in result.get('files', []): if file_item.get('type') == 'image' and file_item.get('url', '').startswith('data:'): @@ -6136,8 +6137,9 @@ async def streaming_chat_response_handler(response, ctx): image_url = await store_tool_result_image(request, file_item['url'], metadata, user) output_parts.append({'type': 'input_image', 'image_url': image_url}) else: - # Frontend display (MCP images, audio, etc.) display_files.append(file_item) + if file_item.get('type') == 'image' and file_item.get('url'): + output_parts.append({'type': 'input_image', 'image_url': file_item['url']}) output.append( {