Skip to content

Commit cd793e2

Browse files
committed
create semantic kernel plugin
1 parent 1d70359 commit cd793e2

File tree

5 files changed

+222
-0
lines changed

5 files changed

+222
-0
lines changed

BotSharp.sln

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.MongoStorag
6363
EndProject
6464
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.GoogleAI", "src\Plugins\BotSharp.Plugin.GoogleAI\BotSharp.Plugin.GoogleAI.csproj", "{8BC29F8A-78D6-422C-B522-10687ADC38ED}"
6565
EndProject
66+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.SemanticKernel", "src\Plugins\BotSharp.Plugin.SemanticKernel\BotSharp.Plugin.SemanticKernel.csproj", "{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}"
67+
EndProject
6668
Global
6769
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6870
Debug|Any CPU = Debug|Any CPU
@@ -223,6 +225,14 @@ Global
223225
{8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|Any CPU.Build.0 = Release|Any CPU
224226
{8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.ActiveCfg = Release|Any CPU
225227
{8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.Build.0 = Release|Any CPU
228+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
229+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
230+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|x64.ActiveCfg = Debug|Any CPU
231+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Debug|x64.Build.0 = Debug|Any CPU
232+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
233+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|Any CPU.Build.0 = Release|Any CPU
234+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|x64.ActiveCfg = Release|Any CPU
235+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0}.Release|x64.Build.0 = Release|Any CPU
226236
EndGlobalSection
227237
GlobalSection(SolutionProperties) = preSolution
228238
HideSolutionNode = FALSE
@@ -254,6 +264,7 @@ Global
254264
{5CD330E1-9E5A-4112-8346-6E31CA98EF78} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C}
255265
{DB3DE37B-1208-4ED3-9615-A52AD0AAD69C} = {5CD330E1-9E5A-4112-8346-6E31CA98EF78}
256266
{8BC29F8A-78D6-422C-B522-10687ADC38ED} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
267+
{73EE2CD0-3B27-4F02-A67B-762CBDD740D0} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
257268
EndGlobalSection
258269
GlobalSection(ExtensibilityGlobals) = postSolution
259270
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.1</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.SemanticKernel" Version="1.0.0-beta6" />
10+
</ItemGroup>
11+
12+
<ItemGroup>
13+
<ProjectReference Include="..\..\Infrastructure\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
14+
</ItemGroup>
15+
16+
</Project>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using BotSharp.Abstraction.Agents.Enums;
2+
using BotSharp.Abstraction.Agents;
3+
using BotSharp.Abstraction.Agents.Models;
4+
using BotSharp.Abstraction.Conversations.Models;
5+
using BotSharp.Abstraction.MLTasks;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Runtime;
10+
using System.Threading.Tasks;
11+
using BotSharp.Abstraction.Conversations;
12+
using Microsoft.SemanticKernel;
13+
using Microsoft.Extensions.DependencyInjection;
14+
using BotSharp.Abstraction.Models;
15+
16+
namespace BotSharp.Plugin.SemanticKernel
17+
{
18+
public class SemanticKernelChatCompletionProvider : IChatCompletion
19+
{
20+
private IKernel _kernel;
21+
private IServiceProvider _services;
22+
private ITokenStatistics _tokenStatistics;
23+
private string? _model = null;
24+
25+
public string Provider => throw new NotImplementedException();
26+
27+
public SemanticKernelChatCompletionProvider(IKernel kernel,
28+
IServiceProvider services,
29+
ITokenStatistics tokenStatistics)
30+
{
31+
this._kernel = kernel;
32+
this._services = services;
33+
this._tokenStatistics = tokenStatistics;
34+
}
35+
36+
37+
public RoleDialogModel GetChatCompletions(Agent agent, List<RoleDialogModel> conversations)
38+
{
39+
var hooks = _services.GetServices<IContentGeneratingHook>().ToList();
40+
41+
// Before chat completion hook
42+
Task.WaitAll(hooks.Select(hook =>
43+
hook.BeforeGenerating(agent, conversations)).ToArray());
44+
45+
var completion = _kernel.GetService<Microsoft.SemanticKernel.AI.ChatCompletion.IChatCompletion>(_model);
46+
47+
var agentService = _services.GetRequiredService<IAgentService>();
48+
var instruction = agentService.RenderedInstruction(agent);
49+
50+
var chatHistory = completion.CreateNewChat(instruction);
51+
52+
foreach (var message in conversations)
53+
{
54+
if (message.Role == AgentRole.User)
55+
{
56+
chatHistory.AddUserMessage(message.Content);
57+
}
58+
else
59+
{
60+
chatHistory.AddAssistantMessage(message.Content);
61+
}
62+
}
63+
64+
65+
var response = completion.GetChatCompletionsAsync(chatHistory)
66+
.ContinueWith(async t =>
67+
{
68+
var result = await t;
69+
var message = await result.First().GetChatMessageAsync();
70+
return message.Content;
71+
}).ConfigureAwait(false).GetAwaiter().GetResult()
72+
.ConfigureAwait(false).GetAwaiter().GetResult();
73+
74+
75+
var msg = new RoleDialogModel(AgentRole.Assistant, response)
76+
{
77+
CurrentAgentId = agent.Id
78+
};
79+
80+
// After chat completion hook
81+
Task.WaitAll(hooks.Select(hook =>
82+
hook.AfterGenerated(msg, new TokenStatsModel
83+
{
84+
Model = _model ?? "default"
85+
})).ToArray());
86+
87+
return msg;
88+
}
89+
90+
public Task<bool> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived, Func<RoleDialogModel, Task> onFunctionExecuting)
91+
{
92+
throw new NotImplementedException();
93+
}
94+
95+
public Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived)
96+
{
97+
throw new NotImplementedException();
98+
}
99+
100+
public void SetModelName(string model)
101+
{
102+
this._model = model;
103+
}
104+
}
105+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using BotSharp.Abstraction.MLTasks;
2+
using BotSharp.Abstraction.Plugins;
3+
using Microsoft.Extensions.Configuration;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using System.Text;
6+
7+
namespace BotSharp.Plugin.SemanticKernel
8+
{
9+
public class SemanticKernelPlugin : IBotSharpPlugin
10+
{
11+
public string Name => "Semantic Kernel";
12+
public string Description => "Semantic Kernel Service";
13+
public void RegisterDI(IServiceCollection services, IConfiguration config)
14+
{
15+
services.AddScoped<ITextCompletion, SemanticKernelTextCompletionProvider>();
16+
services.AddScoped<IChatCompletion, SemanticKernelChatCompletionProvider>();
17+
}
18+
}
19+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using BotSharp.Abstraction.Agents.Enums;
2+
using BotSharp.Abstraction.Agents.Models;
3+
using BotSharp.Abstraction.Conversations.Models;
4+
using BotSharp.Abstraction.Conversations;
5+
using BotSharp.Abstraction.MLTasks;
6+
using Microsoft.SemanticKernel;
7+
using System;
8+
using System.Threading.Tasks;
9+
using Microsoft.Extensions.DependencyInjection;
10+
using System.Linq;
11+
using System.Collections.Generic;
12+
using Microsoft.SemanticKernel.AI.TextCompletion;
13+
14+
namespace BotSharp.Plugin.SemanticKernel
15+
{
16+
public class SemanticKernelTextCompletionProvider : Abstraction.MLTasks.ITextCompletion
17+
{
18+
private readonly IKernel _kernel;
19+
private readonly IServiceProvider _services;
20+
private readonly ITokenStatistics _tokenStatistics;
21+
private string? _model = null;
22+
23+
public string Provider => "semantic-kernel";
24+
25+
public SemanticKernelTextCompletionProvider(IKernel kernel,
26+
IServiceProvider services,
27+
ITokenStatistics tokenStatistics)
28+
{
29+
this._kernel = kernel;
30+
this._services = services;
31+
this._tokenStatistics = tokenStatistics;
32+
}
33+
34+
35+
public async Task<string> GetCompletion(string text, string agentId, string messageId)
36+
{
37+
var hooks = _services.GetServices<IContentGeneratingHook>().ToList();
38+
39+
// Before chat completion hook
40+
var agent = new Agent()
41+
{
42+
Id = agentId
43+
};
44+
var userMessage = new RoleDialogModel(AgentRole.User, text)
45+
{
46+
MessageId = messageId
47+
};
48+
Task.WaitAll(hooks.Select(hook =>
49+
hook.BeforeGenerating(agent, new List<RoleDialogModel> { userMessage })).ToArray());
50+
51+
var completion = _kernel.GetService<Microsoft.SemanticKernel.AI.TextCompletion.ITextCompletion>(_model);
52+
_tokenStatistics.StartTimer();
53+
var result = await completion.CompleteAsync(text);
54+
_tokenStatistics.StopTimer();
55+
56+
// After chat completion hook
57+
Task.WaitAll(hooks.Select(hook =>
58+
hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, result), new TokenStatsModel
59+
{
60+
Model = _model ?? "default"
61+
})).ToArray());
62+
63+
return result;
64+
}
65+
66+
public void SetModelName(string model)
67+
{
68+
this._model = model;
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)