From ec863041f90984667a2b99cd62036ea704170cea Mon Sep 17 00:00:00 2001 From: Antigravity Assistant Date: Thu, 30 Apr 2026 22:53:49 -0300 Subject: [PATCH] fix: disableStreamOptions toggle for OpenAI compatible providers (#1836) --- open-sse/executors/default.ts | 30 ++++++++++++++---------- src/shared/validation/schemas.ts | 9 +++++++ tests/unit/executor-default-base.test.ts | 16 +++++++++++++ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/open-sse/executors/default.ts b/open-sse/executors/default.ts index 2f568f7630..bbd814b8bc 100644 --- a/open-sse/executors/default.ts +++ b/open-sse/executors/default.ts @@ -48,15 +48,15 @@ function normalizeDataRobotChatUrl(baseUrl) { return buildDataRobotChatUrl(baseUrl); } -function normalizeAzureAiChatUrl(baseUrl, apiType = "chat") { +function normalizeAzureAiChatUrl(baseUrl: string, apiType: "chat" | "responses" = "chat") { return buildAzureAiChatUrl(baseUrl, apiType); } -function normalizeWatsonxChatUrl(baseUrl) { +function normalizeWatsonxChatUrl(baseUrl: string) { return buildWatsonxChatUrl(baseUrl); } -function normalizeOciChatUrl(baseUrl, apiType = "chat") { +function normalizeOciChatUrl(baseUrl: string, apiType: "chat" | "responses" = "chat") { return buildOciChatUrl(baseUrl, apiType); } @@ -353,7 +353,7 @@ export class DefaultExecutor extends BaseExecutor { if (typeof withDefaults === "object" && withDefaults !== null && !Array.isArray(withDefaults)) { if (this.provider?.startsWith?.("anthropic-compatible-")) { if (Object.prototype.hasOwnProperty.call(withDefaults, "stream_options")) { - const withoutStreamOptions = { ...withDefaults }; + const withoutStreamOptions = { ...withDefaults } as Record; delete withoutStreamOptions.stream_options; withDefaults = withoutStreamOptions; } @@ -361,18 +361,24 @@ export class DefaultExecutor extends BaseExecutor { stream && getTargetFormat(this.provider, credentials?.providerSpecificData) === "openai" ) { - withDefaults = { - ...withDefaults, - stream_options: { - ...(withDefaults.stream_options || {}), - include_usage: true, - }, - }; + if (!credentials?.providerSpecificData?.disableStreamOptions) { + withDefaults = { + ...withDefaults, + stream_options: { + ...((withDefaults as any).stream_options || {}), + include_usage: true, + }, + }; + } else if (Object.prototype.hasOwnProperty.call(withDefaults, "stream_options")) { + const withoutStreamOptions = { ...withDefaults } as Record; + delete withoutStreamOptions.stream_options; + withDefaults = withoutStreamOptions; + } } } if (this.provider === "qwen" && typeof withDefaults === "object" && withDefaults !== null) { - return sanitizeQwenThinkingToolChoice(withDefaults, "QwenExecutor"); + return sanitizeQwenThinkingToolChoice(withDefaults as any, "QwenExecutor"); } return withDefaults; } diff --git a/src/shared/validation/schemas.ts b/src/shared/validation/schemas.ts index 091719d4c3..9b6dbfdbe6 100644 --- a/src/shared/validation/schemas.ts +++ b/src/shared/validation/schemas.ts @@ -81,6 +81,15 @@ function validateProviderSpecificData( }); } + const disableStreamOptions = data.disableStreamOptions; + if (disableStreamOptions !== undefined && typeof disableStreamOptions !== "boolean") { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "providerSpecificData.disableStreamOptions must be a boolean", + path: ["disableStreamOptions"], + }); + } + const requestDefaults = data.requestDefaults; if (requestDefaults !== undefined) { if (!requestDefaults || typeof requestDefaults !== "object" || Array.isArray(requestDefaults)) { diff --git a/tests/unit/executor-default-base.test.ts b/tests/unit/executor-default-base.test.ts index e856528f7f..b78e86c737 100644 --- a/tests/unit/executor-default-base.test.ts +++ b/tests/unit/executor-default-base.test.ts @@ -611,6 +611,22 @@ test("DefaultExecutor.transformRequest only injects stream usage for OpenAI chat assert.equal((responsesResult as any).stream_options, undefined); }); +test("DefaultExecutor.transformRequest respects disableStreamOptions for OpenAI chat targets", () => { + const openAICompat = new DefaultExecutor("openai-compatible-test"); + const chatBody = { model: "gpt-4.1", messages: [{ role: "user", content: "hi" }] }; + + const chatResultDisabled = openAICompat.transformRequest("gpt-4.1", chatBody, true, { + providerSpecificData: { baseUrl: "https://proxy.example/v1", disableStreamOptions: true }, + }); + + const chatResultEnabled = openAICompat.transformRequest("gpt-4.1", chatBody, true, { + providerSpecificData: { baseUrl: "https://proxy.example/v1", disableStreamOptions: false }, + }); + + assert.equal((chatResultDisabled as any).stream_options, undefined); + assert.deepEqual((chatResultEnabled as any).stream_options, { include_usage: true }); +}); + test("DefaultExecutor.transformRequest strips stream_options from Anthropic-compatible targets", () => { const anthropicCompat = new DefaultExecutor("anthropic-compatible-test"); const anthropicCcCompat = new DefaultExecutor("anthropic-compatible-cc-test");