From 2f926354095d308d4daf4c25e7b074d962c1513a Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Tue, 22 Sep 2026 22:47:20 +0200 Subject: [PATCH] fix: keep the model system prompt on Ollama tool-call follow-ups (#30375) With native function calling on an Ollama model, every request sent after a tool result was missing the model's system prompt, so the final answer ignored the model's instructions. Only other system content, such as the attached knowledge tag, was left. OpenAI connections were not affected. Tool-call follow-ups are rebuilt from the chat's message list and skip the router's system prompt step, because the first request is expected to have already added it to that list. The OpenAI path does add it there, but the Ollama path converts the messages into a copy first and adds the prompt only to the copy, so the follow-ups never see it. The model system prompt is now applied to the messages before the Ollama conversion, and the Ollama router is told to skip it for that request so it is not added twice. Ollama now behaves the same as the OpenAI path. Direct calls to /ollama/api/chat still get the prompt from the router as before. Checked baseline against patched: first request and follow-up for plain, custom and arena Ollama models, with and without a chat system prompt, with template variables and on the OpenAI path. The prompt is now present exactly once on every Ollama follow-up, and nothing else changed. Fixes #30161 --- backend/open_webui/utils/chat.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/chat.py b/backend/open_webui/utils/chat.py index 5d5f6f60c4..c97985dde4 100644 --- a/backend/open_webui/utils/chat.py +++ b/backend/open_webui/utils/chat.py @@ -33,7 +33,7 @@ from open_webui.utils.filter import ( ) from open_webui.utils.json_codec import JSONCodec from open_webui.utils.models import check_model_access, get_all_models -from open_webui.utils.payload import convert_payload_openai_to_ollama +from open_webui.utils.payload import apply_system_prompt_to_body, convert_payload_openai_to_ollama from open_webui.utils.response import ( convert_response_ollama_to_openai, convert_streaming_response_ollama_to_openai, @@ -281,6 +281,14 @@ async def generate_chat_completion( # Below does not require bypass_filter because this is the only route the uses this function and it is already bypassing the filter return await generate_function_chat_completion(request, form_data, user=user, models=models) if model.get('owned_by') == 'ollama': + # Apply before Ollama conversion so tool follow-ups keep the model system prompt + if not bypass_system_prompt: + model_info = await Models.get_model_by_id(form_data['model']) + if model_info: + system = model_info.params.model_dump().get('system') + form_data = await apply_system_prompt_to_body(system, form_data, metadata, user) + request.state.bypass_system_prompt = True + # Using /ollama/api/chat endpoint form_data = convert_payload_openai_to_ollama(form_data) response = await generate_ollama_chat_completion(