mirror of
https://github.com/open-webui/open-webui.git
synced 2026-05-07 03:18:23 -05:00
[GH-ISSUE #13397] issue: Problems with calling functions in the Google Gemini API compatible with OpenAI and MCPO #16897
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @holasoygeorgee on GitHub (May 1, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/13397
Check Existing Issues
Installation Method
Git Clone
Open WebUI Version
v0.6.5
Ollama Version (if applicable)
V0.6.0
Operating System
windows
Browser (if applicable)
Brave
Confirmation
README.md.Expected Behavior
I've been testing the Google Gemini API with OpenAI support and trying to use it with MCPO and native function calls.
Actual Behavior
Native function call in openwebui with google gemini compatible with openai api does not work and throws this error:
Steps to Reproduce
Logs & Screenshots
2025-05-01 00:50:12.888 | ERROR | open_webui.routers.openai:generate_chat_completion:749 - 400, message='Bad Request', url='https://generativelanguage.googleapis.com/v1beta/openai/chat/completions' - {}
Traceback (most recent call last):
File "", line 198, in _run_module_as_main
File "", line 88, in _run_code
File "C:\GENERIC_PATH\envs\my_env\Scripts\uvicorn.exe_main_.py", line 7, in
sys.exit(main())
│ │ └
│ └
└ <module 'sys' (built-in)>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\click\core.py", line 1161, in call
return self.main(args, **kwargs)
│ │ │ └ {}
│ │ └ ()
│ └ <function BaseCommand.main at 0x000001C71823AAC0>
└
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\click\core.py", line 1082, in main
rv = self.invoke(ctx)
│ │ └ <click.core.Context object at 0x000001C7184AB890>
│ └ <function Command.invoke at 0x000001C71823B6A0>
└
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\click\core.py", line 1443, in invoke
return ctx.invoke(self.callback, **ctx.params)
│ │ │ │ │ └ {'host': '0.0.0.0', 'port': 8080, 'forwarded_allow_ips': "''", 'workers': 1, 'ws': 'auto', 'app': 'open_webui.main:app', 'ud...
│ │ │ │ └ <click.core.Context object at 0x000001C7184AB890>
│ │ │ └ <function main at 0x000001C718497BA0>
│ │ └
│ └ <function Context.invoke at 0x000001C71823A020>
└ <click.core.Context object at 0x000001C7184AB890>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\click\core.py", line 788, in invoke
return __callback(args, **kwargs)
│ └ {'host': '0.0.0.0', 'port': 8080, 'forwarded_allow_ips': "''", 'workers': 1, 'ws': 'auto', 'app': 'open_webui.main:app', 'ud...
└ ()
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\uvicorn\main.py", line 412, in main
run(
└ <function run at 0x000001C7182C11C0>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\uvicorn\main.py", line 579, in run
server.run()
│ └ <function Server.run at 0x000001C718318CC0>
└ <uvicorn.server.Server object at 0x000001C7182A9850>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\uvicorn\server.py", line 66, in run
return asyncio.run(self.serve(sockets=sockets))
│ │ │ │ └ None
│ │ │ └ <function Server.serve at 0x000001C718318D60>
│ │ └ <uvicorn.server.Server object at 0x000001C7182A9850>
│ └ <function run at 0x000001C717AD9A80>
└ <module 'asyncio' from 'C:\GENERIC_PATH\envs\my_env\Lib\asyncio\init.py'>
File "C:\GENERIC_PATH\envs\my_env\Lib\asyncio\runners.py", line 190, in run
return runner.run(main)
│ │ └ <coroutine object Server.serve at 0x000001C718432F20>
│ └ <function Runner.run at 0x000001C717B49580>
└ <asyncio.runners.Runner object at 0x000001C7184B2F90>
File "C:\GENERIC_PATH\envs\my_env\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
│ │ │ └ <Task pending name='Task-1' coro=<Server.serve() running at C:\GENERIC_PATH\envs\my_env\Lib\site-packages\uvicor...
│ │ └ <function BaseEventLoop.run_until_complete at 0x000001C717B431A0>
│ └
└ <asyncio.runners.Runner object at 0x000001C7184B2F90>
File "C:\GENERIC_PATH\envs\my_env\Lib\asyncio\base_events.py", line 641, in run_until_complete
self.run_forever()
│ └ <function ProactorEventLoop.run_forever at 0x000001C717C127A0>
└
File "C:\GENERIC_PATH\envs\my_env\Lib\asyncio\windows_events.py", line 321, in run_forever
super().run_forever()
File "C:\GENERIC_PATH\envs\my_env\Lib\asyncio\base_events.py", line 608, in run_forever
self._run_once()
│ └ <function BaseEventLoop._run_once at 0x000001C717B48F40>
└
File "C:\GENERIC_PATH\envs\my_env\Lib\asyncio\base_events.py", line 1936, in _run_once
handle._run()
│ └ <function Handle._run at 0x000001C717A932E0>
└ <Handle Task.task_wakeup()>
File "C:\GENERIC_PATH\envs\my_env\Lib\asyncio\events.py", line 84, in _run
self._context.run(self._callback, *self._args)
│ │ │ │ │ └ <member '_args' of 'Handle' objects>
│ │ │ │ └ <Handle Task.task_wakeup()>
│ │ │ └ <member '_callback' of 'Handle' objects>
│ │ └ <Handle Task.task_wakeup()>
│ └ <member '_context' of 'Handle' objects>
└ <Handle Task.task_wakeup()>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette\middleware\base.py", line 141, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
│ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..send_no_error at 0x000001C754DC63E0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x000001C75338E690>
└ <open_webui.main.RedirectMiddleware object at 0x000001C7534EA9D0>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette\middleware\exceptions.py", line 62, in call
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
│ │ │ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..send_no_error at 0x000001C754DC63E0>
│ │ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ │ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
│ │ │ └ <starlette.requests.Request object at 0x000001C754E1C950>
│ │ └ <fastapi.routing.APIRouter object at 0x000001C73C3531D0>
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x000001C75338E690>
└ <function wrap_app_handling_exceptions at 0x000001C71CBE04A0>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x000001C754DC6FC0>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
└ <fastapi.routing.APIRouter object at 0x000001C73C3531D0>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette\routing.py", line 715, in call
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x000001C754DC6FC0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
│ └ <bound method Router.app of <fastapi.routing.APIRouter object at 0x000001C73C3531D0>>
└ <fastapi.routing.APIRouter object at 0x000001C73C3531D0>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette\routing.py", line 735, in app
await route.handle(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x000001C754DC6FC0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
│ └ <function Route.handle at 0x000001C71CBE1B20>
└ APIRoute(path='/api/chat/completions', name='chat_completion', methods=['POST'])
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette\routing.py", line 288, in handle
await self.app(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x000001C754DC6FC0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
│ └ <function request_response..app at 0x000001C754BB2C00>
└ APIRoute(path='/api/chat/completions', name='chat_completion', methods=['POST'])
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette\routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
│ │ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x000001C754DC6FC0>
│ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
│ │ └ <starlette.requests.Request object at 0x000001C754E13410>
│ └ <function request_response..app..app at 0x000001C754DC77E0>
└ <function wrap_app_handling_exceptions at 0x000001C71CBE04A0>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x000001C754DC5B20>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x000001C754DC6980>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8080), 'cl...
└ <function request_response..app..app at 0x000001C754DC77E0>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\starlette\routing.py", line 73, in app
response = await f(request)
│ └ <starlette.requests.Request object at 0x000001C754E13410>
└ <function get_request_handler..app at 0x000001C754BB2B60>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\fastapi\routing.py", line 301, in app
raw_response = await run_endpoint_function(
└ <function run_endpoint_function at 0x000001C71CBE3920>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\fastapi\routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
│ │ └ {'user': UserModel(id='e9526f7e-616d-4015-ab8f-66326629449f', name='[REDACTED_USERNAME]', email='[REDACTED_EMAIL]', role='admin', ...
│ └ <function chat_completion at 0x000001C754BB0B80>
└ Dependant(path_params=[], query_params=[], header_params=[], cookie_params=[], body_params=[ModelField(field_info=Body(Pydant...
File "C:\GENERIC_PATH\project_dir\open-webui\backend\open_webui\main.py", line 1152, in chat_completion
response = await chat_completion_handler(request, form_data, user)
│ │ │ └ UserModel(id='e9526f7e-616d-4015-ab8f-66326629449f', name='[REDACTED_USERNAME]', email='[REDACTED_EMAIL]', role='admin', profile_i...
│ │ └ {'stream': True, 'model': 'models/gemini-2.5-pro-exp-03-25', 'messages': [{'role': 'user', 'content': 'HI'}], 'metadata': {'u...
│ └ <starlette.requests.Request object at 0x000001C754E13410>
└ <function generate_chat_completion at 0x000001C73A1B7920>
File "C:\GENERIC_PATH\project_dir\open-webui\backend\open_webui\utils\chat.py", line 275, in generate_chat_completion
return await generate_openai_chat_completion(
└ <function generate_chat_completion at 0x000001C73A141760>
File "C:\GENERIC_PATH\envs\my_env\Lib\site-packages\aiohttp\client_reqrep.py", line 1161, in raise_for_status
raise ClientResponseError(
└ <class 'aiohttp.client_exceptions.ClientResponseError'>
aiohttp.client_exceptions.ClientResponseError: 400, message='Bad Request', url='https://generativelanguage.googleapis.com/v1beta/openai/chat/completions'
Additional Information
Trying to solve the problem, I discovered that the problem comes from the metadata of the call to native functions of the middleware, I modified the code to be compatible with the Google Gemini API and managed to get the model to work and recognize the tools, but the MCPO tools do not run:
if tools_dict: if metadata.get("function_calling") == "native": # If the function calling is native, then call the tools function calling handler metadata["tools"] = tools_dict tools_list = [] for tool in tools_dict.values(): spec = tool.get("spec", {}).copy() # Eliminar campo 'type' duplicado spec.pop("type", None) # Asegurar estructura de parameters params = spec.get("parameters", {}) params.setdefault("properties", {}) params.setdefault("required", []) spec["parameters"] = params tools_list.append({"type": "function", "function": spec}) form_data["tools"] = tools_list