diff --git a/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs b/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs index 5f8a59b99..f6811dc6a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginMenuDef.cs @@ -25,9 +25,9 @@ public class PluginMenuDef [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? SubMenu { get; set; } - public PluginMenuDef(string lable, string? link = null, string? icon = null, int weight = 0) + public PluginMenuDef(string label, string? link = null, string? icon = null, int weight = 0) { - Label = lable; + Label = label; Link = link; Icon = icon; Weight = weight; diff --git a/src/Infrastructure/BotSharp.Abstraction/VectorStorage/IVectorDb.cs b/src/Infrastructure/BotSharp.Abstraction/VectorStorage/IVectorDb.cs index 8aeb5ee92..5dac3766a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/VectorStorage/IVectorDb.cs +++ b/src/Infrastructure/BotSharp.Abstraction/VectorStorage/IVectorDb.cs @@ -9,7 +9,7 @@ public interface IVectorDb Task> GetCollections(); Task> GetCollectionData(string collectionName, VectorFilter filter); Task CreateCollection(string collectionName, int dim); - Task Upsert(string collectionName, string id, float[] vector, string text, Dictionary? payload = null); + Task Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary? payload = null); Task> Search(string collectionName, float[] vector, IEnumerable? fields, int limit = 5, float confidence = 0.5f, bool withVector = false); - Task DeleteCollectionData(string collectionName, string id); + Task DeleteCollectionData(string collectionName, Guid id); } diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/MemorizeKnowledgeFn.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/MemorizeKnowledgeFn.cs index 237f73854..728a1be93 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/MemorizeKnowledgeFn.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/MemorizeKnowledgeFn.cs @@ -29,9 +29,8 @@ public async Task Execute(RoleDialogModel message) var collectionName = !string.IsNullOrWhiteSpace(_settings.DefaultCollection) ? _settings.DefaultCollection : KnowledgeCollectionName.BotSharp; await vectorDb.CreateCollection(collectionName, vector[0].Length); - var id = Guid.NewGuid().ToString(); - var result = await vectorDb.Upsert(collectionName, id, vector[0], - args.Question, + var result = await vectorDb.Upsert(collectionName, Guid.NewGuid(), vector[0], + args.Question, new Dictionary { { KnowledgePayloadName.Answer, args.Answer } diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs index 51c390bf5..2321cc731 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs @@ -20,8 +20,6 @@ public void RegisterDI(IServiceCollection services, IConfiguration config) return settingService.Bind("KnowledgeBase"); }); - var a = config["KnowledgeBase"]; - services.AddScoped(); services.AddScoped(); services.AddSingleton(); @@ -32,7 +30,14 @@ public void RegisterDI(IServiceCollection services, IConfiguration config) public bool AttachMenu(List menu) { var section = menu.First(x => x.Label == "Apps"); - menu.Add(new PluginMenuDef("Knowledge Base", link: "/page/knowledge-base", icon: "bx bx-book-open", weight: section.Weight + 1)); + menu.Add(new PluginMenuDef("Knowledge Base", icon: "bx bx-book-open", weight: section.Weight + 1) + { + SubMenu = new List + { + new PluginMenuDef("Vector", link: "page/knowledge-base/vector"), + new PluginMenuDef("Graph", link: "page/knowledge-base/graph") + } + }); return true; } } diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemoryVectorDb.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemoryVectorDb.cs index 27863dd32..05677c2fb 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemoryVectorDb.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemoryVectorDb.cs @@ -53,11 +53,11 @@ public async Task> Search(string collectionNam return await Task.FromResult(results); } - public async Task Upsert(string collectionName, string id, float[] vector, string text, Dictionary? payload = null) + public async Task Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary? payload = null) { _vectors[collectionName].Add(new VecRecord { - Id = id, + Id = id.ToString(), Vector = vector, Text = text }); @@ -65,7 +65,7 @@ public async Task Upsert(string collectionName, string id, float[] vector, return true; } - public async Task DeleteCollectionData(string collectionName, string id) + public async Task DeleteCollectionData(string collectionName, Guid id) { return await Task.FromResult(false); } diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Create.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Create.cs index 69a56519d..391fb5fac 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Create.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Create.cs @@ -19,8 +19,7 @@ public async Task FeedVectorKnowledge(string collectionName, KnowledgeCreationMo foreach (var line in lines) { var vec = await textEmbedding.GetVectorAsync(line); - var id = Guid.NewGuid().ToString(); - await db.Upsert(collectionName, id, vec, line); + await db.Upsert(collectionName, Guid.NewGuid(), vec, line); index++; Console.WriteLine($"Saved vector {index}/{lines.Count}: {line}\n"); } diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Delete.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Delete.cs index e7ed1b1ba..3cc72ae2f 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Delete.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Delete.cs @@ -6,8 +6,13 @@ public async Task DeleteVectorCollectionData(string collectionName, string { try { + if (!Guid.TryParse(id, out var guid)) + { + return false; + } + var db = GetVectorDb(); - return await db.DeleteCollectionData(collectionName, id); + return await db.DeleteCollectionData(collectionName, guid); } catch (Exception ex) { diff --git a/src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs b/src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs index f5b35eafc..034f53292 100644 --- a/src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs +++ b/src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs @@ -32,12 +32,12 @@ public Task> Search(string collectionName, flo throw new NotImplementedException(); } - public Task Upsert(string collectionName, string id, float[] vector, string text, Dictionary? payload = null) + public Task Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary? payload = null) { throw new NotImplementedException(); } - public Task DeleteCollectionData(string collectionName, string id) + public Task DeleteCollectionData(string collectionName, Guid id) { throw new NotImplementedException(); } diff --git a/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs b/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs index 3dd064b90..f9071ba22 100644 --- a/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs +++ b/src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs @@ -92,14 +92,14 @@ public async Task CreateCollection(string collectionName, int dim) } } - public async Task Upsert(string collectionName, string id, float[] vector, string text, Dictionary? payload = null) + public async Task Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary? payload = null) { // Insert vectors var point = new PointStruct() { Id = new PointId() { - Uuid = id + Uuid = id.ToString() }, Vectors = vector, Payload = @@ -137,7 +137,11 @@ public async Task> Search(string collectionNam return results; } - var points = await client.SearchAsync(collectionName, vector, limit: (ulong)limit, scoreThreshold: confidence); + var points = await client.SearchAsync(collectionName, + vector, + limit: (ulong)limit, + scoreThreshold: confidence, + vectorsSelector: new WithVectorsSelector { Enable = withVector }); var pickFields = fields != null; foreach (var point in points) @@ -174,15 +178,10 @@ public async Task> Search(string collectionNam return results; } - public async Task DeleteCollectionData(string collectionName, string id) + public async Task DeleteCollectionData(string collectionName, Guid id) { - if (!Guid.TryParse(id, out var guid)) - { - return false; - } - var client = GetClient(); - var result = await client.DeleteAsync(collectionName, guid); + var result = await client.DeleteAsync(collectionName, id); return result.Status == UpdateStatus.Completed; } diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs index e5c32bd28..2cab28354 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs @@ -2,6 +2,7 @@ using BotSharp.Abstraction.VectorStorage; using BotSharp.Abstraction.VectorStorage.Models; using Microsoft.SemanticKernel.Memory; +using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -62,7 +63,7 @@ public async Task> Search(string collectionNam return resultTexts; } - public async Task Upsert(string collectionName, string id, float[] vector, string text, Dictionary? payload) + public async Task Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary? payload) { #pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. await _memoryStore.UpsertAsync(collectionName, MemoryRecord.LocalRecord(id.ToString(), text, null, vector)); @@ -70,13 +71,13 @@ public async Task Upsert(string collectionName, string id, float[] vector, return true; } - public async Task DeleteCollectionData(string collectionName, string id) + public async Task DeleteCollectionData(string collectionName, Guid id) { var exist = await _memoryStore.DoesCollectionExistAsync(collectionName); if (exist) { - await _memoryStore.RemoveAsync(collectionName, id); + await _memoryStore.RemoveAsync(collectionName, id.ToString()); return true; } return false;