From 28225c8d9e69dc4c4ddea1d9775b88da6286243b Mon Sep 17 00:00:00 2001 From: Raghav Kattel Date: Tue, 2 Jun 2026 01:30:27 +0545 Subject: [PATCH] fix: forward extraBodyProperties from requestOptions in autocomplete requests (#12334) The extraBodyProperties() method in OpenAI.ts returned {} by default, causing user-configured requestOptions.extraBodyProperties to be omitted from request bodies constructed at the class level. While the fetch layer (fetchwithRequestOptions) also merges these properties, the adapter and non-adapter paths have inconsistent coverage. This commit changes extraBodyProperties() to return this.requestOptions?.extraBodyProperties ?? {} instead of {}. This fixes autocomplete requests (which go through streamComplete -> _streamChat -> _legacystreamComplete) not sending extra body properties configured via requestOptions.extraBodyProperties, while also ensuring all request types (chat, completions, FIM, embeddings) consistently include them. Also fixes ContinueProxy to propagate super.extraBodyProperties(). Fixes #12334 --- core/llm/llms/OpenAI.ts | 2 +- core/llm/llms/OpenAI.vitest.ts | 95 ++++++++++++++++++++++++++++ core/llm/llms/stubs/ContinueProxy.ts | 1 + 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/core/llm/llms/OpenAI.ts b/core/llm/llms/OpenAI.ts index c65b55dc1a5..fba66c8b054 100644 --- a/core/llm/llms/OpenAI.ts +++ b/core/llm/llms/OpenAI.ts @@ -249,7 +249,7 @@ class OpenAI extends BaseLLM { } protected extraBodyProperties(): Record { - return {}; + return this.requestOptions?.extraBodyProperties ?? {}; } protected getMaxStopWords(): number { diff --git a/core/llm/llms/OpenAI.vitest.ts b/core/llm/llms/OpenAI.vitest.ts index b07f05b15d8..28f4dc245bc 100644 --- a/core/llm/llms/OpenAI.vitest.ts +++ b/core/llm/llms/OpenAI.vitest.ts @@ -395,6 +395,101 @@ describe("OpenAI", () => { }); }); + test("should include extraBodyProperties from requestOptions in request", async () => { + const openai = new OpenAI({ + apiKey: "test-api-key", + model: "gpt-4", + apiBase: "https://api.openai.com/v1/", + requestOptions: { + extraBodyProperties: { + reasoning: { exclude: true }, + custom_field: "test_value", + }, + }, + completionOptions: { + model: "gpt-4", + maxTokens: 100, + }, + }); + + await runLlmTest({ + llm: openai, + methodToTest: "streamChat", + params: [ + [{ role: "user", content: "hello" }], + new AbortController().signal, + ], + expectedRequest: { + url: "https://api.openai.com/v1/chat/completions", + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: "Bearer test-api-key", + "api-key": "test-api-key", + }, + body: { + model: "gpt-4", + messages: [{ role: "user", content: "hello" }], + stream: true, + max_tokens: 100, + reasoning: { exclude: true }, + custom_field: "test_value", + }, + }, + mockStream: [{ choices: [{ delta: { content: "Hello" } }] }], + }); + }); + + test("should include extraBodyProperties in legacy completions endpoint", async () => { + // Legacy completions endpoint is used by autocomplete when the model + // is NOT a chat-only model (e.g., OpenRouter with DeepSeek, etc.) + const openai = new OpenAI({ + apiKey: "test-api-key", + model: "text-davinci-002", + apiBase: "https://api.openai.com/v1/", + requestOptions: { + extraBodyProperties: { + reasoning: { exclude: true }, + }, + }, + completionOptions: { + model: "text-davinci-002", + maxTokens: 100, + }, + }); + + await runLlmTest({ + llm: openai, + methodToTest: "streamChat", + params: [ + [{ role: "user", content: "hello" }], + new AbortController().signal, + ], + expectedRequest: { + url: "https://api.openai.com/v1/completions", + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: "Bearer test-api-key", + "api-key": "test-api-key", + }, + body: { + model: "text-davinci-002", + prompt: "hello", + stream: true, + max_tokens: 100, + reasoning: { exclude: true }, + }, + }, + mockStream: [ + { + choices: [{ text: "Hello", finish_reason: "stop" }], + model: "text-davinci-002", + }, + ], + }); + }); + test("should handle embeddings", async () => { const openai = new OpenAI({ apiKey: "test-api-key", diff --git a/core/llm/llms/stubs/ContinueProxy.ts b/core/llm/llms/stubs/ContinueProxy.ts index 52d7a6b807e..f343f6a9831 100644 --- a/core/llm/llms/stubs/ContinueProxy.ts +++ b/core/llm/llms/stubs/ContinueProxy.ts @@ -71,6 +71,7 @@ class ContinueProxy extends OpenAI { }; return { continueProperties, + ...super.extraBodyProperties(), }; }