fix: normalize stale openai completions transport

This commit is contained in:
Peter Steinberger
2026-03-10 20:23:03 +00:00
parent 0976317f96
commit 283570de4d
2 changed files with 73 additions and 1 deletions

View File

@@ -54,9 +54,33 @@ function normalizeOpenAICodexTransport(params: {
} as Model<Api>;
}
function normalizeOpenAITransport(params: { provider: string; model: Model<Api> }): Model<Api> {
if (normalizeProviderId(params.provider) !== "openai") {
return params.model;
}
const useResponsesTransport =
params.model.api === "openai-completions" &&
(!params.model.baseUrl || isOpenAIApiBaseUrl(params.model.baseUrl));
if (!useResponsesTransport) {
return params.model;
}
return {
...params.model,
api: "openai-responses",
} as Model<Api>;
}
export function normalizeResolvedProviderModel(params: {
provider: string;
model: Model<Api>;
}): Model<Api> {
return normalizeModelCompat(normalizeOpenAICodexTransport(params));
const normalizedOpenAI = normalizeOpenAITransport(params);
const normalizedCodex = normalizeOpenAICodexTransport({
provider: params.provider,
model: normalizedOpenAI,
});
return normalizeModelCompat(normalizedCodex);
}

View File

@@ -518,6 +518,54 @@ describe("resolveModel", () => {
});
});
it("normalizes stale native openai gpt-5.4 completions transport to responses", () => {
mockDiscoveredModel({
provider: "openai",
modelId: "gpt-5.4",
templateModel: buildForwardCompatTemplate({
id: "gpt-5.4",
name: "GPT-5.4",
provider: "openai",
api: "openai-completions",
baseUrl: "https://api.openai.com/v1",
}),
});
const result = resolveModel("openai", "gpt-5.4", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject({
provider: "openai",
id: "gpt-5.4",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
});
});
it("keeps proxied openai completions transport untouched", () => {
mockDiscoveredModel({
provider: "openai",
modelId: "gpt-5.4",
templateModel: buildForwardCompatTemplate({
id: "gpt-5.4",
name: "GPT-5.4",
provider: "openai",
api: "openai-completions",
baseUrl: "https://proxy.example.com/v1",
}),
});
const result = resolveModel("openai", "gpt-5.4", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject({
provider: "openai",
id: "gpt-5.4",
api: "openai-completions",
baseUrl: "https://proxy.example.com/v1",
});
});
it("builds an anthropic forward-compat fallback for claude-opus-4-6", () => {
mockDiscoveredModel({
provider: "anthropic",