From 434c389e395c2310c94b94f5b171d53a54905886 Mon Sep 17 00:00:00 2001 From: Paillat Date: Wed, 1 Mar 2023 21:30:16 +0100 Subject: [PATCH] Added chatgpt model --- code/cogs/chat.py | 9 ++- code/cogs/settings.py | 17 +++++- code/config.py | 1 + code/makeprompt.py | 128 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 151 insertions(+), 4 deletions(-) diff --git a/code/cogs/chat.py b/code/cogs/chat.py index 39cae44..3d71765 100644 --- a/code/cogs/chat.py +++ b/code/cogs/chat.py @@ -12,7 +12,14 @@ class Chat (discord.Cog) : self.bot = bot @discord.Cog.listener() async def on_message(self, message: discord.Message): - await mp.process(self, message) + try: + c.execute("SELECT * FROM model WHERE guild_id = ?", (message.guild.id,)) + model = c.fetchone()[1] + except: model = "davinci" + if model == "davinci": + await mp.davinci_process(self, message) + if model == "chatGPT": + await mp.chat_process(self, message) @discord.slash_command(name="say", description="Say a message") async def say(self, ctx: discord.ApplicationContext, message: str): diff --git a/code/cogs/settings.py b/code/cogs/settings.py index 0196bb9..7673d50 100644 --- a/code/cogs/settings.py +++ b/code/cogs/settings.py @@ -1,5 +1,6 @@ import discord from config import debug, conn, c +models = ["davinci", "chatGPT"] class Settings (discord.Cog) : def __init__(self, bot: discord.Bot) -> None: @@ -179,4 +180,18 @@ class Settings (discord.Cog) : conn.commit() #send a message await ctx.respond("TTS has been disabled", ephemeral=True) - + #autocompletition + async def autocomplete(ctx: discord.AutocompleteContext): + return [model for model in models if model.startswith(ctx.value)] + @discord.slash_command(name="model", description="Change the model used by the bot") + @discord.option(name="model", description="The model you want to use. Leave blank to use the davinci model", required=False, autocomplete=autocomplete) + async def model(self, ctx: discord.ApplicationContext, model: str = "davinci"): + try: + c.execute("SELECT * FROM model WHERE guild_id = ?", (ctx.guild.id,)) + data = c.fetchone()[1] + except: + data = None + if data is None: c.execute("INSERT INTO model VALUES (?, ?)", (ctx.guild.id, model)) + else: c.execute("UPDATE model SET model_name = ? WHERE guild_id = ?", (model, ctx.guild.id)) + conn.commit() + await ctx.respond("Model changed !", ephemeral=True) \ No newline at end of file diff --git a/code/config.py b/code/config.py index f1ae9c0..3888798 100644 --- a/code/config.py +++ b/code/config.py @@ -39,5 +39,6 @@ if actual_columns != expected_columns: else: print("Table already has the correct number of columns") pass +c.execute('''CREATE TABLE IF NOT EXISTS model (guild_id text, model_name text)''') cp.execute('''CREATE TABLE IF NOT EXISTS data (user_id text, guild_id text, premium boolean)''') cp.execute('''CREATE TABLE IF NOT EXISTS channels (guild_id text, channel0 text, channel1 text, channel2 text, channel3 text, channel4 text)''') \ No newline at end of file diff --git a/code/makeprompt.py b/code/makeprompt.py index f7264ce..b063019 100644 --- a/code/makeprompt.py +++ b/code/makeprompt.py @@ -7,7 +7,7 @@ import random import requests import datetime import os -async def process(self, message): +async def davinci_process(self, message): if message.author.bot: return #c.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,)) @@ -31,7 +31,8 @@ async def process(self, message): tts = data[11] pretend_to_be = data[12] pretend_enabled = data[13] - cp.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,)) + try: cp.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,)) + except: pass try: premium = cp.fetchone()[2] except: premium = 0 channels = [] @@ -138,3 +139,126 @@ Botator is an AI and a regular Discord user. He types casually, uses a lot of em await message.channel.send(response, tts=tts) else: await message.channel.send("The AI is not sure what to say (the response was empty)") + +async def chat_process(self, message): + if message.author.bot: + return + try: c.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,)) + except: + return + channel = message.channel.id + data = c.fetchone() + channel_id = data[1] + api_key = data[2] + is_active = data[3] + max_tokens = data[4] + temperature = data[5] + frequency_penalty = data[6] + presence_penalty = data[7] + uses_count_today = data[8] + prompt_size = data[9] + prompt_prefix = data[10] + tts = data[11] + pretend_to_be = data[12] + pretend_enabled = data[13] + try: cp.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,)) + except: pass + try: premium = cp.fetchone()[2] + except: premium = 0 + channels = [] + try: + cp.execute("SELECT * FROM channels WHERE guild_id = ?", (message.guild.id,)) + if premium: channels = cp.fetchone()[1:] + except: channels = [] + if api_key is None: + return + if uses_count_today >= max_uses and premium == 0: + await message.channel.send(f"The bot has been used more than {str(max_uses)} times in the last 24 hours in this guild. Please try again in 24h.") + return + elif uses_count_today >= max_uses*5 and premium == 1: + return + if is_active == 0: + return + if message.content.startswith("-") or message.content.startswith("//"): + return + try : original_message = await message.channel.fetch_message(message.reference.message_id) + except : original_message = None + if original_message != None and original_message.author.id != self.bot.user.id: + original_message = None + if not str(message.channel.id) in channels and message.content.find("<@"+str(self.bot.user.id)+">") == -1 and original_message == None and str(message.channel.id) != str(channel_id): + return + if original_message != None and message.guild.id == 1050769643180146749 and message.author.id != 707196665668436019: + return + if str(message.author.id) == "646739625661956128": + #a random int between 0 and 1 to decide if the bot should respond or not + if random.randint(0, 2) == 0: + await message.channel.send(message.content) # this is a prank done by me, the developer of the bot. It's not a bug, it's a feature. + return + await message.channel.trigger_typing() + if message.guild.id != 1021872219888033903: + c.execute("UPDATE data SET uses_count_today = uses_count_today + 1 WHERE guild_id = ?", (message.guild.id,)) + conn.commit() + if original_message == None: + messages = await message.channel.history(limit=prompt_size).flatten() + messages.reverse() + else : + messages = await message.channel.history(limit=prompt_size, before=original_message).flatten() + messages.reverse() + messages.append(original_message) + messages.append(message) + prompt = "" + msgs = [] + prompt = f'''Server name: {message.guild.name}. Channel name: {message.channel.name}. +The assistant is called Botator. {pretend_to_be} +Botator is an AI and a regular Discord user. He types casually, uses a lot of emojis in each message. Botator has many niche interests. Botator talks normally and is sentient. Botator is really funny and has a good humor. Botator is intelligent. Botator often uses internet shorthand like "lol" and "bruh". He uses "bruh" a lot.''' + if prompt_prefix != "": prompt = f"\n{prompt}\n{prompt_prefix}" + else: prompt = f"\n{prompt}" + #format for msgs is {"role": "role", "content": "content"}, . Roles are system & user & assistant + msgs.append({"role": "system", "content": prompt}) + for msg in messages: + content = msg.content + mentions = re.findall(r"<@!?\d+>", content) + for mention in mentions: + #get the user id + uid = mention[2:-1] + #get the user + user = await self.bot.fetch_user(uid) + #replace the mention with the name + content = content.replace(mention, f"@{user.name}") + if msg.author.id == self.bot.user.id: + role = "assistant" + else: + role = "user" + msgs.append({"role": role, "content": content}) + if pretend_enabled : pretend_to_be = f"In this conversation, the assistant pretends to be {pretend_to_be}" + else: pretend_to_be = "" + if message.content.lower().find("undude") != -1: +# prompt += "System: Undude detected. Botator is now mad. He will start talking in capital letters.\n" + msgs.append({"role": "system", "content": "The assistant is now mad because it has been insulted. He will start talking in capital letters. always and yell at the user."}) + if message.content.lower().find("hello there") != -1: +# prompt += "System: Hello there detected. Botator will now say \"General Kenobi!\"\n in reference to star wars\n" + msgs.append({"role": "system", "content": " Hello there detected. Botator will now say \"General Kenobi!\" in reference to star wars"}) + await asyncio.sleep(1) + await message.channel.send("https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif") + await message.channel.trigger_typing() + openai.api_key = api_key + response = "" + for _ in range(10): + try: + response = await openai.ChatCompletion.acreate( + model="gpt-3.5-turbo", + max_tokens=int(max_tokens), + messages=msgs, + ) + except Exception as e: + response = None + await message.channel.send(f"```diff\n-Error: OpenAI API ERROR.\n\n{e}```", delete_after=10) + return + if response != None: break + response = response.choices[0].message.content + if response != "": + if tts: tts = True + else: tts = False + await message.channel.send(response, tts=tts) + else: + await message.channel.send("The AI is not sure what to say (the response was empty)") \ No newline at end of file