@@ -43,6 +43,7 @@ vi.mock("fs", () => ({
4343vi . mock ( "../litellm" )
4444vi . mock ( "../openrouter" )
4545vi . mock ( "../requesty" )
46+ vi . mock ( "../zoo-gateway" )
4647
4748// Mock ContextProxy with a simple static instance
4849vi . mock ( "../../../core/config/ContextProxy" , ( ) => ( {
@@ -64,10 +65,12 @@ import { getModels, getModelsFromCache } from "../modelCache"
6465import { getLiteLLMModels } from "../litellm"
6566import { getOpenRouterModels } from "../openrouter"
6667import { getRequestyModels } from "../requesty"
68+ import { getZooGatewayModels } from "../zoo-gateway"
6769
6870const mockGetLiteLLMModels = getLiteLLMModels as Mock < typeof getLiteLLMModels >
6971const mockGetOpenRouterModels = getOpenRouterModels as Mock < typeof getOpenRouterModels >
7072const mockGetRequestyModels = getRequestyModels as Mock < typeof getRequestyModels >
73+ const mockGetZooGatewayModels = getZooGatewayModels as Mock < typeof getZooGatewayModels >
7174
7275const DUMMY_REQUESTY_KEY = "requesty-key-for-testing"
7376
@@ -296,6 +299,39 @@ describe("empty cache protection", () => {
296299 expect ( result ) . toEqual ( mockModels )
297300 expect ( mockSet ) . toHaveBeenCalledWith ( "openrouter" , mockModels )
298301 } )
302+
303+ it ( "re-arms the empty-response throttle after a non-empty response from an auth-scoped provider" , async ( ) => {
304+ // zoo-gateway is auth-scoped and skips caching entirely, but a non-empty response
305+ // must still clear the empty-response throttle so a later empty response is reported again.
306+ mockGetZooGatewayModels . mockResolvedValueOnce ( { } )
307+
308+ await getModels ( { provider : "zoo-gateway" , apiKey : "test-key" } )
309+
310+ expect ( TelemetryService . instance . captureEvent ) . toHaveBeenCalledTimes ( 1 )
311+
312+ const mockModels = {
313+ "zoo-gateway/model" : {
314+ maxTokens : 8192 ,
315+ contextWindow : 128000 ,
316+ supportsPromptCache : false ,
317+ description : "Zoo Gateway model" ,
318+ } ,
319+ }
320+ mockGetZooGatewayModels . mockResolvedValueOnce ( mockModels )
321+
322+ await getModels ( { provider : "zoo-gateway" , apiKey : "test-key" } )
323+
324+ // Auth-scoped providers never populate the cache.
325+ expect ( mockSet ) . not . toHaveBeenCalled ( )
326+
327+ mockGetZooGatewayModels . mockResolvedValueOnce ( { } )
328+
329+ await getModels ( { provider : "zoo-gateway" , apiKey : "test-key" } )
330+
331+ // The throttle should have been re-armed by the non-empty response above, so this
332+ // second empty response is reported again instead of being suppressed.
333+ expect ( TelemetryService . instance . captureEvent ) . toHaveBeenCalledTimes ( 2 )
334+ } )
299335 } )
300336
301337 describe ( "refreshModels" , ( ) => {
0 commit comments