From c54e0353d830cebfbd333391ddd330ee86d0c1f8 Mon Sep 17 00:00:00 2001 From: hchen2020 <101423@smsassist.com> Date: Fri, 15 Sep 2023 14:42:14 -0500 Subject: [PATCH 1/2] Get similar work orders before wo creation. --- .../BotSharp.Plugin.KnowledgeBase/MemVecDb/VecRecord.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/VecRecord.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/VecRecord.cs index 563f0c98..79775698 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/VecRecord.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/VecRecord.cs @@ -5,4 +5,9 @@ public class VecRecord public int Id { get; set; } public float[] Vector { get; set; } public string Text { get; set; } + + public override string ToString() + { + return Text; + } } From a13ef3007bc134ac185366063df827f40c29f6dd Mon Sep 17 00:00:00 2001 From: hchen2020 <101423@smsassist.com> Date: Mon, 18 Sep 2023 13:13:49 -0500 Subject: [PATCH 2/2] Eliminate route file configuration. --- .../Agents/IAgentRouting.cs | 4 +- .../Agents/Models/Agent.cs | 18 ++- .../Repositories/IBotSharpRepository.cs | 11 -- .../Routing/IRoutingService.cs | 4 - .../Routing/Models/RoutingItem.cs | 17 +-- .../Routing/Models/RoutingProfile.cs | 14 --- .../Routing/Models/RoutingRule.cs | 21 ++++ .../BotSharp.Abstraction/Using.cs | 1 + .../BotSharpServiceCollectionExtensions.cs | 2 - ...vice.GetChatCompletionsAsyncRecursively.cs | 12 +- .../ConversationService.SendMessage.cs | 1 - .../Repository/BotSharpDbContext.cs | 28 ----- .../Repository/FileRepository.cs | 68 ------------ .../BotSharp.Core/Routing/RouteToAgentFn.cs | 31 ++++-- .../BotSharp.Core/Routing/Router.cs | 40 ++++--- .../BotSharp.Core/Routing/RoutingHook.cs | 18 ++- .../Routing/Services/RoutingService.Create.cs | 66 ----------- .../Routing/Services/RoutingService.Delete.cs | 20 ---- .../Routing/Services/RoutingService.cs | 23 ---- .../BotSharp.Core/Routing/Simulator.cs | 11 +- .../Controllers/RoutingController.cs | 45 -------- .../Routing/RoutingItemCreationModel.cs | 26 ----- .../Routing/RoutingItemViewModel.cs | 28 ----- .../Routing/RoutingProfileCreationModel.cs | 18 --- .../Routing/RoutingProfileViewModel.cs | 20 ---- .../Repository/MongoRepository.cs | 105 ------------------ 26 files changed, 116 insertions(+), 536 deletions(-) delete mode 100644 src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingProfile.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingRule.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Create.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Delete.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.cs delete mode 100644 src/Infrastructure/BotSharp.OpenAPI/Controllers/RoutingController.cs delete mode 100644 src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemCreationModel.cs delete mode 100644 src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemViewModel.cs delete mode 100644 src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileCreationModel.cs delete mode 100644 src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileViewModel.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs index 1e94e5dd..7ab7c2b1 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs @@ -6,7 +6,5 @@ public interface IAgentRouting { string AgentId { get; } Task LoadRouter(); - RoutingItem[] GetRoutingRecords(); - RoutingItem GetRecordByAgentId(string id); - RoutingItem GetRecordByName(string name); + RoutingRule[] GetRulesByName(string name); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 9719f27a..8b968035 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using BotSharp.Abstraction.Routing.Models; namespace BotSharp.Abstraction.Agents.Models; @@ -48,6 +48,22 @@ public class Agent public bool IsPublic { get; set; } + /// + /// Allow to be routed + /// + public bool AllowRouting { get; set; } + + public bool Disabled { get; set; } + + /// + /// Profile by channel + /// + public List Profiles { get; set; } + = new List(); + + public List RoutingRules { get; set; } + = new List(); + public override string ToString() => $"{Name} {Id}"; diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 72e7ccca..5a89f7dd 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -1,5 +1,3 @@ -using BotSharp.Abstraction.Agents.Enums; -using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Models; namespace BotSharp.Abstraction.Repositories; @@ -10,8 +8,6 @@ public interface IBotSharpRepository IQueryable Agents { get; } IQueryable UserAgents { get; } IQueryable Conversations { get; } - IQueryable RoutingItems { get; } - IQueryable RoutingProfiles { get; } int Transaction(Action action); void Add(object entity); @@ -37,11 +33,4 @@ public interface IBotSharpRepository Conversation GetConversation(string conversationId); List GetConversations(string userId); #endregion - - #region Routing - List CreateRoutingItems(List routingItems); - List CreateRoutingProfiles(List profiles); - void DeleteRoutingItems(); - void DeleteRoutingProfiles(); - #endregion } diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs index e65bf0d5..8cf7f5b7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs @@ -1,11 +1,7 @@ -using BotSharp.Abstraction.Routing.Models; - namespace BotSharp.Abstraction.Routing; public interface IRoutingService { - Task> CreateRoutingItems(List routingItems); - Task> CreateRoutingProfiles(List routingProfiles); Task DeleteRoutingItems(); Task DeleteRoutingProfiles(); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingItem.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingItem.cs index a6f50fe5..9866d78a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingItem.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingItem.cs @@ -1,11 +1,7 @@ -using System.Text.Json.Serialization; - namespace BotSharp.Abstraction.Routing.Models; public class RoutingItem { - public string Id { get; set; } - [JsonPropertyName("agent_id")] public string AgentId { get; set; } = string.Empty; @@ -16,16 +12,5 @@ public class RoutingItem public string Description { get; set; } = string.Empty; [JsonPropertyName("required")] - public List RequiredFields { get; set; } = new List(); - - [JsonPropertyName("redirect_to")] - public string? RedirectTo { get; set; } - - [JsonPropertyName("disabled")] - public bool Disabled { get; set; } - - public override string ToString() - { - return Name; - } + public string[] RequiredFields { get; set; } = new string[0]; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingProfile.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingProfile.cs deleted file mode 100644 index c269b5d1..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingProfile.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BotSharp.Abstraction.Routing.Models; - -public class RoutingProfile -{ - public string Id { get; set; } - - [JsonPropertyName("name")] - public string Name { get; set; } - - [JsonPropertyName("agent_ids")] - public List AgentIds { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingRule.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingRule.cs new file mode 100644 index 00000000..40102d4a --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingRule.cs @@ -0,0 +1,21 @@ +namespace BotSharp.Abstraction.Routing.Models; + +public class RoutingRule +{ + [JsonIgnore] + public string AgentId { get; set; } + + [JsonIgnore] + public string AgentName { get; set; } + + public string Field { get; set; } + + public bool Required { get; set; } + + public string? RedirectTo { get; set; } + + public override string ToString() + { + return $"{AgentName} {Field}"; + } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Using.cs b/src/Infrastructure/BotSharp.Abstraction/Using.cs index ff0946ad..87d42791 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Using.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Using.cs @@ -4,6 +4,7 @@ global using System.Text; global using System.Linq; global using System.Threading.Tasks; global using System.ComponentModel.DataAnnotations; +global using System.Text.Json.Serialization; global using BotSharp.Abstraction.Agents.Models; global using BotSharp.Abstraction.Conversations.Models; global using BotSharp.Abstraction.Agents.Enums; \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index 7d5e4d4c..d635d1c0 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -9,7 +9,6 @@ using BotSharp.Abstraction.Templating; using BotSharp.Core.Instructs; using BotSharp.Abstraction.Instructs; using BotSharp.Abstraction.Routing; -using BotSharp.Core.Routing.Services; namespace BotSharp.Core; @@ -20,7 +19,6 @@ public static class BotSharpServiceCollectionExtensions services.AddScoped(); services.AddScoped(); - services.AddScoped(); var agentSettings = new AgentSettings(); config.Bind("Agent", agentSettings); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs index 9ba5e4a5..8d63fc64 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs @@ -77,7 +77,10 @@ public partial class ConversationService var agentService = _services.GetRequiredService(); agent = await agentService.LoadAgent(fn.CurrentAgentId); - wholeDialogs.Add(fn); + if (fn.FunctionName != "route_to_agent") + { + wholeDialogs.Add(fn); + } await GetChatCompletionsAsyncRecursively(agent, wholeDialogs, @@ -99,13 +102,16 @@ public partial class ConversationService return; } - + // Add to dialog history // The server had an error processing your request. Sorry about that! // _storage.Append(conversationId, preAgentId, fn); // After function is executed, pass the result to LLM to get a natural response - wholeDialogs.Add(fn); + if (fn.FunctionName != "route_to_agent") + { + wholeDialogs.Add(fn); + } await GetChatCompletionsAsyncRecursively(agent, wholeDialogs, diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs index 47b144f7..1c297391 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs @@ -1,4 +1,3 @@ -using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Routing.Settings; using BotSharp.Core.Routing; diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index d8f6ef52..9819957f 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -1,6 +1,5 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Repositories; -using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Models; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -16,10 +15,6 @@ public class BotSharpDbContext : Database, IBotSharpRepository public IQueryable Conversations => throw new NotImplementedException(); - public IQueryable RoutingItems => throw new NotImplementedException(); - - public IQueryable RoutingProfiles => throw new NotImplementedException(); - public int Transaction(Action action) { @@ -143,27 +138,4 @@ public class BotSharpDbContext : Database, IBotSharpRepository throw new NotImplementedException(); } #endregion - - - #region Routing - public List CreateRoutingItems(List routingItems) - { - throw new NotImplementedException(); - } - - public List CreateRoutingProfiles(List profiles) - { - throw new NotImplementedException(); - } - - public void DeleteRoutingItems() - { - throw new NotImplementedException(); - } - - public void DeleteRoutingProfiles() - { - throw new NotImplementedException(); - } - #endregion } diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs index 69d369e7..1a6445e7 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -3,11 +3,7 @@ using System.IO; using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef; using BotSharp.Abstraction.Users.Models; using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Routing.Models; using MongoDB.Driver; -using Microsoft.Extensions.Logging; -using System.Xml.Linq; -using static Tensorflow.TensorShapeProto.Types; namespace BotSharp.Core.Repository; @@ -135,48 +131,6 @@ public class FileRepository : IBotSharpRepository } } - private List _routingItems; - public IQueryable RoutingItems - { - get - { - if (!_routingItems.IsNullOrEmpty()) - { - return _routingItems.AsQueryable(); - } - - _routingItems = new List(); - var filePath = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, "route.json"); - if (File.Exists(filePath)) - { - _routingItems = JsonSerializer.Deserialize>(File.ReadAllText(filePath), _options); - } - - return _routingItems.AsQueryable(); - } - } - - private List _routingProfiles; - public IQueryable RoutingProfiles - { - get - { - if (!_routingProfiles.IsNullOrEmpty()) - { - return _routingProfiles.AsQueryable(); - } - - _routingProfiles = new List(); - var filePath = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, "routing-profile.json"); - if (File.Exists(filePath)) - { - _routingProfiles = JsonSerializer.Deserialize>(File.ReadAllText(filePath), _options); - } - - return _routingProfiles.AsQueryable(); - } - } - public void Add(object entity) { if (entity is Conversation conversation) @@ -680,28 +634,6 @@ public class FileRepository : IBotSharpRepository } #endregion - #region Routing - public void DeleteRoutingItems() - { - throw new NotImplementedException(); - } - - public void DeleteRoutingProfiles() - { - throw new NotImplementedException(); - } - - public List CreateRoutingItems(List routingItems) - { - throw new NotImplementedException(); - } - - public List CreateRoutingProfiles(List profiles) - { - throw new NotImplementedException(); - } - #endregion - #region Private methods private string GetAgentDataDir(string agentId) { diff --git a/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs b/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs index bd2df051..b8827598 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Functions; +using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Routing.Models; namespace BotSharp.Core.Routing; @@ -33,8 +34,13 @@ public class RouteToAgentFn : IFunctionCallback } else { - message.CurrentAgentId = agentId; - message.ExecutionResult = $"Routed to {args.AgentName}"; + var db = _services.GetRequiredService(); + var record = db.Agents.FirstOrDefault(x => x.Name.ToLower() == args.AgentName.ToLower()); + if (record != null) + { + message.CurrentAgentId = record.Id; + message.ExecutionResult = $"Routing to {args.AgentName}"; + } } } @@ -51,23 +57,23 @@ public class RouteToAgentFn : IFunctionCallback { var args = JsonSerializer.Deserialize(message.FunctionArgs); var router = _services.GetRequiredService(); - var routingRule = router.GetRecordByName(args.AgentName); - if (routingRule == null) + var routingRules = router.GetRulesByName(args.AgentName); + + if (routingRules == null || !routingRules.Any()) { agentId = message.CurrentAgentId; - message.ExecutionResult = $"Can't find agent {args.AgentName}"; - return true; + return false; } - agentId = routingRule.AgentId; + agentId = routingRules.First().AgentId; // Add routed agent message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "route_to", agentId); // Check required fields var root = JsonSerializer.Deserialize(message.FunctionArgs); var missingFields = new List(); - foreach (var field in routingRule.RequiredFields) + foreach (var field in routingRules.Where(x => x.Required).Select(x => x.Field)) { if (!root.EnumerateObject().Any(x => x.Name == field)) { @@ -96,16 +102,17 @@ public class RouteToAgentFn : IFunctionCallback { // Add field to args message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "missing_fields", missingFields); - message.ExecutionResult = $"missing some information: [{string.Join(',', missingFields)}]"; + message.ExecutionResult = $"missing some information: {string.Join(',', missingFields)}"; // Handle redirect + var routingRule = routingRules.FirstOrDefault(x => missingFields.Contains(x.Field)); if (!string.IsNullOrEmpty(routingRule.RedirectTo)) { - agentId = routingRule.RedirectTo; - var agent = router.GetRecordByAgentId(agentId); + var db = _services.GetRequiredService(); + var record = db.Agents.First(x => x.Id == routingRule.RedirectTo); // Add redirected agent - message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", agent.Name); + message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", record.Name); } else { diff --git a/src/Infrastructure/BotSharp.Core/Routing/Router.cs b/src/Infrastructure/BotSharp.Core/Routing/Router.cs index 1194cc4d..dfc0c92f 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Router.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Router.cs @@ -31,34 +31,44 @@ public class Router : IAgentRouting #if !DEBUG [MemoryCache(10 * 60)] #endif - public RoutingItem[] GetRoutingRecords() + protected RoutingRule[] GetRoutingRecords() { var db = _services.GetRequiredService(); - var records = db.RoutingItems.ToArray(); - var profiles = db.RoutingProfiles.ToList(); - - if (!profiles.IsNullOrEmpty()) + var agents = db.Agents.Where(x => !x.Disabled && x.AllowRouting).ToArray(); + var records = agents.SelectMany(x => { - var state = _services.GetRequiredService(); - var name = state.GetState("channel"); - var specifiedProfile = profiles.FirstOrDefault(x => x.Name == name); - if (specifiedProfile != null) + x.RoutingRules.ForEach(r => { - records = records.Where(x => specifiedProfile.AgentIds.Contains(x.AgentId)).ToArray(); - } + r.AgentId = x.Id; + r.AgentName = x.Name; + }); + return x.RoutingRules; + }).ToArray(); + + // Filter agents by profile + var state = _services.GetRequiredService(); + var name = state.GetState("channel"); + var specifiedProfile = agents.FirstOrDefault(x => x.Profiles.Contains(name)); + if (specifiedProfile != null) + { + records = records.Where(x => specifiedProfile.Profiles.Contains(name)).ToArray(); } return records; } - public RoutingItem GetRecordByName(string name) + public RoutingRule[] GetRulesByName(string name) { - return GetRoutingRecords().FirstOrDefault(x => x.Name.ToLower() == name.ToLower()); + return GetRoutingRecords() + .Where(x => x.AgentName.ToLower() == name.ToLower()) + .ToArray(); } - public RoutingItem GetRecordByAgentId(string id) + public RoutingRule[] GetRulesByAgentId(string id) { - return GetRoutingRecords().FirstOrDefault(x => x.AgentId == id); + return GetRoutingRecords() + .Where(x => x.AgentId == id) + .ToArray(); } } diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingHook.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingHook.cs index 851a9a60..4cbeae48 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingHook.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingHook.cs @@ -1,3 +1,6 @@ +using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Routing.Models; + namespace BotSharp.Core.Routing; public class RoutingHook : AgentHookBase @@ -9,10 +12,19 @@ public class RoutingHook : AgentHookBase public override bool OnInstructionLoaded(string template, Dictionary dict) { + var db = _services.GetRequiredService(); + var agents = db.Agents.Where(x => !x.Disabled && x.AllowRouting).ToArray(); + var router = _services.GetRequiredService(); - dict["routing_records"] = router.GetRoutingRecords() - .Where(x => !x.Disabled) - .ToList(); + dict["routing_records"] = agents.Select(x => new RoutingItem + { + AgentId = x.Id, + Description = x.Description, + Name = x.Name, + RequiredFields = x.RoutingRules.Where(x => x.Required) + .Select(x => x.Field) + .ToArray() + }).ToArray(); return true; } } diff --git a/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Create.cs b/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Create.cs deleted file mode 100644 index 21d0f7e5..00000000 --- a/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Create.cs +++ /dev/null @@ -1,66 +0,0 @@ -using BotSharp.Abstraction.Repositories; -using BotSharp.Abstraction.Routing.Models; -using System.IO; - -namespace BotSharp.Core.Routing.Services; - -public partial class RoutingService -{ - public async Task> CreateRoutingItems(List routingItems) - { - var db = _services.GetRequiredService(); - var items = FetchRoutingItemsFromFile(); - - if (items.IsNullOrEmpty()) - { - items = routingItems?.ToList() ?? new List(); - } - - var savedItems = db.CreateRoutingItems(items); - return await Task.FromResult(savedItems.ToList()); - } - - public async Task> CreateRoutingProfiles(List routingProfiles) - { - var db = _services.GetRequiredService(); - var profiles = FetchRoutingProfilesFromFile(); - - if (profiles.IsNullOrEmpty()) - { - profiles = routingProfiles?.ToList() ?? new List(); - } - - var savedProfiles = db.CreateRoutingProfiles(profiles); - return await Task.FromResult(savedProfiles.ToList()); - } - - private List FetchRoutingItemsFromFile() - { - var routingItems = new List(); - var dbSettings = _services.GetRequiredService(); - var agentSettings = _services.GetRequiredService(); - var filePath = Path.Combine(dbSettings.FileRepository, agentSettings.DataDir, "route.json"); - - if (File.Exists(filePath)) - { - routingItems = JsonSerializer.Deserialize>(File.ReadAllText(filePath), _options); - } - - return routingItems ?? new List(); - } - - private List FetchRoutingProfilesFromFile() - { - var routingProfiles = new List(); - var dbSettings = _services.GetRequiredService(); - var agentSettings = _services.GetRequiredService(); - var filePath = Path.Combine(dbSettings.FileRepository, agentSettings.DataDir, "routing-profile.json"); - - if (File.Exists(filePath)) - { - routingProfiles = JsonSerializer.Deserialize>(File.ReadAllText(filePath), _options); - } - - return routingProfiles ?? new List(); - } -} diff --git a/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Delete.cs b/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Delete.cs deleted file mode 100644 index b61c3e91..00000000 --- a/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.Delete.cs +++ /dev/null @@ -1,20 +0,0 @@ -using BotSharp.Abstraction.Repositories; - -namespace BotSharp.Core.Routing.Services; - -public partial class RoutingService -{ - public async Task DeleteRoutingItems() - { - var db = _services.GetRequiredService(); - db.DeleteRoutingItems(); - await Task.CompletedTask; - } - - public async Task DeleteRoutingProfiles() - { - var db = _services.GetRequiredService(); - db.DeleteRoutingProfiles(); - await Task.CompletedTask; - } -} diff --git a/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.cs deleted file mode 100644 index dc34cc17..00000000 --- a/src/Infrastructure/BotSharp.Core/Routing/Services/RoutingService.cs +++ /dev/null @@ -1,23 +0,0 @@ -using BotSharp.Abstraction.Repositories; -using BotSharp.Abstraction.Routing; -using BotSharp.Abstraction.Routing.Models; -using System.IO; - -namespace BotSharp.Core.Routing.Services; - -public partial class RoutingService : IRoutingService -{ - private readonly IServiceProvider _services; - private readonly JsonSerializerOptions _options; - - public RoutingService(IServiceProvider service) - { - _services = service; - _options = new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true - }; - } -} diff --git a/src/Infrastructure/BotSharp.Core/Routing/Simulator.cs b/src/Infrastructure/BotSharp.Core/Routing/Simulator.cs index 8bcad2f7..7e3cbf3e 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Simulator.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Simulator.cs @@ -3,6 +3,7 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.MLTasks; +using BotSharp.Abstraction.Repositories; namespace BotSharp.Core.Routing; @@ -40,8 +41,9 @@ public class Simulator response.FunctionArgs = JsonSerializer.Serialize(args.Parameters.Arguments); var router = _services.GetRequiredService(); - var record = router.GetRecordByName(args.Parameters.AgentName); - response.CurrentAgentId = record.AgentId; + var db = _services.GetRequiredService(); + var record = db.Agents.First(x => x.Name.ToLower() == args.Parameters.AgentName); + response.CurrentAgentId = record.Id; } else if (args.Function == "interrupt_task_execution") { @@ -84,8 +86,9 @@ public class Simulator // Retrieve information from specific agent var router = _services.GetRequiredService(); - var record = router.GetRecordByName(args.Parameters.AgentName); - response = await SendMessageToAgent(record.AgentId, new List + var db = _services.GetRequiredService(); + var record = db.Agents.First(x => x.Name.ToLower() == args.Parameters.AgentName); + response = await SendMessageToAgent(record.Id, new List { new RoleDialogModel(AgentRole.User, args.Parameters.Question) }); diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/RoutingController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/RoutingController.cs deleted file mode 100644 index 67f7cb98..00000000 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/RoutingController.cs +++ /dev/null @@ -1,45 +0,0 @@ -using BotSharp.Abstraction.ApiAdapters; -using BotSharp.Abstraction.Routing; -using BotSharp.Abstraction.Routing.Models; -using BotSharp.OpenAPI.ViewModels.Routing; - -namespace BotSharp.OpenAPI.Controllers; - -[Authorize] -[ApiController] -public class RoutingController : ControllerBase, IApiAdapter -{ - private readonly IRoutingService _routingService; - public RoutingController(IRoutingService routingService) - { - _routingService = routingService; - } - - [HttpPost("/routing/items")] - public async Task> CreateRoutingItems(List routingItems) - { - var items = routingItems?.Select(x => x.ToRoutingItem())?.ToList() ?? new List(); - var savedItems = await _routingService.CreateRoutingItems(items); - return savedItems.Select(x => RoutingItemViewModel.FromRoutingItem(x)).ToList(); - } - - [HttpPost("/routing/profiles")] - public async Task> CreateRoutingProfiles(List routingProfiles) - { - var profiles = routingProfiles?.Select(x => x.ToRoutingProfile())?.ToList() ?? new List(); - var savedProfiles = await _routingService.CreateRoutingProfiles(profiles); - return savedProfiles.Select(x => RoutingProfileViewModel.FromRoutingProfile(x)).ToList(); - } - - [HttpDelete("/routing/items")] - public async Task RemoveRoutingItems() - { - await _routingService.DeleteRoutingItems(); - } - - [HttpDelete("/routing/profiles")] - public async Task RemoveRoutingProfiles() - { - await _routingService.DeleteRoutingProfiles(); - } -} diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemCreationModel.cs deleted file mode 100644 index 941b7332..00000000 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemCreationModel.cs +++ /dev/null @@ -1,26 +0,0 @@ -using BotSharp.Abstraction.Routing.Models; - -namespace BotSharp.OpenAPI.ViewModels.Routing; - -public class RoutingItemCreationModel -{ - public string AgentId { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public List RequiredFields { get; set; } = new List(); - public string? RedirectTo { get; set; } - public bool Disabled { get; set; } - - public RoutingItem ToRoutingItem() - { - return new RoutingItem - { - AgentId = AgentId, - Name = Name, - Description = Description, - RequiredFields = RequiredFields, - RedirectTo = RedirectTo, - Disabled = Disabled - }; - } -} diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemViewModel.cs deleted file mode 100644 index 93be7d6e..00000000 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingItemViewModel.cs +++ /dev/null @@ -1,28 +0,0 @@ -using BotSharp.Abstraction.Routing.Models; - -namespace BotSharp.OpenAPI.ViewModels.Routing; - -public class RoutingItemViewModel -{ - public string Id { get; set; } - public string AgentId { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public List RequiredFields { get; set; } = new List(); - public string? RedirectTo { get; set; } - public bool Disabled { get; set; } - - public static RoutingItemViewModel FromRoutingItem(RoutingItem routingItem) - { - return new RoutingItemViewModel - { - Id = routingItem.Id, - AgentId = routingItem.AgentId, - Name = routingItem.Name, - Description = routingItem.Description, - RequiredFields = routingItem.RequiredFields, - RedirectTo = routingItem.RedirectTo, - Disabled = routingItem.Disabled - }; - } -} diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileCreationModel.cs deleted file mode 100644 index cd06fcb0..00000000 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileCreationModel.cs +++ /dev/null @@ -1,18 +0,0 @@ -using BotSharp.Abstraction.Routing.Models; - -namespace BotSharp.OpenAPI.ViewModels.Routing; - -public class RoutingProfileCreationModel -{ - public string Name { get; set; } - public List AgentIds { get; set; } - - public RoutingProfile ToRoutingProfile() - { - return new RoutingProfile - { - Name = Name, - AgentIds = AgentIds, - }; - } -} diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileViewModel.cs deleted file mode 100644 index b20b5377..00000000 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Routing/RoutingProfileViewModel.cs +++ /dev/null @@ -1,20 +0,0 @@ -using BotSharp.Abstraction.Routing.Models; - -namespace BotSharp.OpenAPI.ViewModels.Routing; - -public class RoutingProfileViewModel -{ - public string Id { get; set; } - public string Name { get; set; } - public List AgentIds { get; set; } - - public static RoutingProfileViewModel FromRoutingProfile(RoutingProfile profile) - { - return new RoutingProfileViewModel - { - Id = profile.Id, - Name = profile.Name, - AgentIds = profile.AgentIds, - }; - } -} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index 921067d1..6f3ece02 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -1,6 +1,5 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Models; using BotSharp.Plugin.MongoStorage.Collections; @@ -137,54 +136,6 @@ public class MongoRepository : IBotSharpRepository } } - private List _routingItems; - public IQueryable RoutingItems - { - get - { - if (!_routingItems.IsNullOrEmpty()) - { - return _routingItems.AsQueryable(); - } - - var routingItemDocs = _dc.RoutingItems?.AsQueryable()?.ToList() ?? new List(); - _routingItems = routingItemDocs.Select(x => new RoutingItem - { - Id = x.Id.ToString(), - AgentId = x.AgentId.ToString(), - Description = x.Description, - RequiredFields = x.RequiredFields, - RedirectTo = x.RedirectTo.ToString(), - Disabled = x.Disabled - }).ToList(); - - return _routingItems.AsQueryable(); - } - } - - private List _routingProfiles; - public IQueryable RoutingProfiles - { - get - { - if (!_routingProfiles.IsNullOrEmpty()) - { - return _routingProfiles.AsQueryable(); - } - - var routingProfilDocs = _dc.RoutingProfiles?.AsQueryable()?.ToList() ?? new List(); - _routingProfiles = routingProfilDocs.Select(x => new RoutingProfile - { - Id = x.Id.ToString(), - Name = x.Name, - AgentIds = x.AgentIds?.Select(x => x.ToString())?.ToList() ?? new List() - }).ToList(); - - return _routingProfiles.AsQueryable(); - } - } - - List _changedTableNames = new List(); public void Add(object entity) { @@ -667,60 +618,4 @@ public class MongoRepository : IBotSharpRepository _dc.Users.InsertOne(userCollection); } #endregion - - #region Routing - public void DeleteRoutingItems() - { - _dc.RoutingItems.DeleteMany(Builders.Filter.Empty); - } - - public void DeleteRoutingProfiles() - { - _dc.RoutingProfiles.DeleteMany(Builders.Filter.Empty); - } - - public List CreateRoutingItems(List routingItems) - { - var collections = routingItems?.Select(x => new RoutingItemCollection - { - Id = Guid.NewGuid(), - AgentId = Guid.Parse(x.AgentId), - Name = x.Name, - Description = x.Description, - RequiredFields = x.RequiredFields, - RedirectTo = !string.IsNullOrEmpty(x.RedirectTo) ? Guid.Parse(x.RedirectTo) : null, - Disabled = x.Disabled - })?.ToList() ?? new List(); - - _dc.RoutingItems.InsertMany(collections); - return collections.Select(x => new RoutingItem - { - Id = x.Id.ToString(), - AgentId = x.AgentId.ToString(), - Name = x.Name, - Description = x.Description, - RequiredFields = x.RequiredFields, - RedirectTo = x.RedirectTo?.ToString(), - Disabled = x.Disabled - }).ToList(); - } - - public List CreateRoutingProfiles(List profiles) - { - var collections = profiles?.Select(x => new RoutingProfileCollection - { - Id = Guid.NewGuid(), - Name = x.Name, - AgentIds = x.AgentIds.Select(x => Guid.Parse(x)).ToList() - })?.ToList() ?? new List(); - - _dc.RoutingProfiles.InsertMany(collections); - return collections.Select(x => new RoutingProfile - { - Id = x.Id.ToString(), - Name = x.Name, - AgentIds = x.AgentIds.Select(x => x.ToString()).ToList() - }).ToList(); - } - #endregion }