From 42ad511c7e3c58a0bc9a9d9ae6555b840783e8c3 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Fri, 13 Dec 2024 14:34:17 -0600 Subject: [PATCH] add agent max message count --- .../Agents/Enums/AgentField.cs | 3 ++- .../Agents/Models/Agent.cs | 8 ++++++ .../Repositories/IBotSharpRepository.cs | 2 +- .../Agents/Hooks/BasicAgentHook.cs | 2 +- .../Services/AgentService.UpdateAgent.cs | 1 + .../Services/ConversationService.cs | 17 +++++++++++- .../Repository/BotSharpDbContext.cs | 2 +- .../FileRepository/FileRepository.Agent.cs | 19 +++++++++++++- .../ViewModels/Agents/AgentCreationModel.cs | 3 +++ .../ViewModels/Agents/AgentUpdateModel.cs | 4 +++ .../ViewModels/Agents/AgentViewModel.cs | 5 ++++ .../Collections/AgentDocument.cs | 1 + .../Repository/MongoRepository.Agent.cs | 26 ++++++++++++++----- 13 files changed, 81 insertions(+), 12 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs index 1bb221d3..34e8ac19 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs @@ -17,7 +17,8 @@ public enum AgentField Response, Sample, LlmConfig, - Utility + Utility, + MaxMessageCount } public enum AgentTaskField diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index e9fd7c5e..41b3800c 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -104,6 +104,12 @@ public class Agent /// public string? InheritAgentId { get; set; } + /// + /// Maximum message count when load conversation + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? MaxMessageCount { get; set; } + public List RoutingRules { get; set; } = new(); /// @@ -133,6 +139,8 @@ public class Agent Knowledges = agent.Knowledges, IsPublic = agent.IsPublic, Disabled = agent.Disabled, + MergeUtility = agent.MergeUtility, + MaxMessageCount = agent.MaxMessageCount, Profiles = agent.Profiles, RoutingRules = agent.RoutingRules, LlmConfig = agent.LlmConfig, diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 61982cc4..a848b619 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -53,7 +53,7 @@ public interface IBotSharpRepository : IHaveServiceProvider #region Agent void UpdateAgent(Agent agent, AgentField field); - Agent? GetAgent(string agentId); + Agent? GetAgent(string agentId, bool basicsOnly = false); List GetAgents(AgentFilter filter); List GetUserAgents(string userId); void BulkInsertAgents(List agents); diff --git a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs index 2a4a7374..65d454c8 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs @@ -47,7 +47,7 @@ public class BasicAgentHook : AgentHookBase var entryAgentId = routing.EntryAgentId; if (!string.IsNullOrEmpty(entryAgentId)) { - var entryAgent = db.GetAgent(entryAgentId); + var entryAgent = db.GetAgent(entryAgentId, basicsOnly: true); var (fns, tps) = GetUniqueContent(entryAgent?.Utilities); functionNames = functionNames.Concat(fns).Distinct().ToList(); templateNames = templateNames.Concat(tps).Distinct().ToList(); diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index f871a2fe..ffea8f8d 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -28,6 +28,7 @@ public partial class AgentService record.IsPublic = agent.IsPublic; record.Disabled = agent.Disabled; record.MergeUtility = agent.MergeUtility; + record.MaxMessageCount = agent.MaxMessageCount; record.Type = agent.Type; record.Profiles = agent.Profiles ?? []; record.RoutingRules = agent.RoutingRules ?? []; diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 55d80c18..d586b421 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -153,7 +153,10 @@ public partial class ConversationService : IConversationService } } - return dialogs.TakeLast(lastCount).ToList(); + var agentMsgCount = GetAgentMessageCount(); + var count = agentMsgCount.HasValue && agentMsgCount.Value > 0 ? agentMsgCount.Value : lastCount; + + return dialogs.TakeLast(count).ToList(); } public void SetConversationId(string conversationId, List states, bool isReadOnly = false) @@ -192,4 +195,16 @@ public partial class ConversationService : IConversationService { return !string.IsNullOrWhiteSpace(_conversationId); } + + + private int? GetAgentMessageCount() + { + var db = _services.GetRequiredService(); + var routingCtx = _services.GetRequiredService(); + + if (string.IsNullOrEmpty(routingCtx.EntryAgentId)) return null; + + var agent = db.GetAgent(routingCtx.EntryAgentId, basicsOnly: true); + return agent?.MaxMessageCount; + } } diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index d2c519eb..ad2b19b8 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -16,7 +16,7 @@ public class BotSharpDbContext : Database, IBotSharpRepository #endregion #region Agent - public Agent GetAgent(string agentId) + public Agent GetAgent(string agentId, bool basicsOnly = false) => throw new NotImplementedException(); public List GetAgents(AgentFilter filter) diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs index 07915917..a838870f 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs @@ -57,6 +57,9 @@ namespace BotSharp.Core.Repository case AgentField.Utility: UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; + case AgentField.MaxMessageCount: + UpdateAgentMaxMessageCount(agent.Id, agent.MaxMessageCount); + break; case AgentField.All: UpdateAgentAllFields(agent); break; @@ -283,6 +286,17 @@ namespace BotSharp.Core.Repository File.WriteAllText(agentFile, json); } + private void UpdateAgentMaxMessageCount(string agentId, int? maxMessageCount) + { + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + agent.MaxMessageCount = maxMessageCount; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); + } + private void UpdateAgentAllFields(Agent inputAgent) { var (agent, agentFile) = GetAgentFromFile(inputAgent.Id); @@ -298,6 +312,7 @@ namespace BotSharp.Core.Repository agent.Utilities = inputAgent.Utilities; agent.RoutingRules = inputAgent.RoutingRules; agent.LlmConfig = inputAgent.LlmConfig; + agent.MaxMessageCount = inputAgent.MaxMessageCount; agent.UpdatedDateTime = DateTime.UtcNow; var json = JsonSerializer.Serialize(agent, _options); File.WriteAllText(agentFile, json); @@ -329,7 +344,7 @@ namespace BotSharp.Core.Repository return responses; } - public Agent? GetAgent(string agentId) + public Agent? GetAgent(string agentId, bool basicsOnly = false) { var agentDir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir); var dir = Directory.GetDirectories(agentDir).FirstOrDefault(x => x.Split(Path.DirectorySeparatorChar).Last() == agentId); @@ -342,6 +357,8 @@ namespace BotSharp.Core.Repository var record = JsonSerializer.Deserialize(json, _options); if (record == null) return null; + if (basicsOnly) return record; + var (defaultInstruction, channelInstructions) = FetchInstructions(dir); var functions = FetchFunctions(dir); var samples = FetchSamples(dir); diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs index 32b3fdce..44c257df 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs @@ -51,6 +51,8 @@ public class AgentCreationModel public bool MergeUtility { get; set; } + public int? MaxMessageCount { get; set; } + public List Utilities { get; set; } = new(); public List RoutingRules { get; set; } = new(); public AgentLlmConfig? LlmConfig { get; set; } @@ -72,6 +74,7 @@ public class AgentCreationModel Type = Type, Disabled = Disabled, MergeUtility = MergeUtility, + MaxMessageCount = MaxMessageCount, Profiles = Profiles, RoutingRules = RoutingRules?.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?.ToList() ?? new List(), LlmConfig = LlmConfig diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs index 30308c9f..141f0662 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -57,6 +57,9 @@ public class AgentUpdateModel public bool Disabled { get; set; } + [JsonPropertyName("max_message_count")] + public int? MaxMessageCount { get; set; } + /// /// Profile by channel /// @@ -77,6 +80,7 @@ public class AgentUpdateModel IsPublic = IsPublic, Disabled = Disabled, MergeUtility = MergeUtility, + MaxMessageCount = MaxMessageCount, Type = Type, Profiles = Profiles ?? new List(), RoutingRules = RoutingRules?.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?.ToList() ?? new List(), diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs index 34b1bcc1..36a8900f 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -46,6 +46,10 @@ public class AgentViewModel [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public AgentLlmConfig? LlmConfig { get; set; } + [JsonPropertyName("max_message_count")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? MaxMessageCount { get; set; } + public PluginDef Plugin { get; set; } public IEnumerable? Actions { get; set; } @@ -75,6 +79,7 @@ public class AgentViewModel Disabled = agent.Disabled, MergeUtility = agent.MergeUtility, IconUrl = agent.IconUrl, + MaxMessageCount = agent.MaxMessageCount, Profiles = agent.Profiles ?? new List(), RoutingRules = agent.RoutingRules, LlmConfig = agent.LlmConfig, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs index 76fee1b3..3a775025 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs @@ -11,6 +11,7 @@ public class AgentDocument : MongoBase public bool IsPublic { get; set; } public bool Disabled { get; set; } public bool MergeUtility { get; set; } + public int? MaxMessageCount { get; set; } public List ChannelInstructions { get; set; } public List Templates { get; set; } public List Functions { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs index 7f216b6d..9bd72e3e 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs @@ -9,7 +9,7 @@ public partial class MongoRepository { public void UpdateAgent(Agent agent, AgentField field) { - if (agent == null || string.IsNullOrEmpty(agent.Id)) return; + if (agent == null || string.IsNullOrWhiteSpace(agent.Id)) return; switch (field) { @@ -58,6 +58,9 @@ public partial class MongoRepository case AgentField.Utility: UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; + case AgentField.MaxMessageCount: + UpdateAgentMaxMessageCount(agent.Id, agent.MaxMessageCount); + break; case AgentField.All: UpdateAgentAllFields(agent); break; @@ -158,10 +161,8 @@ public partial class MongoRepository private void UpdateAgentInstructions(string agentId, string instruction, List? channelInstructions) { - if (string.IsNullOrWhiteSpace(agentId)) return; - var instructionElements = channelInstructions?.Select(x => ChannelInstructionMongoElement.ToMongoElement(x))? - .ToList() ?? new List(); + .ToList() ?? []; var filter = Builders.Filter.Eq(x => x.Id, agentId); var update = Builders.Update @@ -200,7 +201,7 @@ public partial class MongoRepository private void UpdateAgentResponses(string agentId, List responses) { - if (responses == null) return; + if (responses == null || string.IsNullOrWhiteSpace(agentId)) return; var responsesToUpdate = responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList(); var filter = Builders.Filter.Eq(x => x.Id, agentId); @@ -249,6 +250,16 @@ public partial class MongoRepository _dc.Agents.UpdateOne(filter, update); } + private void UpdateAgentMaxMessageCount(string agentId, int? maxMessageCount) + { + var filter = Builders.Filter.Eq(x => x.Id, agentId); + var update = Builders.Update + .Set(x => x.MaxMessageCount, maxMessageCount) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + private void UpdateAgentAllFields(Agent agent) { var filter = Builders.Filter.Eq(x => x.Id, agent.Id); @@ -258,6 +269,7 @@ public partial class MongoRepository .Set(x => x.Disabled, agent.Disabled) .Set(x => x.MergeUtility, agent.MergeUtility) .Set(x => x.Type, agent.Type) + .Set(x => x.MaxMessageCount, agent.MaxMessageCount) .Set(x => x.Profiles, agent.Profiles) .Set(x => x.RoutingRules, agent.RoutingRules.Select(r => RoutingRuleMongoElement.ToMongoElement(r)).ToList()) .Set(x => x.Instruction, agent.Instruction) @@ -277,7 +289,7 @@ public partial class MongoRepository #endregion - public Agent? GetAgent(string agentId) + public Agent? GetAgent(string agentId, bool basicsOnly = false) { var agent = _dc.Agents.AsQueryable().FirstOrDefault(x => x.Id == agentId); if (agent == null) return null; @@ -420,6 +432,7 @@ public partial class MongoRepository InheritAgentId = x.InheritAgentId, Disabled = x.Disabled, MergeUtility = x.MergeUtility, + MaxMessageCount = x.MaxMessageCount, Profiles = x.Profiles, RoutingRules = x.RoutingRules?.Select(r => RoutingRuleMongoElement.ToMongoElement(r))?.ToList() ?? [], LlmConfig = AgentLlmConfigMongoElement.ToMongoElement(x.LlmConfig), @@ -513,6 +526,7 @@ public partial class MongoRepository Type = agentDoc.Type, InheritAgentId = agentDoc.InheritAgentId, Profiles = agentDoc.Profiles, + MaxMessageCount = agentDoc.MaxMessageCount }; } }