don't send session-id header to opencode openai-responses models (#6645)
fixes #6625
This commit is contained in:
@@ -1370,11 +1370,12 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
|||||||
const npm = m.provider?.npm;
|
const npm = m.provider?.npm;
|
||||||
let api: Api;
|
let api: Api;
|
||||||
let baseUrl: string;
|
let baseUrl: string;
|
||||||
let compat: OpenAICompletionsCompat | undefined;
|
let compat: OpenAICompletionsCompat | OpenAIResponsesCompat | undefined;
|
||||||
|
|
||||||
if (npm === "@ai-sdk/openai") {
|
if (npm === "@ai-sdk/openai") {
|
||||||
api = "openai-responses";
|
api = "openai-responses";
|
||||||
baseUrl = `${variant.basePath}/v1`;
|
baseUrl = `${variant.basePath}/v1`;
|
||||||
|
compat = { sessionAffinityFormat: "openai-nosession" };
|
||||||
} else if (npm === "@ai-sdk/anthropic") {
|
} else if (npm === "@ai-sdk/anthropic") {
|
||||||
api = "anthropic-messages";
|
api = "anthropic-messages";
|
||||||
// Anthropic SDK appends /v1/messages to baseURL
|
// Anthropic SDK appends /v1/messages to baseURL
|
||||||
|
|||||||
@@ -392,6 +392,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null},
|
thinkingLevelMap: {"off":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -410,6 +411,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null},
|
thinkingLevelMap: {"off":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -428,6 +430,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null},
|
thinkingLevelMap: {"off":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -446,6 +449,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null},
|
thinkingLevelMap: {"off":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -464,6 +468,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null},
|
thinkingLevelMap: {"off":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -482,6 +487,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null},
|
thinkingLevelMap: {"off":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -500,6 +506,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null},
|
thinkingLevelMap: {"off":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -518,6 +525,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -536,6 +544,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -554,6 +563,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -572,6 +582,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -590,6 +601,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -608,6 +620,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -626,6 +639,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -644,6 +658,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh"},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -662,6 +677,7 @@ export const OPENCODE_MODELS = {
|
|||||||
api: "openai-responses",
|
api: "openai-responses",
|
||||||
provider: "opencode",
|
provider: "opencode",
|
||||||
baseUrl: "https://opencode.ai/zen/v1",
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
thinkingLevelMap: {"off":null,"xhigh":"xhigh","minimal":null,"low":null},
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh","minimal":null,"low":null},
|
||||||
input: ["text", "image"],
|
input: ["text", "image"],
|
||||||
@@ -674,6 +690,63 @@ export const OPENCODE_MODELS = {
|
|||||||
contextWindow: 1050000,
|
contextWindow: 1050000,
|
||||||
maxTokens: 128000,
|
maxTokens: 128000,
|
||||||
} satisfies Model<"openai-responses">,
|
} satisfies Model<"openai-responses">,
|
||||||
|
"gpt-5.6-luna": {
|
||||||
|
id: "gpt-5.6-luna",
|
||||||
|
name: "GPT-5.6 Luna",
|
||||||
|
api: "openai-responses",
|
||||||
|
provider: "opencode",
|
||||||
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
|
reasoning: true,
|
||||||
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
|
||||||
|
input: ["text", "image"],
|
||||||
|
cost: {
|
||||||
|
input: 1,
|
||||||
|
output: 6,
|
||||||
|
cacheRead: 0.1,
|
||||||
|
cacheWrite: 1.25,
|
||||||
|
},
|
||||||
|
contextWindow: 1050000,
|
||||||
|
maxTokens: 128000,
|
||||||
|
} satisfies Model<"openai-responses">,
|
||||||
|
"gpt-5.6-sol": {
|
||||||
|
id: "gpt-5.6-sol",
|
||||||
|
name: "GPT-5.6 Sol",
|
||||||
|
api: "openai-responses",
|
||||||
|
provider: "opencode",
|
||||||
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
|
reasoning: true,
|
||||||
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
|
||||||
|
input: ["text", "image"],
|
||||||
|
cost: {
|
||||||
|
input: 5,
|
||||||
|
output: 30,
|
||||||
|
cacheRead: 0.5,
|
||||||
|
cacheWrite: 6.25,
|
||||||
|
},
|
||||||
|
contextWindow: 1050000,
|
||||||
|
maxTokens: 128000,
|
||||||
|
} satisfies Model<"openai-responses">,
|
||||||
|
"gpt-5.6-terra": {
|
||||||
|
id: "gpt-5.6-terra",
|
||||||
|
name: "GPT-5.6 Terra",
|
||||||
|
api: "openai-responses",
|
||||||
|
provider: "opencode",
|
||||||
|
baseUrl: "https://opencode.ai/zen/v1",
|
||||||
|
compat: {"sessionAffinityFormat":"openai-nosession"},
|
||||||
|
reasoning: true,
|
||||||
|
thinkingLevelMap: {"off":null,"xhigh":"xhigh","max":"max"},
|
||||||
|
input: ["text", "image"],
|
||||||
|
cost: {
|
||||||
|
input: 2.5,
|
||||||
|
output: 15,
|
||||||
|
cacheRead: 0.25,
|
||||||
|
cacheWrite: 3.125,
|
||||||
|
},
|
||||||
|
contextWindow: 1050000,
|
||||||
|
maxTokens: 128000,
|
||||||
|
} satisfies Model<"openai-responses">,
|
||||||
"grok-4.5": {
|
"grok-4.5": {
|
||||||
id: "grok-4.5",
|
id: "grok-4.5",
|
||||||
name: "Grok 4.5",
|
name: "Grok 4.5",
|
||||||
@@ -726,7 +799,7 @@ export const OPENCODE_MODELS = {
|
|||||||
cacheRead: 0,
|
cacheRead: 0,
|
||||||
cacheWrite: 0,
|
cacheWrite: 0,
|
||||||
},
|
},
|
||||||
contextWindow: 256000,
|
contextWindow: 190000,
|
||||||
maxTokens: 64000,
|
maxTokens: 64000,
|
||||||
} satisfies Model<"openai-completions">,
|
} satisfies Model<"openai-completions">,
|
||||||
"kimi-k2.5": {
|
"kimi-k2.5": {
|
||||||
|
|||||||
+20
@@ -360,6 +360,26 @@ describe("openai-responses provider defaults", () => {
|
|||||||
expect(capturedPayload?.prompt_cache_key).toBe("session-proxy");
|
expect(capturedPayload?.prompt_cache_key).toBe("session-proxy");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("uses OpenAI no-session format for OpenCode Responses models", async () => {
|
||||||
|
const model = getModel("opencode", "gpt-5.4");
|
||||||
|
let capturedPayload: CapturedResponsesPayload | undefined;
|
||||||
|
const captured = await captureOpenAIResponseHeaders(
|
||||||
|
{
|
||||||
|
sessionId: "session-opencode",
|
||||||
|
onPayload: (payload) => {
|
||||||
|
capturedPayload = payload as CapturedResponsesPayload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
model,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(model.compat?.sessionAffinityFormat).toBe("openai-nosession");
|
||||||
|
expect(captured.sessionId).toBeNull();
|
||||||
|
expect(captured.clientRequestId).toBe("session-opencode");
|
||||||
|
expect(captured.xSessionId).toBeNull();
|
||||||
|
expect(capturedPayload?.prompt_cache_key).toBe("session-opencode");
|
||||||
|
});
|
||||||
|
|
||||||
it("can omit OpenAI session_id header while preserving other affinity data", async () => {
|
it("can omit OpenAI session_id header while preserving other affinity data", async () => {
|
||||||
const proxyModel: Model<"openai-responses"> = {
|
const proxyModel: Model<"openai-responses"> = {
|
||||||
...getModel("openai", "gpt-5.4"),
|
...getModel("openai", "gpt-5.4"),
|
||||||
Reference in New Issue
Block a user