fix(models): expose codex runtime context caps

This commit is contained in:
Peter Steinberger
2026-04-25 07:37:56 +01:00
parent 3d554aefdf
commit 2ff7eb36cf
18 changed files with 240 additions and 46 deletions

View File

@@ -333,7 +333,7 @@ describe("openai codex provider", () => {
});
});
it("uses Pi metadata for gpt-5.5 and local launch metadata for gpt-5.5-pro", () => {
it("keeps Pi cost metadata but applies Codex context metadata for gpt-5.5", () => {
const provider = buildOpenAICodexProviderPlugin();
const model = provider.resolveDynamicModel?.({
@@ -343,7 +343,7 @@ describe("openai codex provider", () => {
createCodexTemplate({
id: "gpt-5.5",
cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 },
contextWindow: 400_000,
contextWindow: 272_000,
}),
) as never,
});
@@ -358,6 +358,7 @@ describe("openai codex provider", () => {
api: "openai-codex-responses",
baseUrl: "https://chatgpt.com/backend-api",
contextWindow: 400_000,
contextTokens: 272_000,
maxTokens: 128_000,
cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 },
});
@@ -387,7 +388,7 @@ describe("openai codex provider", () => {
baseUrl: "https://chatgpt.com/backend-api/codex",
reasoning: true,
input: ["text", "image"],
contextWindow: 1_000_000,
contextWindow: 400_000,
contextTokens: 272_000,
maxTokens: 128_000,
});

View File

@@ -50,8 +50,8 @@ const OPENAI_CODEX_GPT_54_MODEL_ID = "gpt-5.4";
const OPENAI_CODEX_GPT_54_LEGACY_MODEL_ID = "gpt-5.4-codex";
const OPENAI_CODEX_GPT_54_PRO_MODEL_ID = "gpt-5.4-pro";
const OPENAI_CODEX_GPT_54_MINI_MODEL_ID = "gpt-5.4-mini";
const OPENAI_CODEX_GPT_55_NATIVE_CONTEXT_TOKENS = 1_000_000;
const OPENAI_CODEX_GPT_55_DEFAULT_CONTEXT_TOKENS = 272_000;
const OPENAI_CODEX_GPT_55_CODEX_CONTEXT_TOKENS = 400_000;
const OPENAI_CODEX_GPT_55_DEFAULT_RUNTIME_CONTEXT_TOKENS = 272_000;
const OPENAI_CODEX_GPT_55_PRO_NATIVE_CONTEXT_TOKENS = 1_000_000;
const OPENAI_CODEX_GPT_55_PRO_DEFAULT_CONTEXT_TOKENS = 272_000;
const OPENAI_CODEX_GPT_54_NATIVE_CONTEXT_TOKENS = 1_050_000;
@@ -188,7 +188,11 @@ function resolveCodexForwardCompatModel(ctx: ProviderResolveDynamicModelContext)
| ProviderRuntimeModel
| undefined;
return (
model ??
withDefaultCodexContextMetadata({
model,
contextWindow: OPENAI_CODEX_GPT_55_CODEX_CONTEXT_TOKENS,
contextTokens: OPENAI_CODEX_GPT_55_DEFAULT_RUNTIME_CONTEXT_TOKENS,
}) ??
normalizeModelCompat({
id: trimmedModelId,
name: trimmedModelId,
@@ -198,8 +202,8 @@ function resolveCodexForwardCompatModel(ctx: ProviderResolveDynamicModelContext)
reasoning: true,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: OPENAI_CODEX_GPT_55_NATIVE_CONTEXT_TOKENS,
contextTokens: OPENAI_CODEX_GPT_55_DEFAULT_CONTEXT_TOKENS,
contextWindow: OPENAI_CODEX_GPT_55_CODEX_CONTEXT_TOKENS,
contextTokens: OPENAI_CODEX_GPT_55_DEFAULT_RUNTIME_CONTEXT_TOKENS,
maxTokens: OPENAI_CODEX_GPT_54_MAX_TOKENS,
} as ProviderRuntimeModel)
);
@@ -280,6 +284,27 @@ function resolveCodexForwardCompatModel(ctx: ProviderResolveDynamicModelContext)
);
}
function withDefaultCodexContextMetadata(params: {
model: ProviderRuntimeModel | undefined;
contextWindow: number;
contextTokens: number;
}): ProviderRuntimeModel | undefined {
if (!params.model) {
return undefined;
}
const contextTokens =
typeof params.model.contextTokens === "number"
? params.model.contextTokens
: typeof params.model.contextWindow === "number" && params.model.contextWindow > 0
? Math.min(params.contextTokens, params.model.contextWindow)
: params.contextTokens;
return {
...params.model,
contextWindow: params.contextWindow,
contextTokens,
};
}
async function refreshOpenAICodexOAuthCredential(cred: OAuthCredential) {
try {
const { refreshOpenAICodexToken } = await import("./openai-codex-provider.runtime.js");