diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs index a7e273d38..975a17d63 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs @@ -18,4 +18,9 @@ public class FunctionParametersDef [JsonPropertyName("required")] public List Required { get; set; } = new List(); + + public FunctionParametersDef() + { + + } } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 7212ab254..daccc6a91 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -56,7 +56,7 @@ public async Task NewConversation(Conversation sess) var dbSettings = _services.GetRequiredService(); var conversationSettings = _services.GetRequiredService(); var user = db.Users.FirstOrDefault(x => x.ExternalId == _user.Id); - var foundUserId = user?.Id ?? _user.Id; + var foundUserId = user?.Id ?? string.Empty; var record = sess; record.Id = sess.Id.IfNullOrEmptyAs(Guid.NewGuid().ToString()); diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs index bd6a0c439..a4830d8d7 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs @@ -1,8 +1,6 @@ using BotSharp.Abstraction.Agents.Enums; -using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.ApiAdapters; using BotSharp.Abstraction.Routing; -using BotSharp.Abstraction.Routing.Settings; using BotSharp.OpenAPI.ViewModels.Agents; namespace BotSharp.OpenAPI.Controllers; diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs index eec7a5591..f6d368d33 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs @@ -1,5 +1,3 @@ -using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Functions.Models; using BotSharp.Plugin.MongoStorage.Models; namespace BotSharp.Plugin.MongoStorage.Collections; @@ -9,9 +7,9 @@ public class AgentCollection : MongoBase public string Name { get; set; } public string Description { get; set; } public string Instruction { get; set; } - public List Templates { get; set; } - public List Functions { get; set; } - public List Responses { get; set; } + public List Templates { get; set; } + public List Functions { get; set; } + public List Responses { get; set; } public bool IsPublic { get; set; } public bool AllowRouting { get; set; } public bool Disabled { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentResponseMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentResponseMongoElement.cs new file mode 100644 index 000000000..ee556549f --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentResponseMongoElement.cs @@ -0,0 +1,30 @@ +using BotSharp.Abstraction.Agents.Models; + +namespace BotSharp.Plugin.MongoStorage.Models; + +public class AgentResponseMongoElement +{ + public string Prefix { get; set; } + public string Intent { get; set; } + public string Content { get; set; } + + public static AgentResponseMongoElement ToMongoElement(AgentResponse response) + { + return new AgentResponseMongoElement + { + Prefix = response.Prefix, + Intent = response.Intent, + Content = response.Content + }; + } + + public static AgentResponse ToDomainElement(AgentResponseMongoElement mongoResponse) + { + return new AgentResponse + { + Prefix = mongoResponse.Prefix, + Intent = mongoResponse.Intent, + Content = mongoResponse.Content + }; + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs new file mode 100644 index 000000000..719a11d90 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs @@ -0,0 +1,27 @@ +using BotSharp.Abstraction.Agents.Models; + +namespace BotSharp.Plugin.MongoStorage.Models; + +public class AgentTemplateMongoElement +{ + public string Name { get; set; } + public string Content { get; set; } + + public static AgentTemplateMongoElement ToMongoElement(AgentTemplate template) + { + return new AgentTemplateMongoElement + { + Name = template.Name, + Content = template.Content + }; + } + + public static AgentTemplate ToDomainElement(AgentTemplateMongoElement mongoTemplate) + { + return new AgentTemplate + { + Name = mongoTemplate.Name, + Content = mongoTemplate.Content + }; + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/FunctionDefMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/FunctionDefMongoElement.cs new file mode 100644 index 000000000..d99435771 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/FunctionDefMongoElement.cs @@ -0,0 +1,58 @@ +using BotSharp.Abstraction.Functions.Models; +using System.Text.Json; + +namespace BotSharp.Plugin.MongoStorage.Models; + +public class FunctionDefMongoElement +{ + public string Name { get; set; } + public string Description { get; set; } + public FunctionParametersDefMongoElement Parameters { get; set; } = new FunctionParametersDefMongoElement(); + + public FunctionDefMongoElement() + { + + } + + public static FunctionDefMongoElement ToMongoElement(FunctionDef function) + { + return new FunctionDefMongoElement + { + Name = function.Name, + Description = function.Description, + Parameters = new FunctionParametersDefMongoElement + { + Type = function.Parameters.Type, + Properties = JsonSerializer.Serialize(function.Parameters.Properties), + Required = function.Parameters.Required, + } + }; + } + + public static FunctionDef ToDomainElement(FunctionDefMongoElement mongoFunction) + { + return new FunctionDef + { + Name = mongoFunction.Name, + Description = mongoFunction.Description, + Parameters = new FunctionParametersDef + { + Type = mongoFunction.Parameters.Type, + Properties = JsonSerializer.Deserialize(mongoFunction.Parameters.Properties), + Required = mongoFunction.Parameters.Required, + } + }; + } +} + +public class FunctionParametersDefMongoElement +{ + public string Type { get; set; } + public string Properties { get; set; } + public List Required { get; set; } = new List(); + + public FunctionParametersDefMongoElement() + { + + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index d360429f1..ef7afb03e 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -41,9 +41,15 @@ public IQueryable Agents Name = x.Name, Description = x.Description, Instruction = x.Instruction, - Templates = x.Templates, - Functions = x.Functions, - Responses = x.Responses, + Templates = x.Templates? + .Select(t => AgentTemplateMongoElement.ToDomainElement(t))? + .ToList() ?? new List(), + Functions = x.Functions? + .Select(f => FunctionDefMongoElement.ToDomainElement(f))? + .ToList() ?? new List(), + Responses = x.Responses? + .Select(r => AgentResponseMongoElement.ToDomainElement(r))? + .ToList() ?? new List(), IsPublic = x.IsPublic, Disabled = x.Disabled, AllowRouting = x.AllowRouting, @@ -183,7 +189,7 @@ public int Transaction(Action action) { Id = string.IsNullOrEmpty(x.Id) ? Guid.NewGuid() : new Guid(x.Id), AgentId = Guid.Parse(x.AgentId), - UserId = Guid.Parse(x.UserId), + UserId = !string.IsNullOrEmpty(x.UserId) && Guid.TryParse(x.UserId, out var _) ? Guid.Parse(x.UserId) : Guid.Empty, Title = x.Title, States = x.States?.ToKeyValueList() ?? new List(), CreatedTime = x.CreatedTime, @@ -211,9 +217,15 @@ public int Transaction(Action action) Name = x.Name, Description = x.Description, Instruction = x.Instruction, - Templates = x.Templates, - Functions = x.Functions, - Responses = x.Responses, + Templates = x.Templates? + .Select(t => AgentTemplateMongoElement.ToMongoElement(t))? + .ToList() ?? new List(), + Functions = x.Functions? + .Select(f => FunctionDefMongoElement.ToMongoElement(f))? + .ToList() ?? new List(), + Responses = x.Responses? + .Select(r => AgentResponseMongoElement.ToMongoElement(r))? + .ToList() ?? new List(), IsPublic = x.IsPublic, AllowRouting = x.AllowRouting, Disabled = x.Disabled, @@ -281,7 +293,7 @@ public int Transaction(Action action) { Id = string.IsNullOrEmpty(x.Id) ? Guid.NewGuid() : new Guid(x.Id), AgentId = Guid.Parse(x.AgentId), - UserId = Guid.Parse(x.UserId), + UserId = !string.IsNullOrEmpty(x.UserId) && Guid.TryParse(x.UserId, out var _) ? Guid.Parse(x.UserId) : Guid.Empty, CreatedTime = x.CreatedTime, UpdatedTime = x.UpdatedTime }).ToList(); @@ -446,9 +458,10 @@ private void UpdateAgentFunctions(string agentId, List functions) { if (functions.IsNullOrEmpty()) return; + var functionsToUpdate = functions.Select(f => FunctionDefMongoElement.ToMongoElement(f)).ToList(); var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); var update = Builders.Update - .Set(x => x.Functions, functions) + .Set(x => x.Functions, functionsToUpdate) .Set(x => x.UpdatedTime, DateTime.UtcNow); _dc.Agents.UpdateOne(filter, update); @@ -458,9 +471,10 @@ private void UpdateAgentTemplates(string agentId, List templates) { if (templates.IsNullOrEmpty()) return; + var templatesToUpdate = templates.Select(t => AgentTemplateMongoElement.ToMongoElement(t)).ToList(); var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); var update = Builders.Update - .Set(x => x.Templates, templates) + .Set(x => x.Templates, templatesToUpdate) .Set(x => x.UpdatedTime, DateTime.UtcNow); _dc.Agents.UpdateOne(filter, update); @@ -470,9 +484,10 @@ private void UpdateAgentResponses(string agentId, List responses) { if (responses.IsNullOrEmpty()) return; + var responsesToUpdate = responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList(); var filter = Builders.Filter.Eq(x => x.Id, Guid.Parse(agentId)); var update = Builders.Update - .Set(x => x.Responses, responses) + .Set(x => x.Responses, responsesToUpdate) .Set(x => x.UpdatedTime, DateTime.UtcNow); _dc.Agents.UpdateOne(filter, update); @@ -487,11 +502,11 @@ private void UpdateAgentAllFields(Agent agent) .Set(x => x.Disabled, agent.Disabled) .Set(x => x.AllowRouting, agent.AllowRouting) .Set(x => x.Profiles, agent.Profiles) - .Set(x => x.RoutingRules, agent.RoutingRules.Select(x => RoutingRuleMongoElement.ToMongoElement(x)).ToList()) + .Set(x => x.RoutingRules, agent.RoutingRules.Select(r => RoutingRuleMongoElement.ToMongoElement(r)).ToList()) .Set(x => x.Instruction, agent.Instruction) - .Set(x => x.Templates, agent.Templates) - .Set(x => x.Functions, agent.Functions) - .Set(x => x.Responses, agent.Responses) + .Set(x => x.Templates, agent.Templates.Select(t => AgentTemplateMongoElement.ToMongoElement(t)).ToList()) + .Set(x => x.Functions, agent.Functions.Select(f => FunctionDefMongoElement.ToMongoElement(f)).ToList()) + .Set(x => x.Responses, agent.Responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList()) .Set(x => x.IsPublic, agent.IsPublic) .Set(x => x.UpdatedTime, DateTime.UtcNow); @@ -535,7 +550,7 @@ public void CreateNewConversation(Conversation conversation) { Id = !string.IsNullOrEmpty(conversation.Id) ? Guid.Parse(conversation.Id) : Guid.NewGuid(), AgentId = Guid.Parse(conversation.AgentId), - UserId = Guid.Parse(conversation.UserId), + UserId = !string.IsNullOrEmpty(conversation.UserId) && Guid.TryParse(conversation.UserId, out var _) ? Guid.Parse(conversation.UserId) : Guid.Empty, Title = conversation.Title, States = conversation.States?.ToKeyValueList() ?? new List(), CreatedTime = DateTime.UtcNow, @@ -637,7 +652,7 @@ public Conversation GetConversation(string conversationId) public List GetConversations(string userId) { var records = new List(); - if (string.IsNullOrEmpty(userId)) return records; + if (string.IsNullOrEmpty(userId) || !Guid.TryParse(userId, out var _)) return records; var filterByUserId = Builders.Filter.Eq(x => x.UserId, Guid.Parse(userId)); var conversations = _dc.Conversations.Find(filterByUserId).ToList();