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);
}
}