From cd793e228d1b5d92b2003fca051ad7be1ec64c42 Mon Sep 17 00:00:00 2001 From: xbotter Date: Sun, 12 Nov 2023 17:12:34 +0800 Subject: [PATCH 1/4] create semantic kernel plugin --- BotSharp.sln | 11 ++ .../BotSharp.Plugin.SemanticKernel.csproj | 16 +++ .../SemanticKernelChatCompletionProvider.cs | 105 ++++++++++++++++++ .../SemanticKernelPlugin.cs | 19 ++++ .../SemanticKernelTextCompletionProvider.cs | 71 ++++++++++++ 5 files changed, 222 insertions(+) create mode 100644 src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj create mode 100644 src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs create mode 100644 src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs create mode 100644 src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs diff --git a/BotSharp.sln b/BotSharp.sln index d0a61d4d..768ae6ee 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -63,6 +63,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.MongoStorag EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.GoogleAI", "src\Plugins\BotSharp.Plugin.GoogleAI\BotSharp.Plugin.GoogleAI.csproj", "{8BC29F8A-78D6-422C-B522-10687ADC38ED}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.SemanticKernel", "src\Plugins\BotSharp.Plugin.SemanticKernel\BotSharp.Plugin.SemanticKernel.csproj", "{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -223,6 +225,14 @@ Global {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|Any CPU.Build.0 = Release|Any CPU {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.ActiveCfg = Release|Any CPU {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.Build.0 = Release|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|x64.ActiveCfg = Debug|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|x64.Build.0 = Debug|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|Any CPU.Build.0 = Release|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|x64.ActiveCfg = Release|Any CPU + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -254,6 +264,7 @@ Global {5CD330E1-9E5A-4112-8346-6E31CA98EF78} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C} {DB3DE37B-1208-4ED3-9615-A52AD0AAD69C} = {5CD330E1-9E5A-4112-8346-6E31CA98EF78} {8BC29F8A-78D6-422C-B522-10687ADC38ED} = {D5293208-2BEF-42FC-A64C-5954F61720BA} + {73EE2CD0-3B27-4F02-A67B-762CBDD740D0} = {D5293208-2BEF-42FC-A64C-5954F61720BA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj new file mode 100644 index 00000000..58a950cb --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.1 + enable + + + + + + + + + + + diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs new file mode 100644 index 00000000..19cce5ed --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs @@ -0,0 +1,105 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents; +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.MLTasks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime; +using System.Threading.Tasks; +using BotSharp.Abstraction.Conversations; +using Microsoft.SemanticKernel; +using Microsoft.Extensions.DependencyInjection; +using BotSharp.Abstraction.Models; + +namespace BotSharp.Plugin.SemanticKernel +{ + public class SemanticKernelChatCompletionProvider : IChatCompletion + { + private IKernel _kernel; + private IServiceProvider _services; + private ITokenStatistics _tokenStatistics; + private string? _model = null; + + public string Provider => throw new NotImplementedException(); + + public SemanticKernelChatCompletionProvider(IKernel kernel, + IServiceProvider services, + ITokenStatistics tokenStatistics) + { + this._kernel = kernel; + this._services = services; + this._tokenStatistics = tokenStatistics; + } + + + public RoleDialogModel GetChatCompletions(Agent agent, List conversations) + { + var hooks = _services.GetServices().ToList(); + + // Before chat completion hook + Task.WaitAll(hooks.Select(hook => + hook.BeforeGenerating(agent, conversations)).ToArray()); + + var completion = _kernel.GetService(_model); + + var agentService = _services.GetRequiredService(); + var instruction = agentService.RenderedInstruction(agent); + + var chatHistory = completion.CreateNewChat(instruction); + + foreach (var message in conversations) + { + if (message.Role == AgentRole.User) + { + chatHistory.AddUserMessage(message.Content); + } + else + { + chatHistory.AddAssistantMessage(message.Content); + } + } + + + var response = completion.GetChatCompletionsAsync(chatHistory) + .ContinueWith(async t => + { + var result = await t; + var message = await result.First().GetChatMessageAsync(); + return message.Content; + }).ConfigureAwait(false).GetAwaiter().GetResult() + .ConfigureAwait(false).GetAwaiter().GetResult(); + + + var msg = new RoleDialogModel(AgentRole.Assistant, response) + { + CurrentAgentId = agent.Id + }; + + // After chat completion hook + Task.WaitAll(hooks.Select(hook => + hook.AfterGenerated(msg, new TokenStatsModel + { + Model = _model ?? "default" + })).ToArray()); + + return msg; + } + + public Task GetChatCompletionsAsync(Agent agent, List conversations, Func onMessageReceived, Func onFunctionExecuting) + { + throw new NotImplementedException(); + } + + public Task GetChatCompletionsStreamingAsync(Agent agent, List conversations, Func onMessageReceived) + { + throw new NotImplementedException(); + } + + public void SetModelName(string model) + { + this._model = model; + } + } +} diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs new file mode 100644 index 00000000..93d59982 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs @@ -0,0 +1,19 @@ +using BotSharp.Abstraction.MLTasks; +using BotSharp.Abstraction.Plugins; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System.Text; + +namespace BotSharp.Plugin.SemanticKernel +{ + public class SemanticKernelPlugin : IBotSharpPlugin + { + public string Name => "Semantic Kernel"; + public string Description => "Semantic Kernel Service"; + public void RegisterDI(IServiceCollection services, IConfiguration config) + { + services.AddScoped(); + services.AddScoped(); + } + } +} diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs new file mode 100644 index 00000000..e4d5cfb3 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs @@ -0,0 +1,71 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.MLTasks; +using Microsoft.SemanticKernel; +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using System.Linq; +using System.Collections.Generic; +using Microsoft.SemanticKernel.AI.TextCompletion; + +namespace BotSharp.Plugin.SemanticKernel +{ + public class SemanticKernelTextCompletionProvider : Abstraction.MLTasks.ITextCompletion + { + private readonly IKernel _kernel; + private readonly IServiceProvider _services; + private readonly ITokenStatistics _tokenStatistics; + private string? _model = null; + + public string Provider => "semantic-kernel"; + + public SemanticKernelTextCompletionProvider(IKernel kernel, + IServiceProvider services, + ITokenStatistics tokenStatistics) + { + this._kernel = kernel; + this._services = services; + this._tokenStatistics = tokenStatistics; + } + + + public async Task GetCompletion(string text, string agentId, string messageId) + { + var hooks = _services.GetServices().ToList(); + + // Before chat completion hook + var agent = new Agent() + { + Id = agentId + }; + var userMessage = new RoleDialogModel(AgentRole.User, text) + { + MessageId = messageId + }; + Task.WaitAll(hooks.Select(hook => + hook.BeforeGenerating(agent, new List { userMessage })).ToArray()); + + var completion = _kernel.GetService(_model); + _tokenStatistics.StartTimer(); + var result = await completion.CompleteAsync(text); + _tokenStatistics.StopTimer(); + + // After chat completion hook + Task.WaitAll(hooks.Select(hook => + hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, result), new TokenStatsModel + { + Model = _model ?? "default" + })).ToArray()); + + return result; + } + + public void SetModelName(string model) + { + this._model = model; + } + } +} From 19df4da111c00caab4915cb9d7a172b05da64bd6 Mon Sep 17 00:00:00 2001 From: xbotter Date: Sun, 12 Nov 2023 22:04:00 +0800 Subject: [PATCH 2/4] format code and add unit tests --- BotSharp.sln | 13 +++- .../BotSharp.Plugin.SemanticKernel.csproj | 5 ++ .../SemanticKernelChatCompletionProvider.cs | 15 ++-- .../SemanticKernelPlugin.cs | 4 +- .../SemanticKernelTextCompletionProvider.cs | 18 ++--- ...arp.Plugin.SemanticKernel.UnitTests.csproj | 31 +++++++++ .../Helpers/MockChatResult.cs | 29 ++++++++ ...manticKernelChatCompletionProviderTests.cs | 68 +++++++++++++++++++ .../SemanticKernelPluginTests.cs | 24 +++++++ ...manticKernelTextCompletionProviderTests.cs | 57 ++++++++++++++++ .../Usings.cs | 1 + 11 files changed, 244 insertions(+), 21 deletions(-) create mode 100644 tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj create mode 100644 tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/MockChatResult.cs create mode 100644 tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs create mode 100644 tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs create mode 100644 tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs create mode 100644 tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs diff --git a/BotSharp.sln b/BotSharp.sln index 768ae6ee..0ca78843 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -63,7 +63,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.MongoStorag EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.GoogleAI", "src\Plugins\BotSharp.Plugin.GoogleAI\BotSharp.Plugin.GoogleAI.csproj", "{8BC29F8A-78D6-422C-B522-10687ADC38ED}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.SemanticKernel", "src\Plugins\BotSharp.Plugin.SemanticKernel\BotSharp.Plugin.SemanticKernel.csproj", "{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.SemanticKernel", "src\Plugins\BotSharp.Plugin.SemanticKernel\BotSharp.Plugin.SemanticKernel.csproj", "{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.SemanticKernel.UnitTests", "tests\BotSharp.Plugin.SemanticKernel.UnitTests\BotSharp.Plugin.SemanticKernel.UnitTests.csproj", "{BC57D428-A1A4-4D38-A2D0-AC6CA943F247}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -233,6 +235,14 @@ Global {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|Any CPU.Build.0 = Release|Any CPU {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|x64.ActiveCfg = Release|Any CPU {73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|x64.Build.0 = Release|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Debug|x64.ActiveCfg = Debug|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Debug|x64.Build.0 = Debug|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Release|Any CPU.Build.0 = Release|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Release|x64.ActiveCfg = Release|Any CPU + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -265,6 +275,7 @@ Global {DB3DE37B-1208-4ED3-9615-A52AD0AAD69C} = {5CD330E1-9E5A-4112-8346-6E31CA98EF78} {8BC29F8A-78D6-422C-B522-10687ADC38ED} = {D5293208-2BEF-42FC-A64C-5954F61720BA} {73EE2CD0-3B27-4F02-A67B-762CBDD740D0} = {D5293208-2BEF-42FC-A64C-5954F61720BA} + {BC57D428-A1A4-4D38-A2D0-AC6CA943F247} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj index 58a950cb..9cbe6db9 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj @@ -7,10 +7,15 @@ + + + + + diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs index 19cce5ed..c6f9e5e9 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs @@ -1,17 +1,15 @@ -using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents; +using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.MLTasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.SemanticKernel; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime; using System.Threading.Tasks; -using BotSharp.Abstraction.Conversations; -using Microsoft.SemanticKernel; -using Microsoft.Extensions.DependencyInjection; -using BotSharp.Abstraction.Models; namespace BotSharp.Plugin.SemanticKernel { @@ -33,7 +31,6 @@ namespace BotSharp.Plugin.SemanticKernel this._tokenStatistics = tokenStatistics; } - public RoleDialogModel GetChatCompletions(Agent agent, List conversations) { var hooks = _services.GetServices().ToList(); @@ -61,7 +58,6 @@ namespace BotSharp.Plugin.SemanticKernel } } - var response = completion.GetChatCompletionsAsync(chatHistory) .ContinueWith(async t => { @@ -71,7 +67,6 @@ namespace BotSharp.Plugin.SemanticKernel }).ConfigureAwait(false).GetAwaiter().GetResult() .ConfigureAwait(false).GetAwaiter().GetResult(); - var msg = new RoleDialogModel(AgentRole.Assistant, response) { CurrentAgentId = agent.Id @@ -102,4 +97,4 @@ namespace BotSharp.Plugin.SemanticKernel this._model = model; } } -} +} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs index 93d59982..1494bf56 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelPlugin.cs @@ -2,7 +2,6 @@ using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Plugins; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using System.Text; namespace BotSharp.Plugin.SemanticKernel { @@ -10,10 +9,11 @@ namespace BotSharp.Plugin.SemanticKernel { public string Name => "Semantic Kernel"; public string Description => "Semantic Kernel Service"; + public void RegisterDI(IServiceCollection services, IConfiguration config) { services.AddScoped(); services.AddScoped(); } } -} +} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs index e4d5cfb3..d0a23ed7 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs @@ -1,15 +1,16 @@ using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.MLTasks; -using Microsoft.SemanticKernel; -using System; -using System.Threading.Tasks; +using Microsoft; using Microsoft.Extensions.DependencyInjection; -using System.Linq; -using System.Collections.Generic; +using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.AI.TextCompletion; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace BotSharp.Plugin.SemanticKernel { @@ -26,12 +27,13 @@ namespace BotSharp.Plugin.SemanticKernel IServiceProvider services, ITokenStatistics tokenStatistics) { + Requires.NotNull(kernel, nameof(kernel)); + this._kernel = kernel; this._services = services; this._tokenStatistics = tokenStatistics; } - public async Task GetCompletion(string text, string agentId, string messageId) { var hooks = _services.GetServices().ToList(); @@ -68,4 +70,4 @@ namespace BotSharp.Plugin.SemanticKernel this._model = model; } } -} +} \ No newline at end of file diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj new file mode 100644 index 00000000..aa984d28 --- /dev/null +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj @@ -0,0 +1,31 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/MockChatResult.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/MockChatResult.cs new file mode 100644 index 00000000..c34d65ba --- /dev/null +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/MockChatResult.cs @@ -0,0 +1,29 @@ +using Microsoft.SemanticKernel.AI.ChatCompletion; +using Microsoft.SemanticKernel.Orchestration; + +namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers +{ + public class MockChatResult : IChatResult + { + public ModelResult ModelResult { get; set; } + private string _response; + + public MockChatResult(string response) + { + ModelResult = new ModelResult(response); + _response = response; + } + + public async Task GetChatMessageAsync(CancellationToken cancellationToken = default) + { + return await Task.FromResult(new MockModelResult(_response)); + } + + public class MockModelResult : ChatMessageBase + { + public MockModelResult(string content) : base(AuthorRole.Assistant, content, null) + { + } + } + } +} \ No newline at end of file diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs new file mode 100644 index 00000000..62f19ae2 --- /dev/null +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using BotSharp.Abstraction.Agents; +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.MLTasks; +using BotSharp.Plugin.SemanticKernel; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.SemanticKernel; +using Moq; +using Xunit; +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents.Models; +using System.Linq; +using System.Runtime; +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Models; +using Microsoft.SemanticKernel.AI.ChatCompletion; +using Microsoft.SemanticKernel.AI; +using Microsoft.SemanticKernel.Connectors.AI.OpenAI.AzureSdk; + +namespace BotSharp.Plugin.SemanticKernel.Tests +{ + public class SemanticKernelChatCompletionProviderTests + { + private readonly Mock _kernelMock; + private readonly Mock _servicesMock; + private readonly Mock _tokenStatisticsMock; + private readonly SemanticKernelChatCompletionProvider _provider; + + public SemanticKernelChatCompletionProviderTests() + { + _kernelMock = new Mock(); + _servicesMock = new Mock(); + _tokenStatisticsMock = new Mock(); + _provider = new SemanticKernelChatCompletionProvider(_kernelMock.Object, _servicesMock.Object, _tokenStatisticsMock.Object); + } + + [Fact] + public void GetChatCompletions_Returns_RoleDialogModel() + { + // Arrange + var agent = new Agent(); + var conversations = new List + { + new RoleDialogModel(AgentRole.User, "Hello") + }; + + var chatHistoryMock = new Mock(); + var chatCompletionMock = 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 MockChatResult("How can I help you?") + }); + + _kernelMock.Setup(x => x.GetService(null)).Returns(chatCompletionMock.Object); + + // Act + var result = _provider.GetChatCompletions(agent, conversations); + + // Assert + Assert.IsType(result); + } + } + +} diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs new file mode 100644 index 00000000..8110c4a1 --- /dev/null +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs @@ -0,0 +1,24 @@ +using BotSharp.Abstraction.MLTasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace BotSharp.Plugin.SemanticKernel.Tests +{ + public class SemanticKernelPluginTests + { + [Fact] + public void TestRegisterDI() + { + var services = new ServiceCollection(); + var config = new ConfigurationBuilder().Build(); + var plugin = new SemanticKernelPlugin(); + + plugin.RegisterDI(services, config); + + var provider = services.BuildServiceProvider(); + + Assert.NotNull(provider.GetService()); + Assert.NotNull(provider.GetService()); + } + } +} \ No newline at end of file diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs new file mode 100644 index 00000000..5bb0e57e --- /dev/null +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs @@ -0,0 +1,57 @@ +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.MLTasks; +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; + +namespace BotSharp.Plugin.SemanticKernel.Tests +{ + public class SemanticKernelTextCompletionProviderTests + { + private readonly Mock _kernel; + private readonly IServiceProvider _services; + private readonly ITokenStatistics _tokenStatistics; + + public SemanticKernelTextCompletionProviderTests() + { + _kernel = new Mock(); + _services = new ServiceCollection().BuildServiceProvider(); + _tokenStatistics = Mock.Of(); + } + + [Fact] + public async Task GetCompletion_ReturnsExpectedResult() + { + // Arrange + var provider = new SemanticKernelTextCompletionProvider(_kernel.Object, _services, _tokenStatistics); + var text = "Hello"; + var agentId = "agent1"; + var messageId = "message1"; + var expected = "Hello, world!"; + + var mockCompletion = new Mock(); + mockCompletion.Setup(c => c.CompleteAsync(text, It.IsAny(), It.IsAny())).ReturnsAsync(expected); + _kernel.Setup(c => c.GetService(It.IsAny())).Returns(mockCompletion.Object); + + // Act + var result = await provider.GetCompletion(text, agentId, messageId); + + // Assert + Assert.Equal(expected, result); + mockCompletion.Verify(c => c.CompleteAsync(text, null, default(CancellationToken)), Times.Once); + + } + } +} diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs new file mode 100644 index 00000000..8c927eb7 --- /dev/null +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file From 0dbecdf2097c8534e159d454ef0231b3e5993331 Mon Sep 17 00:00:00 2001 From: xbotter Date: Mon, 13 Nov 2023 23:11:49 +0800 Subject: [PATCH 3/4] update SK Provider and UnitTest --- .../BotSharp.Plugin.SemanticKernel.csproj | 8 +++- .../SemanticKernelChatCompletionProvider.cs | 6 ++- .../SemanticKernelTextCompletionProvider.cs | 11 ++++- ...arp.Plugin.SemanticKernel.UnitTests.csproj | 1 + .../{MockChatResult.cs => ResultHelper.cs} | 10 +++- .../Helpers/SemanticKernelHelper.cs | 47 +++++++++++++++++++ ...manticKernelChatCompletionProviderTests.cs | 12 ++++- .../SemanticKernelPluginTests.cs | 11 +++++ ...manticKernelTextCompletionProviderTests.cs | 20 ++++---- 9 files changed, 104 insertions(+), 22 deletions(-) rename tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/{MockChatResult.cs => ResultHelper.cs} (71%) create mode 100644 tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj index 9cbe6db9..9ff34130 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/BotSharp.Plugin.SemanticKernel.csproj @@ -3,10 +3,14 @@ netstandard2.1 enable + $(LangVersion) + $(BotSharpVersion) + $(GeneratePackageOnBuild) + True - + @@ -15,7 +19,7 @@ - + diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs index c6f9e5e9..1d65ee45 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs @@ -20,7 +20,7 @@ namespace BotSharp.Plugin.SemanticKernel private ITokenStatistics _tokenStatistics; private string? _model = null; - public string Provider => throw new NotImplementedException(); + public string Provider => "semantic-kernel"; public SemanticKernelChatCompletionProvider(IKernel kernel, IServiceProvider services, @@ -92,9 +92,11 @@ namespace BotSharp.Plugin.SemanticKernel throw new NotImplementedException(); } + public void SetModelName(string model) { - this._model = model; + if (!string.IsNullOrWhiteSpace(model)) + this._model = model; } } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs index d0a23ed7..07b6749a 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs @@ -14,6 +14,9 @@ using System.Threading.Tasks; namespace BotSharp.Plugin.SemanticKernel { + /// + /// User Semantic Kernel as text completion provider + /// public class SemanticKernelTextCompletionProvider : Abstraction.MLTasks.ITextCompletion { private readonly IKernel _kernel; @@ -21,19 +24,21 @@ namespace BotSharp.Plugin.SemanticKernel private readonly ITokenStatistics _tokenStatistics; private string? _model = null; + // public string Provider => "semantic-kernel"; public SemanticKernelTextCompletionProvider(IKernel kernel, IServiceProvider services, ITokenStatistics tokenStatistics) { - Requires.NotNull(kernel, nameof(kernel)); + Requires.NotNull(kernel, nameof(IKernel)); this._kernel = kernel; this._services = services; this._tokenStatistics = tokenStatistics; } + /// public async Task GetCompletion(string text, string agentId, string messageId) { var hooks = _services.GetServices().ToList(); @@ -65,9 +70,11 @@ namespace BotSharp.Plugin.SemanticKernel return result; } + /// public void SetModelName(string model) { - this._model = model; + if (!string.IsNullOrWhiteSpace(model)) + this._model = model; } } } \ No newline at end of file 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 aa984d28..057c117c 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/BotSharp.Plugin.SemanticKernel.UnitTests.csproj @@ -12,6 +12,7 @@ + diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/MockChatResult.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/ResultHelper.cs similarity index 71% rename from tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/MockChatResult.cs rename to tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/ResultHelper.cs index c34d65ba..84d9bbcc 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/MockChatResult.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/ResultHelper.cs @@ -1,14 +1,15 @@ using Microsoft.SemanticKernel.AI.ChatCompletion; +using Microsoft.SemanticKernel.AI.TextCompletion; using Microsoft.SemanticKernel.Orchestration; namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers { - public class MockChatResult : IChatResult + public class ResultHelper : IChatResult, ITextResult { public ModelResult ModelResult { get; set; } private string _response; - public MockChatResult(string response) + public ResultHelper(string response) { ModelResult = new ModelResult(response); _response = response; @@ -19,6 +20,11 @@ namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers return await Task.FromResult(new MockModelResult(_response)); } + public Task GetCompletionAsync(CancellationToken cancellationToken = default) + { + return Task.FromResult(_response); + } + public class MockModelResult : ChatMessageBase { public MockModelResult(string content) : base(AuthorRole.Assistant, content, null) diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs new file mode 100644 index 00000000..ef775f76 --- /dev/null +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Helpers/SemanticKernelHelper.cs @@ -0,0 +1,47 @@ +using Microsoft.SemanticKernel.AI; +using Microsoft.SemanticKernel.AI.ChatCompletion; +using Microsoft.SemanticKernel.AI.TextCompletion; +using Microsoft.SemanticKernel.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BotSharp.Plugin.SemanticKernel.UnitTests.Helpers +{ + internal class SemanticKernelHelper : IChatCompletion, ITextCompletion, IAIService + { + private readonly string _excepted; + + public SemanticKernelHelper(string excepted) + { + this._excepted = excepted; + } + + public ChatHistory CreateNewChat(string? instructions = null) + { + return new ChatHistory(); + } + + public Task> GetChatCompletionsAsync(ChatHistory chat, AIRequestSettings? requestSettings = null, CancellationToken cancellationToken = default) + { + return Task.FromResult>( new List { new ResultHelper(_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) + { + throw new NotImplementedException(); + } + + public IAsyncEnumerable GetStreamingCompletionsAsync(string text, AIRequestSettings? requestSettings = 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 62f19ae2..5be823fa 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs @@ -18,6 +18,7 @@ using BotSharp.Abstraction.Models; using Microsoft.SemanticKernel.AI.ChatCompletion; using Microsoft.SemanticKernel.AI; using Microsoft.SemanticKernel.Connectors.AI.OpenAI.AzureSdk; +using BotSharp.Plugin.SemanticKernel.UnitTests.Helpers; namespace BotSharp.Plugin.SemanticKernel.Tests { @@ -46,13 +47,20 @@ namespace BotSharp.Plugin.SemanticKernel.Tests new RoleDialogModel(AgentRole.User, "Hello") }; + _servicesMock.Setup(x => x.GetService(typeof(IEnumerable))) + .Returns(new List()); + var agentService = new Mock(); + agentService.Setup(x => x.RenderedInstruction(agent)).Returns(""); + _servicesMock.Setup(x => x.GetService(typeof(IAgentService))) + .Returns(agentService.Object); + var chatHistoryMock = new Mock(); var chatCompletionMock = 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 MockChatResult("How can I help you?") + new ResultHelper("How can I help you?") }); _kernelMock.Setup(x => x.GetService(null)).Returns(chatCompletionMock.Object); @@ -64,5 +72,5 @@ namespace BotSharp.Plugin.SemanticKernel.Tests Assert.IsType(result); } } - + } diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs index 8110c4a1..a1ba7214 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelPluginTests.cs @@ -1,6 +1,9 @@ +using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.MLTasks; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.SemanticKernel; +using Moq; namespace BotSharp.Plugin.SemanticKernel.Tests { @@ -12,6 +15,14 @@ namespace BotSharp.Plugin.SemanticKernel.Tests var services = new ServiceCollection(); var config = new ConfigurationBuilder().Build(); var plugin = new SemanticKernelPlugin(); + services.AddScoped(x => + { + return new KernelBuilder() + .WithAzureOpenAIChatCompletionService("test", "test", "test") + .Build(); + }); + services.AddScoped(x=> Mock.Of()); + plugin.RegisterDI(services, config); diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs index 5bb0e57e..1e463cdf 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelTextCompletionProviderTests.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.MLTasks; using BotSharp.Plugin.SemanticKernel; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; @@ -15,18 +14,18 @@ using System; using System.Linq; using Microsoft; using Microsoft.SemanticKernel.AI; +using BotSharp.Plugin.SemanticKernel.UnitTests.Helpers; namespace BotSharp.Plugin.SemanticKernel.Tests { public class SemanticKernelTextCompletionProviderTests { - private readonly Mock _kernel; private readonly IServiceProvider _services; private readonly ITokenStatistics _tokenStatistics; public SemanticKernelTextCompletionProviderTests() { - _kernel = new Mock(); + _services = new ServiceCollection().BuildServiceProvider(); _tokenStatistics = Mock.Of(); } @@ -35,22 +34,19 @@ namespace BotSharp.Plugin.SemanticKernel.Tests public async Task GetCompletion_ReturnsExpectedResult() { // Arrange - var provider = new SemanticKernelTextCompletionProvider(_kernel.Object, _services, _tokenStatistics); + var text = "Hello"; - var agentId = "agent1"; - var messageId = "message1"; var expected = "Hello, world!"; - - var mockCompletion = new Mock(); - mockCompletion.Setup(c => c.CompleteAsync(text, It.IsAny(), It.IsAny())).ReturnsAsync(expected); - _kernel.Setup(c => c.GetService(It.IsAny())).Returns(mockCompletion.Object); + var _kernel = new KernelBuilder() + .WithAIService("", new SemanticKernelHelper(expected)) + .Build(); + var provider = new SemanticKernelTextCompletionProvider(_kernel, _services, _tokenStatistics); // Act - var result = await provider.GetCompletion(text, agentId, messageId); + var result = await provider.GetCompletion(text, "agent1", "message1"); // Assert Assert.Equal(expected, result); - mockCompletion.Verify(c => c.CompleteAsync(text, null, default(CancellationToken)), Times.Once); } } From dce814697d96177e76a58048c9d04a7fd78bbc08 Mon Sep 17 00:00:00 2001 From: xbotter Date: Mon, 13 Nov 2023 23:12:24 +0800 Subject: [PATCH 4/4] add xml doc --- .../SemanticKernelChatCompletionProvider.cs | 18 ++++++++++++++---- .../SemanticKernelTextCompletionProvider.cs | 8 +++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs index 1d65ee45..1b5298fc 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs @@ -13,6 +13,9 @@ using System.Threading.Tasks; namespace BotSharp.Plugin.SemanticKernel { + /// + /// Use Semantic Kernel as chat completion provider + /// public class SemanticKernelChatCompletionProvider : IChatCompletion { private IKernel _kernel; @@ -20,8 +23,15 @@ namespace BotSharp.Plugin.SemanticKernel private ITokenStatistics _tokenStatistics; private string? _model = null; + /// public string Provider => "semantic-kernel"; + /// + /// Create a new instance of + /// + /// + /// + /// public SemanticKernelChatCompletionProvider(IKernel kernel, IServiceProvider services, ITokenStatistics tokenStatistics) @@ -30,7 +40,7 @@ namespace BotSharp.Plugin.SemanticKernel this._services = services; this._tokenStatistics = tokenStatistics; } - + /// public RoleDialogModel GetChatCompletions(Agent agent, List conversations) { var hooks = _services.GetServices().ToList(); @@ -81,18 +91,18 @@ namespace BotSharp.Plugin.SemanticKernel return msg; } - + /// public Task GetChatCompletionsAsync(Agent agent, List conversations, Func onMessageReceived, Func onFunctionExecuting) { throw new NotImplementedException(); } - + /// public Task GetChatCompletionsStreamingAsync(Agent agent, List conversations, Func onMessageReceived) { throw new NotImplementedException(); } - + /// public void SetModelName(string model) { if (!string.IsNullOrWhiteSpace(model)) diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs index 07b6749a..d222e850 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs @@ -24,9 +24,15 @@ namespace BotSharp.Plugin.SemanticKernel private readonly ITokenStatistics _tokenStatistics; private string? _model = null; - // + /// public string Provider => "semantic-kernel"; + /// + /// Create a new instance of + /// + /// + /// + /// public SemanticKernelTextCompletionProvider(IKernel kernel, IServiceProvider services, ITokenStatistics tokenStatistics)