diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 9cb936d3ec..847b714cb0 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -233,6 +233,9 @@ def _split_tool_calls( """ def split_json_objects(raw: str) -> list[str]: + if not isinstance(raw, str): + raw = '' if raw is None else json.dumps(raw) + decoder = json.JSONDecoder() results = [] position = 0 @@ -253,7 +256,11 @@ def _split_tool_calls( expanded = [] for tool_call in tool_calls: - arguments = tool_call.get('function', {}).get('arguments', '') + function = tool_call.setdefault('function', {}) + arguments = function.get('arguments') + if not isinstance(arguments, str): + arguments = '' if arguments is None else json.dumps(arguments) + function['arguments'] = arguments split_arguments = split_json_objects(arguments) if len(split_arguments) <= 1: @@ -4397,7 +4404,13 @@ async def streaming_chat_response_handler(response, ctx): # Add the new tool call delta_tool_call.setdefault('function', {}) delta_tool_call['function'].setdefault('name', '') - delta_tool_call['function'].setdefault('arguments', '') + delta_arguments = delta_tool_call['function'].get('arguments') + if not isinstance(delta_arguments, str): + delta_tool_call['function']['arguments'] = ( + '' + if delta_arguments is None + else json.dumps(delta_arguments) + ) response_tool_calls.append(delta_tool_call) else: # Update the existing tool call @@ -4409,10 +4422,18 @@ async def streaming_chat_response_handler(response, ctx): if delta_name: current_response_tool_call['function']['name'] = delta_name - if delta_arguments: - current_response_tool_call['function']['arguments'] += ( - delta_arguments - ) + if delta_arguments is not None: + if not isinstance(delta_arguments, str): + delta_arguments = json.dumps(delta_arguments) + current_response_tool_call.setdefault('function', {}) + if not isinstance( + current_response_tool_call['function'].get('arguments'), + str, + ): + current_response_tool_call['function']['arguments'] = '' + current_response_tool_call['function'][ + 'arguments' + ] += delta_arguments # Emit pending tool calls in real-time if response_tool_calls: