diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index a0084d5975..be83db29b6 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1044,6 +1044,39 @@ def process_tool_result( return tool_result, tool_result_files, tool_result_embeds +async def display_file_handler( + tool_function_name: str, + tool_function_params: dict, + tool_result, + event_emitter, +): + """Emit a display_file event if the tool is display_file and the file exists.""" + if not event_emitter or tool_function_name != "display_file": + return + + path = tool_function_params.get("path", "") + if not path: + return + + # Parse the result to check if the file exists + parsed = tool_result + if isinstance(parsed, str): + try: + parsed = json.loads(parsed) + except (json.JSONDecodeError, TypeError): + pass + + if isinstance(parsed, dict) and parsed.get("exists") is False: + return + + await event_emitter( + { + "type": "display_file", + "data": {"path": path}, + } + ) + + async def chat_completion_tools_handler( request: Request, body: dict, extra_params: dict, user: UserModel, models, tools ) -> tuple[dict, dict]: @@ -1198,6 +1231,10 @@ async def chat_completion_tools_handler( ) if event_emitter: + await display_file_handler( + tool_function_name, tool_function_params, tool_result, event_emitter + ) + if tool_result_files: await event_emitter( { @@ -4178,6 +4215,10 @@ async def streaming_chat_response_handler(response, ctx): ) ) + await display_file_handler( + tool_function_name, tool_function_params, tool_result, event_emitter + ) + # Extract citation sources from tool results if ( tool_function_name