diff --git a/app/MindWork AI Studio/Pages/Embeddings.razor b/app/MindWork AI Studio/Pages/Embeddings.razor index 2a496f67..033a6867 100644 --- a/app/MindWork AI Studio/Pages/Embeddings.razor +++ b/app/MindWork AI Studio/Pages/Embeddings.razor @@ -19,6 +19,12 @@ @string.Format(T("Skipped files: {0}"), this.TotalPermanentlySkippedFiles) @string.Format(T("Failed files: {0}"), this.TotalFailedFiles) + @if (this.IsWorkingThroughDataSources) + { + + @string.Format(T("Data source {0} of {1} is being worked on. The others are waiting their turn."), this.CurrentDataSourceNumber, this.Statuses.Count) + + } @if (this.Statuses.Count == 0) diff --git a/app/MindWork AI Studio/Pages/Embeddings.razor.cs b/app/MindWork AI Studio/Pages/Embeddings.razor.cs index 95bfb528..51f9d540 100644 --- a/app/MindWork AI Studio/Pages/Embeddings.razor.cs +++ b/app/MindWork AI Studio/Pages/Embeddings.razor.cs @@ -43,6 +43,19 @@ public partial class Embeddings : MSGComponentBase private int TotalPermanentlySkippedFiles => this.Statuses.Sum(status => status.PermanentlySkippedFiles); + /// + /// The chips above count files, which says nothing about how far the list of data sources itself + /// has come. While several of them wait their turn, this is the one line saying so. With a single + /// data source there is nothing to say: its own row already tells the whole story. + /// + private bool IsWorkingThroughDataSources => this.Statuses.Count > 1 && this.Statuses.Any(status => status.State is DataSourceEmbeddingState.RUNNING or DataSourceEmbeddingState.QUEUED); + + /// + /// The one being worked on is the one after those which are done. A data source which needs + /// attention counts as done here: nothing is going to happen to it during this pass. + /// + private int CurrentDataSourceNumber => Math.Min(this.Statuses.Count, this.Statuses.Count(status => status.State is DataSourceEmbeddingState.COMPLETED or DataSourceEmbeddingState.FAILED) + 1); + protected override async Task OnInitializedAsync() { // diff --git a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs index 0ca86c9e..c8646a2d 100644 --- a/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs +++ b/app/MindWork AI Studio/Tools/Services/DataSourceEmbeddingService.cs @@ -1164,6 +1164,31 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM "Starting initial persisted hash check for {DataSourceCount} supported internal data source(s). Incomplete or failed local RAG embedding state will be retried during this pass. File watchers will be activated after this check completes.", supportedDataSources.Count); + // + // Every data source gets its row before the first run starts. This pass works through them + // one after the other, and re-indexing a large source takes its time: without this, the + // embeddings page would show the one source being worked on and nothing else, which reads + // as if the others were gone rather than waiting their turn. The queueing path does the + // same thing when it reserves a slot, which is why it never had this problem. + // + foreach (var dataSource in supportedDataSources) + { + if (this.statuses.TryGetValue(dataSource.Id, out var knownStatus) && knownStatus.State is DataSourceEmbeddingState.RUNNING) + continue; + + this.statuses[dataSource.Id] = this.CreateStatus( + dataSource, + DataSourceEmbeddingState.QUEUED, + knownStatus?.TotalFiles ?? 0, + knownStatus?.IndexedFiles ?? 0, + knownStatus?.FailedFiles ?? 0, + failures: knownStatus?.Failures ?? [], + permanentlySkippedFiles: knownStatus?.PermanentlySkippedFiles ?? 0); + } + + // One message for the whole list, rather than one per data source: + this.PublishStatusChanged(); + foreach (var dataSource in supportedDataSources) { token.ThrowIfCancellationRequested();