@@ -15,15 +15,13 @@ type Args = {
1515 timeoutMs : number
1616 delayMs : number
1717 limit : number | undefined
18- includeMini : boolean
1918}
2019
2120function parseArgs ( argv : string [ ] ) : Args {
2221 const providerIDs : string [ ] = [ ]
2322 let timeoutMs = 20_000
2423 let delayMs = 250
2524 let limit : number | undefined
26- let includeMini = false
2725
2826 for ( let i = 0 ; i < argv . length ; i ++ ) {
2927 const arg = argv [ i ]
@@ -54,7 +52,7 @@ function parseArgs(argv: string[]): Args {
5452 break
5553 }
5654 case "--include-mini" : {
57- includeMini = true
55+ // Deprecated: gpt-5-mini is now included by default.
5856 break
5957 }
6058 case "--help" :
@@ -73,7 +71,7 @@ function parseArgs(argv: string[]): Args {
7371 if ( ! Number . isFinite ( delayMs ) || delayMs < 0 ) throw new Error ( "--delay-ms must be >= 0" )
7472 if ( limit !== undefined && ( ! Number . isFinite ( limit ) || limit <= 0 ) ) throw new Error ( "--limit must be > 0" )
7573
76- return { providerIDs, timeoutMs, delayMs, limit, includeMini }
74+ return { providerIDs, timeoutMs, delayMs, limit }
7775}
7876
7977function printHelp ( ) {
@@ -92,7 +90,7 @@ function printHelp() {
9290 " --timeout-ms <n> Per-model timeout (default: 20000)" ,
9391 " --delay-ms <n> Delay between models (default: 250)" ,
9492 " --limit <n> Only test the first N models per provider" ,
95- " --include-mini Also test gpt-5-mini (expected to fail for some users )" ,
93+ " --include-mini Deprecated ( gpt-5-mini is included by default )" ,
9694 " -h, --help Show help" ,
9795 "" ,
9896 "Notes:" ,
@@ -113,6 +111,41 @@ function getGptMajor(modelID: string): number | undefined {
113111 return Number ( match [ 1 ] )
114112}
115113
114+ function matchesExtraModelID ( modelID : string ) : boolean {
115+ // Include these explicitly, even if they are not GPT-5+.
116+ const extra = [ "gpt-5-mini" , "gpt-4.1" , "gpt-4o" ]
117+ return extra . some ( ( base ) => modelID === base || modelID . startsWith ( `${ base } -` ) )
118+ }
119+
120+ type ApiRoute = "responses" | "chat" | "unknown"
121+
122+ function inferApiRoute ( urls : string [ ] ) : ApiRoute {
123+ const joined = urls . join ( "\n" )
124+ if ( / \/ r e s p o n s e s ( \b | \/ ) / . test ( joined ) ) return "responses"
125+ if ( / \/ c h a t \/ c o m p l e t i o n s ( \b | \/ ) / . test ( joined ) ) return "chat"
126+ return "unknown"
127+ }
128+
129+ const originalFetch = globalThis . fetch
130+ const requestLog = new Map < string , string [ ] > ( )
131+ let activeProbeKey : string | undefined
132+
133+ // Capture request URLs to determine which API path is used.
134+ // Provider.getSDK wraps `fetch`, so overriding global fetch is sufficient.
135+ globalThis . fetch = async ( input : any , init ?: any ) => {
136+ try {
137+ const url = typeof input === "string" ? input : input ?. url ?? String ( input )
138+ if ( activeProbeKey ) {
139+ const existing = requestLog . get ( activeProbeKey ) ?? [ ]
140+ existing . push ( url )
141+ requestLog . set ( activeProbeKey , existing )
142+ }
143+ } catch {
144+ // ignore
145+ }
146+ return originalFetch ( input as any , init as any )
147+ }
148+
116149function buildConfigOverlayJSON ( providerIDs : string [ ] ) : string {
117150 // Merge into any existing OPENCODE_CONFIG_CONTENT the user provided.
118151 const existingRaw = process . env . OPENCODE_CONFIG_CONTENT
@@ -159,7 +192,7 @@ async function probeModel(input: {
159192 providerID : string
160193 modelID : string
161194 timeoutMs : number
162- } ) : Promise < { ok : boolean ; error ?: string } > {
195+ } ) : Promise < { ok : boolean ; api : ApiRoute ; error ?: string } > {
163196 const messages : ModelMessage [ ] = [
164197 {
165198 role : "user" ,
@@ -169,6 +202,10 @@ async function probeModel(input: {
169202
170203 try {
171204 const { Provider } = await import ( "../src/provider/provider" )
205+ const key = `${ input . providerID } /${ input . modelID } `
206+ requestLog . set ( key , [ ] )
207+ activeProbeKey = key
208+
172209 const model = await Provider . getModel ( input . providerID , input . modelID )
173210 const language = await Provider . getLanguage ( model )
174211
@@ -180,10 +217,16 @@ async function probeModel(input: {
180217 abortSignal : AbortSignal . timeout ( input . timeoutMs ) ,
181218 } )
182219
183- return { ok : true }
220+ activeProbeKey = undefined
221+ const urls = requestLog . get ( key ) ?? [ ]
222+ return { ok : true , api : inferApiRoute ( urls ) }
184223 } catch ( e : any ) {
224+ const key = `${ input . providerID } /${ input . modelID } `
225+ activeProbeKey = undefined
226+ const urls = requestLog . get ( key ) ?? [ ]
227+ const api = inferApiRoute ( urls )
185228 const message = e ?. message ? String ( e . message ) : String ( e )
186- return { ok : false , error : message }
229+ return { ok : false , api , error : message }
187230 }
188231}
189232
@@ -215,9 +258,8 @@ async function main() {
215258 const modelIDs = Object . keys ( provider . models )
216259 . filter ( ( id ) => {
217260 const major = getGptMajor ( id )
218- if ( major === undefined || major < 5 ) return false
219- if ( ! args . includeMini && id === "gpt-5-mini" ) return false
220- return true
261+ if ( major !== undefined && major >= 5 ) return true
262+ return matchesExtraModelID ( id )
221263 } )
222264 . sort ( ( a , b ) => a . localeCompare ( b ) )
223265
@@ -239,11 +281,11 @@ async function main() {
239281
240282 if ( result . ok ) {
241283 okCount ++
242- process . stdout . write ( "OK\n" )
284+ process . stdout . write ( `OK (api= ${ result . api } )\n` )
243285 } else {
244286 failCount ++
245287 hadFailure = true
246- process . stdout . write ( `FAIL (${ result . error } )\n` )
288+ process . stdout . write ( `FAIL (api= ${ result . api } ) ( ${ result . error } )\n` )
247289 }
248290
249291 if ( args . delayMs > 0 ) {
@@ -259,7 +301,8 @@ async function main() {
259301 // Important: OpenCode may start background servers/plugins that keep the event loop alive.
260302 // Dispose all instance state and exit explicitly.
261303 await Instance . disposeAll ( )
262- process . exit ( hadFailure ? 1 : 0 )
304+ // One-off diagnostic script: always exit 0 after printing results.
305+ process . exit ( 0 )
263306}
264307
265308await main ( )
0 commit comments