From 06b0dcb63ab241a298368d51a44d080fc468ec6c Mon Sep 17 00:00:00 2001 From: "Jannik S." Date: Tue, 13 Jan 2026 11:59:55 +0100 Subject: [PATCH] Require reasoning tags to start at line beginning --- backend/open_webui/utils/middleware.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index fe2d7e5dc1d..ce1c8a13f79 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -2535,6 +2535,15 @@ def extract_attributes(tag_content): attributes[key] = value return attributes + def is_inside_fenced_code_block(text: str, index: int) -> bool: + """Check if index is inside a fenced ``` code block.""" + return text[:index].count("```") % 2 == 1 + + def is_tag_at_line_start(text: str, index: int) -> bool: + """Return True if tag starts at line start (ignoring whitespace).""" + line_start = text.rfind("\n", 0, index) + 1 + return text[line_start:index].strip() == "" + if content_blocks[-1]["type"] == "text": for start_tag, end_tag in tags: @@ -2547,7 +2556,17 @@ def extract_attributes(tag_content): rf"<{re.escape(start_tag[1:-1])}(\s.*?)?>" ) - match = re.search(start_tag_pattern, content) + match = None + for candidate in re.finditer(start_tag_pattern, content): + if ( + not is_inside_fenced_code_block( + content, candidate.start() + ) + and is_tag_at_line_start(content, candidate.start()) + ): + match = candidate + break + if match: try: attr_content = (