Browse Source

Merge pull request #9387 from open-webui/dev

0.5.9
Timothy Jaeryang Baek 2 months ago
parent
commit
ab94468ffa
4 changed files with 74 additions and 22 deletions
  1. 6 0
      CHANGELOG.md
  2. 65 19
      backend/open_webui/utils/middleware.py
  3. 2 2
      package-lock.json
  4. 1 1
      package.json

+ 6 - 0
CHANGELOG.md

@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.5.9] - 2025-02-05
+
+### Fixed
+
+- **💡 "Think" Tag Display Issue**: Resolved a bug where the "Think" tag was not functioning correctly, ensuring proper visualization of the model's reasoning process before delivering responses.
+
 ## [0.5.8] - 2025-02-05
 
 ### Added

+ 65 - 19
backend/open_webui/utils/middleware.py

@@ -1231,8 +1231,10 @@ async def process_chat_response(
                             content_blocks[-1]["content"] = content_blocks[-1][
                                 "content"
                             ].replace(match.group(0), "")
+
                             if not content_blocks[-1]["content"]:
                                 content_blocks.pop()
+
                             # Append the new block
                             content_blocks.append(
                                 {
@@ -1248,18 +1250,34 @@ async def process_chat_response(
                     tag = content_blocks[-1]["tag"]
                     # Match end tag e.g., </tag>
                     end_tag_pattern = rf"</{tag}>"
+
                     if re.search(end_tag_pattern, content):
+                        end_flag = True
+
                         block_content = content_blocks[-1]["content"]
                         # Strip start and end tags from the content
                         start_tag_pattern = rf"<{tag}(.*?)>"
                         block_content = re.sub(
                             start_tag_pattern, "", block_content
                         ).strip()
-                        block_content = re.sub(
-                            end_tag_pattern, "", block_content
-                        ).strip()
+
+                        end_tag_regex = re.compile(end_tag_pattern, re.DOTALL)
+                        split_content = end_tag_regex.split(block_content, maxsplit=1)
+
+                        # Content inside the tag
+                        block_content = (
+                            split_content[0].strip() if split_content else ""
+                        )
+
+                        # Leftover content (everything after `</tag>`)
+                        leftover_content = (
+                            split_content[1].strip() if len(split_content) > 1 else ""
+                        )
+
+                        print(f"block_content: {block_content}")
+                        print(f"leftover_content: {leftover_content}")
+
                         if block_content:
-                            end_flag = True
                             content_blocks[-1]["content"] = block_content
                             content_blocks[-1]["ended_at"] = time.time()
                             content_blocks[-1]["duration"] = int(
@@ -1270,19 +1288,29 @@ async def process_chat_response(
                             content_blocks.append(
                                 {
                                     "type": "text",
-                                    "content": "",
+                                    "content": leftover_content,
                                 }
                             )
-                            # Clean processed content
-                            content = re.sub(
-                                rf"<{tag}(.*?)>(.|\n)*?</{tag}>",
-                                "",
-                                content,
-                                flags=re.DOTALL,
-                            )
                         else:
                             # Remove the block if content is empty
                             content_blocks.pop()
+
+                            if leftover_content:
+                                content_blocks.append(
+                                    {
+                                        "type": "text",
+                                        "content": leftover_content,
+                                    }
+                                )
+
+                        # Clean processed content
+                        content = re.sub(
+                            rf"<{tag}(.*?)>(.|\n)*?</{tag}>",
+                            "",
+                            content,
+                            flags=re.DOTALL,
+                        )
+
                 return content, content_blocks, end_flag
 
             message = Chats.get_message_by_id_and_message_id(
@@ -1402,6 +1430,15 @@ async def process_chat_response(
 
                                 if value:
                                     content = f"{content}{value}"
+
+                                    if not content_blocks:
+                                        content_blocks.append(
+                                            {
+                                                "type": "text",
+                                                "content": "",
+                                            }
+                                        )
+
                                     content_blocks[-1]["content"] = (
                                         content_blocks[-1]["content"] + value
                                     )
@@ -1461,14 +1498,23 @@ async def process_chat_response(
                                 log.debug("Error: ", e)
                                 continue
 
-                    # Clean up the last text block
-                    if content_blocks[-1]["type"] == "text":
-                        content_blocks[-1]["content"] = content_blocks[-1][
-                            "content"
-                        ].strip()
+                    if content_blocks:
+                        # Clean up the last text block
+                        if content_blocks[-1]["type"] == "text":
+                            content_blocks[-1]["content"] = content_blocks[-1][
+                                "content"
+                            ].strip()
 
-                        if not content_blocks[-1]["content"]:
-                            content_blocks.pop()
+                            if not content_blocks[-1]["content"]:
+                                content_blocks.pop()
+
+                                if not content_blocks:
+                                    content_blocks.append(
+                                        {
+                                            "type": "text",
+                                            "content": "",
+                                        }
+                                    )
 
                     if response_tool_calls:
                         tool_calls.append(response_tool_calls)

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
 	"name": "open-webui",
-	"version": "0.5.8",
+	"version": "0.5.9",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "open-webui",
-			"version": "0.5.8",
+			"version": "0.5.9",
 			"dependencies": {
 				"@codemirror/lang-javascript": "^6.2.2",
 				"@codemirror/lang-python": "^6.1.6",

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 	"name": "open-webui",
-	"version": "0.5.8",
+	"version": "0.5.9",
 	"private": true,
 	"scripts": {
 		"dev": "npm run pyodide:fetch && vite dev --host",