BotSharp/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs

106 lines
3.9 KiB
C#
Raw Normal View History

2023-11-12 09:12:34 +00:00
using BotSharp.Abstraction.Agents;
2023-11-12 14:04:00 +00:00
using BotSharp.Abstraction.Agents.Enums;
2023-11-12 09:12:34 +00:00
using BotSharp.Abstraction.Agents.Models;
2023-11-12 14:04:00 +00:00
using BotSharp.Abstraction.Conversations;
2023-11-12 09:12:34 +00:00
using BotSharp.Abstraction.Conversations.Models;
2023-11-29 23:23:14 +00:00
using BotSharp.Abstraction.Loggers;
2023-11-12 09:12:34 +00:00
using BotSharp.Abstraction.MLTasks;
2023-11-12 14:04:00 +00:00
using Microsoft.Extensions.DependencyInjection;
2024-01-30 11:04:22 +00:00
using Microsoft.SemanticKernel.ChatCompletion;
2023-11-12 09:12:34 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BotSharp.Plugin.SemanticKernel
{
2023-11-13 15:12:24 +00:00
/// <summary>
/// Use Semantic Kernel as chat completion provider
/// </summary>
2023-11-12 09:12:34 +00:00
public class SemanticKernelChatCompletionProvider : IChatCompletion
{
2024-01-30 11:04:22 +00:00
private Microsoft.SemanticKernel.ChatCompletion.IChatCompletionService _kernelChatCompletion;
2023-11-12 09:12:34 +00:00
private IServiceProvider _services;
private ITokenStatistics _tokenStatistics;
private string _model;
2023-11-12 09:12:34 +00:00
2023-11-13 15:12:24 +00:00
/// <inheritdoc/>
2023-11-13 15:11:49 +00:00
public string Provider => "semantic-kernel";
2023-11-12 09:12:34 +00:00
2023-11-13 15:12:24 +00:00
/// <summary>
/// Create a new instance of <see cref="SemanticKernelChatCompletionProvider"/>
/// </summary>
2023-11-19 13:34:13 +00:00
/// <param name="chatCompletion"></param>
2023-11-13 15:12:24 +00:00
/// <param name="services"></param>
/// <param name="tokenStatistics"></param>
2024-01-30 11:04:22 +00:00
public SemanticKernelChatCompletionProvider(IChatCompletionService chatCompletion,
2023-11-12 09:12:34 +00:00
IServiceProvider services,
ITokenStatistics tokenStatistics)
{
2023-11-19 13:34:13 +00:00
this._kernelChatCompletion = chatCompletion;
2023-11-12 09:12:34 +00:00
this._services = services;
this._tokenStatistics = tokenStatistics;
}
2023-11-13 15:12:24 +00:00
/// <inheritdoc/>
2024-01-14 04:48:26 +00:00
public async Task<RoleDialogModel> GetChatCompletions(Agent agent, List<RoleDialogModel> conversations)
2023-11-12 09:12:34 +00:00
{
var hooks = _services.GetServices<IContentGeneratingHook>().ToList();
// Before chat completion hook
Task.WaitAll(hooks.Select(hook =>
hook.BeforeGenerating(agent, conversations)).ToArray());
2023-11-19 13:34:13 +00:00
var completion = this._kernelChatCompletion;
2023-11-12 09:12:34 +00:00
var agentService = _services.GetRequiredService<IAgentService>();
var instruction = agentService.RenderedInstruction(agent);
2024-01-30 11:04:22 +00:00
ChatHistory chatHistory = new ChatHistory(instruction);
2023-11-12 09:12:34 +00:00
foreach (var message in conversations)
{
if (message.Role == AgentRole.User)
{
chatHistory.AddUserMessage(message.Content);
}
else
{
chatHistory.AddAssistantMessage(message.Content);
}
}
2024-01-30 11:04:22 +00:00
var ChatMessage = await completion.GetChatMessageContentsAsync(chatHistory);
var chatMessageContent = ChatMessage?.FirstOrDefault();
var response = chatMessageContent != null ? chatMessageContent.Content :string.Empty;
2023-11-12 09:12:34 +00:00
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;
}
2023-11-13 15:12:24 +00:00
/// <inheritdoc/>
2023-11-12 09:12:34 +00:00
public Task<bool> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived, Func<RoleDialogModel, Task> onFunctionExecuting)
{
throw new NotImplementedException();
}
2023-11-13 15:12:24 +00:00
/// <inheritdoc/>
2023-11-12 09:12:34 +00:00
public Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived)
{
throw new NotImplementedException();
}
2023-11-13 15:12:24 +00:00
/// <inheritdoc/>
2023-11-12 09:12:34 +00:00
public void SetModelName(string model)
{
_model = model;
2023-11-12 09:12:34 +00:00
}
}
2023-11-12 14:04:00 +00:00
}