From f2dbafbec88659b335971b2b3a83cfda4f5e248e Mon Sep 17 00:00:00 2001 From: "ScrewTSW (public-projects)" Date: Thu, 21 May 2026 04:21:23 +0200 Subject: [PATCH 1/2] fix: convert requestOptions.timeout from seconds to milliseconds for OpenAI SDK The OpenAI JS SDK expects timeout in milliseconds, but users configure requestOptions.timeout in seconds. Passing the value directly results in sub-second timeouts (e.g. timeout: 300 becomes 300ms instead of 5 minutes), causing "Connection error" for any model that takes more than a fraction of a second to respond. Fixes #12450 --- packages/openai-adapters/src/apis/OpenAI.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/openai-adapters/src/apis/OpenAI.ts b/packages/openai-adapters/src/apis/OpenAI.ts index d0f8d30ca3a..f220cc8a54b 100644 --- a/packages/openai-adapters/src/apis/OpenAI.ts +++ b/packages/openai-adapters/src/apis/OpenAI.ts @@ -45,7 +45,9 @@ export class OpenAIApi implements BaseLlmApi { apiKey: config.apiKey ?? "", baseURL: this.apiBase, fetch: customFetch(config.requestOptions), - timeout: config?.requestOptions?.timeout || undefined, + timeout: config?.requestOptions?.timeout + ? config.requestOptions.timeout * 1000 + : undefined, }); } modifyChatBody(body: T): T { From 8e0182f8de66ca4a12ca466655381e4ee53194cd Mon Sep 17 00:00:00 2001 From: "ScrewTSW (public-projects)" Date: Wed, 19 Aug 2026 13:46:45 +0200 Subject: [PATCH 2/2] fix: preserve an explicit `timeout: 0` for the OpenAI SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses review feedback from CodeRabbit and Copilot on #8. The truthiness check treated a configured `timeout: 0` as unset and passed `undefined`, so the SDK applied its 10-minute default instead. `timeout` is `z.number().optional()` with no positivity constraint, so 0 is schema-valid and reaches this code. Use a nullish check, matching how both sides already treat 0 as a real value: the SDK resolves its default with `options.timeout ?? DEFAULT_TIMEOUT`, and our own getAgentOptions uses `?? TIMEOUT`. Adds OpenAI.test.ts covering the seconds→ms conversion, the zero case, and the unset case. Verified the zero test fails against the previous code (expected 0, got 600000) rather than merely passing after the fix. Co-Authored-By: Claude Opus 5 --- .../openai-adapters/src/apis/OpenAI.test.ts | 38 +++++++++++++++++++ packages/openai-adapters/src/apis/OpenAI.ts | 11 ++++-- 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 packages/openai-adapters/src/apis/OpenAI.test.ts diff --git a/packages/openai-adapters/src/apis/OpenAI.test.ts b/packages/openai-adapters/src/apis/OpenAI.test.ts new file mode 100644 index 00000000000..70fd3fa7081 --- /dev/null +++ b/packages/openai-adapters/src/apis/OpenAI.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from "vitest"; + +import { OpenAIApi } from "./OpenAI.js"; + +describe("OpenAIApi timeout conversion", () => { + const baseConfig = { + provider: "openai" as const, + apiKey: "test-key", + }; + + it("converts requestOptions.timeout from seconds to milliseconds", () => { + const api = new OpenAIApi({ + ...baseConfig, + requestOptions: { timeout: 300 }, + }); + + expect(api.openai.timeout).toBe(300_000); + }); + + it("preserves an explicit zero timeout instead of falling back to the SDK default", () => { + const api = new OpenAIApi({ + ...baseConfig, + requestOptions: { timeout: 0 }, + }); + + // The schema permits `timeout: 0`, and the SDK resolves its own default + // with `?? DEFAULT_TIMEOUT`, so 0 must survive as 0 rather than becoming + // undefined and silently turning into the 10-minute default. + expect(api.openai.timeout).toBe(0); + }); + + it("leaves the SDK default in place when no timeout is configured", () => { + const api = new OpenAIApi(baseConfig); + + // 10 minutes — the OpenAI SDK's DEFAULT_TIMEOUT. + expect(api.openai.timeout).toBe(600_000); + }); +}); diff --git a/packages/openai-adapters/src/apis/OpenAI.ts b/packages/openai-adapters/src/apis/OpenAI.ts index f220cc8a54b..3f750110c3d 100644 --- a/packages/openai-adapters/src/apis/OpenAI.ts +++ b/packages/openai-adapters/src/apis/OpenAI.ts @@ -45,9 +45,14 @@ export class OpenAIApi implements BaseLlmApi { apiKey: config.apiKey ?? "", baseURL: this.apiBase, fetch: customFetch(config.requestOptions), - timeout: config?.requestOptions?.timeout - ? config.requestOptions.timeout * 1000 - : undefined, + // requestOptions.timeout is in seconds; the OpenAI SDK expects ms. + // Nullish rather than truthy: the schema permits `timeout: 0`, and both + // the SDK (`options.timeout ?? DEFAULT_TIMEOUT`) and our own + // getAgentOptions treat 0 as a real value, not as "unset". + timeout: + config?.requestOptions?.timeout != null + ? config.requestOptions.timeout * 1000 + : undefined, }); } modifyChatBody(body: T): T {