117 lines
3.9 KiB
C#
117 lines
3.9 KiB
C#
using System.ClientModel;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json.Serialization;
|
|
using OpenAI;
|
|
using OpenAI.Chat;
|
|
|
|
namespace TelegramBot;
|
|
|
|
public class OpenAiAgent
|
|
{
|
|
private ApiKeyCredential apikey;
|
|
private OpenAIClient oaiClient;
|
|
private ChatClient chatClient;
|
|
private HttpClient httpClient;
|
|
private Dictionary<(long, Actor), List<(ChatMessage, int)>> oaiChats = new();
|
|
|
|
public OpenAiAgent(string baseUrl, string apiKey, string model) {
|
|
OpenAIClientOptions options = new OpenAIClientOptions() {
|
|
Endpoint = new(baseUrl),
|
|
NetworkTimeout = new(0, 0, 15)
|
|
};
|
|
|
|
apikey = new(apiKey);
|
|
oaiClient = new(apikey, options);
|
|
chatClient = oaiClient.GetChatClient(model);
|
|
|
|
httpClient = new() {
|
|
BaseAddress = new(baseUrl),
|
|
Timeout = new(0, 0, 15)
|
|
};
|
|
|
|
Console.WriteLine(
|
|
$"""
|
|
Base URL: {baseUrl}
|
|
Model: {model}
|
|
API Key: {apiKey}
|
|
""");
|
|
}
|
|
|
|
public int GetTokenLenght(string message) {
|
|
TokenizeRequest request = new(message);
|
|
var req = httpClient.PostAsync("tokenize", JsonContent.Create(request));
|
|
req.Wait();
|
|
var response = req.Result.Content.ReadFromJsonAsync<TokenizeResponseBase>();
|
|
response.Wait();
|
|
return response.Result.Tokens.Length;
|
|
}
|
|
|
|
public void ChatHistoryAppend(Actor actor, long chatId, string message) {
|
|
//get the chat from the dictionary
|
|
var chat = GetChatHistory((chatId, actor));
|
|
//get the token lenght of the message
|
|
var tokenLenght = GetTokenLenght(message);
|
|
//create a new chat message
|
|
switch (actor) {
|
|
case Actor.User:
|
|
chat.Add((new UserChatMessage(message), tokenLenght));
|
|
break;
|
|
case Actor.Krolik:
|
|
chat.Add((new AssistantChatMessage(message), tokenLenght));
|
|
break;
|
|
case Actor.Nemesis:
|
|
chat.Add((new AssistantChatMessage(message), tokenLenght));
|
|
break;
|
|
case Actor.System:
|
|
chat.Add((new SystemChatMessage(message), tokenLenght));
|
|
break;
|
|
}
|
|
}
|
|
|
|
public List<(ChatMessage, int)> GetChatHistory((long, Actor) key) => GetChatHistory(key.Item1, key.Item2);
|
|
|
|
public List<(ChatMessage, int)> GetChatHistory(long chatId, Actor actor) {
|
|
oaiChats.TryGetValue((chatId, actor), out var chat);
|
|
if(chat == null) {
|
|
AddChatToDictionary(chatId, actor);
|
|
chat = oaiChats[(chatId, actor)];
|
|
}
|
|
return chat!;
|
|
}
|
|
|
|
public string GetChatResponse(long chatId, Actor actor) {
|
|
return String.Empty;
|
|
}
|
|
|
|
public void AddChatToDictionary(long id) {
|
|
AddChatToDictionary(id, Actor.Krolik);
|
|
AddChatToDictionary(id, Actor.Nemesis);
|
|
}
|
|
|
|
public void AddChatToDictionary(long id, Actor actor) {
|
|
//Check if the chat already exists
|
|
if (oaiChats.ContainsKey((id, actor))) return;
|
|
//Create a new chat object
|
|
var chat = new List<(ChatMessage, int)>();
|
|
//chat.Add(new SystemChatMessage(nemesisPrompt));
|
|
//add the entry to the dictionary
|
|
oaiChats.Add((id, actor), chat);
|
|
}
|
|
|
|
public void ResetChat(long chatId) {
|
|
//Remove the chat from the dictionary
|
|
oaiChats.Where(x => x.Key.Item1 == chatId).ToList().ForEach(x => oaiChats.Remove(x.Key));
|
|
//Add the chat back to the dictionary
|
|
AddChatToDictionary(chatId);
|
|
}
|
|
}
|
|
|
|
public struct TokenizeRequest(string content) {
|
|
[JsonPropertyName("content")] public string Content { get; set; } = content;
|
|
[JsonPropertyName("add_special")] public bool AddSpecial { get; set; } = false;
|
|
[JsonPropertyName("with_pieces")] public bool WithPieces { get; set; } = false;
|
|
}
|
|
|
|
public struct TokenizeResponseBase(int[] tokens) {
|
|
[JsonPropertyName("tokens")] public int[] Tokens { get; set; } = tokens;
|
|
} |