diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentKnowledgeBase.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentKnowledgeBase.cs index 3f116871..29b7c2c2 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentKnowledgeBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentKnowledgeBase.cs @@ -6,16 +6,22 @@ public class AgentKnowledgeBase public string Type { get; set; } public bool Disabled { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public decimal? Confidence { get; set; } + public AgentKnowledgeBase() { } - public AgentKnowledgeBase(string name, string type, bool enabled) + public AgentKnowledgeBase( + string name, string type, + bool enabled, decimal? confidence = null) { Name = name; Type = type; Disabled = enabled; + Confidence = confidence; } public override string ToString() diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Hooks/KnowledgeHook.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Hooks/KnowledgeHook.cs new file mode 100644 index 00000000..da4add53 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Hooks/KnowledgeHook.cs @@ -0,0 +1,105 @@ +namespace BotSharp.Plugin.KnowledgeBase.Hooks; + +public class KnowledgeHook : IKnowledgeHook +{ + private readonly IKnowledgeService _knowledgeService; + private readonly ITextEmbedding _textEmbedding; + private readonly IServiceProvider _services; + + public KnowledgeHook( + IKnowledgeService knowledgeService, + ITextEmbedding textEmbedding, + IServiceProvider services) + { + _knowledgeService = knowledgeService; + _textEmbedding = textEmbedding; + _services = services; + } + + private async Task> GetKnowledgeBaseNameByAgentIdAsync(string agentId) + { + var agentService = _services.GetRequiredService(); + var agent = await agentService.GetAgent(agentId); + return agent.KnowledgeBases; + } + + public async Task> GetDomainKnowledges(RoleDialogModel message, string text) + { + // Get agent Id by knowledge base name + var knowledgeBases = await GetKnowledgeBaseNameByAgentIdAsync(message.CurrentAgentId); + var results = new List(); + + foreach (var knowledgeBase in knowledgeBases) + { + if (knowledgeBase.Type == "relationships") + { + var options = new GraphSearchOptions + { + Method = "local" + }; + var result = await _knowledgeService.SearchGraphKnowledge(text, options); + results.Add(result.Result); + } + else + { + var options = new VectorSearchOptions + { + Fields = null, + Limit = 5, + Confidence = 0.5f, + WithVector = true + }; + var result = await _knowledgeService.SearchVectorKnowledge(text, knowledgeBase.Name, options); + results.AddRange(result.Where(x => x.Data != null && (x.Data.ContainsKey("text") || x.Data.ContainsKey("answer"))) + .Select(x => x.Data.ContainsKey("answer") ? x.Data["text"].ToString() + "\r\n\r\n" + x.Data["answer"].ToString() : x.Data["text"].ToString()) + .Where(x => x != null)!); + + } + } + + return results; + } + + public async Task> GetGlobalKnowledges(RoleDialogModel message) + { + var text = message.Content; + var results = new List(); + + // Get all knowledge bases + var knowledgeBases = await _knowledgeService.GetVectorCollections(); + + foreach (var knowledgeBase in knowledgeBases) + { + if (knowledgeBase.Type == "relationships") + { + var options = new GraphSearchOptions + { + Method = "local" + }; + var result = await _knowledgeService.SearchGraphKnowledge(text, options); + results.Add(result.Result); + } + else + { + var options = new VectorSearchOptions + { + Fields = null, + Limit = 5, + Confidence = 0.5f, + WithVector = true + }; + var result = await _knowledgeService.SearchVectorKnowledge(text, knowledgeBase.Name, options); + results.AddRange(result.Where(x => x.Data != null && (x.Data.ContainsKey("text") || x.Data.ContainsKey("answer"))) + .Select(x => x.Data.ContainsKey("answer") ? x.Data["text"].ToString() + "\r\n\r\n" + x.Data["answer"].ToString() : x.Data["text"].ToString()) + .Where(x => x != null)!); + } + } + + return results; + } + + public async Task> CollectChunkedKnowledge() + { + return new List(); + } +} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs index 8d89daf6..31fa964c 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs @@ -26,6 +26,8 @@ public class KnowledgeBasePlugin : IBotSharpPlugin services.AddSingleton(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); + } public bool AttachMenu(List menu) diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationDialogDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationDialogDocument.cs index a3f6ee69..4f896678 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationDialogDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationDialogDocument.cs @@ -4,6 +4,7 @@ public class ConversationDialogDocument : MongoBase { public string ConversationId { get; set; } = default!; public string AgentId { get; set; } = default!; + public string UserId { get; set; } = default!; public DateTime UpdatedTime { get; set; } public List Dialogs { get; set; } = []; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationStateDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationStateDocument.cs index 3df58594..be42823b 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationStateDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ConversationStateDocument.cs @@ -4,6 +4,7 @@ public class ConversationStateDocument : MongoBase { public string ConversationId { get; set; } = default!; public string AgentId { get; set; } = default!; + public string UserId { get; set; } = default!; public DateTime UpdatedTime { get; set; } public List States { get; set; } = []; public List Breakpoints { get; set; } = []; diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentKnowledgeBaseMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentKnowledgeBaseMongoElement.cs index 2aca84a2..29dd5e58 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentKnowledgeBaseMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentKnowledgeBaseMongoElement.cs @@ -8,6 +8,7 @@ public class AgentKnowledgeBaseMongoElement public string Name { get; set; } = default!; public string Type { get; set; } = default!; public bool Disabled { get; set; } + public decimal? Confidence { get; set; } public static AgentKnowledgeBaseMongoElement ToMongoElement(AgentKnowledgeBase knowledgeBase) { @@ -15,7 +16,8 @@ public class AgentKnowledgeBaseMongoElement { Name = knowledgeBase.Name, Type = knowledgeBase.Type, - Disabled = knowledgeBase.Disabled + Disabled = knowledgeBase.Disabled, + Confidence = knowledgeBase.Confidence }; } @@ -25,7 +27,8 @@ public class AgentKnowledgeBaseMongoElement { Name = knowledgeBase.Name, Type = knowledgeBase.Type, - Disabled = knowledgeBase.Disabled + Disabled = knowledgeBase.Disabled, + Confidence = knowledgeBase.Confidence }; } } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs index 8b6dded6..06512fb7 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs @@ -10,11 +10,12 @@ public partial class MongoRepository if (conversation == null) return; var utcNow = DateTime.UtcNow; + var userId = !string.IsNullOrEmpty(conversation.UserId) ? conversation.UserId : string.Empty; var convDoc = new ConversationDocument { Id = !string.IsNullOrEmpty(conversation.Id) ? conversation.Id : Guid.NewGuid().ToString(), AgentId = conversation.AgentId, - UserId = !string.IsNullOrEmpty(conversation.UserId) ? conversation.UserId : string.Empty, + UserId = userId, Title = conversation.Title, Channel = conversation.Channel, ChannelId = conversation.ChannelId, @@ -30,6 +31,7 @@ public partial class MongoRepository Id = Guid.NewGuid().ToString(), ConversationId = convDoc.Id, AgentId = conversation.AgentId, + UserId = userId, Dialogs = [], UpdatedTime = utcNow }; @@ -39,6 +41,7 @@ public partial class MongoRepository Id = Guid.NewGuid().ToString(), ConversationId = convDoc.Id, AgentId = conversation.AgentId, + UserId = userId, States = [], Breakpoints = [], UpdatedTime = utcNow