diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs new file mode 100644 index 00000000..5f56004a --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs @@ -0,0 +1,13 @@ +namespace BotSharp.Abstraction.Agents.Enums; + +public enum AgentField +{ + All = 1, + Name, + Description, + IsPublic, + Instruction, + Function, + Template, + Response +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs index 6af6f4b0..83564458 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs @@ -17,7 +17,7 @@ public interface IAgentService Task GetAgent(string id); Task DeleteAgent(string id); - Task UpdateAgent(Agent agent); + Task UpdateAgent(Agent agent, AgentField updateField); Task UpdateAgentFromFile(string id); string GetDataDir(); string GetAgentDataDir(string agentId); diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 2582c993..72e7ccca 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Models; @@ -15,27 +16,32 @@ public interface IBotSharpRepository int Transaction(Action action); void Add(object entity); + #region User User GetUserByEmail(string email); void CreateUser(User user); - void UpdateAgent(Agent agent); + #endregion + #region Agent + void UpdateAgent(Agent agent, AgentField field); + Agent GetAgent(string agentId); + List GetAgentResponses(string agentId, string prefix, string intent); + string GetAgentTemplate(string agentId, string templateName); + #endregion + + #region Conversation + void CreateNewConversation(Conversation conversation); + string GetConversationDialog(string conversationId); + void UpdateConversationDialog(string conversationId, string dialogs); + List GetConversationStates(string conversationId); + void UpdateConversationStates(string conversationId, List states); + Conversation GetConversation(string conversationId); + List GetConversations(string userId); + #endregion + + #region Routing List CreateRoutingItems(List routingItems); List CreateRoutingProfiles(List profiles); void DeleteRoutingItems(); void DeleteRoutingProfiles(); - - Agent GetAgent(string agentId); - List GetAgentResponses(string agentId, string prefix, string intent); - - void CreateNewConversation(Conversation conversation); - string GetConversationDialog(string conversationId); - void UpdateConversationDialog(string conversationId, string dialogs); - - List GetConversationStates(string conversationId); - void UpdateConversationStates(string conversationId, List states); - - Conversation GetConversation(string conversationId); - List GetConversations(string userId); - - string GetAgentTemplate(string agentId, string templateName); + #endregion } diff --git a/src/Infrastructure/BotSharp.Abstraction/Using.cs b/src/Infrastructure/BotSharp.Abstraction/Using.cs index 1a298f42..ff0946ad 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Using.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Using.cs @@ -5,4 +5,5 @@ global using System.Linq; global using System.Threading.Tasks; global using System.ComponentModel.DataAnnotations; global using BotSharp.Abstraction.Agents.Models; -global using BotSharp.Abstraction.Conversations.Models; \ No newline at end of file +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/Agents/Services/AgentService.CreateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs index 0cd24632..567a3dac 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs @@ -8,11 +8,9 @@ public partial class AgentService { public async Task CreateAgent(Agent agent) { - var db = _services.GetRequiredService(); - - var agentRecord = (from a in db.Agents - join ua in db.UserAgents on a.Id equals ua.AgentId - join u in db.Users on ua.UserId equals u.Id + var agentRecord = (from a in _db.Agents + join ua in _db.UserAgents on a.Id equals ua.AgentId + join u in _db.Users on ua.UserId equals u.Id where u.ExternalId == _user.Id && a.Name == agent.Name select a).FirstOrDefault(); @@ -43,7 +41,7 @@ public partial class AgentService .SetResponses(foundAgent.Responses); } - var user = db.Users.FirstOrDefault(x => x.ExternalId == _user.Id); + var user = _db.Users.FirstOrDefault(x => x.ExternalId == _user.Id); var userAgentRecord = new UserAgent { Id = Guid.NewGuid().ToString(), @@ -53,10 +51,10 @@ public partial class AgentService UpdatedTime = DateTime.UtcNow }; - db.Transaction(delegate + _db.Transaction(delegate { - db.Add(agentRecord); - db.Add(userAgentRecord); + _db.Add(agentRecord); + _db.Add(userAgentRecord); }); return agentRecord; @@ -86,7 +84,7 @@ public partial class AgentService private string FetchInstructionFromFile(string fileDir) { - var file = Path.Combine(fileDir, "instruction.liquid"); + var file = Path.Combine(fileDir, $"instruction.{_agentSettings.TemplateFormat}"); if (!File.Exists(file)) return null; var instruction = File.ReadAllText(file); @@ -102,7 +100,7 @@ public partial class AgentService var splits = fileName.ToLower().Split('.'); var name = splits[0]; var extension = splits[1]; - if (name != "instruction" && extension == "liquid") + if (name != "instruction" && extension == _agentSettings.TemplateFormat) { var content = File.ReadAllText(file); templates.Add(new AgentTemplate(name, content)); diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs index f65b7748..4fde0e74 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs @@ -7,10 +7,9 @@ public partial class AgentService { public async Task> GetAgents() { - var db = _services.GetRequiredService(); - var query = from a in db.Agents - join ua in db.UserAgents on a.Id equals ua.AgentId - join u in db.Users on ua.UserId equals u.Id + var query = from a in _db.Agents + join ua in _db.UserAgents on a.Id equals ua.AgentId + join u in _db.Users on ua.UserId equals u.Id where ua.UserId == _user.Id || u.ExternalId == _user.Id || a.IsPublic select a; return query.ToList(); @@ -21,8 +20,7 @@ public partial class AgentService #endif public async Task GetAgent(string id) { - var db = _services.GetRequiredService(); - var profile = db.GetAgent(id); + var profile = _db.GetAgent(id); var instructionFile = profile?.Instruction; if (instructionFile != null) diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index 55a60ad5..7f6b619b 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -6,44 +6,38 @@ namespace BotSharp.Core.Agents.Services; public partial class AgentService { - public async Task UpdateAgent(Agent agent) + public async Task UpdateAgent(Agent agent, AgentField updateField) { - var db = _services.GetRequiredService(); - - var record = (from a in db.Agents - join ua in db.UserAgents on a.Id equals ua.AgentId - join u in db.Users on ua.UserId equals u.Id - where (ua.UserId == _user.Id || u.ExternalId == _user.Id) && - a.Id == agent.Id - select a).FirstOrDefault(); + if (agent == null || string.IsNullOrEmpty(agent.Id)) return; + var record = FindAgent(agent.Id); if (record == null) return; - record.Name = agent.Name; + record.Name = agent.Name ?? string.Empty; + record.Description = agent.Description ?? string.Empty; + record.Instruction = agent.Instruction ?? string.Empty; + record.Functions = agent.Functions ?? new List(); + record.Templates = agent.Templates ?? new List(); + record.Responses = agent.Responses ?? new List(); - if (!string.IsNullOrEmpty(agent.Description)) - record.Description = agent.Description; - - if (!string.IsNullOrEmpty(agent.Instruction)) - record.Instruction = agent.Instruction; - - if (!agent.Templates.IsNullOrEmpty()) - record.Templates = agent.Templates; - - if (!agent.Functions.IsNullOrEmpty()) - record.Functions = agent.Functions; - - if (!agent.Responses.IsNullOrEmpty()) - record.Responses = agent.Responses; - - db.UpdateAgent(record); + _db.UpdateAgent(record, updateField); await Task.CompletedTask; } + private Agent FindAgent(string agentId) + { + var record = (from a in _db.Agents + join ua in _db.UserAgents on a.Id equals ua.AgentId + join u in _db.Users on ua.UserId equals u.Id + where (ua.UserId == _user.Id || u.ExternalId == _user.Id) && + a.Id == agentId + select a).FirstOrDefault(); + return record; + } + public async Task UpdateAgentFromFile(string id) { - var db = _services.GetRequiredService(); - var agent = db.Agents?.FirstOrDefault(x => x.Id == id); + var agent = _db.Agents?.FirstOrDefault(x => x.Id == id); if (agent == null) return; @@ -64,10 +58,9 @@ public partial class AgentService .SetFunctions(foundAgent.Functions) .SetResponses(foundAgent.Responses); - db.UpdateAgent(clonedAgent); + _db.UpdateAgent(clonedAgent, AgentField.All); } - await Task.CompletedTask; } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs index 37d45601..6b613503 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.Repositories; -using Microsoft.Extensions.Logging; using System.IO; namespace BotSharp.Core.Agents.Services; @@ -7,20 +6,23 @@ namespace BotSharp.Core.Agents.Services; public partial class AgentService : IAgentService { private readonly IServiceProvider _services; + private readonly IBotSharpRepository _db; private readonly ILogger _logger; private readonly IUserIdentity _user; - private readonly AgentSettings _settings; + private readonly AgentSettings _agentSettings; private readonly JsonSerializerOptions _options; - public AgentService(IServiceProvider services, + public AgentService(IServiceProvider services, + IBotSharpRepository db, ILogger logger, IUserIdentity user, - AgentSettings settings) + AgentSettings agentSettings) { _services = services; + _db = db; _logger = logger; _user = user; - _settings = settings; + _agentSettings = agentSettings; _options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, @@ -38,7 +40,7 @@ public partial class AgentService : IAgentService public string GetAgentDataDir(string agentId) { var dbSettings = _services.GetRequiredService(); - var dir = Path.Combine(dbSettings.FileRepository, _settings.DataDir, agentId); + var dir = Path.Combine(dbSettings.FileRepository, _agentSettings.DataDir, agentId); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index e54d0d13..d8f6ef52 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -71,77 +71,55 @@ public class BotSharpDbContext : Database, IBotSharpRepository } - - public void CreateNewConversation(Conversation conversation) - { - throw new NotImplementedException(); - } - - public List CreateRoutingItems(List routingItems) - { - throw new NotImplementedException(); - } - - public List CreateRoutingProfiles(List profiles) - { - throw new NotImplementedException(); - } - - public void CreateUser(User user) - { - throw new NotImplementedException(); - } - - public void DeleteRoutingItems() - { - throw new NotImplementedException(); - } - - public void DeleteRoutingProfiles() - { - throw new NotImplementedException(); - } - + #region Agent public Agent GetAgent(string agentId) { throw new NotImplementedException(); } + public void UpdateAgent(Agent agent, AgentField field) + { + throw new NotImplementedException(); + } + + public string GetAgentTemplate(string agentId, string templateName) + { + throw new NotImplementedException(); + } + public List GetAgentResponses(string agentId, string prefix, string intent) { throw new NotImplementedException(); } + #endregion + + + #region Conversation + public void CreateNewConversation(Conversation conversation) + { + throw new NotImplementedException(); + } public Conversation GetConversation(string conversationId) { throw new NotImplementedException(); } - public string GetConversationDialog(string conversationId) - { - throw new NotImplementedException(); - } - public List GetConversations(string userId) { throw new NotImplementedException(); } + public string GetConversationDialog(string conversationId) + { + throw new NotImplementedException(); + } + public List GetConversationStates(string conversationId) { throw new NotImplementedException(); } - public User GetUserByEmail(string email) - { - throw new NotImplementedException(); - } - - public void UpdateAgent(Agent agent) - { - throw new NotImplementedException(); - } - public void UpdateConversationDialog(string conversationId, string dialogs) { throw new NotImplementedException(); @@ -151,9 +129,41 @@ public class BotSharpDbContext : Database, IBotSharpRepository { throw new NotImplementedException(); } + #endregion - public string GetAgentTemplate(string agentId, string templateName) + + #region User + public User GetUserByEmail(string email) { throw new NotImplementedException(); } + + public void CreateUser(User user) + { + 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 ef5489ae..69d369e7 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -4,6 +4,11 @@ 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; public class FileRepository : IBotSharpRepository @@ -66,7 +71,15 @@ public class FileRepository : IBotSharpRepository foreach (var d in Directory.GetDirectories(dir)) { var json = File.ReadAllText(Path.Combine(d, "agent.json")); - _agents.Add(JsonSerializer.Deserialize(json, _options)); + var agent = JsonSerializer.Deserialize(json, _options); + if (agent != null) + { + agent = agent.SetInstruction(FetchInstruction(d)) + .SetTemplates(FetchTemplates(d)) + .SetFunctions(FetchFunctions(d)) + .SetResponses(FetchResponses(d)); + _agents.Add(agent); + } } return _agents.AsQueryable(); } @@ -201,9 +214,7 @@ public class FileRepository : IBotSharpRepository { foreach (var conversation in _conversations) { - var dir = Path.Combine(_dbSettings.FileRepository, - _conversationSettings.DataDir, - conversation.Id); + var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir, conversation.Id); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); @@ -216,9 +227,7 @@ public class FileRepository : IBotSharpRepository { foreach (var agent in _agents) { - var dir = Path.Combine(_dbSettings.FileRepository, - _agentSettings.DataDir, - agent.Id); + var dir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agent.Id); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); @@ -231,9 +240,7 @@ public class FileRepository : IBotSharpRepository { foreach (var user in _users) { - var dir = Path.Combine(_dbSettings.FileRepository, - "users", - user.Id); + var dir = Path.Combine(_dbSettings.FileRepository, "users", user.Id); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); @@ -262,79 +269,189 @@ public class FileRepository : IBotSharpRepository return _changedTableNames.Count; } - public User GetUserByEmail(string email) + + #region Agent + public void UpdateAgent(Agent agent, AgentField field) { - return Users.FirstOrDefault(x => x.Email == email); - } + if (agent == null || string.IsNullOrEmpty(agent.Id)) return; - public void CreateUser(User user) - { - var userId = Guid.NewGuid().ToString(); - var dir = Path.Combine(_dbSettings.FileRepository, "users", userId); - if (!Directory.Exists(dir)) + switch (field) { - Directory.CreateDirectory(dir); + case AgentField.Name: + UpdateAgentName(agent.Id, agent.Name); + break; + case AgentField.Description: + UpdateAgentDescription(agent.Id, agent.Description); + break; + case AgentField.IsPublic: + UpdateAgentIsPublic(agent.Id, agent.IsPublic); + break; + case AgentField.Instruction: + UpdateAgentInstruction(agent.Id, agent.Instruction); + break; + case AgentField.Function: + UpdateAgentFunctions(agent.Id, agent.Functions); + break; + case AgentField.Template: + UpdateAgentTemplates(agent.Id, agent.Templates); + break; + case AgentField.Response: + UpdateAgentResponses(agent.Id, agent.Responses); + break; + case AgentField.All: + UpdateAgentAllFields(agent); + break; + default: + break; } - var path = Path.Combine(dir, "user.json"); - File.WriteAllText(path, JsonSerializer.Serialize(user, _options)); } - public void UpdateAgent(Agent agent) + #region Update Agent Fields + private void UpdateAgentName(string agentId, string name) { + if (string.IsNullOrEmpty(name)) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); if (agent == null) return; - var dir = GetAgentDataDir(agent.Id); + agent.Name = name; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); + } - if (!string.IsNullOrEmpty(agent.Instruction)) + private void UpdateAgentDescription(string agentId, string description) + { + if (string.IsNullOrEmpty(description)) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + agent.Description = description; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); + } + + private void UpdateAgentIsPublic(string agentId, bool isPublic) + { + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + agent.IsPublic = isPublic; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); + } + + private void UpdateAgentInstruction(string agentId, string instruction) + { + if (string.IsNullOrEmpty(instruction)) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + var instructionFile = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, + agentId, $"instruction.{_agentSettings.TemplateFormat}"); + + File.WriteAllText(instructionFile, instruction); + } + + private void UpdateAgentFunctions(string agentId, List inputFunctions) + { + if (inputFunctions.IsNullOrEmpty()) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + var functionFile = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, + agentId, "functions.json"); + + var functions = new List(); + foreach (var function in inputFunctions) { - var instructionFile = Path.Combine(dir, "instruction.liquid"); - File.WriteAllText(instructionFile, agent.Instruction); + var functionDef = JsonSerializer.Deserialize(function, _options); + functions.Add(JsonSerializer.Serialize(functionDef, _options)); } - if (!agent.Functions.IsNullOrEmpty()) + var functionText = JsonSerializer.Serialize(functions, _options); + File.WriteAllText(functionFile, functionText); + } + + private void UpdateAgentTemplates(string agentId, List templates) + { + if (templates.IsNullOrEmpty()) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + var baseDir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId); + + foreach (var file in Directory.GetFiles(baseDir)) { - var functionFile = Path.Combine(dir, "functions.json"); - var functions = new List(); - foreach (var function in agent.Functions) + var fileName = file.Split(Path.DirectorySeparatorChar).Last(); + var splits = fileName.ToLower().Split('.'); + var name = splits[0]; + var extension = splits[1]; + if (name != "instruction" && extension == _agentSettings.TemplateFormat) { - var functionDef = JsonSerializer.Deserialize(function, _options); - functions.Add(JsonSerializer.Serialize(functionDef, _options)); + File.Delete(file); } - - var functionText = JsonSerializer.Serialize(functions, _options); - File.WriteAllText(functionFile, functionText); } - } - private string GetAgentDataDir(string agentId) - { - var dir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId); - if (!Directory.Exists(dir)) + foreach (var template in templates) { - Directory.CreateDirectory(dir); + var file = Path.Combine(baseDir, $"{template.Name}.{_agentSettings.TemplateFormat}"); + File.WriteAllText(file, template.Content); } - return dir; } - public void DeleteRoutingItems() + private void UpdateAgentResponses(string agentId, List responses) { - throw new NotImplementedException(); + if (responses.IsNullOrEmpty()) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + var baseDir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId); + var responseDir = Path.Combine(baseDir, "responses"); + if (!Directory.Exists(responseDir)) + { + Directory.CreateDirectory(responseDir); + } + + foreach (var file in Directory.GetFiles(responseDir)) + { + File.Delete(file); + } + + for (int i = 0; i < responses.Count; i++) + { + var response = responses[i]; + var fileName = $"{response.Prefix}.{response.Intent}.{i}.{_agentSettings.TemplateFormat}"; + var file = Path.Combine(responseDir, fileName); + File.WriteAllText(file, response.Content); + } } - public void DeleteRoutingProfiles() + private void UpdateAgentAllFields(Agent inputAgent) { - throw new NotImplementedException(); - } + var (agent, agentFile) = GetAgentFromFile(inputAgent.Id); + if (agent == null) return; - public List CreateRoutingItems(List routingItems) - { - throw new NotImplementedException(); - } + agent.Name = inputAgent.Name; + agent.Description = inputAgent.Description; + agent.IsPublic = inputAgent.IsPublic; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); - public List CreateRoutingProfiles(List profiles) - { - throw new NotImplementedException(); + UpdateAgentInstruction(inputAgent.Id, inputAgent.Instruction); + UpdateAgentResponses(inputAgent.Id, inputAgent.Responses); + UpdateAgentTemplates(inputAgent.Id, inputAgent.Templates); + UpdateAgentFunctions(inputAgent.Id, inputAgent.Functions); } + #endregion #if !DEBUG [MemoryCache(10 * 60)] @@ -375,26 +492,29 @@ public class FileRepository : IBotSharpRepository return null; } - private string FetchInstruction(string fileDir) + public string GetAgentTemplate(string agentId, string templateName) { - var file = Path.Combine(fileDir, "instruction.liquid"); - if (!File.Exists(file)) return null; + var fileDir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId); + if (!Directory.Exists(fileDir)) return string.Empty; - var instruction = File.ReadAllText(file); - return instruction; - } - - private List FetchFunctions(string fileDir) - { - var file = Path.Combine(fileDir, "functions.json"); - if (!File.Exists(file)) return new List(); - - var functionsJson = File.ReadAllText(file); - var functionDefs = JsonSerializer.Deserialize>(functionsJson, _options); - var functions = functionDefs.Select(x => JsonSerializer.Serialize(x, _options)).ToList(); - return functions; + var lowerTemplateName = templateName?.ToLower(); + foreach (var file in Directory.GetFiles(fileDir)) + { + var fileName = file.Split(Path.DirectorySeparatorChar).Last(); + var splits = fileName.ToLower().Split('.'); + var name = splits[0]; + var extension = splits[1]; + if (name == lowerTemplateName && extension == _agentSettings.TemplateFormat) + { + return File.ReadAllText(file); + } + } + + return string.Empty; } + #endregion + #region Conversation public void CreateNewConversation(Conversation conversation) { var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir, conversation.Id); @@ -473,26 +593,6 @@ public class FileRepository : IBotSharpRepository return curStates; } - private string? FindConversationDirectory(string conversationId) - { - var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir); - - foreach (var d in Directory.GetDirectories(dir)) - { - var path = Path.Combine(d, "conversation.json"); - if (!File.Exists(path)) continue; - - var json = File.ReadAllText(path); - var conv = JsonSerializer.Deserialize(json, _options); - if (conv != null && conv.Id == conversationId) - { - return d; - } - } - - return null; - } - public void UpdateConversationStates(string conversationId, List states) { var localStates = new List(); @@ -559,25 +659,148 @@ public class FileRepository : IBotSharpRepository return records; } + #endregion - public string GetAgentTemplate(string agentId, string templateName) + #region User + public User GetUserByEmail(string email) { - var fileDir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId); - if (!Directory.Exists(fileDir)) return string.Empty; + return Users.FirstOrDefault(x => x.Email == email); + } + + public void CreateUser(User user) + { + var userId = Guid.NewGuid().ToString(); + var dir = Path.Combine(_dbSettings.FileRepository, "users", userId); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + var path = Path.Combine(dir, "user.json"); + File.WriteAllText(path, JsonSerializer.Serialize(user, _options)); + } + #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) + { + var dir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId); + if (!Directory.Exists(dir)) + { + dir = string.Empty; + } + return dir; + } + + private (Agent?, string) GetAgentFromFile(string agentId) + { + var dir = GetAgentDataDir(agentId); + var agentFile = Path.Combine(dir, "agent.json"); + if (!File.Exists(agentFile)) return (null, string.Empty); + + var json = File.ReadAllText(agentFile); + var agent = JsonSerializer.Deserialize(json, _options); + return (agent, agentFile); + } + + private string FetchInstruction(string fileDir) + { + var file = Path.Combine(fileDir, $"instruction.{_agentSettings.TemplateFormat}"); + if (!File.Exists(file)) return string.Empty; + + var instruction = File.ReadAllText(file); + return instruction; + } + + private List FetchFunctions(string fileDir) + { + var file = Path.Combine(fileDir, "functions.json"); + if (!File.Exists(file)) return new List(); + + var functionsJson = File.ReadAllText(file); + var functionDefs = JsonSerializer.Deserialize>(functionsJson, _options); + var functions = functionDefs.Select(x => JsonSerializer.Serialize(x, _options)).ToList(); + return functions; + } + + private List FetchTemplates(string fileDir) + { + var templates = new List(); - var lowerTemplateName = templateName?.ToLower(); foreach (var file in Directory.GetFiles(fileDir)) { var fileName = file.Split(Path.DirectorySeparatorChar).Last(); var splits = fileName.ToLower().Split('.'); var name = splits[0]; var extension = splits[1]; - if (name == lowerTemplateName && extension == "liquid") + if (name != "instruction" && extension == _agentSettings.TemplateFormat) { - return File.ReadAllText(file); + var content = File.ReadAllText(file); + templates.Add(new AgentTemplate(name, content)); } } - return string.Empty; + return templates; } + + private List FetchResponses(string fileDir) + { + var responses = new List(); + var responseDir = Path.Combine(fileDir, "responses"); + if (!Directory.Exists(responseDir)) return responses; + + foreach (var file in Directory.GetFiles(responseDir)) + { + var fileName = file.Split(Path.DirectorySeparatorChar).Last(); + var splits = fileName.ToLower().Split('.'); + var prefix = splits[0]; + var intent = splits[1]; + var content = File.ReadAllText(file); + responses.Add(new AgentResponse(prefix, intent, content)); + } + + return responses; + } + + private string? FindConversationDirectory(string conversationId) + { + var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir); + + foreach (var d in Directory.GetDirectories(dir)) + { + var path = Path.Combine(d, "conversation.json"); + if (!File.Exists(path)) continue; + + var json = File.ReadAllText(path); + var conv = JsonSerializer.Deserialize(json, _options); + if (conv != null && conv.Id == conversationId) + { + return d; + } + } + + return null; + } + #endregion } diff --git a/src/Infrastructure/BotSharp.Core/Using.cs b/src/Infrastructure/BotSharp.Core/Using.cs index d0de3336..41e10730 100644 --- a/src/Infrastructure/BotSharp.Core/Using.cs +++ b/src/Infrastructure/BotSharp.Core/Using.cs @@ -16,6 +16,7 @@ global using BotSharp.Abstraction.Utilities; global using BotSharp.Abstraction.Conversations.Models; global using BotSharp.Abstraction.Agents.Settings; global using BotSharp.Abstraction.Conversations.Settings; +global using BotSharp.Abstraction.Agents.Enums; global using BotSharp.Core.Repository; global using BotSharp.Core.Agents.Services; global using BotSharp.Core.Conversations.Services; diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs index 176d02dc..b5cf73fb 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.ApiAdapters; using BotSharp.OpenAPI.ViewModels.Agents; @@ -13,6 +14,13 @@ public class AgentController : ControllerBase, IApiAdapter _agentService = agentService; } + [HttpGet("/agents")] + public async Task> GetAgents() + { + var agents = await _agentService.GetAgents(); + return agents.Select(x => AgentViewModel.FromAgent(x)).ToList(); + } + [HttpPost("/agent")] public async Task CreateAgent(AgentCreationModel agent) { @@ -20,25 +28,73 @@ public class AgentController : ControllerBase, IApiAdapter return AgentViewModel.FromAgent(createdAgent); } - [HttpPut("/agent/{agentId}")] - public async Task UpdateAgent([FromRoute] string agentId, - [FromBody] AgentUpdateModel agent) - { - var model = agent.ToAgent(); - model.Id = agentId; - await _agentService.UpdateAgent(model); - } - [HttpPut("/agent/file/{agentId}")] public async Task UpdateAgentFromFile([FromRoute] string agentId) { await _agentService.UpdateAgentFromFile(agentId); } - [HttpGet("/agents")] - public async Task> GetAgents() + [HttpPut("/agent/{agentId}/all")] + public async Task UpdateAgent([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) { - var agents = await _agentService.GetAgents(); - return agents.Select(x => AgentViewModel.FromAgent(x)).ToList(); + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.All); + } + + [HttpPut("/agent/{agentId}/name")] + public async Task UpdateAgentName([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.Name); + } + + [HttpPut("/agent/{agentId}/description")] + public async Task UpdateAgentDescription([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.Description); + } + + [HttpPut("/agent/{agentId}/is-public")] + public async Task UpdateAgentIsPublic([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.IsPublic); + } + + [HttpPut("/agent/{agentId}/instruction")] + public async Task UpdateAgentInstruction([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.Instruction); + } + + [HttpPut("/agent/{agentId}/functions")] + public async Task UpdateAgentFunctions([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.Function); + } + + [HttpPut("/agent/{agentId}/templates")] + public async Task UpdateAgenttemplates([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.Template); + } + + [HttpPut("/agent/{agentId}/responses")] + public async Task UpdateAgentResponses([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.Response); } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs index 3d88efc5..3052e5b6 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -4,7 +4,7 @@ namespace BotSharp.OpenAPI.ViewModels.Agents; public class AgentUpdateModel { - public string Name { get; set; } = string.Empty; + public string? Name { get; set; } = string.Empty; public string? Description { get; set; } /// @@ -34,29 +34,16 @@ public class AgentUpdateModel public Agent ToAgent() { - var agent = new Agent + var agent = new Agent() { - Name = Name + Name = Name ?? string.Empty, + Description = Description ?? string.Empty, + Instruction = Instruction ?? string.Empty, + Templates = Templates ?? new List(), + Functions = Functions ?? new List(), + Responses = Responses ?? new List() }; - if (Description != null) - agent.Description = Description; - - if (Instruction != null) - agent.Instruction = Instruction; - - if (!Templates.IsNullOrEmpty()) - agent.Templates = Templates; - - if (Samples != null) - agent.Samples = Samples; - - if (!Functions.IsNullOrEmpty()) - agent.Functions = Functions; - - if (!Responses.IsNullOrEmpty()) - agent.Responses = Responses; - return agent; } } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs index bfa54538..ec9c29ad 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -12,6 +12,7 @@ public class AgentViewModel public List Functions { get; set; } public List Responses { get; set; } public bool IsPublic { get; set; } + public DateTime CreatedDateTime { get; set; } public DateTime UpdatedDateTime { get; set; } public static AgentViewModel FromAgent(Agent agent) @@ -26,6 +27,7 @@ public class AgentViewModel Functions = agent.Functions, Responses = agent.Responses, IsPublic= agent.IsPublic, + CreatedDateTime = agent.CreatedDateTime, UpdatedDateTime = agent.UpdatedDateTime }; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index c42ec29d..921067d1 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -332,61 +332,127 @@ public class MongoRepository : IBotSharpRepository return _changedTableNames.Count; } - public User GetUserByEmail(string email) - { - var user = Users.FirstOrDefault(x => x.Email == email); - return user != null ? new User - { - Id = user.Id.ToString(), - FirstName = user.FirstName, - LastName = user.LastName, - Email = user.Email, - Password = user.Password, - Salt = user.Salt, - ExternalId = user.ExternalId, - CreatedTime = user.CreatedTime, - UpdatedTime = user.UpdatedTime - } : null; - } - - public void CreateUser(User user) - { - if (user == null) return; - - var userCollection = new UserCollection - { - Id = Guid.NewGuid(), - FirstName = user.FirstName, - LastName = user.LastName, - Salt = user.Salt, - Password = user.Password, - Email = user.Email, - ExternalId = user.ExternalId, - CreatedTime = DateTime.UtcNow, - UpdatedTime = DateTime.UtcNow - }; - - _dc.Users.InsertOne(userCollection); - } - - public void UpdateAgent(Agent agent) + #region Agent + public void UpdateAgent(Agent agent, AgentField field) { if (agent == null || string.IsNullOrEmpty(agent.Id)) return; - var agentCollection = new AgentCollection + switch (field) { - Id = Guid.Parse(agent.Id), - Name = agent.Name, - Description = agent.Description, - Instruction = agent.Instruction, - Templates = agent.Templates, - Functions = agent.Functions, - Responses = agent.Responses, - IsPublic = agent.IsPublic, - UpdatedTime = DateTime.UtcNow - }; + case AgentField.Name: + UpdateAgentName(agent.Id, agent.Name); + break; + case AgentField.Description: + UpdateAgentDescription(agent.Id, agent.Description); + break; + case AgentField.IsPublic: + UpdateAgentIsPublic(agent.Id, agent.IsPublic); + break; + case AgentField.Instruction: + UpdateAgentInstruction(agent.Id, agent.Instruction); + break; + case AgentField.Function: + UpdateAgentFunctions(agent.Id, agent.Functions); + break; + case AgentField.Template: + UpdateAgentTemplates(agent.Id, agent.Templates); + break; + case AgentField.Response: + UpdateAgentResponses(agent.Id, agent.Responses); + break; + case AgentField.All: + UpdateAgentAllFields(agent); + break; + default: + break; + } + } + #region Update Agent Fields + private void UpdateAgentName(string agentId, string name) + { + if (string.IsNullOrEmpty(name)) return; + var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); + var update = Builders.Update + .Set(x => x.Name, name) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + + private void UpdateAgentDescription(string agentId, string description) + { + if (string.IsNullOrEmpty(description)) return; + + var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); + var update = Builders.Update + .Set(x => x.Description, description) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + + private void UpdateAgentIsPublic(string agentId, bool isPublic) + { + var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); + var update = Builders.Update + .Set(x => x.IsPublic, isPublic) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + + private void UpdateAgentInstruction(string agentId, string instruction) + { + if (string.IsNullOrEmpty(instruction)) return; + + var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); + var update = Builders.Update + .Set(x => x.Instruction, instruction) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + + private void UpdateAgentFunctions(string agentId, List functions) + { + if (functions.IsNullOrEmpty()) return; + + var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); + var update = Builders.Update + .Set(x => x.Functions, functions) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + + private void UpdateAgentTemplates(string agentId, List templates) + { + if (templates.IsNullOrEmpty()) return; + + var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); + var update = Builders.Update + .Set(x => x.Templates, templates) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + + private void UpdateAgentResponses(string agentId, List responses) + { + if (responses.IsNullOrEmpty()) return; + + var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); + var update = Builders.Update + .Set(x => x.Responses, responses) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + + private void UpdateAgentAllFields(Agent agent) + { var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agent.Id)); var update = Builders.Update .Set(x => x.Name, agent.Name) @@ -396,63 +462,19 @@ public class MongoRepository : IBotSharpRepository .Set(x => x.Functions, agent.Functions) .Set(x => x.Responses, agent.Responses) .Set(x => x.IsPublic, agent.IsPublic) - .Set(x => x.UpdatedTime, agent.UpdatedDateTime); + .Set(x => x.UpdatedTime, DateTime.UtcNow); _dc.Agents.UpdateOne(filter, update); } + #endregion - public void DeleteRoutingItems() + + + + public Agent GetAgent(string agentId) { - _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(); + var foundAgent = Agents.FirstOrDefault(x => x.Id == agentId); + return foundAgent; } public List GetAgentResponses(string agentId, string prefix, string intent) @@ -464,12 +486,16 @@ public class MongoRepository : IBotSharpRepository return agent.Responses.Where(x => x.Prefix == prefix && x.Intent == intent).Select(x => x.Content).ToList(); } - public Agent GetAgent(string agentId) + public string GetAgentTemplate(string agentId, string templateName) { - var foundAgent = Agents.FirstOrDefault(x => x.Id == agentId); - return foundAgent; - } + var agent = Agents.FirstOrDefault(x => x.Id == agentId); + if (agent == null) return string.Empty; + return agent.Templates?.FirstOrDefault(x => x.Name == templateName.ToLower())?.Content ?? string.Empty; + } + #endregion + + #region Conversation public void CreateNewConversation(Conversation conversation) { if (conversation == null) return; @@ -565,7 +591,7 @@ public class MongoRepository : IBotSharpRepository if (conv == null) return null; return new Conversation - { + { Id = conv.Id.ToString(), AgentId = conv.AgentId.ToString(), UserId = conv.UserId.ToString(), @@ -601,12 +627,100 @@ public class MongoRepository : IBotSharpRepository return records; } + #endregion - public string GetAgentTemplate(string agentId, string templateName) + #region User + public User GetUserByEmail(string email) { - var agent = Agents.FirstOrDefault(x => x.Id == agentId); - if (agent == null) return string.Empty; - - return agent.Templates?.FirstOrDefault(x => x.Name == templateName.ToLower())?.Content ?? string.Empty; + var user = Users.FirstOrDefault(x => x.Email == email); + return user != null ? new User + { + Id = user.Id.ToString(), + FirstName = user.FirstName, + LastName = user.LastName, + Email = user.Email, + Password = user.Password, + Salt = user.Salt, + ExternalId = user.ExternalId, + CreatedTime = user.CreatedTime, + UpdatedTime = user.UpdatedTime + } : null; } + + public void CreateUser(User user) + { + if (user == null) return; + + var userCollection = new UserCollection + { + Id = Guid.NewGuid(), + FirstName = user.FirstName, + LastName = user.LastName, + Salt = user.Salt, + Password = user.Password, + Email = user.Email, + ExternalId = user.ExternalId, + CreatedTime = DateTime.UtcNow, + UpdatedTime = DateTime.UtcNow + }; + + _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 } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs index e1de896f..5debd75f 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs @@ -3,9 +3,8 @@ global using System.Collections.Generic; global using System.Text; global using System.Threading.Tasks; global using System.Linq; -global using System.Text.Json; global using BotSharp.Abstraction.Repositories; -global using BotSharp.Abstraction.Repositories.Records; +global using BotSharp.Abstraction.Agents.Enums; global using BotSharp.Abstraction.Utilities; global using BotSharp.Abstraction.Plugins; global using Microsoft.Extensions.Configuration;