diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj index 9ff34130..3aef859b 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -10,7 +10,8 @@ - + + diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs new file mode 100644 index 00000000..3f34e76b --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs @@ -0,0 +1,52 @@ +using BotSharp.Abstraction.VectorStorage; +using Microsoft.SemanticKernel.Memory; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace BotSharp.Plugin.SemanticKernel +{ + internal class SemanticKernelMemoryStoreProvider : IVectorDb + { + private readonly IMemoryStore _memoryStore; + + public SemanticKernelMemoryStoreProvider(IMemoryStore memoryStore) + { + this._memoryStore = memoryStore; + } + public async Task CreateCollection(string collectionName, int dim) + { + await _memoryStore.CreateCollectionAsync(collectionName); + } + + public async Task> GetCollections() + { + var result = new List(); + await foreach (var collection in _memoryStore.GetCollectionsAsync()) + { + result.Add(collection); + } + return result; + } + + public async Task> Search(string collectionName, float[] vector, int limit = 5) + { + var results = _memoryStore.GetNearestMatchesAsync(collectionName, vector, limit); + + var resultTexts = new List(); + await foreach (var (record, _) in results) + { + resultTexts.Add(record.Metadata.Text); + } + + return resultTexts; + + } + + public async Task Upsert(string collectionName, int id, float[] vector, string text) + { + await _memoryStore.UpsertAsync(collectionName, MemoryRecord.LocalRecord(id.ToString(), text, null, vector)); + } + } +} diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs index 1494bf56..dfe1758e 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Plugins; +using BotSharp.Abstraction.VectorStorage; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -12,8 +13,13 @@ namespace BotSharp.Plugin.SemanticKernel public void RegisterDI(IServiceCollection services, IConfiguration config) { + var settings = new SemanticKernelSettings(); + config.Bind("SemanticKernel", settings); + services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); } } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelSettings.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelSettings.cs new file mode 100644 index 00000000..470915a3 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelSettings.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BotSharp.Plugin.SemanticKernel +{ + internal class SemanticKernelSettings + { + + } +} diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextEmbeddingProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextEmbeddingProvider.cs new file mode 100644 index 00000000..6063cbca --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextEmbeddingProvider.cs @@ -0,0 +1,48 @@ +using BotSharp.Abstraction.MLTasks; +using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.AI.Embeddings; +using Microsoft.SemanticKernel.Memory; +using Microsoft.SemanticKernel.Plugins.Memory; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BotSharp.Plugin.SemanticKernel +{ + /// + /// Use Semantic Kernel Memory as text embedding provider + /// + public class SemanticKernelTextEmbeddingProvider : ITextEmbedding + { + private readonly ITextEmbeddingGeneration _embedding; + + /// + /// Constructor of + /// + /// + public SemanticKernelTextEmbeddingProvider(ITextEmbeddingGeneration embedding, int dimension) + { + this._embedding = embedding; + Dimension = dimension; + } + + public int Dimension { get; } + + public float[] GetVector(string text) + { + return this._embedding.GenerateEmbeddingAsync(text) + .ConfigureAwait(false) + .GetAwaiter() + .GetResult() + .ToArray(); + } + + public List GetVectors(List texts) + { + return this._embedding.GenerateEmbeddingsAsync(texts).ConfigureAwait(false).GetAwaiter().GetResult() + .Select(_ => _.ToArray()) + .ToList(); + } + } +}