diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs index 13647bef..740547a3 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -27,21 +27,6 @@ public interface IConversationService Func onMessageReceived, Func onFunctionExecuting); - /// - /// Send message to LLM if frontend passed over the dialog history - /// - /// - /// - /// - /// - /// This delegate is useful when you want to report progress on UI - /// - Task SendMessage(string agentId, - string conversationId, - List wholeDialogs, - Func onMessageReceived, - Func onFunctionExecuting); - List GetDialogHistory(string conversationId, int lastCount = 20); Task CleanHistory(string agentId); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs index 3cac14f8..420f1191 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs @@ -11,5 +11,6 @@ public interface IConversationStateService ConversationState Load(); string GetState(string name); void SetState(string name, string value); + void CleanState(); void Save(); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs index d9b04724..dc883adf 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs @@ -23,7 +23,9 @@ public class RoleDialogModel /// When function callback has been executed, system will pass result to LLM again, /// Set this property to True to stop calling LLM. /// - public bool StopSubsequentInteraction { get;set; } + public bool StopSubsequentInteraction { get; set; } + + public bool IsConversationEnd { get; set; } /// /// Channel name diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 68057d35..8cdfdb23 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -1,4 +1,3 @@ -using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Functions; using BotSharp.Abstraction.MLTasks; @@ -79,18 +78,6 @@ public class ConversationService : IConversationService var wholeDialogs = GetDialogHistory(conversationId); - var response = await SendMessage(agentId, conversationId, wholeDialogs, - onMessageReceived: onMessageReceived, - onFunctionExecuting: onFunctionExecuting); - - return response; - } - - public async Task SendMessage(string agentId, string conversationId, - List wholeDialogs, - Func onMessageReceived, - Func onFunctionExecuting) - { var converation = await GetConversation(conversationId); // Create conversation if this conversation not exists @@ -109,11 +96,11 @@ public class ConversationService : IConversationService stateService.SetConversation(conversationId); stateService.Load(); stateService.SetState("agentId", agentId); - + // load agent var agentService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(agentId); - + // Get relevant domain knowledge /*if (_settings.EnableKnowledgeBase) { @@ -162,6 +149,12 @@ public class ConversationService : IConversationService await onMessageReceived(msg); } + + // Clean conversation + if (msg.IsConversationEnd) + { + stateService.CleanState(); + } }); return result; diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs index e37c6999..ea3c2603 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs @@ -1,6 +1,4 @@ using BotSharp.Abstraction.Conversations.Models; -using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.Extensions.Logging; using System.IO; namespace BotSharp.Core.Conversations.Services; @@ -89,6 +87,11 @@ public class ConversationStateService : IConversationStateService, IDisposable _logger.LogInformation($"Saved state {_conversationId}"); } + public void CleanState() + { + File.Delete(_file); + } + private string GetStorageFile(string conversationId) { var dir = Path.Combine(_dbSettings.FileRepository, "conversations", conversationId); diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index e9506f3d..e3e146f4 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -124,6 +124,15 @@ public class ChatCompletionProvider : IChatCompletion return true; } + if (funcContextIn.IsConversationEnd) + { + await onMessageReceived(new RoleDialogModel(ChatRole.Assistant.ToString(), funcContextIn.Content) + { + IsConversationEnd = true + }); + return true; + } + // After function is executed, pass the result to LLM chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.Function, funcContextIn.ExecutionResult) { diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs index 8d6b9de1..84c8e309 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs @@ -16,6 +16,8 @@ using Microsoft.Extensions.DependencyInjection; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; using Microsoft.AspNetCore.Authorization; +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Agents.Enums; namespace BotSharp.Plugin.ChatbotUI.Controllers; @@ -60,15 +62,16 @@ public class ChatbotUiController : ControllerBase, IApiAdapter Response.Headers.Add(HeaderNames.Connection, "keep-alive"); var outputStream = Response.Body; - var conversations = input.Messages + var conversation = input.Messages + .Where(x => x.Role == AgentRole.User) .Select(x => new RoleDialogModel(x.Role, x.Content)) - .ToList(); + .Last(); var conversationService = _services.GetRequiredService(); var result = await conversationService.SendMessage(input.AgentId, - input.ConversationId, - conversations, + input.ConversationId, + conversation, async msg => await OnChunkReceived(outputStream, msg), async fn