@@ -16,6 +16,7 @@ import { ConfigManager } from '../store/config'
1616import { generateManagementSecret } from '../proxy/middleware/managementAuth'
1717import type { Provider , Account , ProxyStatus , ProviderCheckResult , OAuthResult , AuthType , CredentialField , LogLevel , LogEntry , ProviderVendor , AppConfig } from '../../shared/types'
1818import type { SystemPrompt , SessionConfig , SessionRecord , ManagementApiConfig } from '../store/types'
19+ import type { ProviderType } from '../oauth/types'
1920
2021let proxyServer : ProxyServer | null = null
2122let proxyStartTime : number | null = null
@@ -291,6 +292,155 @@ export async function registerIpcHandlers(mainWindow: BrowserWindow | null): Pro
291292 return CustomProviderManager . importProvider ( jsonData )
292293 } )
293294
295+ ipcMain . handle ( IpcChannels . PROVIDERS_SYNC_MODELS , async ( _ , providerId : string ) : Promise < {
296+ success : boolean
297+ supportedModels ?: string [ ]
298+ modelMappings ?: Record < string , string >
299+ error ?: string
300+ } > => {
301+ try {
302+ const result = await ProviderChecker . fetchProviderModels ( providerId )
303+
304+ const provider = ProviderManager . getById ( providerId )
305+ if ( provider ) {
306+ ProviderManager . update ( providerId , {
307+ supportedModels : result . supportedModels ,
308+ modelMappings : result . modelMappings ,
309+ } )
310+ }
311+
312+ return {
313+ success : true ,
314+ supportedModels : result . supportedModels ,
315+ modelMappings : result . modelMappings ,
316+ }
317+ } catch ( error ) {
318+ return {
319+ success : false ,
320+ error : error instanceof Error ? error . message : 'Failed to sync models' ,
321+ }
322+ }
323+ } )
324+
325+ ipcMain . handle ( IpcChannels . PROVIDERS_UPDATE_MODELS , async ( _ , providerId : string ) : Promise < {
326+ success : boolean
327+ modelsCount ?: number
328+ error ?: string
329+ } > => {
330+ try {
331+ const provider = ProviderManager . getById ( providerId )
332+
333+ if ( ! provider ) {
334+ return {
335+ success : false ,
336+ error : 'Provider not found' ,
337+ }
338+ }
339+
340+ let modelsApiEndpoint : string | undefined
341+ let modelsApiHeaders : Record < string , string > | undefined
342+
343+ if ( provider . type === 'builtin' ) {
344+ const builtinConfig = getBuiltinProvider ( providerId )
345+ if ( builtinConfig ) {
346+ modelsApiEndpoint = builtinConfig . modelsApiEndpoint
347+ modelsApiHeaders = builtinConfig . modelsApiHeaders
348+ }
349+ }
350+
351+ if ( ! modelsApiEndpoint ) {
352+ return {
353+ success : false ,
354+ error : 'This provider does not support dynamic model updates' ,
355+ }
356+ }
357+
358+ // Try to get an active account for authentication (include credentials)
359+ const accounts = AccountManager . getByProviderId ( providerId , true )
360+ const activeAccount = accounts . find ( a => a . status === 'active' )
361+
362+ // Build request headers with optional authentication
363+ const requestHeaders : Record < string , string > = {
364+ 'Content-Type' : 'application/json' ,
365+ Accept : 'application/json' ,
366+ ...modelsApiHeaders ,
367+ }
368+
369+ // Add authorization header if account exists
370+ if ( activeAccount ?. credentials ?. token ) {
371+ requestHeaders [ 'Authorization' ] = `Bearer ${ activeAccount . credentials . token } `
372+ }
373+
374+ // Add cookie header if account has cookies (required for qwen-ai)
375+ if ( activeAccount ?. credentials ?. cookies ) {
376+ requestHeaders [ 'Cookie' ] = activeAccount . credentials . cookies
377+ }
378+
379+ const response = await axios . get ( modelsApiEndpoint , {
380+ headers : requestHeaders ,
381+ timeout : 15000 ,
382+ validateStatus : ( ) => true ,
383+ } )
384+
385+ if ( response . status !== 200 ) {
386+ return {
387+ success : false ,
388+ error : `Failed to fetch models: HTTP ${ response . status } ` ,
389+ }
390+ }
391+
392+ const models = response . data . data || response . data
393+
394+ if ( ! Array . isArray ( models ) || models . length === 0 ) {
395+ return {
396+ success : false ,
397+ error : 'No models found in the response' ,
398+ }
399+ }
400+
401+ const supportedModels : string [ ] = [ ]
402+ const modelMappings : Record < string , string > = { }
403+
404+ models . forEach ( ( model : any ) => {
405+ if ( typeof model === 'string' ) {
406+ supportedModels . push ( model )
407+ modelMappings [ model ] = model
408+ } else if ( model && typeof model === 'object' ) {
409+ const modelId = model . id || model . model_id || model . name
410+ const modelName = model . name || model . display_name || modelId
411+
412+ if ( modelId ) {
413+ supportedModels . push ( modelName || modelId )
414+ modelMappings [ modelName || modelId ] = modelId
415+ }
416+ }
417+ } )
418+
419+ if ( supportedModels . length === 0 ) {
420+ return {
421+ success : false ,
422+ error : 'Failed to parse models from the response' ,
423+ }
424+ }
425+
426+ ProviderManager . update ( providerId , {
427+ supportedModels,
428+ modelMappings,
429+ } )
430+
431+ return {
432+ success : true ,
433+ modelsCount : supportedModels . length ,
434+ }
435+ } catch ( error ) {
436+ console . error ( '[IPC] Failed to update models:' , error )
437+ return {
438+ success : false ,
439+ error : error instanceof Error ? error . message : 'Failed to update models' ,
440+ }
441+ }
442+ } )
443+
294444 ipcMain . handle ( IpcChannels . ACCOUNTS_GET_ALL , async ( _ , includeCredentials ?: boolean ) : Promise < Account [ ] > => {
295445 return AccountManager . getAll ( includeCredentials )
296446 } )
@@ -455,7 +605,7 @@ export async function registerIpcHandlers(mainWindow: BrowserWindow | null): Pro
455605 console . log ( 'Starting OAuth login:' , providerId , providerType )
456606 return await oauthManager . startLogin ( {
457607 providerId,
458- providerType,
608+ providerType : providerType as ProviderType ,
459609 } )
460610 } )
461611
@@ -465,14 +615,14 @@ export async function registerIpcHandlers(mainWindow: BrowserWindow | null): Pro
465615 } )
466616
467617 ipcMain . handle ( IpcChannels . OAUTH_LOGIN_WITH_TOKEN , async ( _ , data : { providerId : string , providerType : ProviderVendor , token : string , realUserID ?: string , mimoUserId ?: string , mimoPhToken ?: string } ) : Promise < OAuthResult > => {
468- return await oauthManager . loginWithToken ( data . providerId , data . providerType , data . token , data . realUserID , data . mimoUserId , data . mimoPhToken )
618+ return await oauthManager . loginWithToken ( data . providerId , data . providerType as ProviderType , data . token , data . realUserID , data . mimoUserId , data . mimoPhToken )
469619 } )
470620
471621 ipcMain . handle ( IpcChannels . OAUTH_START_IN_APP_LOGIN , async ( _ , data : { providerId : string , providerType : ProviderVendor , timeout ?: number } ) : Promise < OAuthResult > => {
472622 console . log ( 'Starting in-app OAuth login:' , data . providerId , data . providerType )
473623 const config = storeManager . getConfig ( )
474624 const proxyMode = ( config as any ) . oauthProxyMode || 'system'
475- return await oauthManager . startInAppLogin ( data . providerId , data . providerType , data . timeout , proxyMode )
625+ return await oauthManager . startInAppLogin ( data . providerId , data . providerType as ProviderType , data . timeout , proxyMode )
476626 } )
477627
478628 ipcMain . handle ( IpcChannels . OAUTH_CANCEL_IN_APP_LOGIN , async ( ) : Promise < void > => {
@@ -485,11 +635,11 @@ export async function registerIpcHandlers(mainWindow: BrowserWindow | null): Pro
485635 } )
486636
487637 ipcMain . handle ( IpcChannels . OAUTH_VALIDATE_TOKEN , async ( _ , data : { providerId : string , providerType : ProviderVendor , credentials : Record < string , string > } ) => {
488- return await oauthManager . validateToken ( data . providerId , data . providerType , data . credentials )
638+ return await oauthManager . validateToken ( data . providerId , data . providerType as ProviderType , data . credentials )
489639 } )
490640
491641 ipcMain . handle ( IpcChannels . OAUTH_REFRESH_TOKEN , async ( _ , data : { providerId : string , providerType : ProviderVendor , credentials : Record < string , string > } ) => {
492- return await oauthManager . refreshToken ( data . providerId , data . providerType , data . credentials )
642+ return await oauthManager . refreshToken ( data . providerId , data . providerType as ProviderType , data . credentials )
493643 } )
494644
495645 ipcMain . handle ( IpcChannels . OAUTH_GET_STATUS , async ( ) : Promise < string > => {
0 commit comments