From 3f2d63c10175216e582daf12beaf7dff3482f2b6 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Tue, 30 Jan 2024 19:04:22 +0800 Subject: [PATCH] feat: upgrade semantic kernel to 1.2 --- .../BotSharp.Plugin.SemanticKernel.csproj | 10 +++- .../SemanticKernelChatCompletionProvider.cs | 19 +++--- .../SemanticKernelMemoryStoreProvider.cs | 6 ++ .../SemanticKernelTextCompletionProvider.cs | 11 ++-- .../SemanticKernelTextEmbeddingProvider.cs | 12 +++- ...arp.Plugin.SemanticKernel.UnitTests.csproj | 4 +- .../Helpers/ResultHelper.cs | 59 +++++++++---------- .../Helpers/SemanticKernelHelper.cs | 34 +++++------ ...manticKernelChatCompletionProviderTests.cs | 29 +++++---- .../SemanticKernelPluginTests.cs | 10 +++- ...manticKernelTextCompletionProviderTests.cs | 17 +----- 11 files changed, 104 insertions(+), 107 deletions(-) diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj index fe605288..bc0c0c2d 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 @@ -11,8 +11,8 @@ - - + + @@ -24,4 +24,8 @@ + + + + diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs index bf7fbc42..22c7fc68 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs @@ -6,7 +6,7 @@ using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Loggers; using BotSharp.Abstraction.MLTasks; using Microsoft.Extensions.DependencyInjection; -using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; using System; using System.Collections.Generic; using System.Linq; @@ -19,7 +19,7 @@ namespace BotSharp.Plugin.SemanticKernel /// public class SemanticKernelChatCompletionProvider : IChatCompletion { - private Microsoft.SemanticKernel.AI.ChatCompletion.IChatCompletion _kernelChatCompletion; + private Microsoft.SemanticKernel.ChatCompletion.IChatCompletionService _kernelChatCompletion; private IServiceProvider _services; private ITokenStatistics _tokenStatistics; private string? _model = null; @@ -33,7 +33,7 @@ namespace BotSharp.Plugin.SemanticKernel /// /// /// - public SemanticKernelChatCompletionProvider(Microsoft.SemanticKernel.AI.ChatCompletion.IChatCompletion chatCompletion, + public SemanticKernelChatCompletionProvider(IChatCompletionService chatCompletion, IServiceProvider services, ITokenStatistics tokenStatistics) { @@ -55,7 +55,7 @@ namespace BotSharp.Plugin.SemanticKernel var agentService = _services.GetRequiredService(); var instruction = agentService.RenderedInstruction(agent); - var chatHistory = completion.CreateNewChat(instruction); + ChatHistory chatHistory = new ChatHistory(instruction); foreach (var message in conversations) { @@ -69,14 +69,9 @@ namespace BotSharp.Plugin.SemanticKernel } } - var response = await completion.GetChatCompletionsAsync(chatHistory) - .ContinueWith(async t => - { - var result = await t; - var message = await result.First().GetChatMessageAsync(); - return message.Content; - }).ConfigureAwait(false).GetAwaiter().GetResult(); - + var ChatMessage = await completion.GetChatMessageContentsAsync(chatHistory); + var chatMessageContent = ChatMessage?.FirstOrDefault(); + var response = chatMessageContent != null ? chatMessageContent.Content :string.Empty; var msg = new RoleDialogModel(AgentRole.Assistant, response) { CurrentAgentId = agent.Id diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs index 3f34e76b..444cab1e 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelMemoryStoreProvider.cs @@ -9,9 +9,13 @@ namespace BotSharp.Plugin.SemanticKernel { internal class SemanticKernelMemoryStoreProvider : IVectorDb { +#pragma warning disable SKEXP0003 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. private readonly IMemoryStore _memoryStore; +#pragma warning restore SKEXP0003 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +#pragma warning disable SKEXP0003 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. public SemanticKernelMemoryStoreProvider(IMemoryStore memoryStore) +#pragma warning restore SKEXP0003 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. { this._memoryStore = memoryStore; } @@ -46,7 +50,9 @@ namespace BotSharp.Plugin.SemanticKernel public async Task Upsert(string collectionName, int id, float[] vector, string text) { +#pragma warning disable SKEXP0003 // 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)); +#pragma warning restore SKEXP0003 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. } } } diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs index 15791931..91dec640 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs @@ -3,10 +3,7 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Loggers; -using Microsoft; using Microsoft.Extensions.DependencyInjection; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.AI.TextCompletion; using System; using System.Collections.Generic; using System.Linq; @@ -19,7 +16,7 @@ namespace BotSharp.Plugin.SemanticKernel /// public class SemanticKernelTextCompletionProvider : Abstraction.MLTasks.ITextCompletion { - private readonly Microsoft.SemanticKernel.AI.TextCompletion.ITextCompletion _kernelTextCompletion; + private readonly Microsoft.SemanticKernel.TextGeneration.ITextGenerationService _kernelTextCompletion; private readonly IServiceProvider _services; private readonly ITokenStatistics _tokenStatistics; private string? _model = null; @@ -33,7 +30,7 @@ namespace BotSharp.Plugin.SemanticKernel /// /// /// - public SemanticKernelTextCompletionProvider(Microsoft.SemanticKernel.AI.TextCompletion.ITextCompletion textCompletion, + public SemanticKernelTextCompletionProvider(Microsoft.SemanticKernel.TextGeneration.ITextGenerationService textCompletion, IServiceProvider services, ITokenStatistics tokenStatistics) { @@ -61,9 +58,11 @@ namespace BotSharp.Plugin.SemanticKernel var completion = this._kernelTextCompletion; _tokenStatistics.StartTimer(); - var result = await completion.CompleteAsync(text); + var textContent = await completion.GetTextContentsAsync(text); + var result = textContent.FirstOrDefault().Text; _tokenStatistics.StopTimer(); + // After chat completion hook Task.WaitAll(hooks.Select(hook => hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, result), new TokenStatsModel diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextEmbeddingProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextEmbeddingProvider.cs index ef6efd49..66884ee8 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextEmbeddingProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextEmbeddingProvider.cs @@ -1,6 +1,6 @@ using BotSharp.Abstraction.MLTasks; using Microsoft.Extensions.Configuration; -using Microsoft.SemanticKernel.AI.Embeddings; +using Microsoft.SemanticKernel.Embeddings; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -12,13 +12,17 @@ namespace BotSharp.Plugin.SemanticKernel /// public class SemanticKernelTextEmbeddingProvider : ITextEmbedding { - private readonly ITextEmbeddingGeneration _embedding; +#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. + private readonly ITextEmbeddingGenerationService _embedding; +#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. private readonly IConfiguration _configuration; /// /// Constructor of /// - public SemanticKernelTextEmbeddingProvider(ITextEmbeddingGeneration embedding, IConfiguration configuration) +#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. + public SemanticKernelTextEmbeddingProvider(ITextEmbeddingGenerationService embedding, IConfiguration configuration) +#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. { this._embedding = embedding; this._configuration = configuration; @@ -33,7 +37,9 @@ namespace BotSharp.Plugin.SemanticKernel /// public async Task GetVectorAsync(string text) { +#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. return (await this._embedding.GenerateEmbeddingAsync(text)).ToArray(); +#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. } /// diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj index 81e6d3b6..0b6a9880 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj @@ -12,9 +12,9 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/ResultHelper.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/ResultHelper.cs index 4a818310..8acc4202 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/ResultHelper.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/ResultHelper.cs @@ -1,35 +1,34 @@ -using Microsoft.SemanticKernel.AI.ChatCompletion; -using Microsoft.SemanticKernel.AI.TextCompletion; -using Microsoft.SemanticKernel.Orchestration; +using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; -namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers -{ - public class ResultHelper : IChatResult, ITextResult - { - public ModelResult ModelResult { get; set; } - private string _response; +//namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers +//{ +// public class ResultHelper : KernelContent +// { +// public TextContent ModelResult { get; set; } +// private string _response; - public ResultHelper(string response) - { - ModelResult = new ModelResult(response); - _response = response; - } +// public ResultHelper(string response) +// { +// ModelResult = new TextContent(response); +// _response = response; +// } - public async Task GetChatMessageAsync(CancellationToken cancellationToken = default) - { - return await Task.FromResult(new MockModelResult(_response)); - } +// public async Task GetChatMessageAsync(CancellationToken cancellationToken = default) +// { +// return await Task.FromResult(new MockModelResult(_response)); +// } - public Task GetCompletionAsync(CancellationToken cancellationToken = default) - { - return Task.FromResult(_response); - } +// public Task GetCompletionAsync(CancellationToken cancellationToken = default) +// { +// return Task.FromResult(_response); +// } - public class MockModelResult : ChatMessage - { - public MockModelResult(string content) : base(AuthorRole.Assistant, content, null) - { - } - } - } -} \ No newline at end of file +// public class MockModelResult : ChatMessageContent +// { +// public MockModelResult(string content) : base(AuthorRole.Assistant, content, null) +// { +// } +// } +// } +//} \ No newline at end of file diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs index 1245a4d2..4920460b 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs @@ -1,16 +1,11 @@ -using Microsoft.SemanticKernel.AI; -using Microsoft.SemanticKernel.AI.ChatCompletion; -using Microsoft.SemanticKernel.AI.TextCompletion; +using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Services; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.SemanticKernel.TextGeneration; namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers { - internal class SemanticKernelHelper : IChatCompletion, ITextCompletion, IAIService + internal class SemanticKernelHelper : IChatCompletionService, ITextGenerationService, IAIService { private Dictionary _attributes = new(); private readonly string _excepted; @@ -22,27 +17,30 @@ namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers public IReadOnlyDictionary Attributes => _attributes; + IReadOnlyDictionary IAIService.Attributes => throw new NotImplementedException(); + public ChatHistory CreateNewChat(string? instructions = null) { return new ChatHistory(); } - public Task> GetChatCompletionsAsync(ChatHistory chat, AIRequestSettings? requestSettings = null, CancellationToken cancellationToken = default) + public Task> GetChatMessageContentsAsync(ChatHistory chatHistory, PromptExecutionSettings? executionSettings = null, Kernel? kernel = null, CancellationToken cancellationToken = default) { - return Task.FromResult>(new List { new ResultHelper(_excepted) }); + return Task.FromResult>(new List { new ChatMessageContent(AuthorRole.Assistant, _excepted) }); + } - public Task> GetCompletionsAsync(string text, AIRequestSettings? requestSettings = null, CancellationToken cancellationToken = default) - { - return Task.FromResult>(new List { new ResultHelper(_excepted) }); - } - - public IAsyncEnumerable GetStreamingChatCompletionsAsync(ChatHistory chat, AIRequestSettings? requestSettings = null, CancellationToken cancellationToken = default) + public IAsyncEnumerable GetStreamingChatMessageContentsAsync(ChatHistory chatHistory, PromptExecutionSettings? executionSettings = null, Kernel? kernel = null, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } - public IAsyncEnumerable GetStreamingCompletionsAsync(string text, AIRequestSettings? requestSettings = null, CancellationToken cancellationToken = default) + public Task> GetTextContentsAsync(string prompt, PromptExecutionSettings? executionSettings = null, Kernel? kernel = null, CancellationToken cancellationToken = default) + { + return Task.FromResult>(new List { new TextContent(_excepted) }); + } + + public IAsyncEnumerable GetStreamingTextContentsAsync(string prompt, PromptExecutionSettings? executionSettings = null, Kernel? kernel = null, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs index 8c564a1a..caf4746e 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs @@ -1,26 +1,25 @@ using BotSharp.Abstraction.Agents; -using BotSharp.Abstraction.Conversations.Models; -using Moq; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; -using Microsoft.SemanticKernel.AI.ChatCompletion; -using Microsoft.SemanticKernel.AI; -using BotSharp.Plugin.SemanticKernel.UnitTests.Helpers; +using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Loggers; +using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; +using Moq; namespace BotSharp.Plugin.SemanticKernel.Tests { public class SemanticKernelChatCompletionProviderTests { - private readonly Mock _chatCompletionMock; + private readonly Mock _chatCompletionMock; private readonly Mock _servicesMock; private readonly Mock _tokenStatisticsMock; private readonly SemanticKernelChatCompletionProvider _provider; public SemanticKernelChatCompletionProviderTests() { - _chatCompletionMock = new Mock(); + _chatCompletionMock = new Mock(); _servicesMock = new Mock(); _tokenStatisticsMock = new Mock(); _provider = new SemanticKernelChatCompletionProvider(_chatCompletionMock.Object, _servicesMock.Object, _tokenStatisticsMock.Object); @@ -39,18 +38,18 @@ namespace BotSharp.Plugin.SemanticKernel.Tests _servicesMock.Setup(x => x.GetService(typeof(IEnumerable))) .Returns(new List()); var agentService = new Mock(); - agentService.Setup(x => x.RenderedInstruction(agent)).Returns(""); + agentService.Setup(x => x.RenderedInstruction(agent)).Returns("How can I help you?"); _servicesMock.Setup(x => x.GetService(typeof(IAgentService))) .Returns(agentService.Object); var chatHistoryMock = new Mock(); - _chatCompletionMock.Setup(x => x.CreateNewChat(It.IsAny())).Returns(chatHistoryMock.Object); - _chatCompletionMock.Setup(x => x.GetChatCompletionsAsync(chatHistoryMock.Object, It.IsAny(), It.IsAny())) - .ReturnsAsync(new List - { - new ResultHelper("How can I help you?") - }); - + //_chatCompletionMock.Setup(x => new ChatHistory(It.IsAny())).Returns(chatHistoryMock.Object); + + _chatCompletionMock.Setup(x => x.GetChatMessageContentsAsync(chatHistoryMock.Object, It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new List + { + new ChatMessageContent(AuthorRole.Assistant,"How can I help you?") + }); // Act var result = await _provider.GetChatCompletions(agent, conversations); diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs index a1ac3963..99d41024 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs @@ -20,10 +20,14 @@ namespace BotSharp.Plugin.SemanticKernel.Tests services.AddSingleton(config); var plugin = new SemanticKernelPlugin(); - services.AddScoped(x => Mock.Of()); - services.AddScoped(x => Mock.Of()); + services.AddScoped(x => Mock.Of()); + services.AddScoped(x => Mock.Of()); +#pragma warning disable SKEXP0003 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. services.AddScoped(x => Mock.Of()); - services.AddScoped(x => Mock.Of()); +#pragma warning restore SKEXP0003 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +#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. + services.AddScoped(x => Mock.Of()); +#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. services.AddScoped(x => Mock.Of()); diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs index 89188973..3eb8f8b5 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs @@ -1,20 +1,7 @@ -using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Plugin.SemanticKernel; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.AI.TextCompletion; -using Moq; -using System.Collections.Generic; -using System.Threading.Tasks; -using Xunit; -using BotSharp.Abstraction.Agents.Enums; -using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; -using System; -using System.Linq; -using Microsoft; -using Microsoft.SemanticKernel.AI; using BotSharp.Plugin.SemanticKernel.UnitTests.Helpers; +using Microsoft.Extensions.DependencyInjection; +using Moq; namespace BotSharp.Plugin.SemanticKernel.Tests {