From c5c2117fd071482687858731eaca478a180b0e42 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Fri, 10 Jan 2025 12:58:16 -0600 Subject: [PATCH 1/3] refine idle conv --- .../Repository/FileRepository/FileRepository.Conversation.cs | 5 +++-- .../Repository/MongoRepository.Conversation.cs | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs index 34345271..f249c9fa 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs @@ -507,12 +507,13 @@ namespace BotSharp.Core.Repository continue; } - if (excludeAgentIds.Contains(conv.AgentId) || conv.UpdatedTime > utcNow.AddHours(-bufferHours)) + if (conv.UpdatedTime > utcNow.AddHours(-bufferHours)) { continue; } - if (conv.DialogCount <= messageLimit) + if ((excludeAgentIds.Contains(conv.AgentId) && conv.DialogCount == 0) + || (!excludeAgentIds.Contains(conv.AgentId) && conv.DialogCount <= messageLimit)) { ids.Add(conv.Id); if (ids.Count >= batchSize) diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs index 468f467a..be2b5ac4 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs @@ -455,7 +455,9 @@ public partial class MongoRepository { var skip = (page - 1) * batchSize; var candidates = _dc.Conversations.AsQueryable() - .Where(x => !excludeAgentIds.Contains(x.AgentId) && x.DialogCount <= messageLimit && x.UpdatedTime <= utcNow.AddHours(-bufferHours)) + .Where(x => ((!excludeAgentIds.Contains(x.AgentId) && x.DialogCount <= messageLimit) + || (excludeAgentIds.Contains(x.AgentId) && x.DialogCount == 0)) + && x.UpdatedTime <= utcNow.AddHours(-bufferHours)) .Skip(skip) .Take(batchSize) .Select(x => x.Id) From 61f04c1543db72d7db828274f058de28e2224981 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Fri, 10 Jan 2025 16:09:56 -0600 Subject: [PATCH 2/3] ignore case --- .../Repository/MongoRepository.Agent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs index af615298..31d6abdf 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs @@ -425,7 +425,7 @@ public partial class MongoRepository var agent = _dc.Agents.AsQueryable().FirstOrDefault(x => x.Id == agentId); if (agent == null) return string.Empty; - return agent.Templates?.FirstOrDefault(x => x.Name == templateName.ToLower())?.Content ?? string.Empty; + return agent.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(templateName))?.Content ?? string.Empty; } public bool PatchAgentTemplate(string agentId, AgentTemplate template) From 6e9f2c93e4be4cc2b4c938270dfd50534320b9b4 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Mon, 13 Jan 2025 01:14:36 -0600 Subject: [PATCH 3/3] add conv append --- .../Conversations/IConversationStorage.cs | 1 + .../Repositories/IBotSharpRepository.cs | 1 + .../Services/ConversationStorage.cs | 74 ++++++++++++++++++- .../Repository/BotSharpDbContext.cs | 3 + .../FileRepository.Conversation.cs | 21 ++++++ .../MongoRepository.Conversation.cs | 18 +++++ 6 files changed, 114 insertions(+), 4 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStorage.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStorage.cs index a586e217..f5f5492c 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStorage.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStorage.cs @@ -3,5 +3,6 @@ namespace BotSharp.Abstraction.Conversations; public interface IConversationStorage { void Append(string conversationId, RoleDialogModel dialog); + void Append(string conversationId, IEnumerable dialogs); List GetDialogs(string conversationId); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 70fecc8a..d0174467 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -90,6 +90,7 @@ public interface IBotSharpRepository : IHaveServiceProvider void UpdateConversationTitle(string conversationId, string title); void UpdateConversationTitleAlias(string conversationId, string titleAlias); bool UpdateConversationTags(string conversationId, List tags); + bool AppendConversationTags(string conversationId, List tags); bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request); void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint); ConversationBreakpoint? GetConversationBreakpoint(string conversationId); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs index ea145ac0..f9ba5b12 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs @@ -1,22 +1,18 @@ using BotSharp.Abstraction.Messaging; using BotSharp.Abstraction.Messaging.Models.RichContent; using BotSharp.Abstraction.Options; -using System.IO; namespace BotSharp.Core.Conversations.Services; public class ConversationStorage : IConversationStorage { - private readonly BotSharpDatabaseSettings _dbSettings; private readonly BotSharpOptions _options; private readonly IServiceProvider _services; public ConversationStorage( - BotSharpDatabaseSettings dbSettings, BotSharpOptions options, IServiceProvider services) { - _dbSettings = dbSettings; _services = services; _options = options; } @@ -94,6 +90,76 @@ public class ConversationStorage : IConversationStorage db.AppendConversationDialogs(conversationId, dialogElements); } + public void Append(string conversationId, IEnumerable dialogs) + { + if (dialogs.IsNullOrEmpty()) return; + + var db = _services.GetRequiredService(); + var dialogElements = new List(); + + foreach ( var dialog in dialogs) + { + if (dialog.Role == AgentRole.Function) + { + var meta = new DialogMetaData + { + Role = dialog.Role, + AgentId = dialog.CurrentAgentId, + MessageId = dialog.MessageId, + MessageType = dialog.MessageType, + FunctionName = dialog.FunctionName, + CreateTime = dialog.CreatedAt + }; + + var content = dialog.Content.RemoveNewLine(); + if (string.IsNullOrEmpty(content)) + { + continue; + } + dialogElements.Add(new DialogElement + { + MetaData = meta, + Content = dialog.Content, + SecondaryContent = dialog.SecondaryContent, + Payload = dialog.Payload + }); + } + else + { + var meta = new DialogMetaData + { + Role = dialog.Role, + AgentId = dialog.CurrentAgentId, + MessageId = dialog.MessageId, + MessageType = dialog.MessageType, + SenderId = dialog.SenderId, + FunctionName = dialog.FunctionName, + CreateTime = dialog.CreatedAt + }; + + var content = dialog.Content.RemoveNewLine(); + if (string.IsNullOrEmpty(content)) + { + continue; + } + + var richContent = dialog.RichContent != null ? JsonSerializer.Serialize(dialog.RichContent, _options.JsonSerializerOptions) : null; + var secondaryRichContent = dialog.SecondaryRichContent != null ? JsonSerializer.Serialize(dialog.SecondaryRichContent, _options.JsonSerializerOptions) : null; + dialogElements.Add(new DialogElement + { + MetaData = meta, + Content = dialog.Content, + SecondaryContent = dialog.SecondaryContent, + RichContent = richContent, + SecondaryRichContent = secondaryRichContent, + Payload = dialog.Payload + }); + } + } + + db.AppendConversationDialogs(conversationId, dialogElements); + } + public List GetDialogs(string conversationId) { var db = _services.GetRequiredService(); diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index 719f3177..7d96357d 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -111,6 +111,9 @@ public class BotSharpDbContext : Database, IBotSharpRepository public bool UpdateConversationTags(string conversationId, List tags) => throw new NotImplementedException(); + public bool AppendConversationTags(string conversationId, List tags) + => throw new NotImplementedException(); + public bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request) => throw new NotImplementedException(); diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs index f249c9fa..c1cdd69f 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Conversation.cs @@ -169,6 +169,27 @@ namespace BotSharp.Core.Repository return true; } + public bool AppendConversationTags(string conversationId, List tags) + { + if (string.IsNullOrEmpty(conversationId) || tags.IsNullOrEmpty()) return false; + + var convDir = FindConversationDirectory(conversationId); + if (string.IsNullOrEmpty(convDir)) return false; + + var convFile = Path.Combine(convDir, CONVERSATION_FILE); + if (!File.Exists(convFile)) return false; + + var json = File.ReadAllText(convFile); + var conv = JsonSerializer.Deserialize(json, _options); + + var curTags = conv.Tags ?? new(); + var newTags = curTags.Concat(tags).Distinct(StringComparer.InvariantCultureIgnoreCase).ToList(); + conv.Tags = newTags; + conv.UpdatedTime = DateTime.UtcNow; + File.WriteAllText(convFile, JsonSerializer.Serialize(conv, _options)); + return true; + } + public bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request) { if (string.IsNullOrEmpty(conversationId)) return false; diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs index be2b5ac4..656ee890 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs @@ -139,6 +139,24 @@ public partial class MongoRepository return res.ModifiedCount > 0; } + public bool AppendConversationTags(string conversationId, List tags) + { + if (string.IsNullOrEmpty(conversationId) || tags.IsNullOrEmpty()) return false; + + var filter = Builders.Filter.Eq(x => x.Id, conversationId); + var conv = _dc.Conversations.Find(filter).FirstOrDefault(); + if (conv == null) return false; + + var curTags = conv.Tags ?? new(); + var newTags = curTags.Concat(tags).Distinct(StringComparer.InvariantCultureIgnoreCase).ToList(); + var update = Builders.Update + .Set(x => x.Tags, newTags) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + var res = _dc.Conversations.UpdateOne(filter, update); + return res.ModifiedCount > 0; + } + public bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request) { if (string.IsNullOrEmpty(conversationId)) return false;