mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	add: Added support for any openai compatible api for the chatterbot feature
change: Changed games.yml to allow input of the apiUrl (needs to be openai compatible) and modelName as a string.
This commit is contained in:
		@@ -225,5 +225,19 @@ public partial class Administration
 | 
			
		||||
            if (!enabled)
 | 
			
		||||
                await Response().Pending(strs.greetdmmsg_enable($"`{prefix}greetdm`")).SendAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Cmd]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [UserPerm(GuildPerm.ManageGuild)]
 | 
			
		||||
        [Ratelimit(5)]
 | 
			
		||||
        public async Task BoostTest([Leftover] IGuildUser? user = null)
 | 
			
		||||
        {
 | 
			
		||||
            user ??= (IGuildUser)ctx.User;
 | 
			
		||||
 | 
			
		||||
            await _service.BoostTest((ITextChannel)ctx.Channel, user);
 | 
			
		||||
            var enabled = _service.GetBoostEnabled(ctx.Guild.Id);
 | 
			
		||||
            if (!enabled)
 | 
			
		||||
                await Response().Pending(strs.boostmsg_enable($"`{prefix}boost`")).SendAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -242,7 +242,7 @@ public class GreetService : INService, IReadyExecutor
 | 
			
		||||
            guild: channel.Guild,
 | 
			
		||||
            channel: channel,
 | 
			
		||||
            users: users.ToArray());
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        var text = SmartText.CreateFrom(conf.ChannelGreetMessageText);
 | 
			
		||||
        text = await _repSvc.ReplaceAsync(text, repCtx);
 | 
			
		||||
        try
 | 
			
		||||
@@ -630,6 +630,13 @@ public class GreetService : INService, IReadyExecutor
 | 
			
		||||
        return conf.SendChannelByeMessage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public bool GetBoostEnabled(ulong guildId)
 | 
			
		||||
    {
 | 
			
		||||
        using var uow = _db.GetDbContext();
 | 
			
		||||
        var conf = uow.GuildConfigsForId(guildId, set => set);
 | 
			
		||||
        return conf.SendBoostMessage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Test Messages
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
using NadekoBot.Common.ModuleBehaviors;
 | 
			
		||||
using NadekoBot.Db.Models;
 | 
			
		||||
using NadekoBot.Modules.Games.Common;
 | 
			
		||||
using NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
using NadekoBot.Modules.Patronage;
 | 
			
		||||
@@ -58,18 +57,21 @@ public class ChatterBotService : IExecOnMessage
 | 
			
		||||
 | 
			
		||||
                Log.Information("Cleverbot will not work as the api key is missing");
 | 
			
		||||
                return null;
 | 
			
		||||
            case ChatBotImplementation.Gpt:
 | 
			
		||||
            case ChatBotImplementation.OpenAi:
 | 
			
		||||
                var data = _gcs.Data;
 | 
			
		||||
                if (!string.IsNullOrWhiteSpace(_creds.Gpt3ApiKey))
 | 
			
		||||
                    return new OfficialGptSession(_creds.Gpt3ApiKey,
 | 
			
		||||
                        _gcs.Data.ChatGpt.ModelName,
 | 
			
		||||
                        _gcs.Data.ChatGpt.ChatHistory,
 | 
			
		||||
                        _gcs.Data.ChatGpt.MaxTokens,
 | 
			
		||||
                        _gcs.Data.ChatGpt.MinTokens,
 | 
			
		||||
                        _gcs.Data.ChatGpt.PersonalityPrompt,
 | 
			
		||||
                    return new OpenAiApiSession(
 | 
			
		||||
                        data.ChatGpt.ApiUrl,
 | 
			
		||||
                        _creds.Gpt3ApiKey,
 | 
			
		||||
                        data.ChatGpt.ModelName,
 | 
			
		||||
                        data.ChatGpt.ChatHistory,
 | 
			
		||||
                        data.ChatGpt.MaxTokens,
 | 
			
		||||
                        data.ChatGpt.MinTokens,
 | 
			
		||||
                        data.ChatGpt.PersonalityPrompt,
 | 
			
		||||
                        _client.CurrentUser.Username,
 | 
			
		||||
                        _httpFactory);
 | 
			
		||||
 | 
			
		||||
                Log.Information("Gpt3 will not work as the api key is missing");
 | 
			
		||||
                Log.Information("Openai Api will likely not work as the api key is missing");
 | 
			
		||||
                return null;
 | 
			
		||||
            default:
 | 
			
		||||
                return null;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								src/NadekoBot/Modules/Games/ChatterBot/_common/Choice.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/NadekoBot/Modules/Games/ChatterBot/_common/Choice.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
using System.Text.Json.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public class Choice
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("message")]
 | 
			
		||||
    public Message Message { get; init; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,61 +0,0 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
using System.Text.Json.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public class OpenAiCompletionResponse
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("choices")]
 | 
			
		||||
    public Choice[] Choices { get; set; }
 | 
			
		||||
    
 | 
			
		||||
    [JsonPropertyName("usage")]
 | 
			
		||||
    public OpenAiUsageData Usage { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class OpenAiUsageData
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("prompt_tokens")]
 | 
			
		||||
    public int PromptTokens { get; set; }
 | 
			
		||||
    
 | 
			
		||||
    [JsonPropertyName("completion_tokens")]
 | 
			
		||||
    public int CompletionTokens { get; set; }
 | 
			
		||||
    
 | 
			
		||||
    [JsonPropertyName("total_tokens")]
 | 
			
		||||
    public int TotalTokens { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class Choice
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("message")]
 | 
			
		||||
    public Message Message { get; init; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class Message {
 | 
			
		||||
    [JsonPropertyName("content")]
 | 
			
		||||
    public string Content { get; init; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class Gpt3ApiRequest
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("model")]
 | 
			
		||||
    public string Model { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("messages")]
 | 
			
		||||
    public List<GPTMessage> Messages { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("temperature")]
 | 
			
		||||
    public int Temperature { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("max_tokens")]
 | 
			
		||||
    public int MaxTokens { get; init; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class GPTMessage
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("role")]
 | 
			
		||||
    public string Role {get; init;}
 | 
			
		||||
    [JsonPropertyName("content")]
 | 
			
		||||
    public string Content {get; init;}
 | 
			
		||||
    [JsonPropertyName("name")]
 | 
			
		||||
    public string Name {get; init;}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,8 @@
 | 
			
		||||
using System.Text.Json.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public class Message {
 | 
			
		||||
    [JsonPropertyName("content")]
 | 
			
		||||
    public string Content { get; init; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
using System.Text.Json.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public class OpenAiApiMessage
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("role")]
 | 
			
		||||
    public string Role { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("content")]
 | 
			
		||||
    public string Content { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("name")]
 | 
			
		||||
    public string Name { get; init; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
using System.Text.Json.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public class OpenAiApiRequest
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("model")]
 | 
			
		||||
    public string Model { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("messages")]
 | 
			
		||||
    public List<OpenAiApiMessage> Messages { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("temperature")]
 | 
			
		||||
    public int Temperature { get; init; }
 | 
			
		||||
 | 
			
		||||
    [JsonPropertyName("max_tokens")]
 | 
			
		||||
    public int MaxTokens { get; init; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
using System.Text.Json.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public class OpenAiApiUsageData
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("prompt_tokens")]
 | 
			
		||||
    public int PromptTokens { get; set; }
 | 
			
		||||
    
 | 
			
		||||
    [JsonPropertyName("completion_tokens")]
 | 
			
		||||
    public int CompletionTokens { get; set; }
 | 
			
		||||
    
 | 
			
		||||
    [JsonPropertyName("total_tokens")]
 | 
			
		||||
    public int TotalTokens { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
using System.Text.Json.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public class OpenAiCompletionResponse
 | 
			
		||||
{
 | 
			
		||||
    [JsonPropertyName("choices")]
 | 
			
		||||
    public Choice[] Choices { get; set; }
 | 
			
		||||
    
 | 
			
		||||
    [JsonPropertyName("usage")]
 | 
			
		||||
    public OpenAiApiUsageData Usage { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,18 +1,15 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using OneOf.Types;
 | 
			
		||||
using System.Net.Http.Json;
 | 
			
		||||
using SharpToken;
 | 
			
		||||
using System.CodeDom;
 | 
			
		||||
using System.Net.Http.Json;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public partial class OfficialGptSession : IChatterBotSession
 | 
			
		||||
public partial class OpenAiApiSession : IChatterBotSession
 | 
			
		||||
{
 | 
			
		||||
    private string Uri
 | 
			
		||||
        => $"https://api.openai.com/v1/chat/completions";
 | 
			
		||||
 | 
			
		||||
    private readonly string _baseUrl;
 | 
			
		||||
    private readonly string _apiKey;
 | 
			
		||||
    private readonly string _model;
 | 
			
		||||
    private readonly int _maxHistory;
 | 
			
		||||
@@ -20,13 +17,14 @@ public partial class OfficialGptSession : IChatterBotSession
 | 
			
		||||
    private readonly int _minTokens;
 | 
			
		||||
    private readonly string _nadekoUsername;
 | 
			
		||||
    private readonly GptEncoding _encoding;
 | 
			
		||||
    private List<GPTMessage> messages = new();
 | 
			
		||||
    private List<OpenAiApiMessage> messages = new();
 | 
			
		||||
    private readonly IHttpClientFactory _httpFactory;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public OfficialGptSession(
 | 
			
		||||
    public OpenAiApiSession(
 | 
			
		||||
        string url,
 | 
			
		||||
        string apiKey,
 | 
			
		||||
        ChatGptModel model,
 | 
			
		||||
        string model,
 | 
			
		||||
        int chatHistory,
 | 
			
		||||
        int maxTokens,
 | 
			
		||||
        int minTokens,
 | 
			
		||||
@@ -34,44 +32,47 @@ public partial class OfficialGptSession : IChatterBotSession
 | 
			
		||||
        string nadekoUsername,
 | 
			
		||||
        IHttpClientFactory factory)
 | 
			
		||||
    {
 | 
			
		||||
        _apiKey = apiKey;
 | 
			
		||||
        _httpFactory = factory;
 | 
			
		||||
 | 
			
		||||
        _model = model switch
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(url) || !Uri.TryCreate(url, UriKind.Absolute, out _))
 | 
			
		||||
        {
 | 
			
		||||
            ChatGptModel.Gpt35Turbo => "gpt-3.5-turbo",
 | 
			
		||||
            ChatGptModel.Gpt4o => "gpt-4o",
 | 
			
		||||
            _ => throw new ArgumentException("Unknown, unsupported or obsolete model", nameof(model))
 | 
			
		||||
        };
 | 
			
		||||
            throw new ArgumentException("Invalid OpenAi api url provided", nameof(url));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _baseUrl = url.TrimEnd('/');
 | 
			
		||||
 | 
			
		||||
        _apiKey = apiKey;
 | 
			
		||||
        _model = model;
 | 
			
		||||
        _httpFactory = factory;
 | 
			
		||||
        _maxHistory = chatHistory;
 | 
			
		||||
        _maxTokens = maxTokens;
 | 
			
		||||
        _minTokens = minTokens;
 | 
			
		||||
        _nadekoUsername = UsernameCleaner().Replace(nadekoUsername, "");
 | 
			
		||||
        _encoding = GptEncoding.GetEncodingForModel(_model);
 | 
			
		||||
        messages.Add(new()
 | 
			
		||||
        _encoding = GptEncoding.GetEncodingForModel("gpt-4o");
 | 
			
		||||
        if (!string.IsNullOrWhiteSpace(personality))
 | 
			
		||||
        {
 | 
			
		||||
            Role = "system",
 | 
			
		||||
            Content = personality,
 | 
			
		||||
            Name = _nadekoUsername
 | 
			
		||||
        });
 | 
			
		||||
            messages.Add(new()
 | 
			
		||||
            {
 | 
			
		||||
                Role = "system",
 | 
			
		||||
                Content = personality,
 | 
			
		||||
                Name = _nadekoUsername
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    [GeneratedRegex("[^a-zA-Z0-9_-]")]
 | 
			
		||||
    private static partial Regex UsernameCleaner();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public async Task<OneOf.OneOf<ThinkResult, Error<string>>> Think(string input, string username)
 | 
			
		||||
    {
 | 
			
		||||
        username = UsernameCleaner().Replace(username, "");
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        messages.Add(new()
 | 
			
		||||
        {
 | 
			
		||||
            Role = "user",
 | 
			
		||||
            Content = input,
 | 
			
		||||
            Name = username
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        while (messages.Count > _maxHistory + 2)
 | 
			
		||||
        {
 | 
			
		||||
            messages.RemoveAt(1);
 | 
			
		||||
@@ -92,28 +93,29 @@ public partial class OfficialGptSession : IChatterBotSession
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                return new Error<string>("Token count exceeded, please increase the number of tokens in the bot config and restart.");
 | 
			
		||||
                return new Error<string>(
 | 
			
		||||
                    "Token count exceeded, please increase the number of tokens in the bot config and restart.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        using var http = _httpFactory.CreateClient();
 | 
			
		||||
        http.DefaultRequestHeaders.Authorization = new("Bearer", _apiKey);
 | 
			
		||||
        
 | 
			
		||||
        var data = await http.PostAsJsonAsync(Uri,
 | 
			
		||||
            new Gpt3ApiRequest()
 | 
			
		||||
 | 
			
		||||
        var data = await http.PostAsJsonAsync($"{_baseUrl}/v1/chat/completions",
 | 
			
		||||
            new OpenAiApiRequest()
 | 
			
		||||
            {
 | 
			
		||||
                Model = _model,
 | 
			
		||||
                Messages = messages,
 | 
			
		||||
                MaxTokens = _maxTokens - tokensUsed,
 | 
			
		||||
                Temperature = 1,
 | 
			
		||||
            });
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        var dataString = await data.Content.ReadAsStringAsync();
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var response = JsonConvert.DeserializeObject<OpenAiCompletionResponse>(dataString);
 | 
			
		||||
            
 | 
			
		||||
            Log.Information("Received response: {response} ", dataString);
 | 
			
		||||
 | 
			
		||||
            // Log.Information("Received response: {Response} ", dataString);
 | 
			
		||||
            var res = response?.Choices?[0];
 | 
			
		||||
            var message = res?.Message?.Content;
 | 
			
		||||
 | 
			
		||||
@@ -121,14 +123,14 @@ public partial class OfficialGptSession : IChatterBotSession
 | 
			
		||||
            {
 | 
			
		||||
                return new Error<string>("ChatGpt: Received no response.");
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            messages.Add(new()
 | 
			
		||||
            {
 | 
			
		||||
                Role = "assistant",
 | 
			
		||||
                Content = message,
 | 
			
		||||
                Name = _nadekoUsername
 | 
			
		||||
            });
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            return new ThinkResult()
 | 
			
		||||
            {
 | 
			
		||||
                Text = message,
 | 
			
		||||
@@ -142,11 +144,4 @@ public partial class OfficialGptSession : IChatterBotSession
 | 
			
		||||
            return new Error<string>("Unexpected response received");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public sealed class ThinkResult
 | 
			
		||||
{
 | 
			
		||||
    public string Text { get; set; }
 | 
			
		||||
    public int TokensIn { get; set; }
 | 
			
		||||
    public int TokensOut { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
using System.CodeDom;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
 | 
			
		||||
 | 
			
		||||
public sealed class ThinkResult
 | 
			
		||||
{
 | 
			
		||||
    public string Text { get; set; }
 | 
			
		||||
    public int TokensIn { get; set; }
 | 
			
		||||
    public int TokensOut { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -8,7 +8,7 @@ namespace NadekoBot.Modules.Games.Common;
 | 
			
		||||
public sealed partial class GamesConfig : ICloneable<GamesConfig>
 | 
			
		||||
{
 | 
			
		||||
    [Comment("DO NOT CHANGE")]
 | 
			
		||||
    public int Version { get; set; } = 4;
 | 
			
		||||
    public int Version { get; set; } = 5;
 | 
			
		||||
 | 
			
		||||
    [Comment("Hangman related settings (.hangman command)")]
 | 
			
		||||
    public HangmanConfig Hangman { get; set; } = new()
 | 
			
		||||
@@ -103,10 +103,13 @@ public sealed partial class GamesConfig : ICloneable<GamesConfig>
 | 
			
		||||
        }
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    [Comment(@"Which chatbot API should bot use.
 | 
			
		||||
'cleverbot' - bot will use Cleverbot API. 
 | 
			
		||||
'gpt' - bot will use GPT API")]
 | 
			
		||||
    public ChatBotImplementation ChatBot { get; set; } = ChatBotImplementation.Gpt;
 | 
			
		||||
    [Comment(
 | 
			
		||||
        """
 | 
			
		||||
         Which chatbot API should bot use.
 | 
			
		||||
        'cleverbot' - bot will use Cleverbot API. 
 | 
			
		||||
        'openai' - bot will use OpenAi API
 | 
			
		||||
        """)]
 | 
			
		||||
    public ChatBotImplementation ChatBot { get; set; } = ChatBotImplementation.OpenAi;
 | 
			
		||||
 | 
			
		||||
    public ChatGptConfig ChatGpt { get; set; } = new();
 | 
			
		||||
}
 | 
			
		||||
@@ -114,19 +117,38 @@ public sealed partial class GamesConfig : ICloneable<GamesConfig>
 | 
			
		||||
[Cloneable]
 | 
			
		||||
public sealed partial class ChatGptConfig
 | 
			
		||||
{
 | 
			
		||||
    [Comment(@"Which GPT Model should bot use.
 | 
			
		||||
    gpt35turbo - cheapest
 | 
			
		||||
    gpt4o - more expensive, higher quality
 | 
			
		||||
")]
 | 
			
		||||
    public ChatGptModel ModelName { get; set; } = ChatGptModel.Gpt35Turbo;
 | 
			
		||||
    [Comment("""
 | 
			
		||||
             Url to any openai api compatible url.
 | 
			
		||||
             Make sure to modify the modelName appropriately
 | 
			
		||||
             DO NOT add /v1/chat/completions suffix to the url
 | 
			
		||||
             """)]
 | 
			
		||||
    public string ApiUrl { get; set; } = "https://api.openai.com";
 | 
			
		||||
 | 
			
		||||
    [Comment(@"How should the chat bot behave, what's its personality? (Usage of this counts towards the max tokens)")]
 | 
			
		||||
    public string PersonalityPrompt { get; set; } = "You are a chat bot willing to have a conversation with anyone about anything.";
 | 
			
		||||
    [Comment("""
 | 
			
		||||
             Which GPT Model should bot use.
 | 
			
		||||
             gpt-3.5-turbo - cheapest
 | 
			
		||||
             gpt-4o - more expensive, higher quality
 | 
			
		||||
 | 
			
		||||
    [Comment(@"The maximum number of messages in a conversation that can be remembered. (This will increase the number of tokens used)")]
 | 
			
		||||
             If you are using another openai compatible api, you may use any of the models supported by that api
 | 
			
		||||
             """)]
 | 
			
		||||
    public string ModelName { get; set; } = "gpt-3.5-turbo";
 | 
			
		||||
 | 
			
		||||
    [Comment("""
 | 
			
		||||
             How should the chatbot behave, what's its personality?
 | 
			
		||||
             This will be sent as a system message.
 | 
			
		||||
             Usage of this counts towards the max tokens.
 | 
			
		||||
             """)]
 | 
			
		||||
    public string PersonalityPrompt { get; set; } =
 | 
			
		||||
        "You are a chat bot willing to have a conversation with anyone about anything.";
 | 
			
		||||
 | 
			
		||||
    [Comment(
 | 
			
		||||
        """
 | 
			
		||||
        The maximum number of messages in a conversation that can be remembered. 
 | 
			
		||||
        This will increase the number of tokens used.
 | 
			
		||||
        """)]
 | 
			
		||||
    public int ChatHistory { get; set; } = 5;
 | 
			
		||||
 | 
			
		||||
    [Comment(@"The maximum number of tokens to use per GPT API call")]
 | 
			
		||||
    [Comment(@"The maximum number of tokens to use per OpenAi API call")]
 | 
			
		||||
    public int MaxTokens { get; set; } = 100;
 | 
			
		||||
 | 
			
		||||
    [Comment(@"The minimum number of tokens to use per GPT API call, such that chat history is removed to make room.")]
 | 
			
		||||
@@ -147,9 +169,9 @@ public sealed partial class TriviaConfig
 | 
			
		||||
    public long CurrencyReward { get; set; }
 | 
			
		||||
 | 
			
		||||
    [Comment("""
 | 
			
		||||
        Users won't be able to start trivia games which have 
 | 
			
		||||
        a smaller win requirement than the one specified by this setting.
 | 
			
		||||
        """)]
 | 
			
		||||
             Users won't be able to start trivia games which have 
 | 
			
		||||
             a smaller win requirement than the one specified by this setting.
 | 
			
		||||
             """)]
 | 
			
		||||
    public int MinimumWinReq { get; set; } = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -163,18 +185,11 @@ public sealed partial class RaceAnimal
 | 
			
		||||
public enum ChatBotImplementation
 | 
			
		||||
{
 | 
			
		||||
    Cleverbot,
 | 
			
		||||
    OpenAi = 1,
 | 
			
		||||
 | 
			
		||||
    [Obsolete]
 | 
			
		||||
    Gpt = 1,
 | 
			
		||||
 | 
			
		||||
    [Obsolete]
 | 
			
		||||
    Gpt3 = 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public enum ChatGptModel
 | 
			
		||||
{
 | 
			
		||||
    [Obsolete]
 | 
			
		||||
    Gpt4,
 | 
			
		||||
    [Obsolete]
 | 
			
		||||
    Gpt432k,
 | 
			
		||||
    
 | 
			
		||||
    Gpt35Turbo,
 | 
			
		||||
    Gpt4o,
 | 
			
		||||
}
 | 
			
		||||
@@ -32,29 +32,21 @@ public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
 | 
			
		||||
            gs => gs.ChatBot,
 | 
			
		||||
            ConfigParsers.InsensitiveEnum,
 | 
			
		||||
            ConfigPrinters.ToString);
 | 
			
		||||
 | 
			
		||||
        AddParsedProp("gpt.apiUrl",
 | 
			
		||||
            gs => gs.ChatGpt.ApiUrl,
 | 
			
		||||
            ConfigParsers.String,
 | 
			
		||||
            ConfigPrinters.ToString);
 | 
			
		||||
 | 
			
		||||
        AddParsedProp("gpt.modelName",
 | 
			
		||||
            gs => gs.ChatGpt.ModelName,
 | 
			
		||||
            ConfigParsers.InsensitiveEnum,
 | 
			
		||||
            ConfigParsers.String,
 | 
			
		||||
            ConfigPrinters.ToString);
 | 
			
		||||
 | 
			
		||||
        AddParsedProp("gpt.personality",
 | 
			
		||||
            gs => gs.ChatGpt.PersonalityPrompt,
 | 
			
		||||
            ConfigParsers.String,
 | 
			
		||||
            ConfigPrinters.ToString);
 | 
			
		||||
        AddParsedProp("gpt.chathistory",
 | 
			
		||||
            gs => gs.ChatGpt.ChatHistory,
 | 
			
		||||
            int.TryParse,
 | 
			
		||||
            ConfigPrinters.ToString,
 | 
			
		||||
            val => val > 0);
 | 
			
		||||
        AddParsedProp("gpt.max_tokens",
 | 
			
		||||
            gs => gs.ChatGpt.MaxTokens,
 | 
			
		||||
            int.TryParse,
 | 
			
		||||
            ConfigPrinters.ToString,
 | 
			
		||||
            val => val > 0);
 | 
			
		||||
        AddParsedProp("gpt.min_tokens",
 | 
			
		||||
            gs => gs.ChatGpt.MinTokens,
 | 
			
		||||
            int.TryParse,
 | 
			
		||||
            ConfigPrinters.ToString,
 | 
			
		||||
            val => val > 0);
 | 
			
		||||
 | 
			
		||||
        Migrate();
 | 
			
		||||
    }
 | 
			
		||||
@@ -78,7 +70,7 @@ public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
 | 
			
		||||
            ModifyConfig(c =>
 | 
			
		||||
            {
 | 
			
		||||
                c.Version = 3;
 | 
			
		||||
                c.ChatGpt.ModelName = ChatGptModel.Gpt35Turbo;
 | 
			
		||||
                c.ChatGpt.ModelName = "gpt35turbo";
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -89,11 +81,40 @@ public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
 | 
			
		||||
                c.Version = 4;
 | 
			
		||||
#pragma warning disable CS0612 // Type or member is obsolete
 | 
			
		||||
                c.ChatGpt.ModelName =
 | 
			
		||||
                    c.ChatGpt.ModelName == ChatGptModel.Gpt4 || c.ChatGpt.ModelName == ChatGptModel.Gpt432k
 | 
			
		||||
                        ? ChatGptModel.Gpt4o
 | 
			
		||||
                        : c.ChatGpt.ModelName;
 | 
			
		||||
                    c.ChatGpt.ModelName.Equals("gpt4", StringComparison.OrdinalIgnoreCase)
 | 
			
		||||
                    || c.ChatGpt.ModelName.Equals("gpt432k", StringComparison.OrdinalIgnoreCase)
 | 
			
		||||
                        ? "gpt-4o"
 | 
			
		||||
                        : "gpt-3.5-turbo";
 | 
			
		||||
#pragma warning restore CS0612 // Type or member is obsolete
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (data.Version < 5)
 | 
			
		||||
        {
 | 
			
		||||
            ModifyConfig(c =>
 | 
			
		||||
            {
 | 
			
		||||
                c.Version = 5;
 | 
			
		||||
                c.ChatBot = c.ChatBot == ChatBotImplementation.OpenAi
 | 
			
		||||
                    ? ChatBotImplementation.OpenAi
 | 
			
		||||
                    : c.ChatBot;
 | 
			
		||||
 | 
			
		||||
                if (c.ChatGpt.ModelName.Equals("gpt4o", StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
                {
 | 
			
		||||
                    c.ChatGpt.ModelName = "gpt-4o";
 | 
			
		||||
                }
 | 
			
		||||
                else if (c.ChatGpt.ModelName.Equals("gpt35turbo", StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
                {
 | 
			
		||||
                    c.ChatGpt.ModelName = "gpt-3.5-turbo";
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    Log.Warning(
 | 
			
		||||
                        "Unknown OpenAI api model name: {ModelName}. "
 | 
			
		||||
                        + "It will be reset to 'gpt-3.5-turbo' only this time",
 | 
			
		||||
                        c.ChatGpt.ModelName);
 | 
			
		||||
                    c.ChatGpt.ModelName = "gpt-3.5-turbo";
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
# DO NOT CHANGE
 | 
			
		||||
version: 4
 | 
			
		||||
version: 5
 | 
			
		||||
# Hangman related settings (.hangman command)
 | 
			
		||||
hangman:
 | 
			
		||||
  # The amount of currency awarded to the winner of a hangman game
 | 
			
		||||
@@ -56,19 +56,27 @@ raceAnimals:
 | 
			
		||||
    name: Unicorn
 | 
			
		||||
# Which chatbot API should bot use.
 | 
			
		||||
# 'cleverbot' - bot will use Cleverbot API.
 | 
			
		||||
# 'gpt' - bot will use GPT API
 | 
			
		||||
chatBot: Gpt
 | 
			
		||||
# 'openai' - bot will use OpenAi API
 | 
			
		||||
chatBot: OpenAi
 | 
			
		||||
chatGpt:
 | 
			
		||||
  # Url to any openai api compatible url.
 | 
			
		||||
  # Make sure to modify the modelName appropriately
 | 
			
		||||
  # DO NOT add /v1/chat/completions suffix to the url
 | 
			
		||||
  apiUrl: https://api.openai.com
 | 
			
		||||
  # Which GPT Model should bot use.
 | 
			
		||||
  # gpt35turbo - cheapest
 | 
			
		||||
  # gpt4o - more expensive, higher quality
 | 
			
		||||
  # gpt-3.5-turbo - cheapest
 | 
			
		||||
  # gpt-4o - more expensive, higher quality
 | 
			
		||||
  # 
 | 
			
		||||
  modelName: Gpt35Turbo
 | 
			
		||||
  # How should the chat bot behave, what's its personality? (Usage of this counts towards the max tokens)
 | 
			
		||||
  # If you are using another openai compatible api, you may use any of the models supported by that api
 | 
			
		||||
  modelName: gpt-3.5-turbo
 | 
			
		||||
  # How should the chatbot behave, what's its personality?
 | 
			
		||||
  # This will be sent as a system message.
 | 
			
		||||
  # Usage of this counts towards the max tokens.
 | 
			
		||||
  personalityPrompt: You are a chat bot willing to have a conversation with anyone about anything.
 | 
			
		||||
  # The maximum number of messages in a conversation that can be remembered. (This will increase the number of tokens used)
 | 
			
		||||
  # The maximum number of messages in a conversation that can be remembered.
 | 
			
		||||
  # This will increase the number of tokens used.
 | 
			
		||||
  chatHistory: 5
 | 
			
		||||
  # The maximum number of tokens to use per GPT API call
 | 
			
		||||
  # The maximum number of tokens to use per OpenAi API call
 | 
			
		||||
  maxTokens: 100
 | 
			
		||||
  # The minimum number of tokens to use per GPT API call, such that chat history is removed to make room.
 | 
			
		||||
  minTokens: 30
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user