test(openai): cover GPT-5.5 defaults

This commit is contained in:
Peter Steinberger
2026-04-23 20:00:51 +01:00
parent a36903b94c
commit cd5bc2fc93
65 changed files with 437 additions and 181 deletions

View File

@@ -224,7 +224,7 @@ describe("openai codex provider", () => {
},
},
],
defaultModel: "openai-codex/gpt-5.4",
defaultModel: "openai-codex/gpt-5.5",
});
expect(result?.profiles[0]?.credential).not.toHaveProperty("idToken");
expect(result?.profiles[0]?.credential).not.toHaveProperty("accountId");
@@ -329,6 +329,40 @@ describe("openai codex provider", () => {
});
});
it("resolves gpt-5.5 and gpt-5.5-pro with launch pricing and codex-sized runtime cap", () => {
const provider = buildOpenAICodexProviderPlugin();
const model = provider.resolveDynamicModel?.({
provider: "openai-codex",
modelId: "gpt-5.5",
modelRegistry: createSingleModelRegistry(createCodexTemplate({ id: "gpt-5.4" })) as never,
});
const pro = provider.resolveDynamicModel?.({
provider: "openai-codex",
modelId: "gpt-5.5-pro",
modelRegistry: createSingleModelRegistry(createCodexTemplate({ id: "gpt-5.4-pro" })) as never,
});
expect(model).toMatchObject({
id: "gpt-5.5",
api: "openai-codex-responses",
baseUrl: "https://chatgpt.com/backend-api",
contextWindow: 1_000_000,
contextTokens: 272_000,
maxTokens: 128_000,
cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 },
});
expect(pro).toMatchObject({
id: "gpt-5.5-pro",
api: "openai-codex-responses",
baseUrl: "https://chatgpt.com/backend-api",
contextWindow: 1_000_000,
contextTokens: 272_000,
maxTokens: 128_000,
cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 },
});
});
it("resolves gpt-5.4-pro from a gpt-5.4 runtime template when legacy codex rows are absent", () => {
const provider = buildOpenAICodexProviderPlugin();
@@ -398,7 +432,7 @@ describe("openai codex provider", () => {
expect(model).not.toHaveProperty("contextTokens");
});
it("augments catalog with gpt-5.4 native contextWindow and runtime cap", () => {
it("augments catalog with gpt-5.5 and gpt-5.4 native metadata", () => {
const provider = buildOpenAICodexProviderPlugin();
const entries = provider.augmentModelCatalog?.({
@@ -415,6 +449,22 @@ describe("openai codex provider", () => {
],
} as never);
expect(entries).toContainEqual(
expect.objectContaining({
id: "gpt-5.5",
contextWindow: 1_000_000,
contextTokens: 272_000,
cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 },
}),
);
expect(entries).toContainEqual(
expect.objectContaining({
id: "gpt-5.5-pro",
contextWindow: 1_000_000,
contextTokens: 272_000,
cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 },
}),
);
expect(entries).toContainEqual(
expect.objectContaining({
id: "gpt-5.4",

View File

@@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest";
import { buildOpenAIProvider } from "./openai-provider.js";
const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? "";
const DEFAULT_LIVE_MODEL_IDS = ["gpt-5.4-mini", "gpt-5.4-nano"] as const;
const DEFAULT_LIVE_MODEL_IDS = ["gpt-5.5", "gpt-5.4-mini", "gpt-5.4-nano"] as const;
const liveEnabled = OPENAI_API_KEY.trim().length > 0 && process.env.OPENCLAW_LIVE_TEST === "1";
const describeLive = liveEnabled ? describe : describe.skip;
@@ -18,6 +18,24 @@ type LiveModelCase = {
function resolveLiveModelCase(modelId: string): LiveModelCase {
switch (modelId) {
case "gpt-5.5":
return {
modelId,
templateId: "gpt-5.4",
templateName: "GPT-5.4",
cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 },
contextWindow: 1_000_000,
maxTokens: 128_000,
};
case "gpt-5.5-pro":
return {
modelId,
templateId: "gpt-5.4-pro",
templateName: "GPT-5.4 Pro",
cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 },
contextWindow: 1_000_000,
maxTokens: 128_000,
};
case "gpt-5.4":
return {
modelId,

View File

@@ -229,6 +229,101 @@ describe("buildOpenAIProvider", () => {
});
});
it("resolves gpt-5.5 and gpt-5.5-pro with launch metadata", () => {
const provider = buildOpenAIProvider();
const model = provider.resolveDynamicModel?.({
provider: "openai",
modelId: "gpt-5.5",
modelRegistry: {
find: (_provider: string, id: string) =>
id === "gpt-5.4"
? {
id,
name: "GPT-5.4",
provider: "openai",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
input: ["text", "image"],
cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 },
contextWindow: 1_050_000,
maxTokens: 128_000,
}
: null,
} as never,
});
const pro = provider.resolveDynamicModel?.({
provider: "openai",
modelId: "gpt-5.5-pro",
modelRegistry: {
find: (_provider: string, id: string) =>
id === "gpt-5.4-pro"
? {
id,
name: "GPT-5.4 Pro",
provider: "openai",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
input: ["text", "image"],
cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 },
contextWindow: 1_050_000,
maxTokens: 128_000,
}
: null,
} as never,
});
expect(model).toMatchObject({
provider: "openai",
id: "gpt-5.5",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
contextWindow: 1_000_000,
maxTokens: 128_000,
cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 },
});
expect(pro).toMatchObject({
provider: "openai",
id: "gpt-5.5-pro",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
contextWindow: 1_000_000,
maxTokens: 128_000,
cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 },
});
});
it("surfaces gpt-5.5 in xhigh and augmented catalog metadata", () => {
const provider = buildOpenAIProvider();
expect(
provider
.resolveThinkingProfile?.({
provider: "openai",
modelId: "gpt-5.5",
} as never)
?.levels.some((level) => level.id === "xhigh"),
).toBe(true);
const entries = provider.augmentModelCatalog?.({
env: process.env,
entries: [{ provider: "openai", id: "gpt-5.4", name: "GPT-5.4" }],
} as never);
expect(entries).toContainEqual(
expect.objectContaining({
provider: "openai",
id: "gpt-5.5",
name: "gpt-5.5",
reasoning: true,
input: ["text", "image"],
contextWindow: 1_000_000,
}),
);
});
it("keeps modern live selection on OpenAI 5.2+ and Codex 5.2+", () => {
const provider = buildOpenAIProvider();
const codexProvider = buildOpenAICodexProviderPlugin();
@@ -251,6 +346,12 @@ describe("buildOpenAIProvider", () => {
modelId: "gpt-5.4",
} as never),
).toBe(true);
expect(
provider.isModernModelRef?.({
provider: "openai",
modelId: "gpt-5.5",
} as never),
).toBe(true);
expect(
codexProvider.isModernModelRef?.({
@@ -276,6 +377,12 @@ describe("buildOpenAIProvider", () => {
modelId: "gpt-5.4",
} as never),
).toBe(true);
expect(
codexProvider.isModernModelRef?.({
provider: "openai-codex",
modelId: "gpt-5.5",
} as never),
).toBe(true);
});
it("owns replay policy for OpenAI and Codex transports", () => {

View File

@@ -17,7 +17,7 @@ import { runRealtimeSttLiveTest } from "../../test/helpers/stt-live-audio.js";
import plugin from "./index.js";
const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? "";
const LIVE_MODEL_ID = process.env.OPENCLAW_LIVE_OPENAI_PLUGIN_MODEL?.trim() || "gpt-5.4-nano";
const LIVE_MODEL_ID = process.env.OPENCLAW_LIVE_OPENAI_PLUGIN_MODEL?.trim() || "gpt-5.5";
const LIVE_IMAGE_MODEL = process.env.OPENCLAW_LIVE_OPENAI_IMAGE_MODEL?.trim() || "gpt-image-2";
const LIVE_VISION_MODEL = process.env.OPENCLAW_LIVE_OPENAI_VISION_MODEL?.trim() || "gpt-4.1-mini";
const liveEnabled = OPENAI_API_KEY.trim().length > 0 && process.env.OPENCLAW_LIVE_TEST === "1";
@@ -29,6 +29,8 @@ const ModelRegistryCtor = ModelRegistry as unknown as {
function resolveTemplateModelId(modelId: string) {
switch (modelId) {
case "gpt-5.5":
return "gpt-5.4";
case "gpt-5.4":
return "gpt-5.2";
case "gpt-5.4-mini":

View File

@@ -1,6 +1,7 @@
import { beforeEach, describe, it, vi } from "vitest";
import {
expectAugmentedCodexCatalog,
expectedAugmentedOpenaiCodexCatalogEntriesWithGpt55,
expectCodexBuiltInSuppression,
expectCodexMissingAuthHint,
importProviderRuntimeCatalogModule,
@@ -116,7 +117,10 @@ export function describeOpenAIProviderCatalogContract() {
it("keeps bundled model augmentation wired through the provider runtime", async () => {
const { augmentModelCatalogWithProviderPlugins } = await contractDepsPromise;
await expectAugmentedCodexCatalog(augmentModelCatalogWithProviderPlugins);
await expectAugmentedCodexCatalog(
augmentModelCatalogWithProviderPlugins,
expectedAugmentedOpenaiCodexCatalogEntriesWithGpt55,
);
});
},
);