MCPcopy Create free account
hub / github.com/Zoo-Code-Org/Zoo-Code / refreshModels

Function refreshModels

src/api/providers/fetchers/modelCache.ts:294–376  ·  view source on GitHub ↗
(options: GetModelsOptions)

Source from the content-addressed store, hash-verified

292 * @returns Fresh models from API, or existing cache if refresh yields worse data
293 */
294export const refreshModels = async (options: GetModelsOptions): Promise<ModelRecord> => {
295 const { provider } = options
296 const cacheKey = getCacheKey(options)
297
298 const shouldSkipCache = isAuthScopedProvider(provider)
299
300 // Check if there's already an in-flight refresh for this provider+url combination.
301 // This prevents race conditions where multiple concurrent refreshes might
302 // overwrite each other's results. Skip de-duplication for auth-scoped
303 // providers because two concurrent calls may carry different tokens
304 // (e.g., after a sign-out/sign-in within the same session) and we must
305 // not return the first caller's results to the second caller.
306 if (!shouldSkipCache) {
307 const existingRequest = inFlightRefresh.get(cacheKey)
308 if (existingRequest) {
309 return existingRequest
310 }
311 }
312
313 // Create the refresh promise and track it.
314 //
315 // The `finally` cleanup below runs only after the first `await` inside this async
316 // function yields, which cannot happen until the current synchronous run -- including
317 // the `inFlightRefresh.set(cacheKey, ...)` registration below -- has completed. So the
318 // entry is always present in the map before `finally` can delete it; the registration
319 // can never be lost to a microtask race even if the fetch resolves immediately.
320 const refreshPromise = (async (): Promise<ModelRecord> => {
321 try {
322 // Force fresh API fetch - skip getModelsFromCache() check
323 const models = await fetchModelsFromProvider(options)
324 const modelCount = Object.keys(models).length
325
326 // Get existing cached data for comparison
327 const existingCache = shouldSkipCache ? undefined : getModelsFromCache(options)
328 const existingCount = existingCache ? Object.keys(existingCache).length : 0
329
330 if (modelCount === 0) {
331 TelemetryService.instance.captureEvent(TelemetryEventName.MODEL_CACHE_EMPTY_RESPONSE, {
332 provider,
333 context: "refreshModels",
334 hasExistingCache: existingCount > 0,
335 existingCacheSize: existingCount,
336 })
337 if (existingCount > 0) {
338 return existingCache!
339 } else {
340 return {}
341 }
342 }
343
344 if (!shouldSkipCache) {
345 memoryCache.set(cacheKey, models)
346
347 await writeModels(cacheKey, models).catch((err) =>
348 console.error(`[refreshModels] Error writing ${cacheKey} models to disk:`, err),
349 )
350 }
351

Callers 3

flushModelsFunction · 0.85
modelCache.spec.tsFile · 0.85

Calls 11

isAuthScopedProviderFunction · 0.85
fetchModelsFromProviderFunction · 0.85
getModelsFromCacheFunction · 0.85
writeModelsFunction · 0.85
getCacheKeyFunction · 0.70
getMethod · 0.65
keysMethod · 0.65
setMethod · 0.65
errorMethod · 0.65
deleteMethod · 0.65
captureEventMethod · 0.45

Tested by

no test coverage detected