@@ -117,6 +117,115 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
117117 telemetryService . updateTelemetryState ( isOptedIn )
118118 } )
119119
120+ // Auto-request router models if API keys are configured
121+ // Add a slight delay to ensure the webview is fully initialized
122+ setTimeout ( async ( ) => {
123+ try {
124+ const state = await provider . getStateToPostToWebview ( )
125+ const { apiConfiguration } = state
126+
127+ if (
128+ apiConfiguration . openRouterApiKey ||
129+ apiConfiguration . requestyApiKey ||
130+ apiConfiguration . glamaApiKey ||
131+ apiConfiguration . unboundApiKey ||
132+ ( apiConfiguration . litellmApiKey && apiConfiguration . litellmBaseUrl )
133+ ) {
134+ // Request router models automatically on initialization
135+ provider . log ( "Auto-requesting router models on initialization" )
136+
137+ // Use the same logic as requestRouterModels case
138+ const routerModels : Partial < Record < RouterName , ModelRecord > > = {
139+ openrouter : { } ,
140+ requesty : { } ,
141+ glama : { } ,
142+ unbound : { } ,
143+ litellm : { } ,
144+ }
145+
146+ const safeGetModels = async ( options : GetModelsOptions ) : Promise < ModelRecord > => {
147+ try {
148+ return await getModels ( options )
149+ } catch ( error ) {
150+ console . error (
151+ `Failed to fetch models in auto-initialization for ${ options . provider } :` ,
152+ error ,
153+ )
154+ return { }
155+ }
156+ }
157+
158+ const modelFetchPromises : Array < { key : RouterName ; options : GetModelsOptions } > = [ ]
159+
160+ if ( apiConfiguration . openRouterApiKey ) {
161+ modelFetchPromises . push ( { key : "openrouter" , options : { provider : "openrouter" } } )
162+ }
163+
164+ if ( apiConfiguration . requestyApiKey ) {
165+ modelFetchPromises . push ( {
166+ key : "requesty" ,
167+ options : { provider : "requesty" , apiKey : apiConfiguration . requestyApiKey } ,
168+ } )
169+ }
170+
171+ if ( apiConfiguration . glamaApiKey ) {
172+ modelFetchPromises . push ( { key : "glama" , options : { provider : "glama" } } )
173+ }
174+
175+ if ( apiConfiguration . unboundApiKey ) {
176+ modelFetchPromises . push ( {
177+ key : "unbound" ,
178+ options : { provider : "unbound" , apiKey : apiConfiguration . unboundApiKey } ,
179+ } )
180+ }
181+
182+ if ( apiConfiguration . litellmApiKey && apiConfiguration . litellmBaseUrl ) {
183+ modelFetchPromises . push ( {
184+ key : "litellm" ,
185+ options : {
186+ provider : "litellm" ,
187+ apiKey : apiConfiguration . litellmApiKey ,
188+ baseUrl : apiConfiguration . litellmBaseUrl ,
189+ } ,
190+ } )
191+ }
192+
193+ if ( modelFetchPromises . length > 0 ) {
194+ const results = await Promise . allSettled (
195+ modelFetchPromises . map ( async ( { key, options } ) => {
196+ const models = await safeGetModels ( options )
197+ return { key, models }
198+ } ) ,
199+ )
200+
201+ const fetchedRouterModels : Partial < Record < RouterName , ModelRecord > > = { ...routerModels }
202+
203+ results . forEach ( ( result , index ) => {
204+ const routerName = modelFetchPromises [ index ] . key
205+
206+ if ( result . status === "fulfilled" ) {
207+ fetchedRouterModels [ routerName ] = result . value . models
208+ } else {
209+ fetchedRouterModels [ routerName ] = { }
210+ }
211+ } )
212+
213+ provider . log (
214+ `Auto-fetched router models for: ${ modelFetchPromises . map ( ( p ) => p . key ) . join ( ", " ) } ` ,
215+ )
216+ await provider . postMessageToWebview ( {
217+ type : "routerModels" ,
218+ routerModels : fetchedRouterModels as Record < RouterName , ModelRecord > ,
219+ } )
220+ }
221+ }
222+ } catch ( error ) {
223+ provider . log (
224+ `Error auto-fetching router models: ${ JSON . stringify ( error , Object . getOwnPropertyNames ( error ) , 2 ) } ` ,
225+ )
226+ }
227+ } , 1000 ) // 1 second delay
228+
120229 provider . isViewLaunched = true
121230 break
122231 case "newTask" :
@@ -289,75 +398,65 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
289398 case "requestRouterModels" :
290399 const { apiConfiguration } = await provider . getState ( )
291400
292- const routerModels : Partial < Record < RouterName , ModelRecord > > = {
293- openrouter : { } ,
294- requesty : { } ,
295- glama : { } ,
296- unbound : { } ,
297- litellm : { } ,
298- }
401+ // 只请求用户配置的提供商的模型列表
402+ const promises = [ ]
403+ const routerNames = [ ]
299404
300- const safeGetModels = async ( options : GetModelsOptions ) : Promise < ModelRecord > => {
301- try {
302- return await getModels ( options )
303- } catch ( error ) {
304- console . error (
305- `Failed to fetch models in webviewMessageHandler requestRouterModels for ${ options . provider } :` ,
306- error ,
307- )
308- throw error // Re-throw to be caught by Promise.allSettled
309- }
405+ // 只有在用户配置了API密钥时才请求相应提供商的模型列表
406+ if ( apiConfiguration . openRouterApiKey ) {
407+ promises . push ( getModels ( { provider : "openrouter" } ) )
408+ routerNames . push ( "openrouter" )
310409 }
311410
312- const modelFetchPromises : Array < { key : RouterName ; options : GetModelsOptions } > = [
313- { key : "openrouter" , options : { provider : "openrouter" } } ,
314- { key : "requesty" , options : { provider : "requesty" , apiKey : apiConfiguration . requestyApiKey } } ,
315- { key : "glama" , options : { provider : "glama" } } ,
316- { key : "unbound" , options : { provider : "unbound" , apiKey : apiConfiguration . unboundApiKey } } ,
317- ]
411+ if ( apiConfiguration . requestyApiKey ) {
412+ promises . push ( getModels ( { provider : "requesty" , apiKey : apiConfiguration . requestyApiKey } ) )
413+ routerNames . push ( "requesty" )
414+ }
318415
319- const litellmApiKey = apiConfiguration . litellmApiKey || message ?. values ?. litellmApiKey
320- const litellmBaseUrl = apiConfiguration . litellmBaseUrl || message ?. values ?. litellmBaseUrl
321- if ( litellmApiKey && litellmBaseUrl ) {
322- modelFetchPromises . push ( {
323- key : "litellm" ,
324- options : { provider : "litellm" , apiKey : litellmApiKey , baseUrl : litellmBaseUrl } ,
325- } )
416+ if ( apiConfiguration . glamaApiKey ) {
417+ promises . push ( getModels ( { provider : "glama" } ) )
418+ routerNames . push ( "glama" )
326419 }
327420
328- const results = await Promise . allSettled (
329- modelFetchPromises . map ( async ( { key, options } ) => {
330- const models = await safeGetModels ( options )
331- return { key, models } // key is RouterName here
332- } ) ,
333- )
421+ if ( apiConfiguration . unboundApiKey ) {
422+ promises . push ( getModels ( { provider : "unbound" , apiKey : apiConfiguration . unboundApiKey } ) )
423+ routerNames . push ( "unbound" )
424+ }
334425
335- const fetchedRouterModels : Partial < Record < RouterName , ModelRecord > > = { ...routerModels }
426+ if ( apiConfiguration . litellmApiKey && apiConfiguration . litellmBaseUrl ) {
427+ promises . push (
428+ getModels ( {
429+ provider : "litellm" ,
430+ apiKey : apiConfiguration . litellmApiKey ,
431+ baseUrl : apiConfiguration . litellmBaseUrl ,
432+ } ) ,
433+ )
434+ routerNames . push ( "litellm" )
435+ }
336436
337- results . forEach ( ( result , index ) => {
338- const routerName = modelFetchPromises [ index ] . key // Get RouterName using index
437+ // Use Promise.allSettled to handle API failures gracefully
438+ const results = await Promise . allSettled ( promises )
339439
340- if ( result . status === "fulfilled" ) {
341- fetchedRouterModels [ routerName ] = result . value . models
342- } else {
343- // Handle rejection: Post a specific error message for this provider
344- const errorMessage = result . reason instanceof Error ? result . reason . message : String ( result . reason )
345- console . error ( `Error fetching models for ${ routerName } :` , result . reason )
440+ // Extract results, using empty objects for any failed requests
441+ const modelResults = results . map ( ( result ) => ( result . status === "fulfilled" ? result . value : { } ) )
346442
347- fetchedRouterModels [ routerName ] = { } // Ensure it's an empty object in the main routerModels message
443+ // Build routerModels object with all providers
444+ const routerModels = {
445+ openrouter : { } ,
446+ requesty : { } ,
447+ glama : { } ,
448+ unbound : { } ,
449+ litellm : { } ,
450+ }
348451
349- provider . postMessageToWebview ( {
350- type : "singleRouterModelFetchResponse" ,
351- success : false ,
352- error : errorMessage ,
353- values : { provider : routerName } ,
354- } )
355- }
452+ // Assign results to corresponding providers
453+ routerNames . forEach ( ( name , index ) => {
454+ routerModels [ name as RouterName ] = modelResults [ index ]
356455 } )
357456
358457 provider . postMessageToWebview ( {
359458 type : "routerModels" ,
360- routerModels : fetchedRouterModels as Record < RouterName , ModelRecord > ,
459+ routerModels,
361460 } )
362461 break
363462 case "requestOpenAiModels" :
0 commit comments