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.Loggers;
using BotSharp.Abstraction.MLTasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BotSharp.Plugin.SemanticKernel
{
///
/// Use Semantic Kernel as chat completion provider
///
public class SemanticKernelChatCompletionProvider : IChatCompletion
{
private Microsoft.SemanticKernel.AI.ChatCompletion.IChatCompletion _kernelChatCompletion;
private IServiceProvider _services;
private ITokenStatistics _tokenStatistics;
private string? _model = null;
///
public string Provider => "semantic-kernel";
///
/// Create a new instance of
///
///
///
///
public SemanticKernelChatCompletionProvider(Microsoft.SemanticKernel.AI.ChatCompletion.IChatCompletion chatCompletion,
IServiceProvider services,
ITokenStatistics tokenStatistics)
{
this._kernelChatCompletion = chatCompletion;
this._services = services;
this._tokenStatistics = tokenStatistics;
}
///
public async Task 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 = this._kernelChatCompletion;
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 = 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 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)
{
if (!string.IsNullOrWhiteSpace(model))
this._model = model;
}
}
}