BotSharp/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs

912 lines
36 KiB
C#
Raw Normal View History

2023-09-03 22:43:50 +00:00
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations.Models;
2023-09-27 20:49:44 +00:00
using BotSharp.Abstraction.Functions.Models;
2023-11-27 22:20:49 +00:00
using BotSharp.Abstraction.Repositories.Filters;
2023-09-18 23:14:24 +00:00
using BotSharp.Abstraction.Routing.Models;
2023-09-07 22:04:34 +00:00
using BotSharp.Abstraction.Users.Models;
2023-09-01 22:33:36 +00:00
using BotSharp.Plugin.MongoStorage.Collections;
2023-09-18 23:14:24 +00:00
using BotSharp.Plugin.MongoStorage.Models;
2023-08-26 04:41:01 +00:00
2023-09-01 22:33:36 +00:00
namespace BotSharp.Plugin.MongoStorage.Repository;
2023-08-28 05:28:14 +00:00
public class MongoRepository : IBotSharpRepository
2023-08-26 04:41:01 +00:00
{
2023-08-28 05:28:14 +00:00
private readonly MongoDbContext _dc;
private readonly IServiceProvider _services;
private UpdateOptions _options;
2023-11-29 16:40:27 +00:00
public MongoRepository(MongoDbContext dc, IServiceProvider services)
2023-08-26 04:41:01 +00:00
{
2023-08-28 05:28:14 +00:00
_dc = dc;
_services = services;
_options = new UpdateOptions
2023-08-26 04:41:01 +00:00
{
2023-08-28 05:28:14 +00:00
IsUpsert = true,
};
}
2023-08-26 04:41:01 +00:00
2023-10-17 20:29:40 +00:00
private List<Agent> _agents = new List<Agent>();
private List<User> _users = new List<User>();
private List<UserAgent> _userAgents = new List<UserAgent>();
private List<Conversation> _conversations = new List<Conversation>();
2023-08-28 05:28:14 +00:00
List<string> _changedTableNames = new List<string>();
2023-08-28 05:28:14 +00:00
public void Add<TTableInterface>(object entity)
{
2023-11-27 02:24:40 +00:00
if (entity is Agent agent)
2023-08-26 04:41:01 +00:00
{
2023-08-28 05:28:14 +00:00
_agents.Add(agent);
2023-09-07 22:04:34 +00:00
_changedTableNames.Add(nameof(Agent));
2023-08-28 05:28:14 +00:00
}
2023-09-07 22:04:34 +00:00
else if (entity is User user)
2023-08-28 05:28:14 +00:00
{
_users.Add(user);
2023-09-07 22:04:34 +00:00
_changedTableNames.Add(nameof(User));
2023-08-28 05:28:14 +00:00
}
2023-09-07 22:04:34 +00:00
else if (entity is UserAgent userAgent)
2023-08-28 05:28:14 +00:00
{
_userAgents.Add(userAgent);
2023-09-07 22:04:34 +00:00
_changedTableNames.Add(nameof(UserAgent));
2023-08-28 05:28:14 +00:00
}
}
public int Transaction<TTableInterface>(Action action)
{
_changedTableNames.Clear();
action();
2023-08-26 04:41:01 +00:00
2023-08-28 05:28:14 +00:00
foreach (var table in _changedTableNames)
{
2023-11-27 02:24:40 +00:00
if (table == nameof(Agent))
2023-08-28 05:28:14 +00:00
{
var agents = _agents.Select(x => new AgentDocument
2023-08-26 04:41:01 +00:00
{
Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString(),
2023-08-28 05:28:14 +00:00
Name = x.Name,
Description = x.Description,
Instruction = x.Instruction,
Templates = x.Templates?
.Select(t => AgentTemplateMongoElement.ToMongoElement(t))?
.ToList() ?? new List<AgentTemplateMongoElement>(),
Functions = x.Functions?
.Select(f => FunctionDefMongoElement.ToMongoElement(f))?
.ToList() ?? new List<FunctionDefMongoElement>(),
Responses = x.Responses?
.Select(r => AgentResponseMongoElement.ToMongoElement(r))?
.ToList() ?? new List<AgentResponseMongoElement>(),
Samples = x.Samples ?? new List<string>(),
2023-09-04 15:15:11 +00:00
IsPublic = x.IsPublic,
2023-09-18 23:14:24 +00:00
AllowRouting = x.AllowRouting,
Disabled = x.Disabled,
Profiles = x.Profiles,
RoutingRules = x.RoutingRules?
2023-09-19 18:20:41 +00:00
.Select(r => RoutingRuleMongoElement.ToMongoElement(r))?
.ToList() ?? new List<RoutingRuleMongoElement>(),
2023-12-13 20:26:46 +00:00
LlmConfig = AgentLlmConfigMongoElement.ToMongoElement(x.LlmConfig),
2023-09-08 17:17:54 +00:00
CreatedTime = x.CreatedDateTime,
UpdatedTime = x.UpdatedDateTime
2023-08-28 05:28:14 +00:00
}).ToList();
2023-08-26 04:41:01 +00:00
2023-08-28 05:28:14 +00:00
foreach (var agent in agents)
{
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agent.Id);
var update = Builders<AgentDocument>.Update
2023-08-28 05:28:14 +00:00
.Set(x => x.Name, agent.Name)
.Set(x => x.Description, agent.Description)
.Set(x => x.Instruction, agent.Instruction)
2023-09-12 22:08:58 +00:00
.Set(x => x.Templates, agent.Templates)
2023-08-28 05:28:14 +00:00
.Set(x => x.Functions, agent.Functions)
2023-09-02 05:10:46 +00:00
.Set(x => x.Responses, agent.Responses)
.Set(x => x.Samples, agent.Samples)
2023-09-04 15:15:11 +00:00
.Set(x => x.IsPublic, agent.IsPublic)
2023-09-18 23:14:24 +00:00
.Set(x => x.AllowRouting, agent.AllowRouting)
.Set(x => x.Disabled, agent.Disabled)
.Set(x => x.Profiles, agent.Profiles)
.Set(x => x.RoutingRules, agent.RoutingRules)
2023-12-13 20:26:46 +00:00
.Set(x => x.LlmConfig, agent.LlmConfig)
2023-08-28 05:28:14 +00:00
.Set(x => x.CreatedTime, agent.CreatedTime)
.Set(x => x.UpdatedTime, agent.UpdatedTime);
_dc.Agents.UpdateOne(filter, update, _options);
2023-08-26 04:41:01 +00:00
}
2023-08-28 05:28:14 +00:00
}
2023-09-07 22:04:34 +00:00
else if (table == nameof(User))
2023-08-28 05:28:14 +00:00
{
var users = _users.Select(x => new UserDocument
2023-08-26 04:41:01 +00:00
{
Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString(),
2023-08-28 05:28:14 +00:00
FirstName = x.FirstName,
LastName = x.LastName,
Salt = x.Salt,
Password = x.Password,
Email = x.Email,
ExternalId = x.ExternalId,
2023-11-14 05:37:04 +00:00
Role = x.Role,
2023-08-28 05:28:14 +00:00
CreatedTime = x.CreatedTime,
UpdatedTime = x.UpdatedTime
}).ToList();
2023-08-26 04:41:01 +00:00
2023-08-28 05:28:14 +00:00
foreach (var user in users)
{
var filter = Builders<UserDocument>.Filter.Eq(x => x.Id, user.Id);
var update = Builders<UserDocument>.Update
2023-08-28 05:28:14 +00:00
.Set(x => x.FirstName, user.FirstName)
.Set(x => x.LastName, user.LastName)
.Set(x => x.Email, user.Email)
.Set(x => x.Salt, user.Salt)
.Set(x => x.Password, user.Password)
.Set(x => x.ExternalId, user.ExternalId)
2023-11-14 05:37:04 +00:00
.Set(x => x.Role, user.Role)
2023-08-28 05:28:14 +00:00
.Set(x => x.CreatedTime, user.CreatedTime)
.Set(x => x.UpdatedTime, user.UpdatedTime);
_dc.Users.UpdateOne(filter, update, _options);
2023-08-26 04:41:01 +00:00
}
2023-08-28 05:28:14 +00:00
}
2023-09-07 22:04:34 +00:00
else if (table == nameof(UserAgent))
2023-08-28 05:28:14 +00:00
{
var userAgents = _userAgents.Select(x => new UserAgentDocument
2023-08-26 04:41:01 +00:00
{
Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString(),
AgentId = x.AgentId,
UserId = !string.IsNullOrEmpty(x.UserId) ? x.UserId : string.Empty,
2023-11-14 05:37:04 +00:00
Editable = x.Editable,
2023-08-28 05:28:14 +00:00
CreatedTime = x.CreatedTime,
UpdatedTime = x.UpdatedTime
}).ToList();
2023-08-26 04:41:01 +00:00
2023-08-28 05:28:14 +00:00
foreach (var userAgent in userAgents)
{
var filter = Builders<UserAgentDocument>.Filter.Eq(x => x.Id, userAgent.Id);
var update = Builders<UserAgentDocument>.Update
2023-08-28 05:28:14 +00:00
.Set(x => x.AgentId, userAgent.AgentId)
.Set(x => x.UserId, userAgent.UserId)
2023-11-14 05:37:04 +00:00
.Set(x => x.Editable, userAgent.Editable)
2023-08-28 05:28:14 +00:00
.Set(x => x.CreatedTime, userAgent.CreatedTime)
.Set(x => x.UpdatedTime, userAgent.UpdatedTime);
_dc.UserAgents.UpdateOne(filter, update, _options);
2023-08-26 04:41:01 +00:00
}
}
}
2023-08-28 05:28:14 +00:00
return _changedTableNames.Count;
2023-08-26 04:41:01 +00:00
}
2023-09-02 05:10:46 +00:00
2023-09-15 20:19:44 +00:00
#region Agent
public void UpdateAgent(Agent agent, AgentField field)
2023-09-02 05:10:46 +00:00
{
2023-09-15 20:19:44 +00:00
if (agent == null || string.IsNullOrEmpty(agent.Id)) return;
switch (field)
2023-09-02 05:10:46 +00:00
{
2023-09-15 20:19:44 +00:00
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;
2023-09-18 23:14:24 +00:00
case AgentField.Disabled:
UpdateAgentDisabled(agent.Id, agent.Disabled);
break;
case AgentField.AllowRouting:
UpdateAgentAllowRouting(agent.Id, agent.AllowRouting);
break;
case AgentField.Profiles:
UpdateAgentProfiles(agent.Id, agent.Profiles);
break;
case AgentField.RoutingRule:
2023-09-18 23:14:24 +00:00
UpdateAgentRoutingRules(agent.Id, agent.RoutingRules);
break;
2023-09-15 20:19:44 +00:00
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.Sample:
UpdateAgentSamples(agent.Id, agent.Samples);
break;
2023-12-13 20:26:46 +00:00
case AgentField.LlmConfig:
UpdateAgentLlmConfig(agent.Id, agent.LlmConfig);
break;
2023-09-15 20:19:44 +00:00
case AgentField.All:
UpdateAgentAllFields(agent);
break;
default:
break;
}
2023-09-02 05:10:46 +00:00
}
2023-09-15 20:19:44 +00:00
#region Update Agent Fields
private void UpdateAgentName(string agentId, string name)
2023-09-02 05:10:46 +00:00
{
2023-09-15 20:19:44 +00:00
if (string.IsNullOrEmpty(name)) return;
2023-09-02 05:10:46 +00:00
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-15 20:19:44 +00:00
.Set(x => x.Name, name)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
2023-09-02 05:10:46 +00:00
2023-09-15 20:19:44 +00:00
_dc.Agents.UpdateOne(filter, update);
2023-09-02 05:10:46 +00:00
}
2023-09-15 20:19:44 +00:00
private void UpdateAgentDescription(string agentId, string description)
2023-09-02 05:10:46 +00:00
{
2023-09-15 20:19:44 +00:00
if (string.IsNullOrEmpty(description)) return;
2023-09-02 05:10:46 +00:00
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-15 20:19:44 +00:00
.Set(x => x.Description, description)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
2023-09-02 05:10:46 +00:00
2023-09-15 20:19:44 +00:00
_dc.Agents.UpdateOne(filter, update);
}
private void UpdateAgentIsPublic(string agentId, bool isPublic)
{
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-15 20:19:44 +00:00
.Set(x => x.IsPublic, isPublic)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
2023-09-18 23:14:24 +00:00
private void UpdateAgentDisabled(string agentId, bool disabled)
{
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-18 23:14:24 +00:00
.Set(x => x.Disabled, disabled)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
private void UpdateAgentAllowRouting(string agentId, bool allowRouting)
{
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-18 23:14:24 +00:00
.Set(x => x.AllowRouting, allowRouting)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
private void UpdateAgentProfiles(string agentId, List<string> profiles)
{
if (profiles.IsNullOrEmpty()) return;
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-18 23:14:24 +00:00
.Set(x => x.Profiles, profiles)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
private void UpdateAgentRoutingRules(string agentId, List<RoutingRule> rules)
{
if (rules.IsNullOrEmpty()) return;
2023-09-19 18:20:41 +00:00
var ruleElements = rules.Select(x => RoutingRuleMongoElement.ToMongoElement(x)).ToList();
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-18 23:14:24 +00:00
.Set(x => x.RoutingRules, ruleElements)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
2023-09-15 20:19:44 +00:00
private void UpdateAgentInstruction(string agentId, string instruction)
{
if (string.IsNullOrEmpty(instruction)) return;
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
2023-09-15 20:19:44 +00:00
.Set(x => x.Instruction, instruction)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
2023-09-27 20:49:44 +00:00
private void UpdateAgentFunctions(string agentId, List<FunctionDef> functions)
2023-09-15 20:19:44 +00:00
{
if (functions.IsNullOrEmpty()) return;
2023-09-02 05:10:46 +00:00
var functionsToUpdate = functions.Select(f => FunctionDefMongoElement.ToMongoElement(f)).ToList();
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
.Set(x => x.Functions, functionsToUpdate)
2023-09-15 20:19:44 +00:00
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
private void UpdateAgentTemplates(string agentId, List<AgentTemplate> templates)
{
if (templates.IsNullOrEmpty()) return;
var templatesToUpdate = templates.Select(t => AgentTemplateMongoElement.ToMongoElement(t)).ToList();
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
.Set(x => x.Templates, templatesToUpdate)
2023-09-15 20:19:44 +00:00
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
private void UpdateAgentResponses(string agentId, List<AgentResponse> responses)
{
if (responses.IsNullOrEmpty()) return;
var responsesToUpdate = responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList();
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
.Set(x => x.Responses, responsesToUpdate)
2023-09-15 20:19:44 +00:00
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
private void UpdateAgentSamples(string agentId, List<string> samples)
{
if (samples.IsNullOrEmpty()) return;
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
.Set(x => x.Samples, samples)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
2023-12-13 20:26:46 +00:00
private void UpdateAgentLlmConfig(string agentId, AgentLlmConfig? config)
{
var llmConfig = AgentLlmConfigMongoElement.ToMongoElement(config);
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
.Set(x => x.LlmConfig, llmConfig)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Agents.UpdateOne(filter, update);
}
2023-09-15 20:19:44 +00:00
private void UpdateAgentAllFields(Agent agent)
{
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agent.Id);
var update = Builders<AgentDocument>.Update
2023-09-02 05:10:46 +00:00
.Set(x => x.Name, agent.Name)
.Set(x => x.Description, agent.Description)
2023-09-18 23:14:24 +00:00
.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(r => RoutingRuleMongoElement.ToMongoElement(r)).ToList())
2023-09-02 05:10:46 +00:00
.Set(x => x.Instruction, agent.Instruction)
.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.Samples, agent.Samples)
2023-12-13 20:26:46 +00:00
.Set(x => x.LlmConfig, AgentLlmConfigMongoElement.ToMongoElement(agent.LlmConfig))
2023-09-04 15:15:11 +00:00
.Set(x => x.IsPublic, agent.IsPublic)
2023-09-15 20:19:44 +00:00
.Set(x => x.UpdatedTime, DateTime.UtcNow);
2023-09-02 05:10:46 +00:00
var res = _dc.Agents.UpdateOne(filter, update);
Console.WriteLine();
2023-09-02 05:10:46 +00:00
}
2023-09-15 20:19:44 +00:00
#endregion
2023-09-03 04:11:53 +00:00
public Agent? GetAgent(string agentId)
{
var agent = _dc.Agents.AsQueryable().FirstOrDefault(x => x.Id == agentId);
if (agent == null) return null;
2023-09-03 04:11:53 +00:00
return new Agent
{
Id = agent.Id,
Name = agent.Name,
Description = agent.Description,
Instruction = agent.Instruction,
Templates = !agent.Templates.IsNullOrEmpty() ? agent.Templates
.Select(t => AgentTemplateMongoElement.ToDomainElement(t))
.ToList() : new List<AgentTemplate>(),
Functions = !agent.Functions.IsNullOrEmpty() ? agent.Functions
.Select(f => FunctionDefMongoElement.ToDomainElement(f))
.ToList() : new List<FunctionDef>(),
Responses = !agent.Responses.IsNullOrEmpty() ? agent.Responses
.Select(r => AgentResponseMongoElement.ToDomainElement(r))
.ToList() : new List<AgentResponse>(),
Samples = agent.Samples ?? new List<string>(),
IsPublic = agent.IsPublic,
Disabled = agent.Disabled,
AllowRouting = agent.AllowRouting,
Profiles = agent.Profiles,
RoutingRules = !agent.RoutingRules.IsNullOrEmpty() ? agent.RoutingRules
.Select(r => RoutingRuleMongoElement.ToDomainElement(agent.Id, agent.Name, r))
2023-12-13 20:26:46 +00:00
.ToList() : new List<RoutingRule>(),
LlmConfig = AgentLlmConfigMongoElement.ToDomainElement(agent.LlmConfig)
};
}
2023-09-03 04:11:53 +00:00
2023-11-27 22:20:49 +00:00
public List<Agent> GetAgents(AgentFilter filter)
2023-09-03 04:11:53 +00:00
{
var agents = new List<Agent>();
IQueryable<AgentDocument> query = _dc.Agents.AsQueryable();
2023-11-27 22:20:49 +00:00
if (!string.IsNullOrEmpty(filter.AgentName))
{
2023-11-27 22:20:49 +00:00
query = query.Where(x => x.Name.ToLower() == filter.AgentName.ToLower());
}
2023-11-27 22:20:49 +00:00
if (filter.Disabled.HasValue)
{
2023-11-27 22:20:49 +00:00
query = query.Where(x => x.Disabled == filter.Disabled);
}
2023-11-27 22:20:49 +00:00
if (filter.AllowRouting.HasValue)
{
2023-11-27 22:20:49 +00:00
query = query.Where(x => x.AllowRouting == filter.AllowRouting);
}
2023-11-27 22:20:49 +00:00
if (filter.IsPublic.HasValue)
{
2023-11-27 22:20:49 +00:00
query = query.Where(x => x.IsPublic == filter.IsPublic);
}
2023-11-27 22:20:49 +00:00
if (filter.AgentIds != null)
{
2023-11-27 22:20:49 +00:00
query = query.Where(x => filter.AgentIds.Contains(x.Id));
}
return query.ToList().Select(x => new Agent
{
Id = x.Id,
Name = x.Name,
Description = x.Description,
Instruction = x.Instruction,
Templates = !x.Templates.IsNullOrEmpty() ? x.Templates
.Select(t => AgentTemplateMongoElement.ToDomainElement(t))
.ToList() : new List<AgentTemplate>(),
Functions = !x.Functions.IsNullOrEmpty() ? x.Functions
.Select(f => FunctionDefMongoElement.ToDomainElement(f))
.ToList() : new List<FunctionDef>(),
Responses = !x.Responses.IsNullOrEmpty() ? x.Responses
.Select(r => AgentResponseMongoElement.ToDomainElement(r))
.ToList() : new List<AgentResponse>(),
Samples = x.Samples ?? new List<string>(),
IsPublic = x.IsPublic,
Disabled = x.Disabled,
AllowRouting = x.AllowRouting,
Profiles = x.Profiles,
RoutingRules = !x.RoutingRules.IsNullOrEmpty() ? x.RoutingRules
.Select(r => RoutingRuleMongoElement.ToDomainElement(x.Id, x.Name, r))
2023-12-13 20:26:46 +00:00
.ToList() : new List<RoutingRule>(),
LlmConfig = AgentLlmConfigMongoElement.ToDomainElement(x.LlmConfig)
}).ToList();
}
public List<Agent> GetAgentsByUser(string userId)
{
var agentIds = (from ua in _dc.UserAgents.AsQueryable()
join u in _dc.Users.AsQueryable() on ua.UserId equals u.Id
where ua.UserId == userId || u.ExternalId == userId
select ua.AgentId).ToList();
2023-11-27 22:20:49 +00:00
var filter = new AgentFilter
{
2023-12-13 20:26:46 +00:00
AgentIds = agentIds,
IsPublic = true
2023-11-27 22:20:49 +00:00
};
var agents = GetAgents(filter);
return agents;
2023-09-03 04:11:53 +00:00
}
2023-09-03 04:54:22 +00:00
2023-09-09 20:13:19 +00:00
public List<string> GetAgentResponses(string agentId, string prefix, string intent)
2023-09-03 04:54:22 +00:00
{
var responses = new List<string>();
var agent = _dc.Agents.AsQueryable().FirstOrDefault(x => x.Id == agentId);
2023-09-03 04:54:22 +00:00
if (agent == null) return responses;
2023-09-09 21:44:25 +00:00
return agent.Responses.Where(x => x.Prefix == prefix && x.Intent == intent).Select(x => x.Content).ToList();
2023-09-03 04:54:22 +00:00
}
2023-09-03 19:32:12 +00:00
2023-09-15 20:19:44 +00:00
public string GetAgentTemplate(string agentId, string templateName)
2023-09-03 19:32:12 +00:00
{
var agent = _dc.Agents.AsQueryable().FirstOrDefault(x => x.Id == agentId);
2023-09-15 20:19:44 +00:00
if (agent == null) return string.Empty;
return agent.Templates?.FirstOrDefault(x => x.Name == templateName.ToLower())?.Content ?? string.Empty;
2023-09-03 19:32:12 +00:00
}
2023-10-17 20:29:40 +00:00
public void BulkInsertAgents(List<Agent> agents)
{
if (agents.IsNullOrEmpty()) return;
var agentDocs = agents.Select(x => new AgentDocument
2023-10-17 20:29:40 +00:00
{
Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString(),
2023-10-17 20:29:40 +00:00
Name = x.Name,
Description = x.Description,
Instruction = x.Instruction,
Templates = x.Templates?
.Select(t => AgentTemplateMongoElement.ToMongoElement(t))?
.ToList() ?? new List<AgentTemplateMongoElement>(),
Functions = x.Functions?
.Select(f => FunctionDefMongoElement.ToMongoElement(f))?
.ToList() ?? new List<FunctionDefMongoElement>(),
Responses = x.Responses?
.Select(r => AgentResponseMongoElement.ToMongoElement(r))?
.ToList() ?? new List<AgentResponseMongoElement>(),
Samples = x.Samples ?? new List<string>(),
2023-10-17 20:29:40 +00:00
IsPublic = x.IsPublic,
AllowRouting = x.AllowRouting,
Disabled = x.Disabled,
Profiles = x.Profiles,
RoutingRules = x.RoutingRules?
.Select(r => RoutingRuleMongoElement.ToMongoElement(r))?
.ToList() ?? new List<RoutingRuleMongoElement>(),
2023-12-13 20:26:46 +00:00
LlmConfig = AgentLlmConfigMongoElement.ToMongoElement(x.LlmConfig),
2023-10-17 20:29:40 +00:00
CreatedTime = x.CreatedDateTime,
UpdatedTime = x.UpdatedDateTime
}).ToList();
_dc.Agents.InsertMany(agentDocs);
}
public void BulkInsertUserAgents(List<UserAgent> userAgents)
{
if (userAgents.IsNullOrEmpty()) return;
var userAgentDocs = userAgents.Select(x => new UserAgentDocument
2023-10-17 20:29:40 +00:00
{
Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString(),
AgentId = x.AgentId,
UserId = !string.IsNullOrEmpty(x.UserId) ? x.UserId : string.Empty,
2023-11-14 05:37:04 +00:00
Editable = x.Editable,
2023-10-17 20:29:40 +00:00
CreatedTime = x.CreatedTime,
UpdatedTime = x.UpdatedTime
}).ToList();
_dc.UserAgents.InsertMany(userAgentDocs);
}
public bool DeleteAgents()
{
try
{
_dc.UserAgents.DeleteMany(Builders<UserAgentDocument>.Filter.Empty);
_dc.Agents.DeleteMany(Builders<AgentDocument>.Filter.Empty);
2023-10-17 20:29:40 +00:00
return true;
}
catch
{
return false;
}
}
2023-09-15 20:19:44 +00:00
#endregion
2023-09-03 22:43:50 +00:00
2023-09-15 20:19:44 +00:00
#region Conversation
2023-09-07 22:04:34 +00:00
public void CreateNewConversation(Conversation conversation)
2023-09-03 22:43:50 +00:00
{
if (conversation == null) return;
var conv = new ConversationDocument
2023-09-03 22:43:50 +00:00
{
Id = !string.IsNullOrEmpty(conversation.Id) ? conversation.Id : Guid.NewGuid().ToString(),
AgentId = conversation.AgentId,
UserId = !string.IsNullOrEmpty(conversation.UserId) ? conversation.UserId : string.Empty,
2023-09-03 22:43:50 +00:00
Title = conversation.Title,
2023-11-27 02:24:40 +00:00
Channel = conversation.Channel,
2023-11-15 16:44:10 +00:00
Status = conversation.Status,
2023-09-09 21:44:25 +00:00
States = conversation.States?.ToKeyValueList() ?? new List<StateKeyValue>(),
2023-09-06 04:41:49 +00:00
CreatedTime = DateTime.UtcNow,
UpdatedTime = DateTime.UtcNow,
};
var dialog = new ConversationDialogDocument
2023-09-06 04:41:49 +00:00
{
Id = Guid.NewGuid().ToString(),
2023-09-06 04:41:49 +00:00
ConversationId = conv.Id,
2023-11-22 00:16:45 +00:00
Dialogs = new List<DialogMongoElement>()
2023-09-03 22:43:50 +00:00
};
2023-09-06 04:41:49 +00:00
_dc.Conversations.InsertOne(conv);
_dc.ConversationDialogs.InsertOne(dialog);
2023-09-03 22:43:50 +00:00
}
2023-11-26 06:29:06 +00:00
public bool DeleteConversation(string conversationId)
{
if (string.IsNullOrEmpty(conversationId)) return false;
2023-12-01 16:36:34 +00:00
var filterConv = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
var filterDialog = Builders<ConversationDialogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
var filterExeLog = Builders<ExecutionLogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
var filterPromptLog = Builders<LlmCompletionLogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
2023-11-26 06:29:06 +00:00
2023-12-01 16:36:34 +00:00
var exeLogDeleted = _dc.ExectionLogs.DeleteMany(filterExeLog);
var promptLogDeleted = _dc.LlmCompletionLogs.DeleteMany(filterPromptLog);
2023-11-26 06:29:06 +00:00
var dialogDeleted = _dc.ConversationDialogs.DeleteMany(filterDialog);
var convDeleted = _dc.Conversations.DeleteMany(filterConv);
return convDeleted.DeletedCount > 0 || dialogDeleted.DeletedCount > 0;
}
2023-11-22 00:16:45 +00:00
public List<DialogElement> GetConversationDialogs(string conversationId)
2023-09-03 22:43:50 +00:00
{
2023-11-22 00:16:45 +00:00
var dialogs = new List<DialogElement>();
if (string.IsNullOrEmpty(conversationId)) return dialogs;
2023-09-03 22:43:50 +00:00
var filter = Builders<ConversationDialogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
2023-09-06 04:41:49 +00:00
var foundDialog = _dc.ConversationDialogs.Find(filter).FirstOrDefault();
2023-11-22 00:16:45 +00:00
if (foundDialog == null) return dialogs;
2023-09-03 22:43:50 +00:00
2023-11-22 00:16:45 +00:00
var formattedDialog = foundDialog.Dialogs?.Select(x => DialogMongoElement.ToDomainElement(x))?.ToList();
return formattedDialog ?? new List<DialogElement>();
2023-09-03 22:43:50 +00:00
}
2023-11-22 00:16:45 +00:00
public void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
2023-09-03 22:43:50 +00:00
{
if (string.IsNullOrEmpty(conversationId)) return;
var filterConv = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
2023-09-07 22:04:34 +00:00
var foundConv = _dc.Conversations.Find(filterConv).FirstOrDefault();
if (foundConv == null) return;
var filterDialog = Builders<ConversationDialogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
2023-09-07 22:04:34 +00:00
var foundDialog = _dc.ConversationDialogs.Find(filterDialog).FirstOrDefault();
2023-09-06 04:41:49 +00:00
if (foundDialog == null) return;
2023-09-03 22:43:50 +00:00
2023-11-22 00:16:45 +00:00
var dialogElements = dialogs.Select(x => DialogMongoElement.ToMongoElement(x)).ToList();
var updateDialog = Builders<ConversationDialogDocument>.Update.PushEach(x => x.Dialogs, dialogElements);
var updateConv = Builders<ConversationDocument>.Update.Set(x => x.UpdatedTime, DateTime.UtcNow);
2023-09-03 22:43:50 +00:00
2023-09-07 22:04:34 +00:00
_dc.ConversationDialogs.UpdateOne(filterDialog, updateDialog);
_dc.Conversations.UpdateOne(filterConv, updateConv);
2023-09-03 22:43:50 +00:00
}
2023-11-27 02:24:40 +00:00
public void UpdateConversationTitle(string conversationId, string title)
{
if (string.IsNullOrEmpty(conversationId)) return;
2023-09-03 22:43:50 +00:00
var filterConv = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
var foundConv = _dc.Conversations.Find(filterConv).FirstOrDefault();
if (foundConv == null) return;
var updateConv = Builders<ConversationDocument>.Update
.Set(x => x.UpdatedTime, DateTime.UtcNow)
.Set(x => x.Title, title);
_dc.Conversations.UpdateOne(filterConv, updateConv);
}
2023-11-27 02:24:40 +00:00
2023-09-09 21:44:25 +00:00
public List<StateKeyValue> GetConversationStates(string conversationId)
2023-09-03 22:43:50 +00:00
{
2023-09-09 21:44:25 +00:00
var states = new List<StateKeyValue>();
2023-09-03 22:43:50 +00:00
if (string.IsNullOrEmpty(conversationId)) return states;
var filter = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
2023-09-07 22:04:34 +00:00
var foundConversation = _dc.Conversations.Find(filter).FirstOrDefault();
2023-09-09 21:44:25 +00:00
var savedStates = foundConversation?.States ?? new List<StateKeyValue>();
2023-09-03 22:43:50 +00:00
return savedStates;
}
2023-09-09 21:44:25 +00:00
public void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
2023-09-03 22:43:50 +00:00
{
if (string.IsNullOrEmpty(conversationId)) return;
var filter = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
2023-09-07 22:04:34 +00:00
var foundConv = _dc.Conversations.Find(filter).FirstOrDefault();
if (foundConv == null) return;
2023-09-03 22:43:50 +00:00
var update = Builders<ConversationDocument>.Update
2023-09-07 22:04:34 +00:00
.Set(x => x.States, states)
2023-09-03 22:43:50 +00:00
.Set(x => x.UpdatedTime, DateTime.UtcNow);
2023-09-07 22:04:34 +00:00
_dc.Conversations.UpdateOne(filter, update);
2023-11-15 18:35:24 +00:00
}
public void UpdateConversationStatus(string conversationId, string status)
{
if (string.IsNullOrEmpty(conversationId) || string.IsNullOrEmpty(status)) return;
var filter = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
2023-11-15 18:35:24 +00:00
var foundConv = _dc.Conversations.Find(filter).FirstOrDefault();
if (foundConv == null) return;
var update = Builders<ConversationDocument>.Update
2023-11-15 18:35:24 +00:00
.Set(x => x.Status, status)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Conversations.UpdateOne(filter, update);
2023-09-03 22:43:50 +00:00
}
2023-09-07 22:04:34 +00:00
public Conversation GetConversation(string conversationId)
2023-09-03 22:43:50 +00:00
{
if (string.IsNullOrEmpty(conversationId)) return null;
var filterConv = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
var filterDialog = Builders<ConversationDialogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
2023-09-06 04:41:49 +00:00
2023-09-07 22:04:34 +00:00
var conv = _dc.Conversations.Find(filterConv).FirstOrDefault();
2023-09-06 04:41:49 +00:00
var dialog = _dc.ConversationDialogs.Find(filterDialog).FirstOrDefault();
if (conv == null) return null;
2023-09-03 22:43:50 +00:00
2023-11-22 00:16:45 +00:00
var dialogElements = dialog?.Dialogs?.Select(x => DialogMongoElement.ToDomainElement(x))?.ToList() ?? new List<DialogElement>();
2023-09-07 22:04:34 +00:00
return new Conversation
2023-09-15 20:19:44 +00:00
{
2023-09-06 04:41:49 +00:00
Id = conv.Id.ToString(),
AgentId = conv.AgentId.ToString(),
UserId = conv.UserId.ToString(),
Title = conv.Title,
2023-11-27 02:24:40 +00:00
Channel = conv.Channel,
2023-11-15 16:44:10 +00:00
Status = conv.Status,
2023-11-22 00:16:45 +00:00
Dialogs = dialogElements,
2023-09-09 21:44:25 +00:00
States = new ConversationState(conv.States ?? new List<StateKeyValue>()),
2023-09-06 04:41:49 +00:00
CreatedTime = conv.CreatedTime,
UpdatedTime = conv.UpdatedTime
};
2023-09-03 22:43:50 +00:00
}
2023-11-27 22:20:49 +00:00
public List<Conversation> GetConversations(ConversationFilter filter)
2023-09-03 22:43:50 +00:00
{
2023-09-07 22:04:34 +00:00
var records = new List<Conversation>();
var builder = Builders<ConversationDocument>.Filter;
var filters = new List<FilterDefinition<ConversationDocument>>();
2023-11-27 02:24:40 +00:00
2023-11-27 22:20:49 +00:00
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));
2023-11-27 02:24:40 +00:00
var conversations = _dc.Conversations.Find(builder.And(filters)).ToList();
2023-09-06 04:41:49 +00:00
foreach (var conv in conversations)
2023-09-03 22:43:50 +00:00
{
2023-09-06 04:41:49 +00:00
var convId = conv.Id.ToString();
2023-09-07 22:04:34 +00:00
records.Add(new Conversation
2023-09-06 04:41:49 +00:00
{
Id = convId,
AgentId = conv.AgentId.ToString(),
UserId = conv.UserId.ToString(),
Title = conv.Title,
2023-11-27 02:24:40 +00:00
Channel = conv.Channel,
2023-11-15 16:44:10 +00:00
Status = conv.Status,
2023-09-06 04:41:49 +00:00
CreatedTime = conv.CreatedTime,
UpdatedTime = conv.UpdatedTime
});
}
return records;
2023-09-03 22:43:50 +00:00
}
2023-10-23 20:33:24 +00:00
2023-11-10 16:01:03 +00:00
public List<Conversation> GetLastConversations()
{
var records = new List<Conversation>();
var conversations = _dc.Conversations.Aggregate()
2023-11-22 00:16:45 +00:00
.Group(c => c.UserId, g => g.OrderByDescending(x => x.CreatedTime).First())
.ToList();
2023-11-10 16:01:03 +00:00
return conversations.Select(c => new Conversation()
{
Id = c.Id.ToString(),
AgentId = c.AgentId.ToString(),
UserId = c.UserId.ToString(),
Title = c.Title,
2023-11-27 02:24:40 +00:00
Channel = c.Channel,
2023-11-15 16:44:10 +00:00
Status = c.Status,
2023-11-10 16:01:03 +00:00
CreatedTime = c.CreatedTime,
UpdatedTime = c.UpdatedTime
}).ToList();
}
2023-09-15 20:19:44 +00:00
#endregion
2023-09-12 22:08:58 +00:00
2023-09-15 20:19:44 +00:00
#region User
2023-10-17 20:29:40 +00:00
public User? GetUserByEmail(string email)
2023-09-12 22:08:58 +00:00
{
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.Email == email);
2023-09-15 20:19:44 +00:00
return user != null ? new User
{
Id = user.Id,
2023-09-15 20:19:44 +00:00
FirstName = user.FirstName,
LastName = user.LastName,
Email = user.Email,
Password = user.Password,
Salt = user.Salt,
2023-11-14 05:37:04 +00:00
ExternalId = user.ExternalId,
Role = user.Role
} : null;
}
2023-11-14 01:25:25 +00:00
public User? GetUserById(string id)
{
2023-11-14 01:25:25 +00:00
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.Id == id || x.ExternalId == id);
return user != null ? new User
{
Id = user.Id,
FirstName = user.FirstName,
LastName = user.LastName,
Email = user.Email,
Password = user.Password,
Salt = user.Salt,
2023-11-14 05:37:04 +00:00
ExternalId = user.ExternalId,
Role = user.Role
2023-09-15 20:19:44 +00:00
} : null;
}
2023-09-12 22:08:58 +00:00
2023-09-15 20:19:44 +00:00
public void CreateUser(User user)
{
if (user == null) return;
var userCollection = new UserDocument
2023-09-15 20:19:44 +00:00
{
Id = Guid.NewGuid().ToString(),
2023-09-15 20:19:44 +00:00
FirstName = user.FirstName,
LastName = user.LastName,
Salt = user.Salt,
Password = user.Password,
Email = user.Email,
ExternalId = user.ExternalId,
2023-11-14 05:37:04 +00:00
Role = user.Role,
2023-09-15 20:19:44 +00:00
CreatedTime = DateTime.UtcNow,
UpdatedTime = DateTime.UtcNow
};
_dc.Users.InsertOne(userCollection);
}
#endregion
2023-11-27 23:49:24 +00:00
2023-11-29 16:21:03 +00:00
#region Execution Log
public void AddExecutionLogs(string conversationId, List<string> logs)
{
if (string.IsNullOrEmpty(conversationId) || logs.IsNullOrEmpty()) return;
var filter = Builders<ExecutionLogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
var update = Builders<ExecutionLogDocument>.Update
2023-11-29 16:21:03 +00:00
.SetOnInsert(x => x.Id, Guid.NewGuid().ToString())
.PushEach(x => x.Logs, logs);
_dc.ExectionLogs.UpdateOne(filter, update, _options);
}
public List<string> GetExecutionLogs(string conversationId)
{
var logs = new List<string>();
if (string.IsNullOrEmpty(conversationId)) return logs;
var filter = Builders<ExecutionLogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
2023-11-29 16:21:03 +00:00
var logCollection = _dc.ExectionLogs.Find(filter).FirstOrDefault();
logs = logCollection?.Logs ?? new List<string>();
return logs;
}
#endregion
2023-11-27 23:49:24 +00:00
#region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log)
{
2023-12-19 03:23:09 +00:00
if (log == null || string.IsNullOrEmpty(log.ConversationId)) return;
var completiongLog = new LlmCompletionLogDocument
2023-11-27 23:49:24 +00:00
{
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
2023-08-26 04:41:01 +00:00
}