mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
Merge branch 'v4' of https://gitlab.com/Kwoth/nadekobot into v4
This commit is contained in:
@@ -53,6 +53,9 @@ go to https://www.patreon.com/portal -> my clients -> create client")]
|
||||
|
||||
[Comment(@"Official cleverbot api key.")]
|
||||
public string CleverbotApiKey { get; set; }
|
||||
|
||||
[Comment(@"Official GPT-3 api key.")]
|
||||
public string Gpt3ApiKey { get; set; }
|
||||
|
||||
[Comment(@"Which cache implementation should bot use.
|
||||
'memory' - Cache will be in memory of the bot's process itself. Only use this on bots with a single shard. When the bot is restarted the cache is reset.
|
||||
@@ -118,7 +121,7 @@ Windows default
|
||||
|
||||
public Creds()
|
||||
{
|
||||
Version = 6;
|
||||
Version = 7;
|
||||
Token = string.Empty;
|
||||
UsePrivilegedIntents = true;
|
||||
OwnerIds = new List<ulong>();
|
||||
@@ -128,6 +131,7 @@ Windows default
|
||||
Patreon = new(string.Empty, string.Empty, string.Empty, string.Empty);
|
||||
BotListToken = string.Empty;
|
||||
CleverbotApiKey = string.Empty;
|
||||
Gpt3ApiKey = string.Empty;
|
||||
BotCache = BotCacheImplemenation.Memory;
|
||||
RedisOptions = "localhost:6379,syncTimeout=30000,responseTimeout=30000,allowAdmin=true,password=";
|
||||
Db = new()
|
||||
|
@@ -14,6 +14,7 @@ public interface IBotCredentials
|
||||
int TotalShards { get; }
|
||||
Creds.PatreonSettings Patreon { get; }
|
||||
string CleverbotApiKey { get; }
|
||||
string Gpt3ApiKey { get; }
|
||||
RestartConfig RestartCommand { get; }
|
||||
Creds.VotesSettings Votes { get; }
|
||||
string BotListToken { get; }
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db.Models;
|
||||
using NadekoBot.Modules.Games.Common;
|
||||
using NadekoBot.Modules.Games.Common.ChatterBot;
|
||||
using NadekoBot.Modules.Permissions;
|
||||
using NadekoBot.Modules.Permissions.Common;
|
||||
@@ -27,6 +28,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly IPatronageService _ps;
|
||||
private readonly CmdCdService _ccs;
|
||||
private readonly GamesConfigService _gcs;
|
||||
|
||||
public ChatterBotService(
|
||||
DiscordSocketClient client,
|
||||
@@ -38,7 +40,8 @@ public class ChatterBotService : IExecOnMessage
|
||||
IBotCredentials creds,
|
||||
IEmbedBuilderService eb,
|
||||
IPatronageService ps,
|
||||
CmdCdService cmdCdService)
|
||||
CmdCdService cmdCdService,
|
||||
GamesConfigService gcs)
|
||||
{
|
||||
_client = client;
|
||||
_perms = perms;
|
||||
@@ -49,6 +52,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
_httpFactory = factory;
|
||||
_ps = ps;
|
||||
_ccs = cmdCdService;
|
||||
_gcs = gcs;
|
||||
|
||||
_flKey = new FeatureLimitKey()
|
||||
{
|
||||
@@ -64,11 +68,26 @@ public class ChatterBotService : IExecOnMessage
|
||||
|
||||
public IChatterBotSession CreateSession()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_creds.CleverbotApiKey))
|
||||
return new OfficialCleverbotSession(_creds.CleverbotApiKey, _httpFactory);
|
||||
switch (_gcs.Data.ChatBot)
|
||||
{
|
||||
case ChatBotImplementation.Cleverbot:
|
||||
if (!string.IsNullOrWhiteSpace(_creds.CleverbotApiKey))
|
||||
return new OfficialCleverbotSession(_creds.CleverbotApiKey, _httpFactory);
|
||||
|
||||
Log.Information("Cleverbot will not work as the api key is missing.");
|
||||
return null;
|
||||
Log.Information("Cleverbot will not work as the api key is missing.");
|
||||
return null;
|
||||
case ChatBotImplementation.Gpt3:
|
||||
if (!string.IsNullOrWhiteSpace(_creds.Gpt3ApiKey))
|
||||
return new OfficialGpt3Session(_creds.Gpt3ApiKey,
|
||||
_gcs.Data.ChatGpt.Model,
|
||||
_gcs.Data.ChatGpt.MaxTokens,
|
||||
_httpFactory);
|
||||
|
||||
Log.Information("Gpt3 will not work as the api key is missing.");
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string PrepareMessage(IUserMessage msg, out IChatterBotSession cleverbot)
|
||||
@@ -102,7 +121,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
{
|
||||
if (guild is not SocketGuild sg)
|
||||
return false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var message = PrepareMessage(usrMsg, out var cbs);
|
||||
@@ -147,7 +166,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
uint? monthly = quota.Quota is int mVal and >= 0
|
||||
? (uint)mVal
|
||||
: null;
|
||||
|
||||
|
||||
var maybeLimit = await _ps.TryIncrementQuotaCounterAsync(sg.OwnerId,
|
||||
sg.OwnerId == usrMsg.Author.Id,
|
||||
FeatureType.Limit,
|
||||
@@ -155,7 +174,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
null,
|
||||
daily,
|
||||
monthly);
|
||||
|
||||
|
||||
if (maybeLimit.TryPickT1(out var ql, out var counters))
|
||||
{
|
||||
if (ql.Quota == 0)
|
||||
@@ -166,7 +185,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
"In order to use the cleverbot feature, the owner of this server should be [Patron Tier X](https://patreon.com/join/nadekobot) on patreon.",
|
||||
footer:
|
||||
"You may disable the cleverbot feature, and this message via '.cleverbot' command");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -174,7 +193,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
null!,
|
||||
$"You've reached your quota limit of **{ql.Quota}** responses {ql.QuotaPeriod.ToFullName()} for the cleverbot feature.",
|
||||
footer: "You may wait for the quota reset or .");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -185,7 +204,7 @@ public class ChatterBotService : IExecOnMessage
|
||||
title: null,
|
||||
response.SanitizeMentions(true)
|
||||
// , footer: counter > 0 ? counter.ToString() : null
|
||||
);
|
||||
);
|
||||
|
||||
Log.Information(@"CleverBot Executed
|
||||
Server: {GuildName} [{GuildId}]
|
||||
|
@@ -1,8 +0,0 @@
|
||||
#nullable disable
|
||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
|
||||
|
||||
public class ChatterBotResponse
|
||||
{
|
||||
public string Convo_id { get; set; }
|
||||
public string BotSay { get; set; }
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
#nullable disable
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
|
||||
|
||||
public class Gpt3Response
|
||||
{
|
||||
[JsonPropertyName("choices")]
|
||||
public Choice[] Choices { get; set; }
|
||||
}
|
||||
|
||||
public class Choice
|
||||
{
|
||||
public string Text { get; set; }
|
||||
}
|
||||
|
||||
public class Gpt3ApiRequest
|
||||
{
|
||||
[JsonPropertyName("model")]
|
||||
public string Model { get; init; }
|
||||
|
||||
[JsonPropertyName("prompt")]
|
||||
public string Prompt { get; init; }
|
||||
|
||||
[JsonPropertyName("temperature")]
|
||||
public int Temperature { get; init; }
|
||||
|
||||
[JsonPropertyName("max_tokens")]
|
||||
public int MaxTokens { get; init; }
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
#nullable disable
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Common.ChatterBot;
|
||||
|
||||
public class OfficialGpt3Session : IChatterBotSession
|
||||
{
|
||||
private string Uri
|
||||
=> $"https://api.openai.com/v1/completions";
|
||||
|
||||
private readonly string _apiKey;
|
||||
private readonly string _model;
|
||||
private readonly int _maxTokens;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
|
||||
public OfficialGpt3Session(
|
||||
string apiKey,
|
||||
Gpt3Model model,
|
||||
int maxTokens,
|
||||
IHttpClientFactory factory)
|
||||
{
|
||||
_apiKey = apiKey;
|
||||
_httpFactory = factory;
|
||||
switch (model)
|
||||
{
|
||||
case Gpt3Model.Ada001:
|
||||
_model = "text-ada-001";
|
||||
break;
|
||||
case Gpt3Model.Babbage001:
|
||||
_model = "text-babbage-001";
|
||||
break;
|
||||
case Gpt3Model.Curie001:
|
||||
_model = "text-curie-001";
|
||||
break;
|
||||
case Gpt3Model.Davinci003:
|
||||
_model = "text-davinci-003";
|
||||
break;
|
||||
}
|
||||
|
||||
_maxTokens = maxTokens;
|
||||
}
|
||||
|
||||
public async Task<string> Think(string input)
|
||||
{
|
||||
using var http = _httpFactory.CreateClient();
|
||||
http.DefaultRequestHeaders.Authorization = new("Bearer", _apiKey);
|
||||
var data = await http.PostAsJsonAsync(Uri, new Gpt3ApiRequest()
|
||||
{
|
||||
Model = _model,
|
||||
Prompt = input,
|
||||
MaxTokens = _maxTokens,
|
||||
Temperature = 1,
|
||||
});
|
||||
var dataString = await data.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
var response = JsonConvert.DeserializeObject<Gpt3Response>(dataString);
|
||||
|
||||
return response?.Choices[0]?.Text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Warning("Unexpected GPT-3 response received: {ResponseString}", dataString);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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; }
|
||||
public int Version { get; set; } = 2;
|
||||
|
||||
[Comment("Hangman related settings (.hangman command)")]
|
||||
public HangmanConfig Hangman { get; set; } = new()
|
||||
@@ -95,6 +95,27 @@ public sealed partial class GamesConfig : ICloneable<GamesConfig>
|
||||
Name = "Unicorn"
|
||||
}
|
||||
};
|
||||
|
||||
[Comment(@"Which chatbot API should bot use.
|
||||
'cleverbot' - bot will use Cleverbot API.
|
||||
'gpt3' - bot will use GPT-3 API")]
|
||||
public ChatBotImplementation ChatBot { get; set; } = ChatBotImplementation.Gpt3;
|
||||
|
||||
public ChatGptConfig ChatGpt { get; set; } = new();
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public sealed partial class ChatGptConfig
|
||||
{
|
||||
[Comment(@"Which GPT-3 Model should bot use.
|
||||
'ada' - cheapest and fastest
|
||||
'babbage' - 2nd option
|
||||
'curie' - 3rd option
|
||||
'davinci' - Most expensive, slowest")]
|
||||
public Gpt3Model Model { get; set; } = Gpt3Model.Ada001;
|
||||
|
||||
[Comment(@"The maximum number of tokens to use per GPT-3 API call")]
|
||||
public int MaxTokens { get; set; } = 100;
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
@@ -120,4 +141,18 @@ public sealed partial class RaceAnimal
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public enum ChatBotImplementation
|
||||
{
|
||||
Cleverbot,
|
||||
Gpt3
|
||||
}
|
||||
|
||||
public enum Gpt3Model
|
||||
{
|
||||
Ada001,
|
||||
Babbage001,
|
||||
Curie001,
|
||||
Davinci003
|
||||
}
|
@@ -28,6 +28,20 @@ public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
|
||||
long.TryParse,
|
||||
ConfigPrinters.ToString,
|
||||
val => val >= 0);
|
||||
|
||||
AddParsedProp("chatbot",
|
||||
gs => gs.ChatBot,
|
||||
ConfigParsers.InsensitiveEnum,
|
||||
ConfigPrinters.ToString);
|
||||
AddParsedProp("gpt.model",
|
||||
gs => gs.ChatGpt.Model,
|
||||
ConfigParsers.InsensitiveEnum,
|
||||
ConfigPrinters.ToString);
|
||||
AddParsedProp("gpt.max_tokens",
|
||||
gs => gs.ChatGpt.MaxTokens,
|
||||
int.TryParse,
|
||||
ConfigPrinters.ToString,
|
||||
val => val > 0);
|
||||
|
||||
Migrate();
|
||||
}
|
||||
@@ -45,5 +59,14 @@ public sealed class GamesConfigService : ConfigServiceBase<GamesConfig>
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (data.Version < 2)
|
||||
{
|
||||
ModifyConfig(c =>
|
||||
{
|
||||
c.Version = 2;
|
||||
c.ChatBot = ChatBotImplementation.Cleverbot;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -23,7 +23,6 @@ public class GamesService : INService, IReadyExecutor
|
||||
|
||||
//channelId, game
|
||||
public ConcurrentDictionary<ulong, AcrophobiaGame> AcrophobiaGames { get; } = new();
|
||||
public ConcurrentDictionary<ulong, TriviaGame> RunningTrivias { get; } = new();
|
||||
public Dictionary<ulong, TicTacToe> TicTacToeGames { get; } = new();
|
||||
public ConcurrentDictionary<ulong, TypingGame> RunningContests { get; } = new();
|
||||
public ConcurrentDictionary<ulong, NunchiGame> NunchiGames { get; } = new();
|
||||
|
@@ -34,19 +34,19 @@ public sealed class BotCredsProvider : IBotCredsProvider
|
||||
|
||||
public BotCredsProvider(int? totalShards = null, string credPath = null)
|
||||
{
|
||||
_totalShards = totalShards;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(credPath))
|
||||
{
|
||||
CredsPath = credPath;
|
||||
CredsExamplePath = Path.Combine(Path.GetDirectoryName(credPath), CREDS_EXAMPLE_FILE_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
CredsPath = Path.Combine(Directory.GetCurrentDirectory(), CREDS_FILE_NAME);
|
||||
CredsExamplePath = Path.Combine(Directory.GetCurrentDirectory(), CREDS_EXAMPLE_FILE_NAME);
|
||||
_totalShards = totalShards;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(credPath))
|
||||
{
|
||||
CredsPath = credPath;
|
||||
CredsExamplePath = Path.Combine(Path.GetDirectoryName(credPath), CREDS_EXAMPLE_FILE_NAME);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
CredsPath = Path.Combine(Directory.GetCurrentDirectory(), CREDS_FILE_NAME);
|
||||
CredsExamplePath = Path.Combine(Directory.GetCurrentDirectory(), CREDS_EXAMPLE_FILE_NAME);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!File.Exists(CredsExamplePath))
|
||||
@@ -69,8 +69,8 @@ public sealed class BotCredsProvider : IBotCredsProvider
|
||||
|
||||
_config = new ConfigurationBuilder().AddYamlFile(CredsPath, false, true)
|
||||
.AddEnvironmentVariables("NadekoBot_")
|
||||
.Build();
|
||||
|
||||
.Build();
|
||||
|
||||
_changeToken = ChangeToken.OnChange(() => _config.GetReloadToken(), Reload);
|
||||
Reload();
|
||||
}
|
||||
@@ -131,14 +131,14 @@ public sealed class BotCredsProvider : IBotCredsProvider
|
||||
|
||||
ymlData = Yaml.Serializer.Serialize(creds);
|
||||
File.WriteAllText(CREDS_FILE_NAME, ymlData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private string OldCredsJsonPath
|
||||
=> Path.Combine(Directory.GetCurrentDirectory(), "credentials.json");
|
||||
|
||||
private string OldCredsJsonBackupPath
|
||||
=> Path.Combine(Directory.GetCurrentDirectory(), "credentials.json.bak");
|
||||
|
||||
=> Path.Combine(Directory.GetCurrentDirectory(), "credentials.json.bak");
|
||||
|
||||
private void MigrateCredentials()
|
||||
{
|
||||
if (File.Exists(OldCredsJsonPath))
|
||||
@@ -177,15 +177,18 @@ public sealed class BotCredsProvider : IBotCredsProvider
|
||||
|
||||
Log.Warning(
|
||||
"Data from credentials.json has been moved to creds.yml\nPlease inspect your creds.yml for correctness");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (File.Exists(CREDS_FILE_NAME))
|
||||
{
|
||||
var creds = Yaml.Deserializer.Deserialize<Creds>(File.ReadAllText(CREDS_FILE_NAME));
|
||||
if (creds.Version <= 5)
|
||||
{
|
||||
creds.Version = 6;
|
||||
creds.BotCache = BotCacheImplemenation.Redis;
|
||||
}
|
||||
if (creds.Version <= 6)
|
||||
{
|
||||
creds.Version = 7;
|
||||
File.WriteAllText(CREDS_FILE_NAME, Yaml.Serializer.Serialize(creds));
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# DO NOT CHANGE
|
||||
version: 6
|
||||
version: 7
|
||||
# Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/
|
||||
token: ''
|
||||
# List of Ids of the users who have bot owner permissions
|
||||
@@ -56,6 +56,8 @@ patreon:
|
||||
botListToken: ''
|
||||
# Official cleverbot api key.
|
||||
cleverbotApiKey: ''
|
||||
# Official GPT-3 api key.
|
||||
gpt3ApiKey: ''
|
||||
# Which cache implementation should bot use.
|
||||
# 'memory' - Cache will be in memory of the bot's process itself. Only use this on bots with a single shard. When the bot is restarted the cache is reset.
|
||||
# 'redis' - Uses redis (which needs to be separately downloaded and installed). The cache will persist through bot restarts. You can configure connection string in creds.yml
|
||||
|
@@ -807,6 +807,7 @@ hentaibomb:
|
||||
- hentaibomb
|
||||
cleverbot:
|
||||
- cleverbot
|
||||
- chatgpt
|
||||
shorten:
|
||||
- shorten
|
||||
wikia:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# DO NOT CHANGE
|
||||
version: 1
|
||||
version: 2
|
||||
# Hangman related settings (.hangman command)
|
||||
hangman:
|
||||
# The amount of currency awarded to the winner of a hangman game
|
||||
@@ -8,8 +8,8 @@ hangman:
|
||||
trivia:
|
||||
# The amount of currency awarded to the winner of the trivia game.
|
||||
currencyReward: 0
|
||||
# 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.
|
||||
minimumWinReq: 1
|
||||
# List of responses for the .8ball command. A random one will be selected every time
|
||||
eightBallResponses:
|
||||
@@ -54,3 +54,17 @@ raceAnimals:
|
||||
name: Crab
|
||||
- icon: "🦄"
|
||||
name: Unicorn
|
||||
# Which chatbot API should bot use.
|
||||
# 'cleverbot' - bot will use Cleverbot API.
|
||||
# 'gpt3' - bot will use GPT-3 API
|
||||
chatBot: gpt3
|
||||
|
||||
chatGpt:
|
||||
# Which GPT-3 Model should bot use.
|
||||
# 'ada001' - cheapest and fastest
|
||||
# 'babbage001' - 2nd option
|
||||
# 'curie001' - 3rd option
|
||||
# 'davinci003' - Most expensive, slowest
|
||||
model: davinci003
|
||||
# The maximum number of tokens to use per GPT-3 API call
|
||||
maxTokens: 100
|
||||
|
@@ -1377,7 +1377,7 @@ listservers:
|
||||
args:
|
||||
- "3"
|
||||
cleverbot:
|
||||
desc: "Toggles cleverbot session. When enabled, the bot will reply to messages starting with bot mention in the server. Expressions starting with %bot.mention% won't work if cleverbot is enabled."
|
||||
desc: "Toggles cleverbot/chatgpt session. When enabled, the bot will reply to messages starting with bot mention in the server. Expressions starting with %bot.mention% won't work if cleverbot/chatgpt is enabled."
|
||||
args:
|
||||
- ""
|
||||
shorten:
|
||||
|
Reference in New Issue
Block a user