From 51c83bbbc81a8aeec2a50923c19c51b36e5051a7 Mon Sep 17 00:00:00 2001 From: perf3ct Date: Sat, 8 Mar 2025 23:21:21 +0000 Subject: [PATCH] show fancier stats --- .../type_widgets/options/ai_settings.ts | 29 ++++++++++++++++++- src/public/translations/en/translation.json | 4 +++ src/services/llm/embeddings/vector_store.ts | 21 +++++++++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/public/app/widgets/type_widgets/options/ai_settings.ts b/src/public/app/widgets/type_widgets/options/ai_settings.ts index 749c54a6e..fd666958b 100644 --- a/src/public/app/widgets/type_widgets/options/ai_settings.ts +++ b/src/public/app/widgets/type_widgets/options/ai_settings.ts @@ -201,7 +201,10 @@ export default class AiSettingsWidget extends OptionsWidget {
${t("ai_llm.queued_notes")}: -
${t("ai_llm.failed_notes")}: -
${t("ai_llm.last_processed")}: -
-
+
+ ${t("ai_llm.progress")}: - +
+
0%
@@ -456,6 +459,30 @@ export default class AiSettingsWidget extends OptionsWidget { $progressBar.css('width', `${stats.percentComplete}%`); $progressBar.attr('aria-valuenow', stats.percentComplete.toString()); $progressBar.text(`${stats.percentComplete}%`); + + // Update status text based on state + const $statusText = this.$widget.find('.embedding-status-text'); + if (stats.queuedNotesCount > 0) { + $statusText.text(t("ai_llm.processing", { percentage: stats.percentComplete })); + } else if (stats.percentComplete < 100) { + $statusText.text(t("ai_llm.incomplete", { percentage: stats.percentComplete })); + } else { + $statusText.text(t("ai_llm.complete")); + } + + // Change progress bar color based on state + if (stats.queuedNotesCount > 0) { + // Processing in progress - use animated progress bar + $progressBar.addClass('progress-bar-striped progress-bar-animated bg-info'); + $progressBar.removeClass('bg-success'); + } else if (stats.percentComplete < 100) { + // Incomplete - use standard progress bar + $progressBar.removeClass('progress-bar-striped progress-bar-animated bg-info bg-success'); + } else { + // Complete - show success color + $progressBar.removeClass('progress-bar-striped progress-bar-animated bg-info'); + $progressBar.addClass('bg-success'); + } } } catch (error) { console.error("Error fetching embedding stats:", error); diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index 446fa055b..25ab6263d 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -1174,6 +1174,10 @@ "failed_notes": "Failed Notes", "last_processed": "Last Processed", "never": "Never", + "progress": "Progress", + "processing": "Processing ({{percentage}}%)", + "incomplete": "Incomplete ({{percentage}}%)", + "complete": "Complete (100%)", "refresh_stats": "Refresh Stats", "refreshing": "Refreshing...", "stats_error": "Error fetching embedding statistics", diff --git a/src/services/llm/embeddings/vector_store.ts b/src/services/llm/embeddings/vector_store.ts index 568fedbfa..3f17c0227 100644 --- a/src/services/llm/embeddings/vector_store.ts +++ b/src/services/llm/embeddings/vector_store.ts @@ -496,13 +496,32 @@ export async function getEmbeddingStats() { "SELECT utcDateCreated FROM note_embeddings ORDER BY utcDateCreated DESC LIMIT 1" ) as string | null || null; + // Calculate the actual completion percentage + // When reprocessing, we need to consider notes in the queue as not completed yet + // We calculate the percentage of notes that are embedded and NOT in the queue + + // First, get the count of notes that are both in the embeddings table and queue + const notesInQueueWithEmbeddings = await sql.getValue(` + SELECT COUNT(DISTINCT eq.noteId) + FROM embedding_queue eq + JOIN note_embeddings ne ON eq.noteId = ne.noteId + `) as number; + + // The number of notes with valid, up-to-date embeddings + const upToDateEmbeddings = embeddedNotesCount - notesInQueueWithEmbeddings; + + // Calculate the percentage of notes that are properly embedded + const percentComplete = totalNotesCount > 0 + ? Math.round((upToDateEmbeddings / totalNotesCount) * 100) + : 0; + return { totalNotesCount, embeddedNotesCount, queuedNotesCount, failedNotesCount, lastProcessedDate, - percentComplete: totalNotesCount > 0 ? Math.round((embeddedNotesCount / totalNotesCount) * 100) : 0 + percentComplete: Math.max(0, Math.min(100, percentComplete)) // Ensure between 0-100 }; }