From 8e1a66cb24a1f4d2f7733e53c0240d210e4d2255 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Tue, 10 Nov 2026 12:18:51 +0100 Subject: [PATCH] Fixed a crash when switching steps in the BeyondFacts Lab (#1183) --- .../Assistants/BeyondFactsLab/BflChat.razor.cs | 13 ++++++++++++- .../BeyondFactsLab/BflWorkStatePanel.razor.cs | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflChat.razor.cs b/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflChat.razor.cs index 06a158555..176afc66d 100644 --- a/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflChat.razor.cs +++ b/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflChat.razor.cs @@ -65,6 +65,16 @@ public partial class BflChat : MSGComponentBase /// private readonly CancellationTokenSource countCancellation = new(); + /// + /// The token of countCancellation, taken while the source still lives. + /// + /// + /// A count goes on after an await, when the component may have gone away meanwhile, e.g., because the person moved + /// on to another step. The source is disposed by then and refuses to hand out its token; the token taken before + /// still tells that the count was cancelled. + /// + private CancellationToken countToken; + /// /// What the next request carries, as far as it was counted. /// @@ -133,6 +143,7 @@ public partial class BflChat : MSGComponentBase /// protected override async Task OnInitializedAsync() { + this.countToken = this.countCancellation.Token; this.ConversationService.ConversationChanged += this.OnConversationChangedAsync; this.MaterialService.MaterialsChanged += this.OnMaterialsChangedAsync; this.SettingsManager.InjectSpellchecking(this.inputAttributes); @@ -221,7 +232,7 @@ public partial class BflChat : MSGComponentBase { var systemPrompt = await this.ConversationService.ComposeSystemPromptAsync(this.Location, this.Provider); var parts = ConversationParts.Of(thread, systemPrompt, string.Empty, null, false, null); - this.tokens = await this.TokenCounter.CountAsync(this.Provider, parts, thread.ReportedHistoryFor(this.Provider.Model), this.countCancellation.Token); + this.tokens = await this.TokenCounter.CountAsync(this.Provider, parts, thread.ReportedHistoryFor(this.Provider.Model), this.countToken); } catch (OperationCanceledException) { diff --git a/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflWorkStatePanel.razor.cs b/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflWorkStatePanel.razor.cs index 234485470..eca9e2935 100644 --- a/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflWorkStatePanel.razor.cs +++ b/app/MindWork AI Studio/Assistants/BeyondFactsLab/BflWorkStatePanel.razor.cs @@ -64,7 +64,7 @@ public partial class BflWorkStatePanel : MSGComponentBase /// Gets or sets the provider which writes the work state. /// [Parameter, EditorRequired] - public AIStudio.Settings.Provider Provider { get; set; } = AIStudio.Settings.Provider.NONE; + public AIStudio.Settings.Provider Provider { get; set; } = Settings.Provider.NONE; /// /// Gets or sets why the provider cannot write, or null when it can.