diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs index 055db3cc8..2aa8a72fc 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -54,4 +54,6 @@ Task SendMessage(string agentId, /// /// Task UpdateBreakpoint(bool resetStates = false, string? reason = null, params string[] excludedStates); + + Task GetConversationSummary(string conversationId); } diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index 0ddc52e83..10e21b3cc 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -56,6 +56,7 @@ + @@ -142,6 +143,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.Summary.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.Summary.cs new file mode 100644 index 000000000..25d754d66 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.Summary.cs @@ -0,0 +1,67 @@ +using BotSharp.Abstraction.MLTasks; +using BotSharp.Abstraction.Templating; + +namespace BotSharp.Core.Conversations.Services; + +public partial class ConversationService +{ + public async Task GetConversationSummary(string conversationId) + { + if (string.IsNullOrEmpty(conversationId)) return string.Empty; + + var routing = _services.GetRequiredService(); + var agentService = _services.GetRequiredService(); + + var dialogs = _storage.GetDialogs(conversationId); + if (dialogs.IsNullOrEmpty()) return string.Empty; + + var router = await agentService.LoadAgent(AIAssistant); + var prompt = GetPrompt(router); + var summary = await Summarize(router, prompt, dialogs); + + return summary; + } + + private string GetPrompt(Agent agent) + { + var template = agent.Templates.First(x => x.Name == "conversation.summary").Content; + var render = _services.GetRequiredService(); + return render.Render(template, new Dictionary { }); + } + + private async Task Summarize(Agent agent, string prompt, List dialogs) + { + var provider = "openai"; + string? model; + + var providerService = _services.GetRequiredService(); + var modelSettings = providerService.GetProviderModels(provider); + var modelSetting = modelSettings.FirstOrDefault(x => x.Name.IsEqualTo("gpt4-turbo") || x.Name.IsEqualTo("gpt-4o")); + + if (modelSetting != null) + { + model = modelSetting.Name; + } + else + { + provider = agent?.LlmConfig?.Provider; + model = agent?.LlmConfig?.Model; + if (provider == null || model == null) + { + var agentSettings = _services.GetRequiredService(); + provider = agentSettings.LlmConfig.Provider; + model = agentSettings.LlmConfig.Model; + } + } + + var chatCompletion = CompletionProvider.GetChatCompletion(_services, provider, model); + var response = await chatCompletion.GetChatCompletions(new Agent + { + Id = agent.Id, + Name = agent.Name, + Instruction = prompt + }, dialogs); + + return response.Content; + } +} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 4de36b9dc..8e1132263 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -12,6 +12,8 @@ public partial class ConversationService : IConversationService private readonly IConversationStorage _storage; private readonly IConversationStateService _state; private string _conversationId; + private const string AIAssistant = "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a"; + public string ConversationId => _conversationId; public IConversationStateService States => _state; diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/conversation.summary.liquid b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/conversation.summary.liquid new file mode 100644 index 000000000..e2ffe5db1 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/conversation.summary.liquid @@ -0,0 +1,8 @@ +Please summarize the conversation. + +*** Super Important! Please consider the entire conversation. Do not only consider the recent sentences. *** +** Please do not respond to the latest conversation. +** If there are different topics in the conversation, please summarize each topic in different sentences and list them with bullets. +* Please use concise sentences to summarize each topic. +* Please do not include excessive details in the summaries. +* Please use 'user' instead of 'you', 'he' or 'she'. \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs index 6ed27b324..18d5ab18c 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs @@ -139,6 +139,13 @@ public async Task GetConversation([FromRoute] string conv return result; } + [HttpGet("/conversation/{conversationId}/summary")] + public async Task GetConversationSummary([FromRoute] string conversationId) + { + var service = _services.GetRequiredService(); + return await service.GetConversationSummary(conversationId); + } + [HttpGet("/conversation/{conversationId}/user")] public async Task GetConversationUser([FromRoute] string conversationId) {