From 1729ed5371cd1ac6f6d6f3226f8803b080042839 Mon Sep 17 00:00:00 2001 From: Kyozzz <1147385157@qq.com> Date: Tue, 25 Aug 2026 22:35:22 +0800 Subject: [PATCH] server : reject prefilled assistant messages with tool calls (#27626) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * server: fix tool calls getting silently stripped with --prefill-assistant Last assistant carries tool_calls + --prefill-assistant is on → request flips into continuation mode, add_generation_prompt forced off, tail rebuilt from reasoning_content + content only. Tool calls just vanish. - Auto-continuation now skips trailing assistant msgs that have tool calls - continue_final_message on those throws a clear error instead of silently corrupting the prompt - Regression tests included, red before / green after Fixes #27588 Developed with AI assistance, disclosed per the contribution policy. * server : address review: fail on prefill-assistant + trailing tool_calls Move validation into oaicompat_chat_params_parse (next to the existing two-or-more-assistant check) and remove it from common_chat_templates_apply, which has no precedent for validation. Drop the regression tests. Per review: --prefill-assistant with a trailing assistant message containing tool calls is not supported and should fail loudly. --- tools/server/server-common.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/server/server-common.cpp b/tools/server/server-common.cpp index 4f5b8202a..7997d4016 100644 --- a/tools/server/server-common.cpp +++ b/tools/server/server-common.cpp @@ -1280,6 +1280,12 @@ json oaicompat_chat_params_parse( if (inputs.continue_final_message != COMMON_CHAT_CONTINUATION_NONE && inputs.add_generation_prompt) { throw std::invalid_argument("Cannot set both add_generation_prompt and continue_final_message to true."); } + if (inputs.continue_final_message != COMMON_CHAT_CONTINUATION_NONE + && !inputs.messages.empty() + && inputs.messages.back().role == "assistant" + && !inputs.messages.back().tool_calls.empty()) { + throw std::invalid_argument("Cannot continue an assistant message that contains tool calls."); + } inputs.reasoning_format = opt.reasoning_format; if (body.contains("reasoning_format")) { inputs.reasoning_format = common_reasoning_format_from_name(body.at("reasoning_format").get());