diff --git a/AI.NET/Resources/Strings/Strings.Designer.cs b/AI.NET/Resources/Strings/Strings.Designer.cs index bc94c22..b84485f 100644 --- a/AI.NET/Resources/Strings/Strings.Designer.cs +++ b/AI.NET/Resources/Strings/Strings.Designer.cs @@ -70,11 +70,11 @@ public static string About { } /// - /// 查找类似 Delete Current Chat (Ctrl+D) 的本地化字符串。 + /// 查找类似 Retry Last AI Response (Ctrl+R) 的本地化字符串。 /// - public static string DeleteChat { + public static string RetryGeneration { get { - return ResourceManager.GetString("DeleteChat", resourceCulture); + return ResourceManager.GetString("RetryGeneration", resourceCulture); } } diff --git a/AI.NET/Resources/Strings/Strings.resx b/AI.NET/Resources/Strings/Strings.resx index 307f96a..e11d51b 100644 --- a/AI.NET/Resources/Strings/Strings.resx +++ b/AI.NET/Resources/Strings/Strings.resx @@ -120,8 +120,8 @@ About - - Delete Current Chat (Ctrl+D) + + Retry Last AI Response (Ctrl+R) Mem0 Server URL diff --git a/AI.NET/Resources/Strings/Strings.zh-CHS.resx b/AI.NET/Resources/Strings/Strings.zh-CHS.resx index 297d6e3..088c0e0 100644 --- a/AI.NET/Resources/Strings/Strings.zh-CHS.resx +++ b/AI.NET/Resources/Strings/Strings.zh-CHS.resx @@ -120,8 +120,8 @@ 关于 - - 删除当前聊天 (Ctrl+D) + + 重新生成 AI 回复 (Ctrl+R) Mem0 服务器地址 diff --git a/AI.NET/Resources/Strings/Strings.zh-CN.resx b/AI.NET/Resources/Strings/Strings.zh-CN.resx index a2e4900..c90319a 100644 --- a/AI.NET/Resources/Strings/Strings.zh-CN.resx +++ b/AI.NET/Resources/Strings/Strings.zh-CN.resx @@ -123,8 +123,8 @@ 关于 - - 删除当前聊天 (Ctrl+D) + + 重新生成 AI 回复 (Ctrl+R) Mem0 服务器地址 diff --git a/AI.NET/Service/AI.cs b/AI.NET/Service/AI.cs index 6a79882..644b31b 100644 --- a/AI.NET/Service/AI.cs +++ b/AI.NET/Service/AI.cs @@ -40,11 +40,53 @@ public static async Task RequestAIAsync(string message, MarkdownScrollViewer out TopicsHelper.SaveTopicsAsync(Topics); } /// - /// Delete a chat session + /// Retry generating the last AI response /// - public static void DeleteMessages() + /// The UI element to update + public static async Task RetryLastResponseAsync(MarkdownScrollViewer outputBox) { - Topics.RemoveAt(Topics.CurrentTopicIndex); + var messages = Topics.CurrentTopic.MessageList; + + // Find the last user message and remove any subsequent AI/system messages + int lastUserIndex = -1; + for (int i = messages.Count - 1; i >= 0; i--) + { + if (messages[i].Role == ChatMessageRole.User) + { + lastUserIndex = i; + break; + } + } + + if (lastUserIndex == -1) + { + return; // No user message found to retry + } + + // Remove all messages after the last user message + while (messages.Count > lastUserIndex + 1) + { + messages.RemoveAt(messages.Count - 1); + } + + string lastUserMessage = messages[lastUserIndex].Content; + + // Update the output box to show we're retrying + string currentMarkdown = await Topics.CurrentTopic.GetMarkdownAsync(); + outputBox.Markdown = currentMarkdown + "AI:"; + + // Handle memory if enabled + if (Mem0.IsEnabled) + await HandleMemoryAsync(lastUserMessage); + + // Generate new AI response + Topics.CurrentTopic.Add(new Chat() + { + Content = await OpenAI.GenerateReplyAsync(outputBox), + Role = ChatMessageRole.Assistant + }); + + // Save topics to file TopicsHelper.SaveTopicsAsync(Topics); } public static void NewChat(Data.SystemPrompt prompt) diff --git a/AI.NET/Windows/MainWindow.xaml b/AI.NET/Windows/MainWindow.xaml index 75823f5..c1460dc 100644 --- a/AI.NET/Windows/MainWindow.xaml +++ b/AI.NET/Windows/MainWindow.xaml @@ -64,8 +64,8 @@ - diff --git a/AI.NET/Windows/MainWindow.xaml.cs b/AI.NET/Windows/MainWindow.xaml.cs index 5d4ab5b..dfade1a 100644 --- a/AI.NET/Windows/MainWindow.xaml.cs +++ b/AI.NET/Windows/MainWindow.xaml.cs @@ -87,7 +87,7 @@ private void SetBusyState(bool isBusy) sendButton.IsChecked = isBusy; sendButton.IsEnabled = !isBusy; newButton.IsEnabled = !isBusy; - deleteChatButton.IsEnabled = !isBusy; + retryButton.IsEnabled = !isBusy; } private void NewChatButton_Click(object sender, RoutedEventArgs e) { @@ -98,14 +98,25 @@ private void NewChatButton_Click(object sender, RoutedEventArgs e) topicBox.SelectedIndex = Service.AI.Topics.TopicList.Count - 1; } - private void DeleteChatButton_Click(object sender, RoutedEventArgs e) + private async void RetryButton_Click(object sender, RoutedEventArgs e) { if (topicBox.SelectedIndex >= 0 && topicBox.Items.Count > 0) { - outputBox.Markdown = string.Empty; - int index = topicBox.SelectedIndex; - Service.AI.DeleteMessages(); - topicBox.SelectedIndex = index - 1; + SetBusyState(true); + try + { + await Service.AI.RetryLastResponseAsync(outputBox); + } + catch (Exception ex) + { + Growl.Error(new() { StaysOpen = true, Message = ex.Message }); + Log.Error("Error when retrying AI response", ex); + } + finally + { + outputBox.Markdown += markdownNewLine; + SetBusyState(false); + } } } @@ -165,8 +176,8 @@ private void Window_KeyDown(object sender, KeyEventArgs e) NewChatButton_Click(sender, e); else if (e.Key == Key.Enter) SendButton_Click(sender, e); - else if (e.Key == Key.D) - DeleteChatButton_Click(sender, e); + else if (e.Key == Key.R) + RetryButton_Click(sender, e); } }