From 9f6739643a9d12979c15c0a5ce8936af1a80b79c Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Thu, 31 Aug 2023 06:40:51 -0500 Subject: [PATCH] RenderIntentResponse --- .../Conversations/ConversationHookBase.cs | 3 ++ .../Conversations/IConversationHook.cs | 1 + .../Conversations/Models/RoleDialogModel.cs | 5 +++ .../Templating/IResponseTemplateService.cs | 4 +- .../ConversationService.CallFunctions.cs | 3 +- .../Templating/ResponseTemplateService.cs | 37 +++++++++++++++++-- .../RoutingConversationHook.cs | 24 +++++++++++- 7 files changed, 69 insertions(+), 8 deletions(-) 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 50d74fe8..1a894c1c 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs @@ -1,15 +1,35 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Templating; +using Microsoft.Extensions.DependencyInjection; +using System; using System.Threading.Tasks; namespace BotSharp.Plugin.RoutingSpeeder; public class RoutingConversationHook: ConversationHookBase { + private readonly IServiceProvider _services; + public RoutingConversationHook(IServiceProvider services) + { + _services = services; + } + public override async Task BeforeCompletion(RoleDialogModel message) { // 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; + } } }