diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs
index 055db3cc..2aa8a72f 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs
@@ -54,4 +54,6 @@ public interface IConversationService
///
///
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 0ddc52e8..10e21b3c 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 00000000..25d754d6
--- /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 4de36b9d..8e113226 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 00000000..e2ffe5db
--- /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 71d824b3..fa4fea59 100644
--- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
+++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
@@ -139,6 +139,13 @@ public class ConversationController : ControllerBase
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)
{