From c676303a55b9c78800efbd7fd70c84b4ccc356ed Mon Sep 17 00:00:00 2001 From: Rory <16675082+roryeckel@users.noreply.github.com> Date: Wed, 5 Feb 2025 23:26:13 -0600 Subject: [PATCH 1/2] enh: automatically remove incorrect backticks before code_interpreter tags --- backend/open_webui/utils/middleware.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 06763483c..402b699c1 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1188,6 +1188,23 @@ async def process_chat_response( output = block.get("output", None) lang = attributes.get("lang", "") + # Separate content from ending whitespace but preserve it + original_whitespace = '' + content_stripped = content.rstrip() + if len(content) > len(content_stripped): + original_whitespace = content[len(content_stripped):] + + # Count the number of backticks to identify if we are in an opening code block + backtick_segments = content_stripped.split('```') + # Odd number of ``` segments -> the last backticks are closing a block + # Even number -> the last backticks are opening a new block + if len(backtick_segments) > 1 and len(backtick_segments) % 2 == 0: + # The trailing backticks are opening a new block, they need to be removed or it will break the code interpreter markdown + content = content_stripped.rstrip('`').rstrip() + original_whitespace + else: + # The trailing backticks are closing a block (or there are no backticks), so it won't cause issues + content = content_stripped + original_whitespace + if output: output = html.escape(json.dumps(output)) From 74b971b88861b26c9be76cd11c068de4336187b0 Mon Sep 17 00:00:00 2001 From: Rory <16675082+roryeckel@users.noreply.github.com> Date: Wed, 5 Feb 2025 23:38:35 -0600 Subject: [PATCH 2/2] refac: clean up solution for correcting code_interpreter backticks --- backend/open_webui/utils/middleware.py | 27 +++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 402b699c1..331b850ff 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1122,6 +1122,16 @@ async def process_chat_response( }, ) + def split_content_and_whitespace(content): + content_stripped = content.rstrip() + original_whitespace = content[len(content_stripped):] if len(content) > len(content_stripped) else '' + return content_stripped, original_whitespace + + def is_opening_code_block(content): + backtick_segments = content.split('```') + # Even number of segments means the last backticks are opening a new block + return len(backtick_segments) > 1 and len(backtick_segments) % 2 == 0 + # Handle as a background task async def post_response_handler(response, events): def serialize_content_blocks(content_blocks, raw=False): @@ -1188,21 +1198,12 @@ async def process_chat_response( output = block.get("output", None) lang = attributes.get("lang", "") - # Separate content from ending whitespace but preserve it - original_whitespace = '' - content_stripped = content.rstrip() - if len(content) > len(content_stripped): - original_whitespace = content[len(content_stripped):] - - # Count the number of backticks to identify if we are in an opening code block - backtick_segments = content_stripped.split('```') - # Odd number of ``` segments -> the last backticks are closing a block - # Even number -> the last backticks are opening a new block - if len(backtick_segments) > 1 and len(backtick_segments) % 2 == 0: - # The trailing backticks are opening a new block, they need to be removed or it will break the code interpreter markdown + content_stripped, original_whitespace = split_content_and_whitespace(content) + if is_opening_code_block(content_stripped): + # Remove trailing backticks that would open a new block content = content_stripped.rstrip('`').rstrip() + original_whitespace else: - # The trailing backticks are closing a block (or there are no backticks), so it won't cause issues + # Keep content as is - either closing backticks or no backticks content = content_stripped + original_whitespace if output: