diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs index b207bbcb..3634255a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs @@ -11,6 +11,9 @@ public abstract class ConversationHookBase : IConversationHook protected List _dialogs; public List Dialogs => _dialogs; + protected int _priority = 0; + public int Priority => _priority; + public IConversationHook SetAgent(Agent agent) { _agent = agent; diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs index b677da3f..8e55dab7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs @@ -2,6 +2,7 @@ namespace BotSharp.Abstraction.Conversations; public interface IConversationHook { + int Priority { get; } Agent Agent { get; } IConversationHook SetAgent(Agent agent); diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs index 063a5432..2740c8c8 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs @@ -30,6 +30,11 @@ public class RoleDialogModel /// public object ExecutionData { get; set; } + /// + /// Intent name + /// + public string IntentName { get; set; } + /// /// Stop conversation completion /// diff --git a/src/Infrastructure/BotSharp.Abstraction/Templating/IResponseTemplateService.cs b/src/Infrastructure/BotSharp.Abstraction/Templating/IResponseTemplateService.cs index 2aecafcc..da52c432 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Templating/IResponseTemplateService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Templating/IResponseTemplateService.cs @@ -2,5 +2,7 @@ namespace BotSharp.Abstraction.Templating; public interface IResponseTemplateService { - Task RenderFunctionResponse(string agentId, RoleDialogModel fn); + Task RenderFunctionResponse(string agentId, RoleDialogModel message); + + Task RenderIntentResponse(string agentId, RoleDialogModel message); } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs index 66f0a25d..02a81350 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs @@ -7,7 +7,8 @@ public partial class ConversationService { private async Task CallFunctions(RoleDialogModel msg) { - var hooks = _services.GetServices().ToList(); + var hooks = _services.GetServices() + .OrderBy(x => x.Priority).ToList(); // Invoke functions var functions = _services.GetServices() diff --git a/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs b/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs index 495d42a3..b7be790a 100644 --- a/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs +++ b/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs @@ -12,13 +12,13 @@ public class ResponseTemplateService : IResponseTemplateService _services = services; } - public async Task RenderFunctionResponse(string agentId, RoleDialogModel fn) + public async Task RenderFunctionResponse(string agentId, RoleDialogModel message) { // Find response template var agentService = _services.GetRequiredService(); var dir = Path.Combine(agentService.GetAgentDataDir(agentId), "responses"); var responses = Directory.GetFiles(dir) - .Where(f => f.Split(Path.DirectorySeparatorChar).Last().Split('.')[1] == fn.FunctionName) + .Where(f => f.Split(Path.DirectorySeparatorChar).Last().Split('.')[1] == message.FunctionName) .ToList(); if (responses.Count == 0) @@ -33,8 +33,37 @@ public class ResponseTemplateService : IResponseTemplateService // Convert args and execute data to dictionary var dict = new Dictionary(); - ExtractArgs(JsonSerializer.Deserialize(fn.FunctionArgs), dict); - ExtractExecuteData(fn.ExecutionData, dict); + ExtractArgs(JsonSerializer.Deserialize(message.FunctionArgs), dict); + ExtractExecuteData(message.ExecutionData, dict); + + var text = render.Render(template, dict); + + return text; + } + + public async Task RenderIntentResponse(string agentId, RoleDialogModel message) + { + // Find response template + var agentService = _services.GetRequiredService(); + var dir = Path.Combine(agentService.GetAgentDataDir(agentId), "responses"); + var responses = Directory.GetFiles(dir) + .Where(f => f.Split(Path.DirectorySeparatorChar).Last().Split('.')[1] == message.IntentName) + .ToList(); + + if (responses.Count == 0) + { + return string.Empty; + } + + var randomIndex = new Random().Next(0, responses.Count); + var template = File.ReadAllText(responses[randomIndex]); + + var render = _services.GetRequiredService(); + + // Convert args and execute data to dictionary + var dict = new Dictionary(); + ExtractArgs(JsonSerializer.Deserialize(message.FunctionArgs), dict); + ExtractExecuteData(message.ExecutionData, dict); var text = render.Render(template, dict); diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs index bc37e117..2307c079 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.MLTasks; @@ -25,7 +27,16 @@ public class RoutingConversationHook: ConversationHookBase .FirstOrDefault(x => x.GetType().FullName.EndsWith(_settings.TextEmbedding)); // Utilize local discriminative model to predict intent - message.Content = "response content"; - message.StopCompletion = true; + message.IntentName = "greeting"; + + // Render by template + var templateService = _services.GetRequiredService(); + var response = await templateService.RenderIntentResponse(_agent.Id, message); + + if (!string.IsNullOrEmpty(response)) + { + message.Content = response; + message.StopCompletion = true; + } } }