server, webui: accept continue_final_message flag for vLLM API compat (#23012)

* server, webui: accept continue_final_message flag for vLLM API compat

Add the continue_final_message body flag from the vLLM and transformers
API. When set together with add_generation_prompt false, it triggers the
existing prefill_assistant code path, regardless of the server side
opt.prefill_assistant option. Mutual exclusion with add_generation_prompt
true is enforced, matching vLLM behavior.

WebUI sends continue_final_message and add_generation_prompt false on
the Continue button, with the matching opt in option on the chat service.

Pure API alignment, no change to the prefill logic itself. Paves the way
for the upcoming per-template prefill plumbing in common/chat.

* test: add coverage for continue_final_message vLLM compat flag

Two cases on top of the existing assistant prefill coverage. First,
continue_final_message true with add_generation_prompt false produces
the same rendered prompt as the prefill_assistant heuristic, proving
the new flag is a correct alias of the existing path. Second, both
flags set to true is rejected with HTTP 400, matching the
vLLM/transformers mutual exclusion contract.

* chore: update webui build output
This commit is contained in:
Pascal
2026-05-13 20:47:58 +02:00
committed by GitHub
parent 1e4579fbb8
commit 95d469a915
7 changed files with 176 additions and 118 deletions
@@ -130,7 +130,8 @@ export class ChatService {
timings_per_token,
// Config options
disableReasoningParsing,
excludeReasoningFromContext
excludeReasoningFromContext,
continueFinalMessage
} = options;
const normalizedMessages: ApiChatMessageData[] = messages
@@ -209,6 +210,11 @@ export class ChatService {
? ReasoningFormat.NONE
: ReasoningFormat.AUTO;
if (continueFinalMessage) {
requestBody.continue_final_message = true;
requestBody.add_generation_prompt = false;
}
if (temperature !== undefined) requestBody.temperature = temperature;
if (max_tokens !== undefined) {
// Set max_tokens to -1 (infinite) when explicitly configured as 0 or null
@@ -1301,6 +1301,7 @@ class ChatStore {
contextWithContinue,
{
...this.getApiOptions(),
continueFinalMessage: true,
onChunk: (chunk: string) => {
appendedContent += chunk;
hasReceivedContent = true;
+3
View File
@@ -239,6 +239,9 @@ export interface ApiChatCompletionRequest {
// Custom parameters (JSON string)
custom?: Record<string, unknown>;
timings_per_token?: boolean;
// Continuation control (vLLM compat)
add_generation_prompt?: boolean;
continue_final_message?: boolean;
}
export interface ApiChatCompletionToolCallFunctionDelta {
+2
View File
@@ -92,6 +92,8 @@ export interface SettingsChatServiceOptions {
// Custom parameters
custom?: string;
timings_per_token?: boolean;
// Continuation control (vLLM compat), opt in to the explicit continue final message flag
continueFinalMessage?: boolean;
// Callbacks
onChunk?: (chunk: string) => void;
onReasoningChunk?: (chunk: string) => void;