diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 490505f416..2d685a2e03 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -4631,7 +4631,6 @@ async def streaming_chat_response_handler(response, ctx): ) async def stream_body_handler(response, form_data): - nonlocal content_parts nonlocal usage nonlocal output nonlocal prior_output @@ -4648,22 +4647,28 @@ async def streaming_chat_response_handler(response, ctx): last_delta_type = None last_delta_key = None - def response_stream_content(stream_output: list | None = None): - return ''.join(content_parts) or get_output_text( - stream_output if stream_output is not None else full_output() - ) + joined_content = '' + joined_part_count = 0 async def save_current_response_stream(stream_output: list | None = None): + nonlocal joined_content + nonlocal joined_part_count + if not chat_id or not metadata.get('message_id'): return + # content_parts is append-only, so its length tells us when the join is stale + if joined_part_count != len(content_parts): + joined_content = ''.join(content_parts) + joined_part_count = len(content_parts) + current_stream_output = stream_output if stream_output is not None else full_output() await save_response_stream( request.app.state.redis, response_stream_task_id, chat_id, metadata.get('message_id'), - response_stream_content(current_stream_output), + joined_content or get_output_text(current_stream_output), current_stream_output, ) diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py index beb91d2b04..21368c8fd3 100644 --- a/backend/open_webui/utils/misc.py +++ b/backend/open_webui/utils/misc.py @@ -254,7 +254,8 @@ def get_output_text(output: list | None) -> str: text = ''.join( str(part.get('text')) for part in parts if isinstance(part, dict) and part.get('text') is not None ) - if text.strip(): + # isspace() avoids the full-string copy strip() would make + if text and not text.isspace(): texts.append(text) return '\n'.join(texts)