diff --git a/extensions/openai/openai-provider.ts b/extensions/openai/openai-provider.ts index a34fdd725430..679e7307af74 100644 --- a/extensions/openai/openai-provider.ts +++ b/extensions/openai/openai-provider.ts @@ -84,7 +84,7 @@ function classifyOpenAiFailoverCode(code: string | undefined) { const OPENAI_MODELS_ENDPOINT = "https://api.openai.com/v1/models"; // Keep synchronized with extensions/codex's exact @openai/codex dependency; // the provider contract test fails when that managed-runtime pin changes. -const OPENAI_CODEX_CLIENT_VERSION = "0.144.6"; +const OPENAI_CODEX_CLIENT_VERSION = "0.145.0"; const OPENAI_CODEX_MODELS_ENDPOINT = `${OPENAI_CODEX_RESPONSES_BASE_URL}/models?client_version=${OPENAI_CODEX_CLIENT_VERSION}`; const OPENAI_MODELS_CACHE_TTL_MS = 60_000; const OPENAI_CODEX_MODELS_CACHE_TTL_MS = 60_000; diff --git a/scripts/test-projects.test-support.mjs b/scripts/test-projects.test-support.mjs index 5fe99472e0c2..06901e9005fd 100644 --- a/scripts/test-projects.test-support.mjs +++ b/scripts/test-projects.test-support.mjs @@ -2350,6 +2350,7 @@ const APPCAST_TEST_TARGETS = ["test/appcast.test.ts", "test/scripts/make-appcast const CODEX_VERSION_CONTRACT_TEST_TARGETS = [ "extensions/codex/src/manifest.test.ts", "extensions/openai/openai-provider.test.ts", + "test/scripts/codex-client-version-contract.test.ts", ]; const SOURCE_TEST_TARGETS = new Map([ ...PRECISE_SOURCE_TEST_TARGETS, diff --git a/test/scripts/codex-client-version-contract.test.ts b/test/scripts/codex-client-version-contract.test.ts new file mode 100644 index 000000000000..e8731563d075 --- /dev/null +++ b/test/scripts/codex-client-version-contract.test.ts @@ -0,0 +1,33 @@ +// Codex Client Version Contract tests cover cross-plugin managed version alignment. +import fs from "node:fs"; +import { describe, expect, it } from "vitest"; + +const CODEX_PACKAGE_JSON_URL = new URL("../../extensions/codex/package.json", import.meta.url); +const OPENAI_PROVIDER_URL = new URL("../../extensions/openai/openai-provider.ts", import.meta.url); +const OPENAI_CODEX_CLIENT_VERSION_PATTERN = /^const OPENAI_CODEX_CLIENT_VERSION = "([^"]+)";$/mu; + +function readManagedCodexVersion(): string { + const packageJson = JSON.parse(fs.readFileSync(CODEX_PACKAGE_JSON_URL, "utf8")) as { + dependencies?: Record; + }; + const version = packageJson.dependencies?.["@openai/codex"]; + if (typeof version !== "string") { + throw new Error("extensions/codex/package.json must pin @openai/codex exactly"); + } + return version; +} + +function readOpenAICodexClientVersion(): string { + const providerSource = fs.readFileSync(OPENAI_PROVIDER_URL, "utf8"); + const version = OPENAI_CODEX_CLIENT_VERSION_PATTERN.exec(providerSource)?.[1]; + if (!version) { + throw new Error("extensions/openai/openai-provider.ts must declare the Codex client version"); + } + return version; +} + +describe("Codex client version contract", () => { + it("matches OpenAI model discovery to the managed Codex package", () => { + expect(readOpenAICodexClientVersion()).toBe(readManagedCodexVersion()); + }); +}); diff --git a/test/scripts/test-projects.test.ts b/test/scripts/test-projects.test.ts index b77048cc9669..f674c701a711 100644 --- a/test/scripts/test-projects.test.ts +++ b/test/scripts/test-projects.test.ts @@ -298,6 +298,7 @@ describe("scripts/test-projects changed-target routing", () => { targets: [ "extensions/codex/src/manifest.test.ts", "extensions/openai/openai-provider.test.ts", + "test/scripts/codex-client-version-contract.test.ts", ], }); },