@@ -26,6 +26,7 @@ import { getOllamaModels } from "./ollama"
2626import { getLMStudioModels } from "./lmstudio"
2727import { getPoeModels } from "./poe"
2828import { getDeepSeekModels } from "./deepseek"
29+ import { getZooGatewayModels } from "./zoo-gateway"
2930
3031const memoryCache = new NodeCache ( { stdTTL : 5 * 60 , checkperiod : 5 * 60 } )
3132
@@ -92,6 +93,9 @@ async function fetchModelsFromProvider(options: GetModelsOptions): Promise<Model
9293 case "deepseek" :
9394 models = await getDeepSeekModels ( options . baseUrl , options . apiKey )
9495 break
96+ case "zoo-gateway" :
97+ models = await getZooGatewayModels ( { zooSessionToken : options . apiKey , zooGatewayBaseUrl : options . baseUrl } )
98+ break
9599 default : {
96100 // Ensures router is exhaustively checked if RouterName is a strict union.
97101 const exhaustiveCheck : never = provider
@@ -116,7 +120,10 @@ async function fetchModelsFromProvider(options: GetModelsOptions): Promise<Model
116120export const getModels = async ( options : GetModelsOptions ) : Promise < ModelRecord > => {
117121 const { provider } = options
118122
119- let models = getModelsFromCache ( provider )
123+ // Always fetch fresh to prevent serving stale models from different auth contexts.
124+ const shouldSkipCache = provider === "zoo-gateway"
125+
126+ let models = shouldSkipCache ? undefined : getModelsFromCache ( provider )
120127
121128 if ( models ) {
122129 return models
@@ -128,13 +135,14 @@ export const getModels = async (options: GetModelsOptions): Promise<ModelRecord>
128135
129136 // Only cache non-empty results to prevent persisting failed API responses
130137 // Empty results could indicate API failure rather than "no models exist"
131- if ( modelCount > 0 ) {
138+ // Zoo Gateway models are user-specific - skip caching entirely
139+ if ( modelCount > 0 && ! shouldSkipCache ) {
132140 memoryCache . set ( provider , models )
133141
134142 await writeModels ( provider , models ) . catch ( ( err ) =>
135143 console . error ( `[MODEL_CACHE] Error writing ${ provider } models to file cache:` , err ) ,
136144 )
137- } else {
145+ } else if ( modelCount === 0 ) {
138146 TelemetryService . instance . captureEvent ( TelemetryEventName . MODEL_CACHE_EMPTY_RESPONSE , {
139147 provider,
140148 context : "getModels" ,
@@ -163,6 +171,11 @@ export const getModels = async (options: GetModelsOptions): Promise<ModelRecord>
163171export const refreshModels = async ( options : GetModelsOptions ) : Promise < ModelRecord > => {
164172 const { provider } = options
165173
174+ // Zoo Gateway models are user-specific (auth-scoped). Mirror the bypass in
175+ // getModels() so we never persist one user's model list and serve it to a
176+ // different authenticated user from cache.
177+ const shouldSkipCache = provider === "zoo-gateway"
178+
166179 // Check if there's already an in-flight refresh for this provider
167180 // This prevents race conditions where multiple concurrent refreshes might
168181 // overwrite each other's results
@@ -179,7 +192,7 @@ export const refreshModels = async (options: GetModelsOptions): Promise<ModelRec
179192 const modelCount = Object . keys ( models ) . length
180193
181194 // Get existing cached data for comparison
182- const existingCache = getModelsFromCache ( provider )
195+ const existingCache = shouldSkipCache ? undefined : getModelsFromCache ( provider )
183196 const existingCount = existingCache ? Object . keys ( existingCache ) . length : 0
184197
185198 if ( modelCount === 0 ) {
@@ -196,18 +209,23 @@ export const refreshModels = async (options: GetModelsOptions): Promise<ModelRec
196209 }
197210 }
198211
199- // Update memory cache first
200- memoryCache . set ( provider , models )
212+ if ( ! shouldSkipCache ) {
213+ memoryCache . set ( provider , models )
201214
202- // Atomically write to disk (safeWriteJson handles atomic writes)
203- await writeModels ( provider , models ) . catch ( ( err ) =>
204- console . error ( `[refreshModels] Error writing ${ provider } models to disk:` , err ) ,
205- )
215+ await writeModels ( provider , models ) . catch ( ( err ) =>
216+ console . error ( `[refreshModels] Error writing ${ provider } models to disk:` , err ) ,
217+ )
218+ }
206219
207220 return models
208221 } catch ( error ) {
209- // Log the error for debugging, then return existing cache if available (graceful degradation)
222+ // Log the error for debugging, then return existing cache if available (graceful degradation).
223+ // For auth-scoped providers (zoo-gateway) we MUST NOT return cached models from a prior
224+ // session, since they could belong to a different user — return empty instead.
210225 console . error ( `[refreshModels] Failed to refresh ${ provider } models:` , error )
226+ if ( shouldSkipCache ) {
227+ return { }
228+ }
211229 return getModelsFromCache ( provider ) || { }
212230 } finally {
213231 // Always clean up the in-flight tracking
0 commit comments