diff --git a/packages/ai/src/providers/openai-responses.ts b/packages/ai/src/providers/openai-responses.ts index cc99bbb0..b8a991b6 100644 --- a/packages/ai/src/providers/openai-responses.ts +++ b/packages/ai/src/providers/openai-responses.ts @@ -179,7 +179,7 @@ function createClient( Object.assign(headers, copilotHeaders); } - if (sessionId && model.provider === "openai" && model.baseUrl.includes("api.openai.com")) { + if (sessionId) { headers.session_id = sessionId; headers["x-client-request-id"] = sessionId; } diff --git a/packages/ai/test/openai-responses-copilot-provider.test.ts b/packages/ai/test/openai-responses-copilot-provider.test.ts index df1ccb8a..ef55603b 100644 --- a/packages/ai/test/openai-responses-copilot-provider.test.ts +++ b/packages/ai/test/openai-responses-copilot-provider.test.ts @@ -1,6 +1,7 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { getModel } from "../src/models.js"; import { streamOpenAIResponses } from "../src/providers/openai-responses.js"; +import type { Model } from "../src/types.js"; type CapturedHeaders = Headers | string[][] | Record | undefined; @@ -22,6 +23,7 @@ function getHeader(headers: CapturedHeaders, name: string): string | null { async function captureOpenAIResponseHeaders( options: Parameters[2], + model: Model<"openai-responses"> = getModel("openai", "gpt-5.4"), ): Promise<{ sessionId: string | null; clientRequestId: string | null }> { const captured = { sessionId: null as string | null, clientRequestId: null as string | null }; vi.spyOn(globalThis, "fetch").mockImplementation(async (_input, init) => { @@ -34,7 +36,7 @@ async function captureOpenAIResponseHeaders( }); const stream = streamOpenAIResponses( - getModel("openai", "gpt-5.4"), + model, { systemPrompt: "sys", messages: [{ role: "user", content: "hi", timestamp: Date.now() }], @@ -95,6 +97,17 @@ describe("openai-responses provider defaults", () => { expect(captured).toEqual({ sessionId: "session-123", clientRequestId: "session-123" }); }); + it("sets cache-affinity headers for proxy OpenAI Responses requests with a sessionId", async () => { + const proxyModel: Model<"openai-responses"> = { + ...getModel("openai", "gpt-5.4"), + provider: "opencode", + baseUrl: "https://proxy.example.com/v1", + }; + const captured = await captureOpenAIResponseHeaders({ sessionId: "session-123" }, proxyModel); + + expect(captured).toEqual({ sessionId: "session-123", clientRequestId: "session-123" }); + }); + it("lets explicit headers override the default OpenAI cache-affinity headers", async () => { const captured = await captureOpenAIResponseHeaders({ sessionId: "session-123",