diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index d68936d02a..1de1592da1 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1284,124 +1284,134 @@ async def process_chat_response( # Non-streaming response if not isinstance(response, StreamingResponse): if event_emitter: - if isinstance(response, dict) or isinstance(response, JSONResponse): + try: + if isinstance(response, dict) or isinstance(response, JSONResponse): + if isinstance(response, list) and len(response) == 1: + # If the response is a single-item list, unwrap it #17213 + response = response[0] - if isinstance(response, JSONResponse) and isinstance( - response.body, bytes - ): - try: - response_data = json.loads(response.body.decode("utf-8")) - except json.JSONDecodeError: - response_data = {"error": {"detail": "Invalid JSON response"}} - else: - response_data = response - - if "error" in response_data: - error = response_data.get("error") - - if isinstance(error, dict): - error = error.get("detail", error) + if isinstance(response, JSONResponse) and isinstance( + response.body, bytes + ): + try: + response_data = json.loads(response.body.decode("utf-8")) + except json.JSONDecodeError: + response_data = { + "error": {"detail": "Invalid JSON response"} + } else: - error = str(error) + response_data = response - Chats.upsert_message_to_chat_by_id_and_message_id( - metadata["chat_id"], - metadata["message_id"], - { - "error": {"content": error}, - }, - ) - if isinstance(error, str) or isinstance(error, dict): - await event_emitter( - { - "type": "chat:message:error", - "data": {"error": {"content": error}}, - } - ) + if "error" in response_data: + error = response_data.get("error") - if "selected_model_id" in response_data: - Chats.upsert_message_to_chat_by_id_and_message_id( - metadata["chat_id"], - metadata["message_id"], - { - "selectedModelId": response_data["selected_model_id"], - }, - ) + if isinstance(error, dict): + error = error.get("detail", error) + else: + error = str(error) - choices = response_data.get("choices", []) - if choices and choices[0].get("message", {}).get("content"): - content = response_data["choices"][0]["message"]["content"] - - if content: - await event_emitter( - { - "type": "chat:completion", - "data": response_data, - } - ) - - title = Chats.get_chat_title_by_id(metadata["chat_id"]) - - await event_emitter( - { - "type": "chat:completion", - "data": { - "done": True, - "content": content, - "title": title, - }, - } - ) - - # Save message in the database Chats.upsert_message_to_chat_by_id_and_message_id( metadata["chat_id"], metadata["message_id"], { - "role": "assistant", - "content": content, + "error": {"content": error}, + }, + ) + if isinstance(error, str) or isinstance(error, dict): + await event_emitter( + { + "type": "chat:message:error", + "data": {"error": {"content": error}}, + } + ) + + if "selected_model_id" in response_data: + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "selectedModelId": response_data["selected_model_id"], }, ) - # Send a webhook notification if the user is not active - if not get_active_status_by_user_id(user.id): - webhook_url = Users.get_user_webhook_url_by_id(user.id) - if webhook_url: - await post_webhook( - request.app.state.WEBUI_NAME, - webhook_url, - f"{title} - {request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}\n\n{content}", - { - "action": "chat", - "message": content, + choices = response_data.get("choices", []) + if choices and choices[0].get("message", {}).get("content"): + content = response_data["choices"][0]["message"]["content"] + + if content: + await event_emitter( + { + "type": "chat:completion", + "data": response_data, + } + ) + + title = Chats.get_chat_title_by_id(metadata["chat_id"]) + + await event_emitter( + { + "type": "chat:completion", + "data": { + "done": True, + "content": content, "title": title, - "url": f"{request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}", }, - ) + } + ) - await background_tasks_handler() + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "role": "assistant", + "content": content, + }, + ) - if events and isinstance(events, list): - extra_response = {} - for event in events: - if isinstance(event, dict): - extra_response.update(event) - else: - extra_response[event] = True + # Send a webhook notification if the user is not active + if not get_active_status_by_user_id(user.id): + webhook_url = Users.get_user_webhook_url_by_id(user.id) + if webhook_url: + await post_webhook( + request.app.state.WEBUI_NAME, + webhook_url, + f"{title} - {request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}\n\n{content}", + { + "action": "chat", + "message": content, + "title": title, + "url": f"{request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}", + }, + ) - response_data = { - **extra_response, - **response_data, - } + await background_tasks_handler() - if isinstance(response, dict): - response = response_data - if isinstance(response, JSONResponse): - response = JSONResponse( - content=response_data, - headers=response.headers, - status_code=response.status_code, - ) + if events and isinstance(events, list): + extra_response = {} + for event in events: + if isinstance(event, dict): + extra_response.update(event) + else: + extra_response[event] = True + + response_data = { + **extra_response, + **response_data, + } + + if isinstance(response, dict): + response = response_data + if isinstance(response, JSONResponse): + response = JSONResponse( + content=response_data, + headers=response.headers, + status_code=response.status_code, + ) + + except Exception as e: + log.debug(f"Error occurred while processing request: {e}") + pass return response else: