From 68431dee46c58e942d827476b9ec5343125caa7f Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Mon, 20 Jul 2026 15:49:36 -0400 Subject: [PATCH] Replace stale model files when the model revision changes download() skipped every existing file, so after a revision bump the old files were kept and then marked as the new revision. Stamp the directory with the revision being downloaded and clear it on mismatch, so bumps replace the files while interrupted downloads of the same revision still resume. --- chrome/content/zotero/xpcom/embeddings.js | 26 ++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/chrome/content/zotero/xpcom/embeddings.js b/chrome/content/zotero/xpcom/embeddings.js index 07fe12be2a..7bde528cb9 100644 --- a/chrome/content/zotero/xpcom/embeddings.js +++ b/chrome/content/zotero/xpcom/embeddings.js @@ -85,6 +85,11 @@ Zotero.Embeddings = new function () { // that isDownloaded() doesn't have to re-check each file on every call. const MARKER_FILE = '.download-complete.json'; + // Written into the model directory before the first file is downloaded, + // so download() can tell a resumable partial download of the current + // revision from stale files that have to be replaced. + const REVISION_MARKER_FILE = '.download-revision.json'; + const SUBDIR = 'embeddings'; /** @@ -375,9 +380,10 @@ Zotero.Embeddings = new function () { }; /** - * Download the active model's files into its directory. Files that already - * exist are skipped, so this can be safely called again to resume after a - * failure. On success a completion marker is written. + * Download the active model's files into its directory. Files already + * downloaded for the same revision are skipped, so this can be safely + * called again to resume after a failure. On success a completion marker + * is written. * * @return {Promise} - Path to the model directory */ @@ -392,7 +398,21 @@ Zotero.Embeddings = new function () { } Zotero.debug(`Embeddings: downloading model '${this.getModelName()}' from ${baseURL}`); + // A revision marker is written before the first file, so files from a + // partial download of the same revision can be kept for resuming while + // anything else -- e.g. a complete download of an older revision, + // whose files _downloadFile() would otherwise keep -- is replaced + let revisionPath = PathUtils.join(dir, REVISION_MARKER_FILE); + let downloadingRevision = null; + try { + downloadingRevision = JSON.parse(await Zotero.File.getContentsAsync(revisionPath)).revision; + } + catch {} + if (downloadingRevision !== model.revision) { + await IOUtils.remove(dir, { recursive: true, ignoreAbsent: true }); + } await Zotero.File.createDirectoryIfMissingAsync(dir, { from: Zotero.DataDirectory.dir }); + await Zotero.File.putContentsAsync(revisionPath, JSON.stringify({ revision: model.revision })); for (let file of model.files) { await _downloadFile(baseURL + file, dir, file);