[GH-ISSUE #14583] issue: Ollama backend improperly handles native multi-tool calls #55971

Closed
opened 2026-05-05 18:24:44 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @JRomainG on GitHub (Jun 1, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/14583

Check Existing Issues

  • I have searched the existing issues and discussions.
  • I am using the latest version of Open WebUI.

Installation Method

Docker

Open WebUI Version

v0.6.13

Ollama Version (if applicable)

0.9.0

Operating System

macOS Sequoia (15.5)

Browser (if applicable)

Firefox 139.0.1

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

When the Ollama API returns multiple tools to run, Open WebUI calls each tool one by one, like for the OpenAI-compatible backends

Actual Behavior

The Open WebUI middleware concatenates all tool calls together when using the Ollama backend, resulting in a single invalid tool. In addition, because the tool does not exist, the Open WebUI frontend loads indefinitely without ever performing a request to the tool server (which might be related to #14577)

Steps to Reproduce

  1. Install the latest version of ollama
  2. Download a model compatible with tool-calling (in this example, devstral:latest)
  3. Run the mcp-time server using mcpo:
docker run -d -p 8000:8000 ghcr.io/open-webui/mcpo:main -- uvx mcp-server-time --local-timezone=America/New_York
  1. Run Open WebUI using docker with debug logs:
docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -e GLOBAL_LOG_LEVEL=DEBUG -v open-webui:/app/backend/data ghcr.io/open-webui/open-webui:v0.6.13
  1. Configure the Ollama backend in Open WebUI
  2. Configure the mcp-time tool server in Open WebUI
  3. Open a new chat with the tool-calling model, configure Function Calling as "native" and perform a request which requires calling multiple tools (or the same tool multiple time) such as "What time is it in Paris and New-York?"

Logs & Screenshots

Example of invalid tool call using the Ollama backend:
Ollama backend multi-tool-calling bug example

Associated Open WebUI response log:

{ "model": "devstral:latest", "stream": true, "tools": [ { "type": "function", "function": { "type": "function", "name": "tool_get_current_time_post", "description": "Get current time in a specific timezones", "parameters": { "type": "object", "properties": { "timezone": { "type": "string", "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no timezone provided by the user." } }, "required": [ "timezone" ] } } }, { "type": "function", "function": { "type": "function", "name": "tool_convert_time_post", "description": "Convert time between timezones", "parameters": { "type": "object", "properties": { "source_timezone": { "type": "string", "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no source timezone provided by the user." }, "time": { "type": "string", "description": "Time to convert in 24-hour format (HH:MM)" }, "target_timezone": { "type": "string", "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'America/New_York' as local timezone if no target timezone provided by the user." } }, "required": [ "source_timezone", "time", "target_timezone" ] } } } ], "messages": [ { "role": "user", "content": "What time is it in Paris and New York?" }, { "role": "assistant", "content": "", "tool_calls": [ { "index": 0, "id": "call_9edcccec-beb6-4bb3-a135-b898f9f87f6a", "type": "function", "function": { "name": "tool_get_current_time_posttool_get_current_time_post", "arguments": "{\"timezone\": \"Europe/Paris\"}{\"timezone\": \"America/New_York\"}" } } ] }, { "role": "tool", "tool_call_id": "call_9edcccec-beb6-4bb3-a135-b898f9f87f6a", "content": null } ] }

Performing the request manually using curl:

$ curl -s http://localhost:11434/api/chat -d '{ "model": "devstral", "messages": [ { "role": "user", "content": "What time is it in Paris and New York" } ], "stream": false, "tools": [ { "type": "function", "function": { "name": "tool_get_current_time_post", "description": "Get current time in a specific timezones", "parameters": { "type": "object", "properties": { "timezone": { "type": "string", "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no timezone provided by the user." } }, "required": ["timezone"] } } }, { "type": "function", "function": { "name": "tool_convert_time_post", "description": "Convert time between timezones", "parameters": { "type": "object", "properties": { "source_timezone": { "type": "string", "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no source timezone provided by the user." }, "time": { "type": "string", "description": "Time to convert in 24-hour format (HH:MM)" }, "target_timezone": { "type": "string", "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'America/New_York' as local timezone if no target timezone provided by the user." } }, "required": ["source_timezone", "time", "target_timezone"] } } } ] }' | jq

{
"model": "devstral",
"created_at": "2025-06-01T15:55:15.518588Z",
"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"function": {
"name": "tool_get_current_time_post",
"arguments": {
"timezone": "Europe/Paris"
}
}
},
{
"function": {
"name": "tool_get_current_time_post",
"arguments": {
"timezone": "America/New_York"
}
}
}
]
},
"done_reason": "stop",
"done": true,
"total_duration": 6700734042,
"load_duration": 26193667,
"prompt_eval_count": 1491,
"prompt_eval_duration": 2590387959,
"eval_count": 45,
"eval_duration": 4075518458
}

Example of the same call with the same model running on an OpenAI-compatible backend (in this example, LM Studio):
OpenAI-compatible backend working multi-tool-calling example

Associated Open WebUI response log:

{ "model": "devstral", "stream": true, "tools": [ { "type": "function", "function": { "type": "function", "name": "tool_get_current_time_post", "description": "Get current time in a specific timezones", "parameters": { "type": "object", "properties": { "timezone": { "type": "string", "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no timezone provided by the user." } }, "required": [ "timezone" ] } } }, { "type": "function", "function": { "type": "function", "name": "tool_convert_time_post", "description": "Convert time between timezones", "parameters": { "type": "object", "properties": { "source_timezone": { "type": "string", "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no source timezone provided by the user." }, "time": { "type": "string", "description": "Time to convert in 24-hour format (HH:MM)" }, "target_timezone": { "type": "string", "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'America/New_York' as local timezone if no target timezone provided by the user." } }, "required": [ "source_timezone", "time", "target_timezone" ] } } } ], "messages": [ { "role": "user", "content": "What time is it in Paris and New-York?" }, { "role": "assistant", "content": "", "tool_calls": [ { "index": 0, "id": "550202006", "type": "function", "function": { "name": "tool_get_current_time_post", "arguments": "{\"timezone\": \"Europe/Paris\"}" } }, { "index": 1, "id": "782814921", "type": "function", "function": { "name": "tool_get_current_time_post", "arguments": "{\"timezone\": \"America/New_York\"}" } } ] }, { "role": "tool", "tool_call_id": "550202006", "content": "{\n \"timezone\": \"Europe/Paris\",\n \"datetime\": \"2025-06-01T18:04:59+02:00\",\n \"is_dst\": true\n}" }, { "role": "tool", "tool_call_id": "782814921", "content": "{\n \"timezone\": \"America/New_York\",\n \"datetime\": \"2025-06-01T12:04:59-04:00\",\n \"is_dst\": true\n}" } ] }

Additional Information

I believe this behavior stems from the following code snippet:

53764fe648/backend/open_webui/utils/middleware.py (L1811-L1821)

I added debug logs and compared output with both the Ollama and LM Studio backends.

Ollama:

open_webui.utils.middleware:stream_body_handler:1787 - current_response_tool_call is None - {} open_webui.utils.middleware:stream_body_handler:1788 - BEFORE delta_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1802 - AFTER delta_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1803 - response_tool_calls: [{'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}}] - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_posttool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}{"timezone": "America/New_York"}'}} - {}

LM Studio:

open_webui.utils.middleware:stream_body_handler:1787 - current_response_tool_call is None - {} open_webui.utils.middleware:stream_body_handler:1788 - BEFORE delta_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1802 - AFTER delta_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1803 - response_tool_calls: [{'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}}] - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1787 - current_response_tool_call is None - {} open_webui.utils.middleware:stream_body_handler:1788 - BEFORE delta_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1802 - AFTER delta_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1803 - response_tool_calls: [{'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}}, {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}}] - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_Y'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_Y'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York"}'}} - {}

However, I believe the bug itself is in this code instead:

53764fe648/backend/open_webui/utils/response.py (L9-L24)

From the manual curl request in pasted above, you can see that the Ollama tool_calls array does not contain an index parameter. As such, it always defaults to 0 in convert_ollama_tool_call_to_openai. Because there are multiple tools, they all end up sharing the same index, which is why they are later concatenated together by stream_body_handler.

I believe the fix would be to change the convert_ollama_tool_call_to_openai function so that it increments the default value for index and makes sure there are no collisions

Originally created by @JRomainG on GitHub (Jun 1, 2025). Original GitHub issue: https://github.com/open-webui/open-webui/issues/14583 ### Check Existing Issues - [x] I have searched the existing issues and discussions. - [x] I am using the latest version of Open WebUI. ### Installation Method Docker ### Open WebUI Version v0.6.13 ### Ollama Version (if applicable) 0.9.0 ### Operating System macOS Sequoia (15.5) ### Browser (if applicable) Firefox 139.0.1 ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior When the Ollama API returns multiple tools to run, Open WebUI calls each tool one by one, like for the OpenAI-compatible backends ### Actual Behavior The Open WebUI middleware concatenates all tool calls together when using the Ollama backend, resulting in a single invalid tool. In addition, because the tool does not exist, the Open WebUI frontend loads indefinitely without ever performing a request to the tool server (which might be related to #14577) ### Steps to Reproduce 1. Install the latest version of ollama 2. Download a model compatible with tool-calling (in this example, [`devstral:latest`](https://ollama.com/library/devstral:latest)) 3. Run the mcp-time server using mcpo: ```sh docker run -d -p 8000:8000 ghcr.io/open-webui/mcpo:main -- uvx mcp-server-time --local-timezone=America/New_York ``` 4. Run Open WebUI using docker with debug logs: ```sh docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -e GLOBAL_LOG_LEVEL=DEBUG -v open-webui:/app/backend/data ghcr.io/open-webui/open-webui:v0.6.13 ``` 5. Configure the Ollama backend in Open WebUI 6. Configure the mcp-time tool server in Open WebUI 7. Open a new chat with the tool-calling model, configure Function Calling as "native" and perform a request which requires calling multiple tools (or the same tool multiple time) such as "What time is it in Paris and New-York?" ### Logs & Screenshots Example of invalid tool call using the Ollama backend: <img width="1512" alt="Ollama backend multi-tool-calling bug example" src="https://github.com/user-attachments/assets/e5a712c3-46d0-4c74-ba1f-0a04293d9470" /> Associated Open WebUI response log: <details> { "model": "devstral:latest", "stream": true, "tools": [ { "type": "function", "function": { "type": "function", "name": "tool_get_current_time_post", "description": "Get current time in a specific timezones", "parameters": { "type": "object", "properties": { "timezone": { "type": "string", "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no timezone provided by the user." } }, "required": [ "timezone" ] } } }, { "type": "function", "function": { "type": "function", "name": "tool_convert_time_post", "description": "Convert time between timezones", "parameters": { "type": "object", "properties": { "source_timezone": { "type": "string", "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no source timezone provided by the user." }, "time": { "type": "string", "description": "Time to convert in 24-hour format (HH:MM)" }, "target_timezone": { "type": "string", "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'America/New_York' as local timezone if no target timezone provided by the user." } }, "required": [ "source_timezone", "time", "target_timezone" ] } } } ], "messages": [ { "role": "user", "content": "What time is it in Paris and New York?" }, { "role": "assistant", "content": "", "tool_calls": [ { "index": 0, "id": "call_9edcccec-beb6-4bb3-a135-b898f9f87f6a", "type": "function", "function": { "name": "tool_get_current_time_posttool_get_current_time_post", "arguments": "{\"timezone\": \"Europe/Paris\"}{\"timezone\": \"America/New_York\"}" } } ] }, { "role": "tool", "tool_call_id": "call_9edcccec-beb6-4bb3-a135-b898f9f87f6a", "content": null } ] } </details> Performing the request manually using `curl`: <details> $ curl -s http://localhost:11434/api/chat -d '{ "model": "devstral", "messages": [ { "role": "user", "content": "What time is it in Paris and New York" } ], "stream": false, "tools": [ { "type": "function", "function": { "name": "tool_get_current_time_post", "description": "Get current time in a specific timezones", "parameters": { "type": "object", "properties": { "timezone": { "type": "string", "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no timezone provided by the user." } }, "required": ["timezone"] } } }, { "type": "function", "function": { "name": "tool_convert_time_post", "description": "Convert time between timezones", "parameters": { "type": "object", "properties": { "source_timezone": { "type": "string", "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no source timezone provided by the user." }, "time": { "type": "string", "description": "Time to convert in 24-hour format (HH:MM)" }, "target_timezone": { "type": "string", "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'America/New_York' as local timezone if no target timezone provided by the user." } }, "required": ["source_timezone", "time", "target_timezone"] } } } ] }' | jq { "model": "devstral", "created_at": "2025-06-01T15:55:15.518588Z", "message": { "role": "assistant", "content": "", "tool_calls": [ { "function": { "name": "tool_get_current_time_post", "arguments": { "timezone": "Europe/Paris" } } }, { "function": { "name": "tool_get_current_time_post", "arguments": { "timezone": "America/New_York" } } } ] }, "done_reason": "stop", "done": true, "total_duration": 6700734042, "load_duration": 26193667, "prompt_eval_count": 1491, "prompt_eval_duration": 2590387959, "eval_count": 45, "eval_duration": 4075518458 } </details> Example of the same call with the same model running on an OpenAI-compatible backend (in this example, LM Studio): <img width="1512" alt="OpenAI-compatible backend working multi-tool-calling example" src="https://github.com/user-attachments/assets/6f9d7477-0d0c-440c-9d5e-22a49ef24d01" /> Associated Open WebUI response log: <details> { "model": "devstral", "stream": true, "tools": [ { "type": "function", "function": { "type": "function", "name": "tool_get_current_time_post", "description": "Get current time in a specific timezones", "parameters": { "type": "object", "properties": { "timezone": { "type": "string", "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no timezone provided by the user." } }, "required": [ "timezone" ] } } }, { "type": "function", "function": { "type": "function", "name": "tool_convert_time_post", "description": "Convert time between timezones", "parameters": { "type": "object", "properties": { "source_timezone": { "type": "string", "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no source timezone provided by the user." }, "time": { "type": "string", "description": "Time to convert in 24-hour format (HH:MM)" }, "target_timezone": { "type": "string", "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'America/New_York' as local timezone if no target timezone provided by the user." } }, "required": [ "source_timezone", "time", "target_timezone" ] } } } ], "messages": [ { "role": "user", "content": "What time is it in Paris and New-York?" }, { "role": "assistant", "content": "", "tool_calls": [ { "index": 0, "id": "550202006", "type": "function", "function": { "name": "tool_get_current_time_post", "arguments": "{\"timezone\": \"Europe/Paris\"}" } }, { "index": 1, "id": "782814921", "type": "function", "function": { "name": "tool_get_current_time_post", "arguments": "{\"timezone\": \"America/New_York\"}" } } ] }, { "role": "tool", "tool_call_id": "550202006", "content": "{\n \"timezone\": \"Europe/Paris\",\n \"datetime\": \"2025-06-01T18:04:59+02:00\",\n \"is_dst\": true\n}" }, { "role": "tool", "tool_call_id": "782814921", "content": "{\n \"timezone\": \"America/New_York\",\n \"datetime\": \"2025-06-01T12:04:59-04:00\",\n \"is_dst\": true\n}" } ] } </details> ### Additional Information I believe this behavior stems from the following code snippet: https://github.com/open-webui/open-webui/blob/53764fe64884da147359e54ed6d9607fe57f1600/backend/open_webui/utils/middleware.py#L1811-L1821 I added debug logs and compared output with both the Ollama and LM Studio backends. Ollama: <details> open_webui.utils.middleware:stream_body_handler:1787 - current_response_tool_call is None - {} open_webui.utils.middleware:stream_body_handler:1788 - BEFORE delta_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1802 - AFTER delta_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1803 - response_tool_calls: [{'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}}] - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': 'call_38a3474f-8838-4b9f-a22a-a506c9678c52', 'type': 'function', 'function': {'name': 'tool_get_current_time_posttool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}{"timezone": "America/New_York"}'}} - {} </details> LM Studio: <details> open_webui.utils.middleware:stream_body_handler:1787 - current_response_tool_call is None - {} open_webui.utils.middleware:stream_body_handler:1788 - BEFORE delta_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1802 - AFTER delta_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1803 - response_tool_calls: [{'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}}] - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}} - {} open_webui.utils.middleware:stream_body_handler:1787 - current_response_tool_call is None - {} open_webui.utils.middleware:stream_body_handler:1788 - BEFORE delta_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1802 - AFTER delta_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1803 - response_tool_calls: [{'index': 0, 'id': '918251941', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "Europe/Paris"}'}}, {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}}] - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': ''}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"time'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone":'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_Y'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_Y'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York"'}} - {} open_webui.utils.middleware:stream_body_handler:1805 - current_response_tool_call is not None, updating tool call - {} open_webui.utils.middleware:stream_body_handler:1806 - BEFORE current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York"'}} - {} open_webui.utils.middleware:stream_body_handler:1828 - AFTER current_response_tool_call: {'index': 1, 'id': '664445966', 'type': 'function', 'function': {'name': 'tool_get_current_time_post', 'arguments': '{"timezone": "America/New_York"}'}} - {} </details> However, I believe the bug itself is in this code instead: https://github.com/open-webui/open-webui/blob/53764fe64884da147359e54ed6d9607fe57f1600/backend/open_webui/utils/response.py#L9-L24 From the manual `curl` request in pasted above, you can see that the Ollama `tool_calls` array does not contain an `index` parameter. As such, it always defaults to 0 in `convert_ollama_tool_call_to_openai`. Because there are multiple tools, they all end up sharing the same index, which is why they are later concatenated together by `stream_body_handler`. I believe the fix would be to change the `convert_ollama_tool_call_to_openai` function so that it increments the default value for `index` and makes sure there are no collisions
GiteaMirror added the bug label 2026-05-05 18:24:44 -05:00
Author
Owner

@taylorwilsdon commented on GitHub (Jun 1, 2025):

Works fine for me. You're probably using the default 2048 max num_ctx length and its running out of tokens while deciding whether to use the tool, causing failure. Try increasing it to 10-15k tokens minimum. I can reproduce if I set it to 2048 and it works fine at 12k.

This doesn't happen with LM Studio because you're using it as a generic OpenAI API compatible endpoint and it's not passing Open WebUI's default num_ctx to the backend, and thus respecting whatever the configured baseline max context settings is for the model running. With Ollama, you are overriding whatever is set at the model level (in ollama show)

Image
<!-- gh-comment-id:2927919190 --> @taylorwilsdon commented on GitHub (Jun 1, 2025): Works fine for me. You're probably using the default 2048 max num_ctx length and its running out of tokens while deciding whether to use the tool, causing failure. Try increasing it to 10-15k tokens minimum. I can reproduce if I set it to 2048 and it works fine at 12k. This doesn't happen with LM Studio because you're using it as a generic OpenAI API compatible endpoint and it's not passing Open WebUI's default num_ctx to the backend, and thus respecting whatever the configured baseline max context settings is for the model running. With Ollama, you are overriding whatever is set at the model level (in `ollama show`) <img width="1027" alt="Image" src="https://github.com/user-attachments/assets/1eaa0f08-f9b0-4a68-ab01-a9f541618c8c" />
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#55971