From d23577535349200b169e901e4fc9817f32191562 Mon Sep 17 00:00:00 2001 From: Yum-wu <118118663+Yum-wu@users.noreply.github.com> Date: Thu, 17 Sep 2026 18:57:53 +0800 Subject: [PATCH 1/3] fix(retry): extend transient-5xx replay to openai-responses --- src/providers/key-failover.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/key-failover.ts b/src/providers/key-failover.ts index d5ccd759e3..575b8e4b0e 100644 --- a/src/providers/key-failover.ts +++ b/src/providers/key-failover.ts @@ -306,7 +306,7 @@ export function rateLimitRetryPolicyFor( * explicitly disabled, not key-auth, or not the `openai-chat` adapter. * * The adapter gate is part of the accepted scope, not incidental: this first version covers - * key-auth `openai-chat` only, and without an explicit check any generic key-auth adapter + * key-auth `openai-chat` and `openai-responses` passthrough providers, and without an explicit check any generic key-auth adapter * could opt in. Auth mode follows the same fail-closed rule as `rateLimitRetryPolicyFor` — * explicit `key` or the documented omitted default, never OAuth, forward, local, or an * unknown value. @@ -316,7 +316,7 @@ export function transientRetryPolicyFor( ): Required | null { const policy = provider.transientRetryOn5xx; if (!policy || policy.enabled === false) return null; - if (provider.adapter !== "openai-chat") return null; + if (provider.adapter !== "openai-chat" && provider.adapter !== "openai-responses") return null; if (provider.authMode !== undefined && provider.authMode !== "key") return null; return { enabled: policy.enabled ?? DEFAULT_TRANSIENT_RETRY.enabled, From 613153695e197224f3bafbb51c5f84eed9ad01ce Mon Sep 17 00:00:00 2001 From: Yum-wu <118118663+Yum-wu@users.noreply.github.com> Date: Thu, 17 Sep 2026 18:57:55 +0800 Subject: [PATCH 2/3] test(retry): verify transient-5xx qualification for openai-responses --- tests/providers/upstream-transient-retry.test.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/providers/upstream-transient-retry.test.ts b/tests/providers/upstream-transient-retry.test.ts index 313451d023..57851ac280 100644 --- a/tests/providers/upstream-transient-retry.test.ts +++ b/tests/providers/upstream-transient-retry.test.ts @@ -40,12 +40,16 @@ describe("transientRetryPolicyFor", () => { expect(transientRetryPolicyFor({ ...base, transientRetryOn5xx: { attempts: 5 } })).toEqual({ enabled: true, attempts: 5 }); }); - test("only key-auth openai-chat qualifies", () => { + test("only key-auth openai-chat and openai-responses qualify", () => { // The adapter gate is the accepted scope, not an incidental detail: without it any // generic key-auth provider would inherit the policy. - for (const adapter of ["openai-responses", "anthropic", "google"]) { + for (const adapter of ["anthropic", "google"]) { expect(transientRetryPolicyFor({ ...base, adapter, transientRetryOn5xx: {} } as unknown as OcxProviderConfig)).toBeNull(); } + // openai-responses also qualifies + expect(transientRetryPolicyFor({ ...base, adapter: "openai-responses", transientRetryOn5xx: {} } as unknown as OcxProviderConfig)) + .toEqual({ enabled: true, attempts: 3 }); + // Fail closed on credential shape: OAuth/forward/local are never replayed here. for (const authMode of ["oauth", "forward", "local"]) { expect(transientRetryPolicyFor({ ...base, authMode, transientRetryOn5xx: {} } as unknown as OcxProviderConfig)).toBeNull(); @@ -53,6 +57,8 @@ describe("transientRetryPolicyFor", () => { // An omitted authMode is the documented key-auth default for custom providers. expect(transientRetryPolicyFor({ adapter: "openai-chat", transientRetryOn5xx: {} } as unknown as OcxProviderConfig)) .toEqual({ enabled: true, attempts: 3 }); + expect(transientRetryPolicyFor({ adapter: "openai-responses", transientRetryOn5xx: {} } as unknown as OcxProviderConfig)) + .toEqual({ enabled: true, attempts: 3 }); }); }); From 0173d3def369b48653e7ecf137a9a950a6fbc9bb Mon Sep 17 00:00:00 2001 From: Yum-wu <118118663+Yum-wu@users.noreply.github.com> Date: Thu, 17 Sep 2026 19:05:20 +0800 Subject: [PATCH 3/3] chore: sync review readiness checklist state