@@ -65,29 +65,56 @@ const CLOUDFLARE_TEXT_GENERATION_MODELS = [
6565 '@cf/meta/llama-3.1-8b-instruct-fast' ,
6666] ;
6767
68+ interface OpenAIModelsResponse {
69+ data ?: Array < { id ?: unknown } > ;
70+ }
71+
72+ interface AnthropicModelsResponse {
73+ data ?: Array < { id ?: unknown } > ;
74+ }
75+
76+ interface GeminiModelsResponse {
77+ models ?: Array < {
78+ name ?: unknown ;
79+ supportedGenerationMethods ?: unknown ;
80+ } > ;
81+ }
82+
83+ interface CloudflareModelItem {
84+ id ?: unknown ;
85+ name ?: unknown ;
86+ model ?: unknown ;
87+ model_id ?: unknown ;
88+ }
89+
90+ interface CloudflareModelsResponse {
91+ result ?: CloudflareModelItem [ ] | { data ?: CloudflareModelItem [ ] } ;
92+ data ?: CloudflareModelItem [ ] ;
93+ }
94+
6895function cleanGeminiModelName ( name : string ) {
6996 return name . startsWith ( 'models/' ) ? name . slice ( 'models/' . length ) : name ;
7097}
7198
72- function extractOpenAiModels ( data : any ) {
99+ function extractOpenAiModels ( data : OpenAIModelsResponse ) {
73100 return Array . isArray ( data ?. data )
74- ? data . data . map ( ( item : any ) => item ?. id ) . filter ( ( id : unknown ) : id is string => typeof id === 'string' && id . length > 0 )
101+ ? data . data . map ( ( item ) => item ?. id ) . filter ( ( id : unknown ) : id is string => typeof id === 'string' && id . length > 0 )
75102 : [ ] ;
76103}
77104
78- function extractAnthropicModels ( data : any ) {
105+ function extractAnthropicModels ( data : AnthropicModelsResponse ) {
79106 return Array . isArray ( data ?. data )
80- ? data . data . map ( ( item : any ) => item ?. id ) . filter ( ( id : unknown ) : id is string => typeof id === 'string' && id . length > 0 )
107+ ? data . data . map ( ( item ) => item ?. id ) . filter ( ( id : unknown ) : id is string => typeof id === 'string' && id . length > 0 )
81108 : [ ] ;
82109}
83110
84- function extractGeminiModels ( data : any ) {
111+ function extractGeminiModels ( data : GeminiModelsResponse ) {
85112 if ( ! Array . isArray ( data ?. models ) ) return [ ] ;
86113 return data . models
87- . filter ( ( model : any ) => Array . isArray ( model ?. supportedGenerationMethods )
114+ . filter ( ( model ) => Array . isArray ( model ?. supportedGenerationMethods )
88115 ? model . supportedGenerationMethods . includes ( 'generateContent' )
89116 : true )
90- . map ( ( model : any ) => typeof model ?. name === 'string' ? cleanGeminiModelName ( model . name ) : null )
117+ . map ( ( model ) => typeof model ?. name === 'string' ? cleanGeminiModelName ( model . name ) : null )
91118 . filter ( ( id : unknown ) : id is string => typeof id === 'string' && id . length > 0 ) ;
92119}
93120
@@ -112,7 +139,7 @@ export async function listProviderModels(input: {
112139 } ) ,
113140 ) ;
114141 if ( ! response . ok ) throw new Error ( `OpenAI model list failed with ${ response . status } : ${ await limitedErrorBody ( response ) } ` ) ;
115- return extractOpenAiModels ( await response . json ( ) ) ;
142+ return extractOpenAiModels ( await response . json ( ) as OpenAIModelsResponse ) ;
116143 }
117144
118145 if ( input . apiFormat === 'anthropic' ) {
@@ -128,18 +155,23 @@ export async function listProviderModels(input: {
128155 } ) ,
129156 ) ;
130157 if ( ! response . ok ) throw new Error ( `Anthropic model list failed with ${ response . status } : ${ await limitedErrorBody ( response ) } ` ) ;
131- return extractAnthropicModels ( await response . json ( ) ) ;
158+ return extractAnthropicModels ( await response . json ( ) as AnthropicModelsResponse ) ;
132159 }
133160
134161 if ( input . apiFormat === 'gemini' ) {
135162 if ( ! input . apiKey ) throw new Error ( 'Google API key is required to list models.' ) ;
136163 const apiKey = input . apiKey ;
137- const url = `${ baseUrl } /models?key= ${ encodeURIComponent ( apiKey ) } ` ;
164+ const url = `${ baseUrl } /models` ;
138165 const response = await withTimeout ( 'Google model list' , MODEL_LIST_TIMEOUT_MS , ( signal ) =>
139- fetch ( url , { signal } ) ,
166+ fetch ( url , {
167+ signal,
168+ headers : {
169+ 'x-goog-api-key' : apiKey ,
170+ } ,
171+ } ) ,
140172 ) ;
141173 if ( ! response . ok ) throw new Error ( `Google model list failed with ${ response . status } : ${ await limitedErrorBody ( response ) } ` ) ;
142- return extractGeminiModels ( await response . json ( ) ) ;
174+ return extractGeminiModels ( await response . json ( ) as GeminiModelsResponse ) ;
143175 }
144176
145177 return listCloudflareModels ( input . cloudflareAccountId , input . cloudflareApiToken ) ;
@@ -165,21 +197,21 @@ async function listCloudflareModels(accountId?: string, apiToken?: string) {
165197 return CLOUDFLARE_TEXT_GENERATION_MODELS ;
166198 }
167199 if ( ! response . ok ) throw new Error ( `Cloudflare model list failed with ${ response . status } : ${ await limitedErrorBody ( response ) } ` ) ;
168- const models = extractCloudflareModels ( await response . json ( ) ) ;
200+ const models = extractCloudflareModels ( await response . json ( ) as CloudflareModelsResponse ) ;
169201 return models . length > 0 ? models : CLOUDFLARE_TEXT_GENERATION_MODELS ;
170202}
171203
172- function extractCloudflareModels ( data : any ) {
204+ function extractCloudflareModels ( data : CloudflareModelsResponse ) {
173205 const items = Array . isArray ( data ?. result )
174206 ? data . result
175- : Array . isArray ( data ? .result ? .data )
176- ? data . result . data
207+ : typeof data ?. result === 'object' && data . result !== null && 'data' in data . result && Array . isArray ( ( data . result as { data ?: unknown [ ] } ) . data )
208+ ? ( data . result as { data ?: unknown [ ] } ) . data
177209 : Array . isArray ( data ?. data )
178210 ? data . data
179211 : [ ] ;
180212
181213 return Array . from ( new Set (
182- items
214+ ( items || [ ] )
183215 . map ( ( item : any ) => normalizeCloudflareModelId ( item ?. id ?? item ?. name ?? item ?. model ?? item ?. model_id ) )
184216 . filter ( ( id : unknown ) : id is string => typeof id === 'string' && id . startsWith ( '@cf/' ) ) ,
185217 ) ) ;
0 commit comments