@@ -377,6 +377,58 @@ describe("webviewMessageHandler - requestRouterModels", () => {
377377 } )
378378 } )
379379
380+ it ( "recovers zoo-gateway credentials from a separate profile when not the active provider" , async ( ) => {
381+ // Regression: when zoo-gateway is NOT the active provider, the active apiConfiguration
382+ // will not contain zooSessionToken / zooGatewayBaseUrl. The aggregate model fetcher must
383+ // fall back to scanning providerSettingsManager profiles for a zoo-gateway entry so the
384+ // model picker still populates.
385+ mockClineProvider . getState = vi . fn ( ) . mockResolvedValue ( {
386+ apiConfiguration : {
387+ // Active provider is anthropic (or anything other than zoo-gateway).
388+ apiProvider : "anthropic" ,
389+ openRouterApiKey : "openrouter-key" ,
390+ requestyApiKey : "requesty-key" ,
391+ // No zooSessionToken / zooGatewayBaseUrl on the active config.
392+ } ,
393+ } )
394+ ; ( mockClineProvider as any ) . providerSettingsManager = {
395+ listConfig : vi . fn ( ) . mockResolvedValue ( [
396+ { name : "Anthropic" , apiProvider : "anthropic" } ,
397+ { name : "My Zoo Gateway Profile" , apiProvider : "zoo-gateway" } ,
398+ ] ) ,
399+ getProfile : vi . fn ( ) . mockResolvedValue ( {
400+ apiProvider : "zoo-gateway" ,
401+ zooSessionToken : "recovered-zoo-token" ,
402+ zooGatewayBaseUrl : "https://zoo.example.com/api/gateway/v1" ,
403+ } ) ,
404+ }
405+
406+ const mockModels : ModelRecord = {
407+ "model-1" : {
408+ maxTokens : 4096 ,
409+ contextWindow : 8192 ,
410+ supportsPromptCache : false ,
411+ description : "Test model 1" ,
412+ } ,
413+ }
414+ mockGetModels . mockResolvedValue ( mockModels )
415+
416+ await webviewMessageHandler ( mockClineProvider , { type : "requestRouterModels" } )
417+
418+ expect ( ( mockClineProvider as any ) . providerSettingsManager . listConfig ) . toHaveBeenCalled ( )
419+ expect ( ( mockClineProvider as any ) . providerSettingsManager . getProfile ) . toHaveBeenCalledWith ( {
420+ name : "My Zoo Gateway Profile" ,
421+ } )
422+ expect ( mockGetModels ) . toHaveBeenCalledWith ( {
423+ provider : "zoo-gateway" ,
424+ apiKey : "recovered-zoo-token" ,
425+ baseUrl : "https://zoo.example.com/api/gateway/v1" ,
426+ } )
427+
428+ // Reset to avoid bleeding into other tests
429+ delete ( mockClineProvider as any ) . providerSettingsManager
430+ } )
431+
380432 it ( "handles LiteLLM models with values from message when config is missing" , async ( ) => {
381433 mockClineProvider . getState = vi . fn ( ) . mockResolvedValue ( {
382434 apiConfiguration : {
0 commit comments