Ver código fonte

refac: mcp spec/response handling

Timothy Jaeryang Baek 1 semana atrás
pai
commit
db9d3d386d
1 arquivos alterados com 33 adições e 20 exclusões
  1. 33 20
      backend/open_webui/utils/middleware.py

+ 33 - 20
backend/open_webui/utils/middleware.py

@@ -1177,8 +1177,11 @@ async def process_chat_payload(request, form_data, user, metadata, model):
 
                         tool_function = make_tool_function(tool_spec["name"])
 
-                        mcp_tools_dict[tool_spec["name"]] = {
-                            "spec": tool_spec,
+                        mcp_tools_dict[f"{server_id}_{tool_spec['name']}"] = {
+                            "spec": {
+                                **tool_spec,
+                                "name": f"{server_id}_{tool_spec['name']}",
+                            },
                             "callable": tool_function,
                             "type": "mcp",
                             "client": mcp_client,
@@ -1226,7 +1229,6 @@ async def process_chat_payload(request, form_data, user, metadata, model):
                 {"type": "function", "function": tool.get("spec", {})}
                 for tool in tools_dict.values()
             ]
-
         else:
             # If the function calling is not native, then call the tools function calling handler
             try:
@@ -2689,23 +2691,19 @@ async def process_chat_response(
 
                         tool_result_files = []
                         if isinstance(tool_result, list):
-                            for item in tool_result:
-                                # check if string
-                                if isinstance(item, str) and item.startswith("data:"):
-                                    tool_result_files.append(
-                                        {
-                                            "type": "data",
-                                            "content": item,
-                                        }
-                                    )
-                                    tool_result.remove(item)
-
-                                if tool.get("type") == "mcp":
+                            if tool.get("type") == "mcp":  # MCP
+                                response = []
+                                for item in tool_result:
                                     if isinstance(item, dict):
-                                        if (
-                                            item.get("type") == "image"
-                                            or item.get("type") == "audio"
-                                        ):
+                                        if item.get("type") == "text":
+                                            text = item.get("text", "")
+                                            if isinstance(text, str):
+                                                try:
+                                                    text = json.loads(text)
+                                                except json.JSONDecodeError:
+                                                    pass
+                                            response.append(text)
+                                        elif item.get("type") in ["image", "audio"]:
                                             file_url = get_file_url_from_base64(
                                                 request,
                                                 f"data:{item.get('mimeType')};base64,{item.get('data', item.get('blob', ''))}",
@@ -2730,7 +2728,22 @@ async def process_chat_response(
                                                     "url": file_url,
                                                 }
                                             )
-                                            tool_result.remove(item)
+                                tool_result = (
+                                    response[0] if len(response) == 1 else response
+                                )
+                            else:  # OpenAPI
+                                for item in tool_result:
+                                    # check if string
+                                    if isinstance(item, str) and item.startswith(
+                                        "data:"
+                                    ):
+                                        tool_result_files.append(
+                                            {
+                                                "type": "data",
+                                                "content": item,
+                                            }
+                                        )
+                                        tool_result.remove(item)
 
                         if tool_result_files:
                             if not isinstance(tool_result, list):