@@ -27,6 +27,7 @@ import { getOllamaModels } from "./ollama"
2727import { getLMStudioModels } from "./lmstudio"
2828import { getPoeModels } from "./poe"
2929import { getDeepSeekModels } from "./deepseek"
30+ import { getZooGatewayModels } from "./zoo-gateway"
3031
3132const memoryCache = new NodeCache ( { stdTTL : 5 * 60 , checkperiod : 5 * 60 } )
3233
@@ -96,6 +97,9 @@ async function fetchModelsFromProvider(options: GetModelsOptions): Promise<Model
9697 case "deepseek" :
9798 models = await getDeepSeekModels ( options . baseUrl , options . apiKey )
9899 break
100+ case "zoo-gateway" :
101+ models = await getZooGatewayModels ( { zooSessionToken : options . apiKey , zooGatewayBaseUrl : options . baseUrl } )
102+ break
99103 default : {
100104 // Ensures router is exhaustively checked if RouterName is a strict union.
101105 const exhaustiveCheck : never = provider
@@ -120,7 +124,10 @@ async function fetchModelsFromProvider(options: GetModelsOptions): Promise<Model
120124export const getModels = async ( options : GetModelsOptions ) : Promise < ModelRecord > => {
121125 const { provider } = options
122126
123- let models = getModelsFromCache ( provider )
127+ // Always fetch fresh to prevent serving stale models from different auth contexts.
128+ const shouldSkipCache = provider === "zoo-gateway"
129+
130+ let models = shouldSkipCache ? undefined : getModelsFromCache ( provider )
124131
125132 if ( models ) {
126133 return models
@@ -132,13 +139,14 @@ export const getModels = async (options: GetModelsOptions): Promise<ModelRecord>
132139
133140 // Only cache non-empty results to prevent persisting failed API responses
134141 // Empty results could indicate API failure rather than "no models exist"
135- if ( modelCount > 0 ) {
142+ // Zoo Gateway models are user-specific - skip caching entirely
143+ if ( modelCount > 0 && ! shouldSkipCache ) {
136144 memoryCache . set ( provider , models )
137145
138146 await writeModels ( provider , models ) . catch ( ( err ) =>
139147 console . error ( `[MODEL_CACHE] Error writing ${ provider } models to file cache:` , err ) ,
140148 )
141- } else {
149+ } else if ( modelCount === 0 ) {
142150 TelemetryService . instance . captureEvent ( TelemetryEventName . MODEL_CACHE_EMPTY_RESPONSE , {
143151 provider,
144152 context : "getModels" ,
@@ -167,6 +175,11 @@ export const getModels = async (options: GetModelsOptions): Promise<ModelRecord>
167175export const refreshModels = async ( options : GetModelsOptions ) : Promise < ModelRecord > => {
168176 const { provider } = options
169177
178+ // Zoo Gateway models are user-specific (auth-scoped). Mirror the bypass in
179+ // getModels() so we never persist one user's model list and serve it to a
180+ // different authenticated user from cache.
181+ const shouldSkipCache = provider === "zoo-gateway"
182+
170183 // Check if there's already an in-flight refresh for this provider
171184 // This prevents race conditions where multiple concurrent refreshes might
172185 // overwrite each other's results
@@ -183,7 +196,7 @@ export const refreshModels = async (options: GetModelsOptions): Promise<ModelRec
183196 const modelCount = Object . keys ( models ) . length
184197
185198 // Get existing cached data for comparison
186- const existingCache = getModelsFromCache ( provider )
199+ const existingCache = shouldSkipCache ? undefined : getModelsFromCache ( provider )
187200 const existingCount = existingCache ? Object . keys ( existingCache ) . length : 0
188201
189202 if ( modelCount === 0 ) {
@@ -200,18 +213,23 @@ export const refreshModels = async (options: GetModelsOptions): Promise<ModelRec
200213 }
201214 }
202215
203- // Update memory cache first
204- memoryCache . set ( provider , models )
216+ if ( ! shouldSkipCache ) {
217+ memoryCache . set ( provider , models )
205218
206- // Atomically write to disk (safeWriteJson handles atomic writes)
207- await writeModels ( provider , models ) . catch ( ( err ) =>
208- console . error ( `[refreshModels] Error writing ${ provider } models to disk:` , err ) ,
209- )
219+ await writeModels ( provider , models ) . catch ( ( err ) =>
220+ console . error ( `[refreshModels] Error writing ${ provider } models to disk:` , err ) ,
221+ )
222+ }
210223
211224 return models
212225 } catch ( error ) {
213- // Log the error for debugging, then return existing cache if available (graceful degradation)
226+ // Log the error for debugging, then return existing cache if available (graceful degradation).
227+ // For auth-scoped providers (zoo-gateway) we MUST NOT return cached models from a prior
228+ // session, since they could belong to a different user — return empty instead.
214229 console . error ( `[refreshModels] Failed to refresh ${ provider } models:` , error )
230+ if ( shouldSkipCache ) {
231+ return { }
232+ }
215233 return getModelsFromCache ( provider ) || { }
216234 } finally {
217235 // Always clean up the in-flight tracking
0 commit comments