11import type { Hooks , PluginInput } from "@opencode-ai/plugin"
2- import * as Log from "@opencode-ai/core/ util/log "
2+ import { Log } from "../ util"
33import { Installation } from "../installation"
44import { InstallationVersion } from "@opencode-ai/core/installation/version"
55import { OAUTH_DUMMY_KEY } from "../auth"
@@ -14,7 +14,6 @@ const ISSUER = "https://auth.openai.com"
1414const CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses"
1515const OAUTH_PORT = 1455
1616const OAUTH_POLLING_SAFETY_MARGIN_MS = 3000
17- const ALLOWED_MODELS = new Set ( [ "gpt-5.5" , "gpt-5.2" , "gpt-5.3-codex" , "gpt-5.4" , "gpt-5.4-mini" ] )
1817
1918interface PkceCodes {
2019 verifier : string
@@ -359,45 +358,51 @@ function waitForOAuthCallback(pkce: PkceCodes, state: string): Promise<TokenResp
359358
360359export async function CodexAuthPlugin ( input : PluginInput ) : Promise < Hooks > {
361360 return {
362- provider : {
363- id : "openai" ,
364- async models ( provider , ctx ) {
365- if ( ctx . auth ?. type !== "oauth" ) return provider . models
366-
367- return Object . fromEntries (
368- Object . entries ( provider . models )
369- . filter ( ( [ , model ] ) => {
370- if ( ALLOWED_MODELS . has ( model . api . id ) ) return true
371- const match = model . api . id . match ( / ^ g p t - ( \d + \. \d + ) / )
372- return match ? parseFloat ( match [ 1 ] ) > 5.4 : false
373- } )
374- . map ( ( [ modelID , model ] ) => [
375- modelID ,
376- {
377- ...model ,
378- cost : {
379- input : 0 ,
380- output : 0 ,
381- cache : { read : 0 , write : 0 } ,
382- } ,
383- limit : model . id . includes ( "gpt-5.5" )
384- ? {
385- context : 400_000 ,
386- input : 272_000 ,
387- output : 128_000 ,
388- }
389- : model . limit ,
390- } ,
391- ] ) ,
392- )
393- } ,
394- } ,
395361 auth : {
396362 provider : "openai" ,
397- async loader ( getAuth ) {
363+ async loader ( getAuth , provider ) {
398364 const auth = await getAuth ( )
399365 if ( auth . type !== "oauth" ) return { }
400366
367+ // Filter models to only allowed Codex models for OAuth
368+ const allowedModels = new Set ( [
369+ "gpt-5.1-codex" ,
370+ "gpt-5.1-codex-max" ,
371+ "gpt-5.1-codex-mini" ,
372+ "gpt-5.2" ,
373+ "gpt-5.2-codex" ,
374+ "gpt-5.3-codex" ,
375+ "gpt-5.4" ,
376+ "gpt-5.4-mini" ,
377+ "gpt-5.5" ,
378+ ] )
379+ for ( const [ modelId , model ] of Object . entries ( provider . models ) ) {
380+ if ( modelId . includes ( "codex" ) ) continue
381+ if ( allowedModels . has ( model . api . id ) ) continue
382+ const match = model . api . id . match ( / ^ g p t - ( \d + \. \d + ) / )
383+ if ( match && parseFloat ( match [ 1 ] ) > 5.4 ) continue
384+ delete provider . models [ modelId ]
385+ }
386+
387+ // Zero out costs for Codex (included with ChatGPT subscription)
388+ for ( const model of Object . values ( provider . models ) ) {
389+ model . cost = {
390+ input : 0 ,
391+ output : 0 ,
392+ cache : { read : 0 , write : 0 } ,
393+ }
394+
395+ // gpt-5.5 models temporarily have restricted context window size for codex plans
396+ if ( model . id . includes ( "gpt-5.5" ) ) {
397+ model . limit = {
398+ context : 400_000 ,
399+ //@ts -expect-error incorrect type for v1 sdk but works
400+ input : 272_000 ,
401+ output : 128_000 ,
402+ }
403+ }
404+ }
405+
401406 return {
402407 apiKey : OAUTH_DUMMY_KEY ,
403408 async fetch ( requestInput : RequestInfo | URL , init ?: RequestInit ) {
0 commit comments