Merge pull request #856 from iceljc/features/refine-agent-filter

Features/refine agent filter
This commit is contained in:
iceljc 2025-01-30 15:59:19 -06:00 committed by GitHub
commit 7c5383343c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 407 additions and 186 deletions

View file

@ -9,7 +9,8 @@ public enum AgentField
Disabled,
Type,
InheritAgentId,
Profiles,
Profile,
Label,
RoutingRule,
Instruction,
Function,
@ -30,5 +31,5 @@ public enum AgentTaskField
Description,
Enabled,
Content,
DirectAgentId
Status
}

View file

@ -89,6 +89,11 @@ public class Agent
/// </summary>
public List<string> Profiles { get; set; } = new();
/// <summary>
/// Agent labels
/// </summary>
public List<string> Labels { get; set; } = new();
/// <summary>
/// Merge utilities from entry agent
/// </summary>
@ -158,6 +163,7 @@ public class Agent
MergeUtility = agent.MergeUtility,
MaxMessageCount = agent.MaxMessageCount,
Profiles = agent.Profiles,
Labels = agent.Labels,
RoutingRules = agent.RoutingRules,
Rules = agent.Rules,
LlmConfig = agent.LlmConfig,
@ -269,6 +275,12 @@ public class Agent
return this;
}
public Agent SetLables(List<string> labels)
{
Labels = labels ?? [];
return this;
}
public Agent SetRoutingRules(List<RoutingRule> rules)
{
RoutingRules = rules ?? [];

View file

@ -3,13 +3,14 @@ namespace BotSharp.Abstraction.Repositories.Filters;
public class AgentFilter
{
public Pagination Pager { get; set; } = new Pagination();
public string? AgentName { get; set; }
public List<string>? AgentIds { get; set; }
public List<string>? AgentNames { get; set; }
public string? SimilarName { get; set; }
public bool? Disabled { get; set; }
public bool? Installed { get; set; }
public string? Type { get; set; }
public List<string>? Types { get; set; }
public List<string>? Labels { get; set; }
public bool? IsPublic { get; set; }
public List<string>? AgentIds { get; set; }
public static AgentFilter Empty()
{

View file

@ -16,108 +16,187 @@ namespace BotSharp.Abstraction.Repositories;
public interface IBotSharpRepository : IHaveServiceProvider
{
#region Plugin
PluginConfig GetPluginConfig();
void SavePluginConfig(PluginConfig config);
PluginConfig GetPluginConfig()
=> throw new NotImplementedException();
void SavePluginConfig(PluginConfig config)
=> throw new NotImplementedException();
#endregion
#region Role
bool RefreshRoles(IEnumerable<Role> roles) => throw new NotImplementedException();
IEnumerable<Role> GetRoles(RoleFilter filter) => throw new NotImplementedException();
Role? GetRoleDetails(string roleId, bool includeAgent = false) => throw new NotImplementedException();
bool UpdateRole(Role role, bool updateRoleAgents = false) => throw new NotImplementedException();
bool RefreshRoles(IEnumerable<Role> roles)
=> throw new NotImplementedException();
IEnumerable<Role> GetRoles(RoleFilter filter)
=> throw new NotImplementedException();
Role? GetRoleDetails(string roleId, bool includeAgent = false)
=> throw new NotImplementedException();
bool UpdateRole(Role role, bool updateRoleAgents = false)
=> throw new NotImplementedException();
#endregion
#region User
User? GetUserByEmail(string email) => throw new NotImplementedException();
User? GetUserByPhone(string phone, string type = UserType.Client, string regionCode = "CN") => throw new NotImplementedException();
User? GetAffiliateUserByPhone(string phone) => throw new NotImplementedException();
User? GetUserById(string id) => throw new NotImplementedException();
List<User> GetUserByIds(List<string> ids) => throw new NotImplementedException();
List<User> GetUsersByAffiliateId(string affiliateId) => throw new NotImplementedException();
User? GetUserByUserName(string userName) => throw new NotImplementedException();
void UpdateUserName(string userId, string userName) => throw new NotImplementedException();
Dashboard? GetDashboard(string id = null) => throw new NotImplementedException();
void CreateUser(User user) => throw new NotImplementedException();
void UpdateExistUser(string userId, User user) => throw new NotImplementedException();
void UpdateUserVerified(string userId) => throw new NotImplementedException();
void AddDashboardConversation(string userId, string conversationId) => throw new NotImplementedException();
void RemoveDashboardConversation(string userId, string conversationId) => throw new NotImplementedException();
void UpdateDashboardConversation(string userId, DashboardConversation dashConv) => throw new NotImplementedException();
void UpdateUserVerificationCode(string userId, string verficationCode) => throw new NotImplementedException();
void UpdateUserPassword(string userId, string password) => throw new NotImplementedException();
void UpdateUserEmail(string userId, string email) => throw new NotImplementedException();
void UpdateUserPhone(string userId, string Iphone, string regionCode) => throw new NotImplementedException();
void UpdateUserIsDisable(string userId, bool isDisable) => throw new NotImplementedException();
void UpdateUsersIsDisable(List<string> userIds, bool isDisable) => throw new NotImplementedException();
PagedItems<User> GetUsers(UserFilter filter) => throw new NotImplementedException();
User? GetUserDetails(string userId, bool includeAgent = false) => throw new NotImplementedException();
bool UpdateUser(User user, bool updateUserAgents = false) => throw new NotImplementedException();
User? GetUserByEmail(string email)
=> throw new NotImplementedException();
User? GetUserByPhone(string phone, string type = UserType.Client, string regionCode = "CN")
=> throw new NotImplementedException();
User? GetAffiliateUserByPhone(string phone)
=> throw new NotImplementedException();
User? GetUserById(string id)
=> throw new NotImplementedException();
List<User> GetUserByIds(List<string> ids)
=> throw new NotImplementedException();
List<User> GetUsersByAffiliateId(string affiliateId)
=> throw new NotImplementedException();
User? GetUserByUserName(string userName)
=> throw new NotImplementedException();
void UpdateUserName(string userId, string userName)
=> throw new NotImplementedException();
Dashboard? GetDashboard(string id = null)
=> throw new NotImplementedException();
void CreateUser(User user)
=> throw new NotImplementedException();
void UpdateExistUser(string userId, User user)
=> throw new NotImplementedException();
void UpdateUserVerified(string userId)
=> throw new NotImplementedException();
void AddDashboardConversation(string userId, string conversationId)
=> throw new NotImplementedException();
void RemoveDashboardConversation(string userId, string conversationId)
=> throw new NotImplementedException();
void UpdateDashboardConversation(string userId, DashboardConversation dashConv)
=> throw new NotImplementedException();
void UpdateUserVerificationCode(string userId, string verficationCode)
=> throw new NotImplementedException();
void UpdateUserPassword(string userId, string password)
=> throw new NotImplementedException();
void UpdateUserEmail(string userId, string email)
=> throw new NotImplementedException();
void UpdateUserPhone(string userId, string Iphone, string regionCode)
=> throw new NotImplementedException();
void UpdateUserIsDisable(string userId, bool isDisable)
=> throw new NotImplementedException();
void UpdateUsersIsDisable(List<string> userIds, bool isDisable)
=> throw new NotImplementedException();
PagedItems<User> GetUsers(UserFilter filter)
=> throw new NotImplementedException();
User? GetUserDetails(string userId, bool includeAgent = false)
=> throw new NotImplementedException();
bool UpdateUser(User user, bool updateUserAgents = false)
=> throw new NotImplementedException();
#endregion
#region Agent
void UpdateAgent(Agent agent, AgentField field);
Agent? GetAgent(string agentId, bool basicsOnly = false);
List<Agent> GetAgents(AgentFilter filter);
List<UserAgent> GetUserAgents(string userId);
void BulkInsertAgents(List<Agent> agents);
void BulkInsertUserAgents(List<UserAgent> userAgents);
bool DeleteAgents();
bool DeleteAgent(string agentId);
List<string> GetAgentResponses(string agentId, string prefix, string intent);
string GetAgentTemplate(string agentId, string templateName);
bool PatchAgentTemplate(string agentId, AgentTemplate template);
void UpdateAgent(Agent agent, AgentField field)
=> throw new NotImplementedException();
Agent? GetAgent(string agentId, bool basicsOnly = false)
=> throw new NotImplementedException();
List<Agent> GetAgents(AgentFilter filter)
=> throw new NotImplementedException();
List<UserAgent> GetUserAgents(string userId)
=> throw new NotImplementedException();
void BulkInsertAgents(List<Agent> agents)
=> throw new NotImplementedException();
void BulkInsertUserAgents(List<UserAgent> userAgents)
=> throw new NotImplementedException();
bool DeleteAgents()
=> throw new NotImplementedException();
bool DeleteAgent(string agentId)
=> throw new NotImplementedException();
List<string> GetAgentResponses(string agentId, string prefix, string intent)
=> throw new NotImplementedException();
string GetAgentTemplate(string agentId, string templateName)
=> throw new NotImplementedException();
bool PatchAgentTemplate(string agentId, AgentTemplate template)
=> throw new NotImplementedException();
bool UpdateAgentLabels(string agentId, List<string> labels)
=> throw new NotImplementedException();
bool AppendAgentLabels(string agentId, List<string> labels)
=> throw new NotImplementedException();
#endregion
#region Agent Task
PagedItems<AgentTask> GetAgentTasks(AgentTaskFilter filter);
AgentTask? GetAgentTask(string agentId, string taskId);
void InsertAgentTask(AgentTask task);
void BulkInsertAgentTasks(List<AgentTask> tasks);
void UpdateAgentTask(AgentTask task, AgentTaskField field);
bool DeleteAgentTask(string agentId, List<string> taskIds);
bool DeleteAgentTasks();
PagedItems<AgentTask> GetAgentTasks(AgentTaskFilter filter)
=> throw new NotImplementedException();
AgentTask? GetAgentTask(string agentId, string taskId)
=> throw new NotImplementedException();
void InsertAgentTask(AgentTask task)
=> throw new NotImplementedException();
void BulkInsertAgentTasks(List<AgentTask> tasks)
=> throw new NotImplementedException();
void UpdateAgentTask(AgentTask task, AgentTaskField field)
=> throw new NotImplementedException();
bool DeleteAgentTask(string agentId, List<string> taskIds)
=> throw new NotImplementedException();
bool DeleteAgentTasks()
=> throw new NotImplementedException();
#endregion
#region Conversation
void CreateNewConversation(Conversation conversation);
bool DeleteConversations(IEnumerable<string> conversationIds);
List<DialogElement> GetConversationDialogs(string conversationId);
void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs);
ConversationState GetConversationStates(string conversationId);
void UpdateConversationStates(string conversationId, List<StateKeyValue> states);
void UpdateConversationStatus(string conversationId, string status);
Conversation GetConversation(string conversationId);
PagedItems<Conversation> GetConversations(ConversationFilter filter);
void UpdateConversationTitle(string conversationId, string title);
void UpdateConversationTitleAlias(string conversationId, string titleAlias);
bool UpdateConversationTags(string conversationId, List<string> tags);
bool AppendConversationTags(string conversationId, List<string> tags);
bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request);
void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint);
ConversationBreakpoint? GetConversationBreakpoint(string conversationId);
List<Conversation> GetLastConversations();
List<string> GetIdleConversations(int batchSize, int messageLimit, int bufferHours, IEnumerable<string> excludeAgentIds);
IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false);
void CreateNewConversation(Conversation conversation)
=> throw new NotImplementedException();
bool DeleteConversations(IEnumerable<string> conversationIds)
=> throw new NotImplementedException();
List<DialogElement> GetConversationDialogs(string conversationId)
=> throw new NotImplementedException();
void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
=> throw new NotImplementedException();
ConversationState GetConversationStates(string conversationId)
=> throw new NotImplementedException();
void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
=> throw new NotImplementedException();
void UpdateConversationStatus(string conversationId, string status)
=> throw new NotImplementedException();
Conversation GetConversation(string conversationId)
=> throw new NotImplementedException();
PagedItems<Conversation> GetConversations(ConversationFilter filter)
=> throw new NotImplementedException();
void UpdateConversationTitle(string conversationId, string title)
=> throw new NotImplementedException();
void UpdateConversationTitleAlias(string conversationId, string titleAlias)
=> throw new NotImplementedException();
bool UpdateConversationTags(string conversationId, List<string> tags)
=> throw new NotImplementedException();
bool AppendConversationTags(string conversationId, List<string> tags)
=> throw new NotImplementedException();
bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request)
=> throw new NotImplementedException();
void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint)
=> throw new NotImplementedException();
ConversationBreakpoint? GetConversationBreakpoint(string conversationId)
=> throw new NotImplementedException();
List<Conversation> GetLastConversations()
=> throw new NotImplementedException();
List<string> GetIdleConversations(int batchSize, int messageLimit, int bufferHours, IEnumerable<string> excludeAgentIds)
=> throw new NotImplementedException();
IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
=> throw new NotImplementedException();
#endregion
#region Execution Log
void AddExecutionLogs(string conversationId, List<string> logs);
List<string> GetExecutionLogs(string conversationId);
void AddExecutionLogs(string conversationId, List<string> logs)
=> throw new NotImplementedException();
List<string> GetExecutionLogs(string conversationId)
=> throw new NotImplementedException();
#endregion
#region LLM Completion Log
void SaveLlmCompletionLog(LlmCompletionLog log);
void SaveLlmCompletionLog(LlmCompletionLog log)
=> throw new NotImplementedException();
#endregion
#region Conversation Content Log
void SaveConversationContentLog(ContentLogOutputModel log);
List<ContentLogOutputModel> GetConversationContentLogs(string conversationId);
void SaveConversationContentLog(ContentLogOutputModel log)
=> throw new NotImplementedException();
List<ContentLogOutputModel> GetConversationContentLogs(string conversationId)
=> throw new NotImplementedException();
#endregion
#region Conversation State Log
void SaveConversationStateLog(ConversationStateLogModel log);
List<ConversationStateLogModel> GetConversationStateLogs(string conversationId);
void SaveConversationStateLog(ConversationStateLogModel log)
=> throw new NotImplementedException();
List<ConversationStateLogModel> GetConversationStateLogs(string conversationId)
=> throw new NotImplementedException();
#endregion
#region Statistics
@ -129,8 +208,10 @@ public interface IBotSharpRepository : IHaveServiceProvider
#endregion
#region Translation
IEnumerable<TranslationMemoryOutput> GetTranslationMemories(IEnumerable<TranslationMemoryQuery> queries);
bool SaveTranslationMemories(IEnumerable<TranslationMemoryInput> inputs);
IEnumerable<TranslationMemoryOutput> GetTranslationMemories(IEnumerable<TranslationMemoryQuery> queries)
=> throw new NotImplementedException();
bool SaveTranslationMemories(IEnumerable<TranslationMemoryInput> inputs)
=> throw new NotImplementedException();
#endregion
@ -141,10 +222,15 @@ public interface IBotSharpRepository : IHaveServiceProvider
/// <param name="configs"></param>
/// <param name="reset"></param>
/// <returns></returns>
bool AddKnowledgeCollectionConfigs(List<VectorCollectionConfig> configs, bool reset = false);
bool DeleteKnowledgeCollectionConfig(string collectionName);
IEnumerable<VectorCollectionConfig> GetKnowledgeCollectionConfigs(VectorCollectionConfigFilter filter);
bool SaveKnolwedgeBaseFileMeta(KnowledgeDocMetaData metaData);
bool AddKnowledgeCollectionConfigs(List<VectorCollectionConfig> configs, bool reset = false)
=> throw new NotImplementedException();
bool DeleteKnowledgeCollectionConfig(string collectionName)
=> throw new NotImplementedException();
IEnumerable<VectorCollectionConfig> GetKnowledgeCollectionConfigs(VectorCollectionConfigFilter filter)
=> throw new NotImplementedException();
bool SaveKnolwedgeBaseFileMeta(KnowledgeDocMetaData metaData)
=> throw new NotImplementedException();
/// <summary>
/// Delete file meta data in a knowledge collection, given the vector store provider. If "fileId" is null, delete all in the collection.
/// </summary>
@ -152,13 +238,18 @@ public interface IBotSharpRepository : IHaveServiceProvider
/// <param name="vectorStoreProvider"></param>
/// <param name="fileId"></param>
/// <returns></returns>
bool DeleteKnolwedgeBaseFileMeta(string collectionName, string vectorStoreProvider, Guid? fileId = null);
PagedItems<KnowledgeDocMetaData> GetKnowledgeBaseFileMeta(string collectionName, string vectorStoreProvider, KnowledgeFileFilter filter);
bool DeleteKnolwedgeBaseFileMeta(string collectionName, string vectorStoreProvider, Guid? fileId = null)
=> throw new NotImplementedException();
PagedItems<KnowledgeDocMetaData> GetKnowledgeBaseFileMeta(string collectionName, string vectorStoreProvider, KnowledgeFileFilter filter)
=> throw new NotImplementedException();
#endregion
#region Crontab
bool UpsertCrontabItem(CrontabItem cron) => throw new NotImplementedException();
bool DeleteCrontabItem(string conversationId) => throw new NotImplementedException();
PagedItems<CrontabItem> GetCrontabItems(CrontabItemFilter filter) => throw new NotImplementedException();
bool UpsertCrontabItem(CrontabItem cron)
=> throw new NotImplementedException();
bool DeleteCrontabItem(string conversationId)
=> throw new NotImplementedException();
PagedItems<CrontabItem> GetCrontabItems(CrontabItemFilter filter)
=> throw new NotImplementedException();
#endregion
}

View file

@ -14,13 +14,13 @@
limitations under the License.
******************************************************************************/
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Tasks;
using BotSharp.Abstraction.Tasks.Models;
using BotSharp.Abstraction.Utilities;
using BotSharp.Core.Infrastructures;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
@ -60,23 +60,22 @@ public class CrontabService : ICrontabService, ITaskFeeder
public async Task<List<AgentTask>> GetTasks()
{
var agentService = _services.GetRequiredService<IAgentService>();
var tasks = new List<AgentTask>();
var agentService = _services.GetRequiredService<IAgentService>();
var cronsources = _services.GetServices<ICrontabSource>();
// Get all agent subscribed to this cron
var agents = await agentService.GetAgents(new AgentFilter
{
Pager = new Pagination
{
Size = 1000
}
});
foreach (var source in cronsources)
{
var cron = source.GetCrontabItem();
// Get all agent subscribed to this cron
var agents = await agentService.GetAgents(new AgentFilter
{
Pager = new Pagination
{
Size = 1000
}
});
var preFilteredAgents = agents.Items.Where(x =>
x.Rules.Exists(r => r.TriggerName == cron.Title)).ToList();
@ -84,7 +83,7 @@ public class CrontabService : ICrontabService, ITaskFeeder
{
Id = Guid.Empty.ToString(),
AgentId = x.Id,
Agent = new BotSharp.Abstraction.Agents.Models.Agent
Agent = new Agent
{
Name = x.Name,
Description = x.Description

View file

@ -31,6 +31,7 @@ public partial class AgentService
record.MaxMessageCount = agent.MaxMessageCount;
record.Type = agent.Type;
record.Profiles = agent.Profiles ?? [];
record.Labels = agent.Labels ?? [];
record.RoutingRules = agent.RoutingRules ?? [];
record.Instruction = agent.Instruction ?? string.Empty;
record.ChannelInstructions = agent.ChannelInstructions ?? [];
@ -96,6 +97,7 @@ public partial class AgentService
.SetMergeUtility(foundAgent.MergeUtility)
.SetAgentType(foundAgent.Type)
.SetProfiles(foundAgent.Profiles)
.SetLables(foundAgent.Labels)
.SetRoutingRules(foundAgent.RoutingRules)
.SetInstruction(foundAgent.Instruction)
.SetChannelInstructions(foundAgent.ChannelInstructions)

View file

@ -136,6 +136,7 @@ public class ConversationStateService : IConversationStateService, IDisposable
public Dictionary<string, string> Load(string conversationId, bool isReadOnly = false)
{
_conversationId = !isReadOnly ? conversationId : null;
Reset();
var routingCtx = _services.GetRequiredService<IRoutingContext>();
var curMsgId = routingCtx.MessageId;

View file

@ -30,9 +30,12 @@ namespace BotSharp.Core.Repository
case AgentField.InheritAgentId:
UpdateAgentInheritAgentId(agent.Id, agent.InheritAgentId);
break;
case AgentField.Profiles:
case AgentField.Profile:
UpdateAgentProfiles(agent.Id, agent.Profiles);
break;
case AgentField.Label:
UpdateAgentLabels(agent.Id, agent.Labels);
break;
case AgentField.RoutingRule:
UpdateAgentRoutingRules(agent.Id, agent.RoutingRules);
break;
@ -160,6 +163,20 @@ namespace BotSharp.Core.Repository
File.WriteAllText(agentFile, json);
}
public bool UpdateAgentLabels(string agentId, List<string> labels)
{
if (labels == null) return false;
var (agent, agentFile) = GetAgentFromFile(agentId);
if (agent == null) return false;
agent.Labels = labels;
agent.UpdatedDateTime = DateTime.UtcNow;
var json = JsonSerializer.Serialize(agent, _options);
File.WriteAllText(agentFile, json);
return true;
}
private void UpdateAgentUtilities(string agentId, bool mergeUtility, List<AgentUtility> utilities)
{
if (utilities == null) return;
@ -341,6 +358,7 @@ namespace BotSharp.Core.Repository
agent.MergeUtility = inputAgent.MergeUtility;
agent.Type = inputAgent.Type;
agent.Profiles = inputAgent.Profiles;
agent.Labels = inputAgent.Labels;
agent.Utilities = inputAgent.Utilities;
agent.KnowledgeBases = inputAgent.KnowledgeBases;
agent.RoutingRules = inputAgent.RoutingRules;
@ -417,9 +435,14 @@ namespace BotSharp.Core.Repository
}
var query = Agents;
if (!string.IsNullOrEmpty(filter.AgentName))
if (filter.AgentIds != null)
{
query = query.Where(x => x.Name.ToLower() == filter.AgentName.ToLower());
query = query.Where(x => filter.AgentIds.Contains(x.Id));
}
if (!filter.AgentNames.IsNullOrEmpty())
{
query = query.Where(x => filter.AgentNames.Contains(x.Name));
}
if (!string.IsNullOrEmpty(filter.SimilarName))
@ -433,10 +456,14 @@ namespace BotSharp.Core.Repository
query = query.Where(x => x.Disabled == filter.Disabled);
}
if (filter.Type != null)
if (!filter.Types.IsNullOrEmpty())
{
var types = filter.Type.Split(",");
query = query.Where(x => types.Contains(x.Type));
query = query.Where(x => filter.Types.Contains(x.Type));
}
if (!filter.Labels.IsNullOrEmpty())
{
query = query.Where(x => x.Labels.Any(y => filter.Labels.Contains(y)));
}
if (filter.IsPublic.HasValue)
@ -444,11 +471,6 @@ namespace BotSharp.Core.Repository
query = query.Where(x => x.IsPublic == filter.IsPublic);
}
if (filter.AgentIds != null)
{
query = query.Where(x => filter.AgentIds.Contains(x.Id));
}
return query.ToList();
}
@ -515,6 +537,22 @@ namespace BotSharp.Core.Repository
return true;
}
public bool AppendAgentLabels(string agentId, List<string> labels)
{
if (labels.IsNullOrEmpty()) return false;
var (agent, agentFile) = GetAgentFromFile(agentId);
if (agent == null) return false;
var prevLabels = agent.Labels ?? [];
var curLabels = prevLabels.Concat(labels).Distinct().ToList();
agent.Labels = curLabels;
agent.UpdatedDateTime = DateTime.UtcNow;
var json = JsonSerializer.Serialize(agent, _options);
File.WriteAllText(agentFile, json);
return true;
}
public void BulkInsertAgents(List<Agent> agents)
{
if (agents.IsNullOrEmpty()) return;

View file

@ -50,6 +50,11 @@ public partial class FileRepository
matched = matched && task.Enabled == filter.Enabled;
}
if (!string.IsNullOrEmpty(filter?.Status))
{
matched = matched && task.Status == filter.Status;
}
if (!matched) continue;
totalCount++;

View file

@ -18,7 +18,7 @@ public class FallbackToRouterFn : IFunctionCallback
var agentService = _services.GetRequiredService<IAgentService>();
var agents = await agentService.GetAgents(new AgentFilter
{
AgentName = args.AgentName
AgentNames = [args.AgentName]
});
var targetAgent = agents.Items.FirstOrDefault();
if (targetAgent == null)

View file

@ -47,7 +47,7 @@ public partial class RouteToAgentFn : IFunctionCallback
}
var db = _services.GetRequiredService<IBotSharpRepository>();
var filter = new AgentFilter { AgentName = args.OriginalAgent };
var filter = new AgentFilter { AgentNames = [args.OriginalAgent] };
var originalAgent = db.GetAgents(filter).FirstOrDefault();
if (originalAgent != null)
{
@ -69,7 +69,7 @@ public partial class RouteToAgentFn : IFunctionCallback
else
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var filter = new AgentFilter { AgentName = args.AgentName };
var filter = new AgentFilter { AgentNames = [args.AgentName] };
var targetAgent = db.GetAgents(filter).FirstOrDefault();
if (targetAgent == null)
{

View file

@ -38,7 +38,7 @@ public class ContinueExecuteTaskRoutingHandler : RoutingHandlerBase//, IRoutingH
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var filter = new AgentFilter { AgentName = inst.AgentName };
var filter = new AgentFilter { AgentNames = [inst.AgentName] };
var record = db.GetAgents(filter).FirstOrDefault();
message.FunctionName = inst.Function;

View file

@ -87,7 +87,7 @@ public class HFReasoner : IRoutingReasoner
if (!string.IsNullOrEmpty(inst.AgentName))
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var filter = new AgentFilter { AgentName = inst.AgentName };
var filter = new AgentFilter { AgentNames = [inst.AgentName] };
var agent = db.GetAgents(filter).FirstOrDefault();
var context = _services.GetRequiredService<IRoutingContext>();

View file

@ -11,7 +11,7 @@ public static class ReasonerHelper
var agentService = services.GetRequiredService<IAgentService>();
var agents = agentService.GetAgents(new AgentFilter
{
Type = AgentType.Task
Types = [AgentType.Task]
}).Result.Items.ToList();
var malformed = false;

View file

@ -41,7 +41,7 @@ public class RoutingContext : IRoutingContext
var agentService = _services.GetRequiredService<IAgentService>();
_routerAgentIds = agentService.GetAgents(new AgentFilter
{
Type = AgentType.Routing,
Types = [AgentType.Routing],
Pager = new Pagination { Size = 100 }
}).Result.Items.Select(x => x.Id).ToArray();
}
@ -86,7 +86,7 @@ public class RoutingContext : IRoutingContext
var agentService = _services.GetRequiredService<IAgentService>();
agentId = agentService.GetAgents(new AgentFilter
{
AgentName = agentId
AgentNames = [agentId]
}).Result.Items.First().Id;
}

View file

@ -21,11 +21,18 @@ public class AgentTaskService : IAgentTaskService
if (filter.Status == TaskStatus.Scheduled)
{
var taskFeeders = _services.GetServices<ITaskFeeder>();
var items = taskFeeders.SelectMany(x => x.GetTasks().Result);
var items = new List<AgentTask>();
foreach (var feeder in taskFeeders)
{
var tasks = await feeder.GetTasks();
items.AddRange(tasks);
}
return new PagedItems<AgentTask>
{
Items = items,
Items = items.OrderByDescending(x => x.UpdatedDateTime)
.Skip(filter.Pager.Offset).Take(filter.Pager.Size),
Count = items.Count()
};
}

View file

@ -39,11 +39,11 @@ public class AgentTaskController : ControllerBase
public async Task<PagedItems<AgentTaskViewModel>> GetAgentTasks([FromQuery] AgentTaskFilter filter)
{
filter.Status = TaskStatus.Scheduled;
var tasks = await _agentTaskService.GetTasks(filter);
var page = await _agentTaskService.GetTasks(filter);
return new PagedItems<AgentTaskViewModel>
{
Items = tasks.Items.Select(AgentTaskViewModel.From),
Count = tasks.Count
Items = page.Items.Select(AgentTaskViewModel.From),
Count = page.Count
};
}

View file

@ -48,6 +48,8 @@ public class AgentCreationModel
/// </summary>
public List<string> Profiles { get; set; } = new();
public List<string> Labels { get; set; } = new();
public bool MergeUtility { get; set; }
public int? MaxMessageCount { get; set; }
@ -77,6 +79,7 @@ public class AgentCreationModel
MergeUtility = MergeUtility,
MaxMessageCount = MaxMessageCount,
Profiles = Profiles,
Labels = Labels,
LlmConfig = LlmConfig,
KnowledgeBases = KnowledgeBases,
Rules = Rules,

View file

@ -15,10 +15,13 @@ public class AgentTaskViewModel
[JsonPropertyName("created_datetime")]
public DateTime CreatedDateTime { get; set; }
[JsonPropertyName("updated_datetime")]
public DateTime UpdatedDateTime { get; set; }
[JsonPropertyName("agent_id")]
public string AgentId { get; set; } = null!;
[JsonPropertyName("agent_name")]
public string AgentName { get; set; } = null!;

View file

@ -72,6 +72,8 @@ public class AgentUpdateModel
/// </summary>
public List<string>? Profiles { get; set; }
public List<string>? Labels { get; set; }
[JsonPropertyName("routing_rules")]
public List<RoutingRuleUpdateModel>? RoutingRules { get; set; }
@ -93,6 +95,7 @@ public class AgentUpdateModel
MaxMessageCount = MaxMessageCount,
Type = Type,
Profiles = Profiles ?? [],
Labels = Labels ?? [],
RoutingRules = RoutingRules?.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?.ToList() ?? [],
Instruction = Instruction ?? string.Empty,
ChannelInstructions = ChannelInstructions ?? [],

View file

@ -37,6 +37,9 @@ public class AgentViewModel
[JsonPropertyName("is_host")]
public bool IsHost { get; set; }
[JsonPropertyName("is_router")]
public bool IsRouter => Type == AgentType.Routing;
public bool Disabled { get; set; }
[JsonPropertyName("icon_url")]
@ -44,6 +47,8 @@ public class AgentViewModel
public List<string> Profiles { get; set; } = new();
public List<string> Labels { get; set; } = new();
[JsonPropertyName("routing_rules")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public List<RoutingRule> RoutingRules { get; set; }
@ -88,6 +93,7 @@ public class AgentViewModel
IconUrl = agent.IconUrl,
MaxMessageCount = agent.MaxMessageCount,
Profiles = agent.Profiles ?? [],
Labels = agent.Labels ?? [],
RoutingRules = agent.RoutingRules ?? [],
Rules = agent.Rules ?? [],
LlmConfig = agent.LlmConfig,

View file

@ -20,6 +20,7 @@ public class AgentDocument : MongoBase
public List<AgentUtilityMongoElement> Utilities { get; set; }
public List<AgentKnowledgeBaseMongoElement> KnowledgeBases { get; set; }
public List<string> Profiles { get; set; }
public List<string> Labels { get; set; }
public List<RoutingRuleMongoElement> RoutingRules { get; set; }
public List<AgentRuleMongoElement> Rules { get; set; }
public AgentLlmConfigMongoElement? LlmConfig { get; set; }

View file

@ -1,3 +1,5 @@
using BotSharp.Abstraction.Tasks.Models;
namespace BotSharp.Plugin.MongoStorage.Collections;
public class AgentTaskDocument : MongoBase
@ -7,7 +9,37 @@ public class AgentTaskDocument : MongoBase
public string Content { get; set; }
public bool Enabled { get; set; }
public string AgentId { get; set; }
public string? DirectAgentId { get; set; }
public string Status { get; set; }
public DateTime CreatedTime { get; set; }
public DateTime UpdatedTime { get; set; }
public static AgentTask ToDomainModel(AgentTaskDocument model)
{
return new AgentTask
{
Id = model.Id,
Description = model.Description,
Content = model.Content,
Enabled = model.Enabled,
AgentId = model.AgentId,
Status = model.Status,
CreatedDateTime = model.CreatedTime,
UpdatedDateTime = model.UpdatedTime
};
}
public static AgentTaskDocument ToMongoModel(AgentTask model)
{
return new AgentTaskDocument
{
Id = model.Id,
Description = model.Description,
Content = model.Content,
Enabled = model.Enabled,
AgentId = model.AgentId,
Status = model.Status,
CreatedTime = model.CreatedDateTime,
UpdatedTime = model.UpdatedDateTime
};
}
}

View file

@ -31,9 +31,12 @@ public partial class MongoRepository
case AgentField.InheritAgentId:
UpdateAgentInheritAgentId(agent.Id, agent.InheritAgentId);
break;
case AgentField.Profiles:
case AgentField.Profile:
UpdateAgentProfiles(agent.Id, agent.Profiles);
break;
case AgentField.Label:
UpdateAgentLabels(agent.Id, agent.Profiles);
break;
case AgentField.RoutingRule:
UpdateAgentRoutingRules(agent.Id, agent.RoutingRules);
break;
@ -152,6 +155,19 @@ public partial class MongoRepository
_dc.Agents.UpdateOne(filter, update);
}
public bool UpdateAgentLabels(string agentId, List<string> labels)
{
if (labels == null) return false;
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var update = Builders<AgentDocument>.Update
.Set(x => x.Labels, labels)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
var result = _dc.Agents.UpdateOne(filter, update);
return result.ModifiedCount > 0;
}
private void UpdateAgentRoutingRules(string agentId, List<RoutingRule> rules)
{
if (rules == null) return;
@ -305,6 +321,7 @@ public partial class MongoRepository
.Set(x => x.Type, agent.Type)
.Set(x => x.MaxMessageCount, agent.MaxMessageCount)
.Set(x => x.Profiles, agent.Profiles)
.Set(x => x.Labels, agent.Labels)
.Set(x => x.RoutingRules, agent.RoutingRules.Select(r => RoutingRuleMongoElement.ToMongoElement(r)).ToList())
.Set(x => x.Instruction, agent.Instruction)
.Set(x => x.ChannelInstructions, agent.ChannelInstructions.Select(i => ChannelInstructionMongoElement.ToMongoElement(i)).ToList())
@ -343,9 +360,14 @@ public partial class MongoRepository
var builder = Builders<AgentDocument>.Filter;
var filters = new List<FilterDefinition<AgentDocument>>() { builder.Empty };
if (!string.IsNullOrEmpty(filter.AgentName))
if (filter.AgentIds != null)
{
filters.Add(builder.Eq(x => x.Name, filter.AgentName));
filters.Add(builder.In(x => x.Id, filter.AgentIds));
}
if (!filter.AgentNames.IsNullOrEmpty())
{
filters.Add(builder.In(x => x.Name, filter.AgentNames));
}
if (!string.IsNullOrEmpty(filter.SimilarName))
@ -358,10 +380,14 @@ public partial class MongoRepository
filters.Add(builder.Eq(x => x.Disabled, filter.Disabled.Value));
}
if (filter.Type != null)
if (!filter.Types.IsNullOrEmpty())
{
var types = filter.Type.Split(",");
filters.Add(builder.In(x => x.Type, types));
filters.Add(builder.In(x => x.Type, filter.Types));
}
if (!filter.Labels.IsNullOrEmpty())
{
filters.Add(builder.AnyIn(x => x.Labels, filter.Labels));
}
if (filter.IsPublic.HasValue)
@ -369,13 +395,7 @@ public partial class MongoRepository
filters.Add(builder.Eq(x => x.IsPublic, filter.IsPublic.Value));
}
if (filter.AgentIds != null)
{
filters.Add(builder.In(x => x.Id, filter.AgentIds));
}
var agentDocs = _dc.Agents.Find(builder.And(filters)).ToList();
return agentDocs.Select(x => TransformAgentDocument(x)).ToList();
}
@ -445,6 +465,24 @@ public partial class MongoRepository
return true;
}
public bool AppendAgentLabels(string agentId, List<string> labels)
{
if (labels.IsNullOrEmpty()) return false;
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var agent = _dc.Agents.Find(filter).FirstOrDefault();
if (agent == null) return false;
var prevLabels = agent.Labels ?? [];
var curLabels = prevLabels.Concat(labels).Distinct().ToList();
var update = Builders<AgentDocument>.Update
.Set(x => x.Labels, curLabels)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
var result = _dc.Agents.UpdateOne(filter, update);
return result.ModifiedCount > 0;
}
public void BulkInsertAgents(List<Agent> agents)
{
if (agents.IsNullOrEmpty()) return;
@ -555,7 +593,8 @@ public partial class MongoRepository
MergeUtility = agentDoc.MergeUtility,
Type = agentDoc.Type,
InheritAgentId = agentDoc.InheritAgentId,
Profiles = agentDoc.Profiles,
Profiles = agentDoc.Profiles ?? [],
Labels = agentDoc.Labels ?? [],
MaxMessageCount = agentDoc.MaxMessageCount,
LlmConfig = AgentLlmConfigMongoElement.ToDomainElement(agentDoc.LlmConfig),
ChannelInstructions = agentDoc.ChannelInstructions?.Select(i => ChannelInstructionMongoElement.ToDomainElement(i))?.ToList() ?? [],

View file

@ -22,6 +22,11 @@ public partial class MongoRepository
filters.Add(builder.Eq(x => x.AgentId, filter.AgentId));
}
if (!string.IsNullOrEmpty(filter.Status))
{
filters.Add(builder.Eq(x => x.Status, filter.Status));
}
if (filter.Enabled.HasValue)
{
filters.Add(builder.Eq(x => x.Enabled, filter.Enabled.Value));
@ -35,17 +40,11 @@ public partial class MongoRepository
var agentIds = taskDocs.Select(x => x.AgentId).Distinct().ToList();
var agents = GetAgents(new AgentFilter { AgentIds = agentIds });
var tasks = taskDocs.Select(x => new AgentTask
var tasks = taskDocs.Select(x =>
{
Id = x.Id,
Name = x.Name,
Description = x.Description,
Enabled = x.Enabled,
AgentId = x.AgentId,
Content = x.Content,
CreatedDateTime = x.CreatedTime,
UpdatedDateTime = x.UpdatedTime,
Agent = agents.FirstOrDefault(a => a.Id == x.AgentId)
var task = AgentTaskDocument.ToDomainModel(x);
task.Agent = agents.FirstOrDefault(a => a.Id == x.AgentId);
return task;
}).ToList();
return new PagedItems<AgentTask>
@ -65,36 +64,15 @@ public partial class MongoRepository
var agentDoc = _dc.Agents.AsQueryable().FirstOrDefault(x => x.Id == taskDoc.AgentId);
var agent = TransformAgentDocument(agentDoc);
var task = new AgentTask
{
Id = taskDoc.Id,
Name = taskDoc.Name,
Description = taskDoc.Description,
Enabled = taskDoc.Enabled,
AgentId = taskDoc.AgentId,
Content = taskDoc.Content,
CreatedDateTime = taskDoc.CreatedTime,
UpdatedDateTime = taskDoc.UpdatedTime,
Agent = agent
};
var task = AgentTaskDocument.ToDomainModel(taskDoc);
task.Agent = agent;
return task;
}
public void InsertAgentTask(AgentTask task)
{
var taskDoc = new AgentTaskDocument
{
Id = Guid.NewGuid().ToString(),
Name = task.Name,
Description = task.Description,
Enabled = task.Enabled,
AgentId = task.AgentId,
Content = task.Content,
CreatedTime = DateTime.UtcNow,
UpdatedTime = DateTime.UtcNow
};
var taskDoc = AgentTaskDocument.ToMongoModel(task);
taskDoc.Id = Guid.NewGuid().ToString();
_dc.AgentTasks.InsertOne(taskDoc);
}
@ -102,16 +80,11 @@ public partial class MongoRepository
{
if (tasks.IsNullOrEmpty()) return;
var taskDocs = tasks.Select(x => new AgentTaskDocument
var taskDocs = tasks.Select(x =>
{
Id = string.IsNullOrEmpty(x.Id) ? Guid.NewGuid().ToString() : x.Id,
Name = x.Name,
Description = x.Description,
Enabled = x.Enabled,
AgentId = x.AgentId,
Content = x.Content,
CreatedTime = x.CreatedDateTime,
UpdatedTime = x.UpdatedDateTime
var task = AgentTaskDocument.ToMongoModel(x);
task.Id = !string.IsNullOrEmpty(x.Id) ? x.Id : Guid.NewGuid().ToString();
return task;
}).ToList();
_dc.AgentTasks.InsertMany(taskDocs);
@ -139,11 +112,15 @@ public partial class MongoRepository
case AgentTaskField.Content:
taskDoc.Content = task.Content;
break;
case AgentTaskField.Status:
taskDoc.Status = task.Status;
break;
case AgentTaskField.All:
taskDoc.Name = task.Name;
taskDoc.Description = task.Description;
taskDoc.Enabled = task.Enabled;
taskDoc.Content = task.Content;
taskDoc.Status = task.Status;
break;
}