BotSharp/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs

158 lines
5 KiB
C#
Raw Normal View History

2023-06-17 02:42:35 +00:00
using Azure;
using Azure.AI.OpenAI;
2023-06-27 18:31:13 +00:00
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations.Models;
2023-06-19 18:32:49 +00:00
using BotSharp.Abstraction.MLTasks;
using BotSharp.Plugin.AzureOpenAI.Settings;
2023-06-17 02:42:35 +00:00
using System;
using System.Collections.Generic;
2023-07-26 21:05:30 +00:00
using System.Text.Json;
2023-06-17 02:42:35 +00:00
using System.Threading.Tasks;
2023-06-17 13:32:39 +00:00
namespace BotSharp.Plugin.AzureOpenAI.Providers;
2023-06-19 18:32:49 +00:00
public class ChatCompletionProvider : IChatCompletion
2023-06-17 02:42:35 +00:00
{
private readonly AzureOpenAiSettings _settings;
public ChatCompletionProvider(AzureOpenAiSettings settings)
{
_settings = settings;
}
2023-07-21 20:15:09 +00:00
public string GetChatCompletions(Agent agent, List<RoleDialogModel> conversations)
2023-06-17 02:42:35 +00:00
{
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
2023-07-21 20:15:09 +00:00
var chatCompletionsOptions = PrepareOptions(agent, conversations);
2023-06-17 02:42:35 +00:00
2023-07-21 20:15:09 +00:00
var response = client.GetChatCompletions(_settings.DeploymentModel.ChatCompletionModel, chatCompletionsOptions);
2023-06-17 02:42:35 +00:00
2023-07-21 20:15:09 +00:00
string output = "";
foreach (var choice in response.Value.Choices)
2023-06-17 02:42:35 +00:00
{
2023-07-21 20:15:09 +00:00
var message = choice.Message;
if (message.Content == null)
continue;
Console.Write(message.Content);
output += message.Content;
2023-06-17 02:42:35 +00:00
}
2023-07-21 20:15:09 +00:00
return output.Trim();
}
2023-06-17 02:42:35 +00:00
2023-06-27 18:31:13 +00:00
public List<RoleDialogModel> GetChatSamples(string sampleText)
2023-06-17 02:42:35 +00:00
{
var samples = new List<RoleDialogModel>();
if (string.IsNullOrEmpty(sampleText))
2023-06-17 02:42:35 +00:00
{
return samples;
}
var lines = sampleText.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
var line = lines[i];
if (string.IsNullOrEmpty(line.Trim()))
2023-06-17 02:42:35 +00:00
{
continue;
2023-06-17 02:42:35 +00:00
}
var role = line.Substring(0, line.IndexOf(' ') - 1).Trim();
var content = line.Substring(line.IndexOf(' ') + 1).Trim();
// comments
if (role == "##")
{
continue;
}
samples.Add(new RoleDialogModel(role, content));
2023-06-17 02:42:35 +00:00
}
2023-06-17 02:42:35 +00:00
return samples;
}
2023-07-26 21:05:30 +00:00
public List<FunctionDef> GetFunctions(string functionsJson)
{
var functions = new List<FunctionDef>();
if (!string.IsNullOrEmpty(functionsJson))
{
functions = JsonSerializer.Deserialize<List<FunctionDef>>(functionsJson, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
AllowTrailingCommas = true
});
}
return functions;
}
2023-06-17 02:42:35 +00:00
public async Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived)
2023-06-17 02:42:35 +00:00
{
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
2023-06-27 18:31:13 +00:00
var chatCompletionsOptions = PrepareOptions(agent, conversations);
2023-06-17 02:42:35 +00:00
2023-06-19 18:32:49 +00:00
var response = await client.GetChatCompletionsStreamingAsync(_settings.DeploymentModel.ChatCompletionModel, chatCompletionsOptions);
2023-06-17 02:42:35 +00:00
using StreamingChatCompletions streaming = response.Value;
string output = "";
await foreach (var choice in streaming.GetChoicesStreaming())
{
if (choice.FinishReason == CompletionsFinishReason.FunctionCall)
{
}
2023-06-17 02:42:35 +00:00
await foreach (var message in choice.GetMessageStreaming())
{
if (message.Content == null)
continue;
Console.Write(message.Content);
output += message.Content;
await onMessageReceived(new RoleDialogModel(message.Role.ToString(), message.Content));
2023-06-17 02:42:35 +00:00
}
output = "";
2023-06-17 02:42:35 +00:00
}
return true;
2023-06-17 02:42:35 +00:00
}
2023-06-27 18:31:13 +00:00
private ChatCompletionsOptions PrepareOptions(Agent agent, List<RoleDialogModel> conversations)
2023-06-17 02:42:35 +00:00
{
2023-06-29 23:14:57 +00:00
var chatCompletionsOptions = new ChatCompletionsOptions();
if (!string.IsNullOrEmpty(agent.Instruction))
2023-06-17 02:42:35 +00:00
{
2023-06-29 23:14:57 +00:00
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.System, agent.Instruction));
}
2023-06-17 02:42:35 +00:00
2023-06-29 23:14:57 +00:00
if (!string.IsNullOrEmpty(agent.Knowledges))
{
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.System, agent.Knowledges));
}
var samples = GetChatSamples(agent.Samples);
foreach (var message in samples)
2023-06-17 02:42:35 +00:00
{
2023-07-21 20:15:09 +00:00
chatCompletionsOptions.Messages.Add(new ChatMessage(message.Role, message.Content));
2023-06-17 02:42:35 +00:00
}
2023-07-26 21:05:30 +00:00
var functions = GetFunctions(agent.Functions);
foreach (var function in functions)
{
chatCompletionsOptions.Functions.Add(new FunctionDefinition
{
Name = function.Name,
Description = function.Description,
Parameters = BinaryData.FromObjectAsJson(function.Parameters)
});
}
2023-06-17 02:42:35 +00:00
foreach (var message in conversations)
{
2023-07-21 20:15:09 +00:00
chatCompletionsOptions.Messages.Add(new ChatMessage(message.Role, message.Content));
2023-06-17 02:42:35 +00:00
}
return chatCompletionsOptions;
}
}