Project Files
dist / retrieval / embeddingCache.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEmbeddingModel = getEmbeddingModel;
exports.clearEmbeddingModelCache = clearEmbeddingModelCache;
let cachedModel = null;
// ── Loop prevention: concurrent-load deduplication ────────────────────────
// Without this, N parallel preprocess() calls that all observe cachedModel===null
// each race to call embedding.model(), launching N simultaneous load operations.
// Only the last one's result would survive (stored to cachedModel), the others
// are silently discarded — but the wasted round-trips can stall the pipeline
// long enough for a timeout, which the caller treats as a failure, which triggers
// an immediate retry, creating a tight retry loop.
// Sharing one in-flight Promise collapses all concurrent callers onto a single
// load operation and eliminates that source of looping.
let loadingPromise = null;
async function getEmbeddingModel(ctl) {
if (cachedModel !== null)
return cachedModel;
// Return the existing in-flight promise so concurrent callers share one load.
if (loadingPromise !== null)
return loadingPromise;
loadingPromise = ctl.client.embedding
.model("nomic-ai/nomic-embed-text-v1.5-GGUF", { signal: ctl.abortSignal })
.then((model) => {
cachedModel = model;
loadingPromise = null;
return model;
})
.catch((error) => {
// Reset both slots so the next caller retries from a clean state rather
// than perpetually awaiting a rejected promise.
cachedModel = null;
loadingPromise = null;
throw error;
});
return loadingPromise;
}
/** Force re-resolution of the embedding model (e.g. after a hot-reload). */
function clearEmbeddingModelCache() {
cachedModel = null;
loadingPromise = null;
}