From 4f24ec0f0922e5e291f821e7f1b2c470a7646f32 Mon Sep 17 00:00:00 2001 From: Yash Raj Pandey Date: Thu, 16 Jul 2026 12:40:36 -0400 Subject: [PATCH] fix(openai-adapters): allow disabling stream_options for strict OpenAI-compatible endpoints --- packages/config-yaml/src/schemas/models.ts | 1 + packages/openai-adapters/src/apis/OpenAI.ts | 2 +- .../src/test/openai-adapter.vitest.ts | 28 ++++++++++++++++++- packages/openai-adapters/src/types.ts | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/config-yaml/src/schemas/models.ts b/packages/config-yaml/src/schemas/models.ts index 7c048e8d548..f3576bfec48 100644 --- a/packages/config-yaml/src/schemas/models.ts +++ b/packages/config-yaml/src/schemas/models.ts @@ -192,6 +192,7 @@ const baseModelFields = { promptTemplates: promptTemplatesSchema.optional(), useLegacyCompletionsEndpoint: z.boolean().optional(), useResponsesApi: z.boolean().optional(), + streamOptions: z.boolean().optional(), env: z .record(z.string(), z.union([z.string(), z.boolean(), z.number()])) .optional(), diff --git a/packages/openai-adapters/src/apis/OpenAI.ts b/packages/openai-adapters/src/apis/OpenAI.ts index d0f8d30ca3a..d30e4c4d963 100644 --- a/packages/openai-adapters/src/apis/OpenAI.ts +++ b/packages/openai-adapters/src/apis/OpenAI.ts @@ -50,7 +50,7 @@ export class OpenAIApi implements BaseLlmApi { } modifyChatBody(body: T): T { // Add stream_options to include usage in streaming responses - if (body.stream) { + if (body.stream && this.config.streamOptions !== false) { (body as any).stream_options = { include_usage: true }; } diff --git a/packages/openai-adapters/src/test/openai-adapter.vitest.ts b/packages/openai-adapters/src/test/openai-adapter.vitest.ts index 6abc49a3af4..43bc3a2fabc 100644 --- a/packages/openai-adapters/src/test/openai-adapter.vitest.ts +++ b/packages/openai-adapters/src/test/openai-adapter.vitest.ts @@ -1,4 +1,5 @@ -import { describe, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; +import { OpenAIApi } from "../apis/OpenAI.js"; import { createAdapterTests } from "./adapter-test-utils.js"; // Mock the fetch package (not needed for OpenAI but required by the shared test utils) @@ -25,4 +26,29 @@ describe("OpenAI Adapter Tests", () => { accept: "application/json", }, }); + + it("includes streaming usage by default unless stream options are disabled", () => { + const body = { + model: "gpt-4", + messages: [{ role: "user" as const, content: "hello" }], + stream: true as const, + }; + const defaultApi = new OpenAIApi({ + provider: "openai", + apiKey: "test-api-key", + }); + const disabledApi = new OpenAIApi({ + provider: "openai", + apiKey: "test-api-key", + streamOptions: false, + }); + + expect(defaultApi.modifyChatBody({ ...body })).toHaveProperty( + "stream_options.include_usage", + true, + ); + expect(disabledApi.modifyChatBody({ ...body })).not.toHaveProperty( + "stream_options", + ); + }); }); diff --git a/packages/openai-adapters/src/types.ts b/packages/openai-adapters/src/types.ts index 14b9512f75b..4b32638e6b9 100644 --- a/packages/openai-adapters/src/types.ts +++ b/packages/openai-adapters/src/types.ts @@ -31,6 +31,7 @@ export const BasePlusConfig = BaseConfig.extend({ // OpenAI and compatible export const OpenAIConfigSchema = BasePlusConfig.extend({ useResponsesApi: z.boolean().optional(), + streamOptions: z.boolean().optional(), provider: z.union([ z.literal("openai"), z.literal("mistral"),