From 15363f47657b733cf8f19d1579eb672f1776534a Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Wed, 8 Jan 2025 14:49:15 -0600 Subject: [PATCH] X-Twilio-BotSharp --- .../Enums/ConversationChannel.cs | 1 + .../BotSharp.Core.Rules/Engines/RuleEngine.cs | 71 +++++++++++++++++-- .../Triggers/IRuleTrigger.cs | 3 +- .../agent.json | 2 +- .../templates/criteria_check.liquid | 2 +- .../Functions/HandleHttpRequestFn.cs | 2 +- .../Services/TwilioMessageQueueService.cs | 1 + 7 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs index d03a4208..f23ff4ba 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs @@ -8,4 +8,5 @@ public class ConversationChannel public const string Messenger = "messenger"; public const string Email = "email"; public const string Cron = "cron"; + public const string Database = "database"; } diff --git a/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs b/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs index c69d654b..5841d08a 100644 --- a/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs +++ b/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs @@ -1,26 +1,85 @@ +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Conversations.Enums; +using BotSharp.Abstraction.Models; +using BotSharp.Abstraction.Repositories.Filters; +using BotSharp.Abstraction.Routing; +using BotSharp.Abstraction.Utilities; using BotSharp.Core.Rules.Triggers; +using Microsoft.Extensions.Logging; +using System.Data; namespace BotSharp.Core.Rules.Engines; public class RuleEngine : IRuleEngine { private readonly IServiceProvider _services; - public RuleEngine(IServiceProvider services) + private readonly ILogger _logger; + + public RuleEngine(IServiceProvider services, ILogger logger) { _services = services; + _logger = logger; } public async Task Triggered(IRuleTrigger trigger, string data) { // Pull all user defined rules - + var agentService = _services.GetRequiredService(); + var agents = await agentService.GetAgents(new AgentFilter + { + Pager = new Pagination + { + Size = 1000 + } + }); + + var preFilteredAgents = agents.Items.Where(x => + x.Rules.Exists(r => r.TriggerName == trigger.Name && + !x.Disabled)).ToList(); + + // Trigger the agents var instructService = _services.GetRequiredService(); + var convService = _services.GetRequiredService(); - var userSay = $"===Input data===\r\n{data}\r\n\r\nWhen WO NTE is greater than 100, notify resident."; + foreach (var agent in preFilteredAgents) + { + var conv = await convService.NewConversation(new Conversation + { + AgentId = agent.Id + }); - var result = await instructService.Execute(BuiltInAgentId.RulesInterpreter, new RoleDialogModel(AgentRole.User, data), "criteria_check", "#TEMPLATE#"); + var message = new RoleDialogModel(AgentRole.User, data); - string[] rules = []; - // Check if meet the criteria + var states = new List + { + new("channel", ConversationChannel.Database), + new("channel_id", trigger.EntityId) + }; + convService.SetConversationId(conv.Id, states); + + await convService.SendMessage(agent.Id, + message, + null, + msg => Task.CompletedTask); + + /*foreach (var rule in agent.Rules) + { + var userSay = $"===Input data with Before and After values===\r\n{data}\r\n\r\n===Trigger Criteria===\r\n{rule.Criteria}\r\n\r\nJust output 1 or 0 without explanation: "; + + var result = await instructService.Execute(BuiltInAgentId.RulesInterpreter, new RoleDialogModel(AgentRole.User, userSay), "criteria_check", "#TEMPLATE#"); + + // Check if meet the criteria + if (result.Text == "1") + { + // Hit rule + _logger.LogInformation($"Hit rule {rule.TriggerName} {rule.EntityType} {rule.EventName}, {data}"); + + await convService.SendMessage(agent.Id, + new RoleDialogModel(AgentRole.User, $"The conversation was triggered by {rule.Criteria}"), + null, + msg => Task.CompletedTask); + } + }*/ + } } } diff --git a/src/Infrastructure/BotSharp.Core.Rules/Triggers/IRuleTrigger.cs b/src/Infrastructure/BotSharp.Core.Rules/Triggers/IRuleTrigger.cs index f4925bfe..dbf88331 100644 --- a/src/Infrastructure/BotSharp.Core.Rules/Triggers/IRuleTrigger.cs +++ b/src/Infrastructure/BotSharp.Core.Rules/Triggers/IRuleTrigger.cs @@ -4,7 +4,8 @@ public interface IRuleTrigger { string Channel => throw new NotImplementedException("Please set the channel of trigger"); - string EventName { get; set; } + string Name { get; set; } + string EntityType { get; set; } string EntityId { get; set; } diff --git a/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/agent.json b/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/agent.json index a58a2ae8..f685413f 100644 --- a/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/agent.json +++ b/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/agent.json @@ -1,7 +1,7 @@ { "id": "201e49a2-40b3-4ccd-b8cc-2476565a1b40", "name": "Rules Agent", - "description": "Utility assistant that can be used to complete many different tasks", + "description": "Rules understands and converts user-defined rules into Triggers, Criterias and Actions", "type": "static", "createdDateTime": "2024-12-30T00:00:00Z", "updatedDateTime": "2024-12-30T00:00:00Z", diff --git a/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/templates/criteria_check.liquid b/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/templates/criteria_check.liquid index 3052e417..834e901d 100644 --- a/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/templates/criteria_check.liquid +++ b/src/Infrastructure/BotSharp.Core.Rules/data/agents/201e49a2-40b3-4ccd-b8cc-2476565a1b40/templates/criteria_check.liquid @@ -1,4 +1,4 @@ You are a rule interpreter, analyze and respond according to the following steps: 1. Understand the rules customized by the user; 2. Determine whether the input data meets the user's action execution conditions; -3. If it meets the conditions, output "true", otherwise output "false" \ No newline at end of file +3. If it meets the conditions, output number "1", otherwise output "0" \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.HttpHandler/Functions/HandleHttpRequestFn.cs b/src/Plugins/BotSharp.Plugin.HttpHandler/Functions/HandleHttpRequestFn.cs index 52f5075b..607ae5a9 100644 --- a/src/Plugins/BotSharp.Plugin.HttpHandler/Functions/HandleHttpRequestFn.cs +++ b/src/Plugins/BotSharp.Plugin.HttpHandler/Functions/HandleHttpRequestFn.cs @@ -9,7 +9,7 @@ namespace BotSharp.Plugin.HttpHandler.Functions; public class HandleHttpRequestFn : IFunctionCallback { public string Name => "util-http-handle_http_request"; - public string Indication => "Handling http request"; + public string Indication => "Give me a second, I'm taking care of it!"; private readonly IServiceProvider _services; private readonly ILogger _logger; diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs index 0d843602..0260320f 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs @@ -65,6 +65,7 @@ namespace BotSharp.Plugin.Twilio.Services var httpContext = sp.GetRequiredService(); httpContext.HttpContext = new DefaultHttpContext(); httpContext.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.HttpContext.Request.Headers["X-Twilio-BotSharp"] = "LOST"; AssistantMessage reply = null; var inputMsg = new RoleDialogModel(AgentRole.User, message.Content);