diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/LlmCompletionLog.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/LlmCompletionLog.cs new file mode 100644 index 00000000..26f55494 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/LlmCompletionLog.cs @@ -0,0 +1,12 @@ +namespace BotSharp.Abstraction.Conversations.Models; + +public class LlmCompletionLog +{ + public string Id { get; set; } = string.Empty; + public string ConversationId { get; set; } = string.Empty; + public string MessageId { get; set; } = string.Empty; + public string AgentId { get; set; } = string.Empty; + public string Prompt { get; set; } = string.Empty; + public string? Response { get; set; } + public DateTime CreateDateTime { get; set; } = DateTime.UtcNow; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/AgentFilter.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/AgentFilter.cs new file mode 100644 index 00000000..1e05f8a6 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/AgentFilter.cs @@ -0,0 +1,10 @@ +namespace BotSharp.Abstraction.Repositories.Filters; + +public class AgentFilter +{ + public string? AgentName { get; set; } + public bool? Disabled { get; set; } + public bool? AllowRouting { get; set; } + public bool? IsPublic { get; set; } + public List? AgentIds { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/ConversationFilter.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/ConversationFilter.cs new file mode 100644 index 00000000..9550125e --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/ConversationFilter.cs @@ -0,0 +1,9 @@ +namespace BotSharp.Abstraction.Repositories.Filters; + +public class ConversationFilter +{ + public string? AgentId { get; set; } + public string? Status { get; set; } + public string? Channel { get; set; } + public string? UserId { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 73f81747..ba8e9d84 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Users.Models; namespace BotSharp.Abstraction.Repositories; @@ -16,8 +17,7 @@ public interface IBotSharpRepository #region Agent void UpdateAgent(Agent agent, AgentField field); Agent? GetAgent(string agentId); - List GetAgents(string? name = null, bool? disabled = null, bool? allowRouting = null, - bool? isPublic = null, List? agentIds = null); + List GetAgents(AgentFilter filter); List GetAgentsByUser(string userId); void BulkInsertAgents(List agents); void BulkInsertUserAgents(List userAgents); @@ -35,10 +35,14 @@ public interface IBotSharpRepository void UpdateConversationStates(string conversationId, List states); void UpdateConversationStatus(string conversationId, string status); Conversation GetConversation(string conversationId); - List GetConversations(string? agentId = null, string? status = null, string? channel = null, string? userId = null); + List GetConversations(ConversationFilter filter); void UpdateConversationTitle(string conversationId, string title); List GetLastConversations(); void AddExectionLogs(string conversationId, List logs); List GetExectionLogs(string conversationId); #endregion + + #region LLM Completion Log + void SaveLlmCompletionLog(LlmCompletionLog log); + #endregion } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs index 6b749b3b..379502a6 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Repositories.Filters; namespace BotSharp.Core.Agents.Services; @@ -9,7 +10,8 @@ public partial class AgentService #endif public async Task> GetAgents(bool? allowRouting = null) { - var agents = _db.GetAgents(allowRouting: allowRouting); + var filter = new AgentFilter { AllowRouting = allowRouting }; + var agents = _db.GetAgents(filter); return await Task.FromResult(agents); } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 6a2c495a..65436ccb 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Users.Enums; namespace BotSharp.Core.Conversations.Services; @@ -57,8 +58,11 @@ public partial class ConversationService : IConversationService { var db = _services.GetRequiredService(); var user = db.GetUserById(_user.Id); - var targetUserId = user.Role == UserRole.CSR ? null : user?.Id; - var conversations = db.GetConversations(userId: targetUserId); + var filter = new ConversationFilter + { + UserId = user.Role == UserRole.CSR ? string.Empty : user?.Id + }; + var conversations = db.GetConversations(filter); return conversations.OrderByDescending(x => x.CreatedTime).ToList(); } diff --git a/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs b/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs index f8b1e7a8..c5c2f13d 100644 --- a/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs +++ b/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs @@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Planning; using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Settings; using BotSharp.Abstraction.Templating; @@ -72,7 +73,8 @@ public class HFPlanner : IPlaner if (!string.IsNullOrEmpty(inst.AgentName)) { var db = _services.GetRequiredService(); - var agent = db.GetAgents(inst.AgentName).FirstOrDefault(); + var filter = new AgentFilter { AgentName = inst.AgentName }; + var agent = db.GetAgents(filter).FirstOrDefault(); var context = _services.GetRequiredService(); context.Push(agent.Id); diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index 15946505..48c1a780 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Users.Models; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -72,8 +73,7 @@ public class BotSharpDbContext : Database, IBotSharpRepository throw new NotImplementedException(); } - public List GetAgents(string? name = null, bool? disabled = null, bool? allowRouting = null, - bool? isPublic = null, List? agentIds = null) + public List GetAgents(AgentFilter filter) { throw new NotImplementedException(); } @@ -131,7 +131,7 @@ public class BotSharpDbContext : Database, IBotSharpRepository throw new NotImplementedException(); } - public List GetConversations(string? agentId = null, string? status = null, string? channel = null, string? userId = null) + public List GetConversations(ConversationFilter filter) { throw new NotImplementedException(); } @@ -197,4 +197,11 @@ public class BotSharpDbContext : Database, IBotSharpRepository throw new NotImplementedException(); } #endregion + + #region LLM Completion Log + public void SaveLlmCompletionLog(LlmCompletionLog log) + { + throw new NotImplementedException(); + } + #endregion } diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs index 6716f9f5..d03dd476 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -5,6 +5,10 @@ using BotSharp.Abstraction.Users.Models; using BotSharp.Abstraction.Agents.Models; using MongoDB.Driver; using BotSharp.Abstraction.Routing.Models; +using BotSharp.Abstraction.Repositories.Filters; +using BotSharp.Abstraction.Utilities; +using BotSharp.Abstraction.Conversations.Models; + namespace BotSharp.Core.Repository; public class FileRepository : IBotSharpRepository @@ -500,33 +504,32 @@ public class FileRepository : IBotSharpRepository return null; } - public List GetAgents(string? name = null, bool? disabled = null, bool? allowRouting = null, - bool? isPublic = null, List? agentIds = null) + public List GetAgents(AgentFilter filter) { var query = Agents; - if (!string.IsNullOrEmpty(name)) + if (!string.IsNullOrEmpty(filter.AgentName)) { - query = query.Where(x => x.Name.ToLower() == name.ToLower()); + query = query.Where(x => x.Name.ToLower() == filter.AgentName.ToLower()); } - if (disabled.HasValue) + if (filter.Disabled.HasValue) { - query = query.Where(x => x.Disabled == disabled); + query = query.Where(x => x.Disabled == filter.Disabled); } - if (allowRouting.HasValue) + if (filter.AllowRouting.HasValue) { - query = query.Where(x => x.AllowRouting == allowRouting); + query = query.Where(x => x.AllowRouting == filter.AllowRouting); } - if (isPublic.HasValue) + if (filter.IsPublic.HasValue) { - query = query.Where(x => x.IsPublic == isPublic); + query = query.Where(x => x.IsPublic == filter.IsPublic); } - if (agentIds != null) + if (filter.AgentIds != null) { - query = query.Where(x => agentIds.Contains(x.Id)); + query = query.Where(x => filter.AgentIds.Contains(x.Id)); } return query.ToList(); @@ -539,7 +542,12 @@ public class FileRepository : IBotSharpRepository where ua.UserId == userId || u.ExternalId == userId select ua.AgentId).ToList(); - var agents = GetAgents(isPublic: true, agentIds: agentIds); + var filter = new AgentFilter + { + IsPublic = true, + AgentIds = agentIds + }; + var agents = GetAgents(filter); return agents; } @@ -552,7 +560,7 @@ public class FileRepository : IBotSharpRepository foreach (var file in Directory.GetFiles(dir)) { var fileName = file.Split(Path.DirectorySeparatorChar).Last(); - var splits = fileName.ToLower().Split('.'); + var splits = ParseFileNameByPath(fileName.ToLower()); var name = splits[0]; var extension = splits[1]; if (name.IsEqualTo(templateName) && extension.IsEqualTo(_agentSettings.TemplateFormat)) @@ -610,10 +618,10 @@ public class FileRepository : IBotSharpRepository { if (string.IsNullOrEmpty(conversationId)) return false; - var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir, conversationId); - if (!Directory.Exists(dir)) return false; + var convDir = FindConversationDirectory(conversationId); + if (string.IsNullOrEmpty(convDir)) return false; - Directory.Delete(dir, true); + Directory.Delete(convDir, true); return true; } @@ -734,7 +742,7 @@ public class FileRepository : IBotSharpRepository return record; } - public List GetConversations(string? agentId = null, string? status = null, string? channel = null, string? userId = null) + public List GetConversations(ConversationFilter filter) { var records = new List(); var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir); @@ -749,10 +757,10 @@ public class FileRepository : IBotSharpRepository if (record == null) continue; var matched = true; - if (!string.IsNullOrEmpty(agentId)) matched = matched && record.AgentId == agentId; - if (!string.IsNullOrEmpty(status)) matched = matched && record.Status == status; - if (!string.IsNullOrEmpty(channel)) matched = matched && record.Channel == channel; - if (!string.IsNullOrEmpty(userId)) matched = matched && record.UserId == userId; + if (!string.IsNullOrEmpty(filter.AgentId)) matched = matched && record.AgentId == filter.AgentId; + if (!string.IsNullOrEmpty(filter.Status)) matched = matched && record.Status == filter.Status; + if (!string.IsNullOrEmpty(filter.Channel)) matched = matched && record.Channel == filter.Channel; + if (!string.IsNullOrEmpty(filter.UserId)) matched = matched && record.UserId == filter.UserId; if (!matched) continue; records.Add(record); @@ -835,6 +843,25 @@ public class FileRepository : IBotSharpRepository } #endregion + #region LLM Completion Log + public void SaveLlmCompletionLog(LlmCompletionLog log) + { + var convDir = FindConversationDirectory(log.ConversationId); + if (!Directory.Exists(convDir)) return; + + var logDir = Path.Combine(convDir, "llm_prompt_log"); + if (!Directory.Exists(logDir)) + { + Directory.CreateDirectory(logDir); + } + + var index = GetLlmCompletionLogIndex(logDir, log.MessageId); + var file = Path.Combine(logDir, $"{log.MessageId}.{index}.log"); + File.WriteAllText(file, JsonSerializer.Serialize(log, _options)); + } + #endregion + + #region Private methods private string GetAgentDataDir(string agentId) { @@ -927,22 +954,10 @@ public class FileRepository : IBotSharpRepository private string? FindConversationDirectory(string conversationId) { - var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir); + var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir, conversationId); + if (!Directory.Exists(dir)) return null; - 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; + return dir; } private List CollectDialogElements(string dialogDir) @@ -993,5 +1008,30 @@ public class FileRepository : IBotSharpRepository } return states; } + + private int GetLlmCompletionLogIndex(string logDir, string id) + { + var files = Directory.GetFiles(logDir); + if (files.IsNullOrEmpty()) + return 0; + + var logIndexes = files.Where(file => + { + var fileName = ParseFileNameByPath(file); + return fileName[0].IsEqualTo(id); + }).Select(file => + { + var fileName = ParseFileNameByPath(file); + return int.Parse(fileName[1]); + }).ToList(); + + return logIndexes.IsNullOrEmpty() ? 0 : logIndexes.Max() + 1; + } + + private string[] ParseFileNameByPath(string path, string separator = ".") + { + var name = path.Split(Path.DirectorySeparatorChar).Last(); + return name.Split(separator); + } #endregion } diff --git a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs index 751dd156..c58ce3b3 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Functions; using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Routing; using BotSharp.Abstraction.Routing.Models; using System.Drawing; @@ -29,7 +30,8 @@ public class RouteToAgentFn : IFunctionCallback if (!string.IsNullOrEmpty(args.OriginalAgent) && args.OriginalAgent.Length < 32) { var db = _services.GetRequiredService(); - var originalAgent = db.GetAgents(name: args.OriginalAgent).FirstOrDefault(); + var filter = new AgentFilter { AgentName = args.OriginalAgent }; + var originalAgent = db.GetAgents(filter).FirstOrDefault(); if (originalAgent != null) { _context.Push(originalAgent.Id); @@ -48,7 +50,8 @@ public class RouteToAgentFn : IFunctionCallback else { var db = _services.GetRequiredService(); - var targetAgent = db.GetAgents(args.AgentName).FirstOrDefault(); + var filter = new AgentFilter { AgentName = args.AgentName }; + var targetAgent = db.GetAgents(filter).FirstOrDefault(); if (targetAgent == null) { message.Data = JsonSerializer.Deserialize(message.FunctionArgs); diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs index 681eaf07..66fe6759 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs @@ -1,6 +1,7 @@ using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Models; using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Routing; using BotSharp.Abstraction.Routing.Settings; using BotSharp.Core.Planning; @@ -37,7 +38,8 @@ public class ContinueExecuteTaskRoutingHandler : RoutingHandlerBase//, IRoutingH public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message) { var db = _services.GetRequiredService(); - var record = db.GetAgents(inst.AgentName).FirstOrDefault(); + var filter = new AgentFilter { AgentName = inst.AgentName }; + var record = db.GetAgents(filter).FirstOrDefault(); message.FunctionName = inst.Function; message.CurrentAgentId = record.Id; diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs index 5527f13f..a92e4a6e 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs @@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Planning; using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Routing; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Settings; @@ -130,7 +131,12 @@ public partial class RoutingService : IRoutingService { var db = _services.GetRequiredService(); - var agents = db.GetAgents(disabled: false, allowRouting: true); + var filter = new AgentFilter + { + Disabled = false, + AllowRouting = true + }; + var agents = db.GetAgents(filter); var records = agents.SelectMany(x => { x.RoutingRules.ForEach(r => @@ -160,7 +166,12 @@ public partial class RoutingService : IRoutingService { var db = _services.GetRequiredService(); - var agents = db.GetAgents(disabled: false, allowRouting: true); + var filter = new AgentFilter + { + Disabled = false, + AllowRouting = true + }; + var agents = db.GetAgents(filter); return agents.Select(x => new RoutingItem { AgentId = x.Id, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/LlmCompletionLogCollection.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/LlmCompletionLogCollection.cs new file mode 100644 index 00000000..26674262 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/LlmCompletionLogCollection.cs @@ -0,0 +1,11 @@ +namespace BotSharp.Plugin.MongoStorage.Collections; + +public class LlmCompletionLogCollection : MongoBase +{ + public string ConversationId { get; set; } + public string MessageId { get; set; } + public string AgentId { get; set; } + public string Prompt { get; set; } + public string? Response { get; set; } + public DateTime CreateDateTime { get; set; } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoBase.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoBase.cs index 6d8842bc..0af038a5 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoBase.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoBase.cs @@ -1,5 +1,3 @@ -using MongoDB.Bson.Serialization.Attributes; - namespace BotSharp.Plugin.MongoStorage; [BsonIgnoreExtraElements(Inherited = true)] diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs index c8fb7e28..86992094 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs @@ -45,4 +45,7 @@ public class MongoDbContext public IMongoCollection UserAgents => Database.GetCollection($"{_collectionPrefix}_UserAgents"); + + public IMongoCollection LlmCompletionLogs + => Database.GetCollection($"{_collectionPrefix}_Llm_Completion_Logs"); } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index cc55794b..553ca34e 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -1,8 +1,10 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Functions.Models; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Models; +using BotSharp.Abstraction.Utilities; using BotSharp.Plugin.MongoStorage.Collections; using BotSharp.Plugin.MongoStorage.Models; @@ -416,35 +418,34 @@ public class MongoRepository : IBotSharpRepository }; } - public List GetAgents(string? name = null, bool? disabled = null, bool? allowRouting = null, - bool? isPublic = null, List? agentIds = null) + public List GetAgents(AgentFilter filter) { var agents = new List(); IQueryable query = _dc.Agents.AsQueryable(); - if (!string.IsNullOrEmpty(name)) + if (!string.IsNullOrEmpty(filter.AgentName)) { - query = query.Where(x => x.Name.ToLower() == name.ToLower()); + query = query.Where(x => x.Name.ToLower() == filter.AgentName.ToLower()); } - if (disabled.HasValue) + if (filter.Disabled.HasValue) { - query = query.Where(x => x.Disabled == disabled); + query = query.Where(x => x.Disabled == filter.Disabled); } - if (allowRouting.HasValue) + if (filter.AllowRouting.HasValue) { - query = query.Where(x => x.AllowRouting == allowRouting); + query = query.Where(x => x.AllowRouting == filter.AllowRouting); } - if (isPublic.HasValue) + if (filter.IsPublic.HasValue) { - query = query.Where(x => x.IsPublic == isPublic); + query = query.Where(x => x.IsPublic == filter.IsPublic); } - if (agentIds != null) + if (filter.AgentIds != null) { - query = query.Where(x => agentIds.Contains(x.Id)); + query = query.Where(x => filter.AgentIds.Contains(x.Id)); } return query.ToList().Select(x => new Agent @@ -480,7 +481,12 @@ public class MongoRepository : IBotSharpRepository where ua.UserId == userId || u.ExternalId == userId select ua.AgentId).ToList(); - var agents = GetAgents(isPublic: true, agentIds: agentIds); + var filter = new AgentFilter + { + IsPublic = true, + AgentIds = agentIds + }; + var agents = GetAgents(filter); return agents; } @@ -726,18 +732,16 @@ public class MongoRepository : IBotSharpRepository }; } - public List GetConversations(string? agentId = null, string? status = null, string? channel = null, string? userId = null) + public List GetConversations(ConversationFilter filter) { var records = new List(); - if (string.IsNullOrEmpty(userId)) return records; - var builder = Builders.Filter; var filters = new List>(); - if (!string.IsNullOrEmpty(agentId)) filters.Add(builder.Eq(x => x.AgentId, agentId)); - if (!string.IsNullOrEmpty(status)) filters.Add(builder.Eq(x => x.Status, status)); - if (!string.IsNullOrEmpty(channel)) filters.Add(builder.Eq(x => x.Channel, channel)); - if (!string.IsNullOrEmpty(userId)) filters.Add(builder.Eq(x => x.UserId, userId)); + if (!string.IsNullOrEmpty(filter.AgentId)) filters.Add(builder.Eq(x => x.AgentId, filter.AgentId)); + if (!string.IsNullOrEmpty(filter.Status)) filters.Add(builder.Eq(x => x.Status, filter.Status)); + if (!string.IsNullOrEmpty(filter.Channel)) filters.Add(builder.Eq(x => x.Channel, filter.Channel)); + if (!string.IsNullOrEmpty(filter.UserId)) filters.Add(builder.Eq(x => x.UserId, filter.UserId)); var conversations = _dc.Conversations.Find(builder.And(filters)).ToList(); @@ -858,4 +862,22 @@ public class MongoRepository : IBotSharpRepository _dc.Users.InsertOne(userCollection); } #endregion + + #region LLM Completion Log + public void SaveLlmCompletionLog(LlmCompletionLog log) + { + var completiongLog = new LlmCompletionLogCollection + { + Id = string.IsNullOrEmpty(log.Id) ? Guid.NewGuid().ToString() : log.Id, + ConversationId = log.ConversationId, + MessageId = log.MessageId, + AgentId = log.AgentId, + Prompt = log.Prompt, + Response = log.Response, + CreateDateTime = log.CreateDateTime + }; + + _dc.LlmCompletionLogs.InsertOne(completiongLog); + } + #endregion }