diff --git a/packages/opencode/src/plugin/codex.ts b/packages/opencode/src/plugin/codex.ts index a0ff0002f4..c573aa8b60 100644 --- a/packages/opencode/src/plugin/codex.ts +++ b/packages/opencode/src/plugin/codex.ts @@ -14,6 +14,13 @@ const ISSUER = "https://auth.openai.com" const CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses" const OAUTH_PORT = 1455 const OAUTH_POLLING_SAFETY_MARGIN_MS = 3000 +const ALLOWED_MODELS = new Set([ + "gpt-5.5", + "gpt-5.2", + "gpt-5.3-codex", + "gpt-5.4", + "gpt-5.4-mini", +]) interface PkceCodes { verifier: string @@ -358,50 +365,45 @@ function waitForOAuthCallback(pkce: PkceCodes, state: string): Promise { return { + provider: { + id: "openai", + async models(provider, ctx) { + if (ctx.auth?.type !== "oauth") return provider.models + + return Object.fromEntries( + Object.entries(provider.models) + .filter(([, model]) => { + if (ALLOWED_MODELS.has(model.api.id)) return true + const match = model.api.id.match(/^gpt-(\d+\.\d+)/) + return match ? parseFloat(match[1]) > 5.4 : false + }) + .map(([modelID, model]) => [ + modelID, + { + ...model, + cost: { + input: 0, + output: 0, + cache: { read: 0, write: 0 }, + }, + limit: model.id.includes("gpt-5.5") + ? { + context: 400_000, + input: 272_000, + output: 128_000, + } + : model.limit, + }, + ]), + ) + }, + }, auth: { provider: "openai", - async loader(getAuth, provider) { + async loader(getAuth) { const auth = await getAuth() if (auth.type !== "oauth") return {} - // Filter models to only allowed Codex models for OAuth - const allowedModels = new Set([ - "gpt-5.1-codex", - "gpt-5.1-codex-max", - "gpt-5.1-codex-mini", - "gpt-5.2", - "gpt-5.2-codex", - "gpt-5.3-codex", - "gpt-5.4", - "gpt-5.4-mini", - ]) - for (const [modelId, model] of Object.entries(provider.models)) { - if (modelId.includes("codex")) continue - if (allowedModels.has(model.api.id)) continue - const match = model.api.id.match(/^gpt-(\d+\.\d+)/) - if (match && parseFloat(match[1]) > 5.4) continue - delete provider.models[modelId] - } - - // Zero out costs for Codex (included with ChatGPT subscription) - for (const model of Object.values(provider.models)) { - model.cost = { - input: 0, - output: 0, - cache: { read: 0, write: 0 }, - } - - // gpt-5.5 models temporarily have restricted context window size for codex plans - if (model.id.includes("gpt-5.5")) { - model.limit = { - context: 400_000, - //@ts-expect-error incorrect type for v1 sdk but works - input: 272_000, - output: 128_000, - } - } - } - return { apiKey: OAUTH_DUMMY_KEY, async fetch(requestInput: RequestInfo | URL, init?: RequestInit) {