From 4468a23b2defb07dae567fbbf6aa9a8d69191a70 Mon Sep 17 00:00:00 2001 From: Nam Thanh Nguyen Macbook Date: Wed, 5 Aug 2026 22:28:55 +0700 Subject: [PATCH] fix: retry without tools when OpenAI-compatible server returns empty response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some OpenAI-compatible servers (NIM, vLLM, TGI) return content: null with an empty tool_calls array when tools are provided in the request but the model decides not to call any tool. This results in blank responses in the Continue GUI. Fix: detect empty response (content: null + tool_calls: []) and retry the same request without the tools parameter. The model then responds with text content normally. Affected models: - nvidia/nemotron-ultra-253b (NIM) — frequently - deepseek-ai/DeepSeek-V4-Flash (vLLM) — occasionally - Any OpenAI-compatible server with tool support Related: https://github.com/continuedev/continue/issues/5508 --- packages/openai-adapters/src/apis/OpenAI.ts | 24 ++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/openai-adapters/src/apis/OpenAI.ts b/packages/openai-adapters/src/apis/OpenAI.ts index d0f8d30ca3a..97e67de8a35 100644 --- a/packages/openai-adapters/src/apis/OpenAI.ts +++ b/packages/openai-adapters/src/apis/OpenAI.ts @@ -134,12 +134,34 @@ export class OpenAIApi implements BaseLlmApi { const response = await this.responsesNonStream(body, signal); return responseToChatCompletion(response); } - const response = await this.openai.chat.completions.create( + let response = await this.openai.chat.completions.create( this.modifyChatBody(body), { signal, }, ); + + // Some OpenAI-compatible servers (e.g. NIM, vLLM) return content: null + // with an empty tool_calls array when tools are provided but the model + // decides not to call any. This is effectively an empty response that + // the GUI renders as blank. Retry without tools so the model responds + // with text content instead. + const msg = response.choices?.[0]?.message; + if ( + msg && + !msg.content && + (!msg.tool_calls || msg.tool_calls.length === 0) && + body.tools?.length + ) { + const { tools, tool_choice, ...bodyWithoutTools } = body; + response = await this.openai.chat.completions.create( + this.modifyChatBody( + bodyWithoutTools as ChatCompletionCreateParamsNonStreaming, + ), + { signal }, + ); + } + return response; }