diff --git a/LM-Kit-Maestro/UI/Razor/Components/Chat.razor b/LM-Kit-Maestro/UI/Razor/Components/Chat.razor index 813c84a..811cc43 100644 --- a/LM-Kit-Maestro/UI/Razor/Components/Chat.razor +++ b/LM-Kit-Maestro/UI/Razor/Components/Chat.razor @@ -6,28 +6,28 @@ @inject IScrollHandler ScrollHandler @inject IResizeHandler ResizeHandler @inject ILogger Logger - +@inject ISnackbar Snackbar @inherits MvvmComponentBase
+ class="chat-element dark @(ViewModel.ConversationListViewModel.CurrentConversation is { IsEmpty: true } ? "centered-container" : "top-align-container")"> @if (ViewModel?.ConversationListViewModel.CurrentConversation != null) { if (ViewModel.ConversationListViewModel.CurrentConversation.IsEmpty) {
-
Maestro at your service—let’s orchestrate something amazing!
-
- Feel free to ask questions, explore ideas, or engage in meaningful conversations. +
Maestro at your service—let’s orchestrate something amazing!
+
+ Feel free to ask questions, explore ideas, or engage in meaningful conversations. -
-
- Whether you need assistance, inspiration, or just some lighthearted chat, I'm here to help. +
+
+ Whether you need assistance, inspiration, or just some lighthearted chat, I'm here to help. -
+
@@ -79,7 +79,7 @@ Tokens: @ViewModel.ConversationListViewModel.CurrentConversation.LMKitConversation.ContextUsedSpace / @ViewModel.ConversationListViewModel.CurrentConversation.LMKitConversation.ContextSize (@CalculateUsagePercentage(ViewModel.ConversationListViewModel.CurrentConversation.LMKitConversation.ContextUsedSpace, - ViewModel.ConversationListViewModel.CurrentConversation.LMKitConversation.ContextSize)%) + ViewModel.ConversationListViewModel.CurrentConversation.LMKitConversation.ContextSize)%) }
@@ -219,6 +219,7 @@ if (_previousConversationViewModel != null) { _previousConversationViewModel.Messages.CollectionChanged -= OnConversationMessagesCollectionChanged; + _previousConversationViewModel.TextGenerationCompleted -= OnTextGenerationCompleted; } _previousConversationViewModel = ViewModel.ConversationListViewModel.CurrentConversation; @@ -226,6 +227,8 @@ if (ViewModel.ConversationListViewModel.CurrentConversation != null) { ViewModel.ConversationListViewModel.CurrentConversation.Messages.CollectionChanged += OnConversationMessagesCollectionChanged; + ViewModel.ConversationListViewModel.CurrentConversation.TextGenerationCompleted += OnTextGenerationCompleted; + _previousScrollTop = null; _ignoreScrollsUntilNextScrollUp = true; IsScrolledToEnd = true; @@ -251,6 +254,14 @@ } } + private void OnTextGenerationCompleted(object? sender, ConversationViewModel.TextGenerationCompletedEventArgs e) + { + if (e.Exception != null) + { + Snackbar.Add($"Text generation failed unexpectedly:\n{e.Exception.Message}", Severity.Error); + } + } + private async void OnLatestAssistantResponseProgressed() { if (_shouldAutoScrollEnd) diff --git a/LM-Kit-Maestro/ViewModels/ConversationViewModel.cs b/LM-Kit-Maestro/ViewModels/ConversationViewModel.cs index 9e405a2..a4226ce 100644 --- a/LM-Kit-Maestro/ViewModels/ConversationViewModel.cs +++ b/LM-Kit-Maestro/ViewModels/ConversationViewModel.cs @@ -87,8 +87,9 @@ public Uri? LastUsedModel } } - public EventHandler? TextGenerationCompleted; - public EventHandler? TextGenerationFailed; + public delegate void TextGenerationCompletedEventHandler(object sender, TextGenerationCompletedEventArgs e); + + public TextGenerationCompletedEventHandler? TextGenerationCompleted; public EventHandler? DatabaseSaveOperationCompleted; public EventHandler? DatabaseSaveOperationFailed; diff --git a/tests/LmKitServiceTests.cs b/tests/LmKitServiceTests.cs index ce9580d..23e85d9 100644 --- a/tests/LmKitServiceTests.cs +++ b/tests/LmKitServiceTests.cs @@ -89,7 +89,7 @@ public async Task HonorsTimeout() var response = await testService.LMKitService.SubmitPrompt(conversation, "tell me a story"); Assert.NotNull(response); - Assert.Equal(LMKitTextGenerationStatus.Cancelled, response.Status); + Assert.Equal(LMKitRequestStatus.Cancelled, response.Status); Assert.True(response.Exception is OperationCanceledException operationCancelled); } @@ -167,7 +167,7 @@ private async Task SubmitOnePromptChangeModelSubmitAnother2() var firstPromptResult = await firstResponseTask; - Assert.True(firstPromptResult.Status == LMKitTextGenerationStatus.Cancelled || firstPromptResult.Status == LMKitTextGenerationStatus.GenericError); + Assert.True(firstPromptResult.Status == LMKitRequestStatus.Cancelled || firstPromptResult.Status == LMKitRequestStatus.GenericError); loadingSuccess = await secondModelLoadingTask; Assert.True(loadingSuccess); @@ -193,10 +193,10 @@ private async Task Submit2PromptsFromDistinctConversationsThenUnloadModel() Assert.True(unloadingSuccess); var result = await conversation1.PromptResultTask.Task; - Assert.True(result != null && result.Status == LMKitTextGenerationStatus.Cancelled); + Assert.True(result != null && result.Status == LMKitRequestStatus.Cancelled); result = await conversation2.PromptResultTask.Task; - Assert.True(result != null && result.Status == LMKitTextGenerationStatus.Cancelled); + Assert.True(result != null && result.Status == LMKitRequestStatus.Cancelled); } [Fact] @@ -214,7 +214,7 @@ private async Task SubmitOnePromptThenUnloadModel() Assert.True(unloadingSuccess); var result = await conversation1.PromptResultTask.Task; - Assert.True(result != null && result.Status == LMKitTextGenerationStatus.Cancelled); + Assert.True(result != null && result.Status == LMKitRequestStatus.Cancelled); } [Fact] diff --git a/tests/Services/ConversationViewModelWrapper.cs b/tests/Services/ConversationViewModelWrapper.cs index 838ae88..29db32f 100644 --- a/tests/Services/ConversationViewModelWrapper.cs +++ b/tests/Services/ConversationViewModelWrapper.cs @@ -14,7 +14,6 @@ public ConversationViewModelWrapper(ConversationViewModel conversationViewModel) { ConversationViewModel = conversationViewModel; ConversationViewModel.TextGenerationCompleted += OnTextGenerationCompleted; - ConversationViewModel.TextGenerationFailed += OnTextGenerationFailed; ConversationViewModel.DatabaseSaveOperationCompleted += OnDatabaseSynchronizationCompleted; ConversationViewModel.PropertyChanged += ConversationViewModel_PropertyChanged; } @@ -27,18 +26,18 @@ private void ConversationViewModel_PropertyChanged(object? sender, System.Compon } } - private void OnTextGenerationCompleted(object? sender, EventArgs e) + private void OnTextGenerationCompleted(object? sender, ConversationViewModel.TextGenerationCompletedEventArgs e) { var conversationViewModel = (ConversationViewModel)sender!; - PromptResultTask.SetResult(true); - } - - private void OnTextGenerationFailed(object? sender, EventArgs e) - { - var conversationViewModel = (ConversationViewModel)sender!; - - PromptResultTask.SetResult(false); + if (e.Exception != null || e.Status != Maestro.Services.LMKitRequestStatus.OK) + { + PromptResultTask.SetResult(false); + } + else + { + PromptResultTask.SetResult(true); + } } private void OnDatabaseSynchronizationCompleted(object? sender, EventArgs e) diff --git a/tests/Services/LMKitMaestroTestsHelpers.cs b/tests/Services/LMKitMaestroTestsHelpers.cs index d836c84..56bc0bc 100644 --- a/tests/Services/LMKitMaestroTestsHelpers.cs +++ b/tests/Services/LMKitMaestroTestsHelpers.cs @@ -9,7 +9,7 @@ internal static class MaestroTestsHelpers { public static void AssertPromptResponseIsSuccessful(LMKitService.LMKitResult promptResult) { - Assert.Equal(LMKitTextGenerationStatus.Undefined, promptResult.Status); + Assert.Equal(LMKitRequestStatus.OK, promptResult.Status); Assert.Null(promptResult.Exception); Assert.NotNull(promptResult.Result); } @@ -18,8 +18,8 @@ public static void AssertConversationPromptSuccessState(ConversationViewModelWra { Assert.True(testConversation.PromptResultTask.Task.Result); Assert.True(testConversation.ConversationViewModel.Messages.Count == expectedMessageCount); - Assert.Equal(LMKitTextGenerationStatus.Undefined, testConversation.ConversationViewModel.Messages[0].Status); - Assert.Equal(LMKitTextGenerationStatus.Undefined, testConversation.ConversationViewModel.Messages[1].Status); + Assert.Equal(LMKitRequestStatus.OK, testConversation.ConversationViewModel.Messages[0].Status); + Assert.Equal(LMKitRequestStatus.OK, testConversation.ConversationViewModel.Messages[1].Status); Assert.False(string.IsNullOrEmpty(testConversation.ConversationViewModel.Messages[0].Content)); Assert.False(string.IsNullOrEmpty(testConversation.ConversationViewModel.Messages[1].Content)); Assert.False(testConversation.ConversationViewModel.AwaitingResponse); @@ -32,7 +32,7 @@ public static void AssertConversationPromptCancelledState(ConversationViewModelW if (testConversation.ConversationViewModel.Messages.Count == 2) { - Assert.Equal(LMKitTextGenerationStatus.Cancelled, testConversation.ConversationViewModel.Messages[1].Status); + Assert.Equal(LMKitRequestStatus.Cancelled, testConversation.ConversationViewModel.Messages[1].Status); Assert.False(string.IsNullOrEmpty(testConversation.ConversationViewModel.Messages[0].Content)); }