mirror of
https://github.com/Paillat-dev/Botator.git
synced 2026-01-02 09:16:19 +00:00
[MAKEPROMPT] Cleaned a bit
Still a lots of work to be done
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import asyncio
|
||||
from config import c, max_uses, cp, conn, debug, moderate
|
||||
from config import curs_data, max_uses, curs_premium, con_data, debug, moderate
|
||||
import vision_processing
|
||||
import re
|
||||
import discord
|
||||
import datetime
|
||||
import openai
|
||||
import emoji # pip install emoji
|
||||
import emoji
|
||||
import os
|
||||
|
||||
|
||||
@@ -46,63 +46,91 @@ async def extract_emoji(string):
|
||||
return found_emojis, string
|
||||
|
||||
|
||||
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
|
||||
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]
|
||||
images_limit_reached = False
|
||||
def get_guild_data(message):
|
||||
"""This function gets the data of the guild where the message was sent.
|
||||
|
||||
Args:
|
||||
message (str): Data of the message that was sent
|
||||
|
||||
Returns:
|
||||
dict: A dictionary with the data of the guild
|
||||
"""
|
||||
guild_data = {}
|
||||
try:
|
||||
cp.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
c.execute(
|
||||
curs_data.execute(
|
||||
"SELECT * FROM model WHERE guild_id = ?", (message.guild.id,)
|
||||
) # get the model in the database
|
||||
model = c.fetchone()[1]
|
||||
data = curs_data.fetchone()
|
||||
model = model[1]
|
||||
except:
|
||||
model = "chatGPT"
|
||||
|
||||
try:
|
||||
premium = cp.fetchone()[2] # get the premium status of the guild
|
||||
data = cp.fetchone() # [2] # get the premium status of the guild
|
||||
premium = data[2]
|
||||
except:
|
||||
premium = 0 # if the guild is not in the database, it's not premium
|
||||
|
||||
try:
|
||||
c.execute(
|
||||
curs_data.execute(
|
||||
"SELECT * FROM images WHERE guild_id = ?", (message.guild.id,)
|
||||
) # get the images setting in the database
|
||||
data = c.fetchone()
|
||||
images = curs_data.fetchone()
|
||||
except:
|
||||
data = None
|
||||
images = None
|
||||
|
||||
guild_data["model"] = model
|
||||
guild_data["premium"] = premium
|
||||
guild_data["images"] = images
|
||||
|
||||
return guild_data
|
||||
|
||||
|
||||
async def chat_process(self, message):
|
||||
if message.author.bot:
|
||||
return
|
||||
try:
|
||||
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
|
||||
except:
|
||||
return
|
||||
data = curs_data.fetchone()
|
||||
# Create a dict with the data
|
||||
data_dict = {
|
||||
"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],
|
||||
}
|
||||
if data is None:
|
||||
data = [message.guild.id, 0, 0]
|
||||
images_usage = data[1]
|
||||
images_enabled = data[2]
|
||||
data_dict["images_usage"] = data[1]
|
||||
data_dict["images_enabled"] = data[2]
|
||||
|
||||
images_limit_reached = False
|
||||
|
||||
guild_data = get_guild_data(message)
|
||||
|
||||
channels = []
|
||||
if message.guild.id == 1050769643180146749:
|
||||
images_usage = 0 # if the guild is the support server, we set the images usage to 0, so the bot can be used as much as possible
|
||||
try:
|
||||
cp.execute("SELECT * FROM channels WHERE guild_id = ?", (message.guild.id,))
|
||||
data = cp.fetchone()
|
||||
if premium:
|
||||
if guild_data["premium"]:
|
||||
# for 5 times, we get c.fetchone()[1] to c.fetchone()[5] and we add it to the channels list, each time with try except
|
||||
for i in range(1, 6):
|
||||
# we use the i variable to get the channel id
|
||||
@@ -113,7 +141,7 @@ async def chat_process(self, message):
|
||||
except:
|
||||
channels = []
|
||||
|
||||
if api_key is None:
|
||||
if data_dict["api_key"] is None:
|
||||
return # if the api key is not set, return
|
||||
|
||||
try:
|
||||
@@ -135,15 +163,15 @@ async def chat_process(self, message):
|
||||
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)
|
||||
and str(message.channel.id) != str(data_dict["channel_id"])
|
||||
):
|
||||
return
|
||||
|
||||
# if the bot has been used more than max_uses times in the last 24 hours in this guild and the guild is not premium
|
||||
# send a message and return
|
||||
if (
|
||||
uses_count_today >= max_uses
|
||||
and premium == 0
|
||||
data_dict["uses_count_today"] >= max_uses
|
||||
and guild_data["premium"] == 0
|
||||
and message.guild.id != 1050769643180146749
|
||||
):
|
||||
return await message.channel.send(
|
||||
@@ -152,11 +180,11 @@ async def chat_process(self, message):
|
||||
|
||||
# if the bot has been used more than max_uses*5 times in the last 24 hours in this guild and the guild is premium
|
||||
# send a message and return
|
||||
elif uses_count_today >= max_uses * 5 and premium == 1:
|
||||
elif data_dict["uses_count_today"] >= max_uses * 5 and guild_data["premium"] == 1:
|
||||
return
|
||||
|
||||
# if the bot is not active in this guild we return
|
||||
if is_active == 0:
|
||||
if data_dict["is_active"] == 0:
|
||||
return
|
||||
|
||||
# if the message starts with - or // it's a comment and we return
|
||||
@@ -168,26 +196,28 @@ async def chat_process(self, message):
|
||||
pass
|
||||
# if the message is not in the owner's guild we update the usage count
|
||||
if message.guild.id != 1021872219888033903:
|
||||
c.execute(
|
||||
curs_data.execute(
|
||||
"UPDATE data SET uses_count_today = uses_count_today + 1 WHERE guild_id = ?",
|
||||
(message.guild.id,),
|
||||
)
|
||||
conn.commit()
|
||||
con_data.commit()
|
||||
# if the message is not a reply
|
||||
if original_message == None:
|
||||
messages = await message.channel.history(limit=prompt_size).flatten()
|
||||
messages = await message.channel.history(
|
||||
limit=data_dict["prompt_size"]
|
||||
).flatten()
|
||||
messages.reverse()
|
||||
# if the message is a reply, we need to handle the message history differently
|
||||
else:
|
||||
messages = await message.channel.history(
|
||||
limit=prompt_size, before=original_message
|
||||
limit=data_dict["prompt_size"], before=original_message
|
||||
).flatten()
|
||||
messages.reverse()
|
||||
messages.append(original_message)
|
||||
messages.append(message)
|
||||
|
||||
# if the pretend to be feature is enabled, we add the pretend to be text to the prompt
|
||||
if pretend_enabled:
|
||||
if data_dict["pretend_enabled"]:
|
||||
pretend_to_be = (
|
||||
f"In this conversation, the assistant pretends to be {pretend_to_be}"
|
||||
)
|
||||
@@ -198,7 +228,7 @@ async def chat_process(self, message):
|
||||
"" # if the prompt prefix is not set, we set it to an empty string
|
||||
)
|
||||
# open the prompt file for the selected model with utf-8 encoding for emojis
|
||||
with open(f"./prompts/{model}.txt", "r", encoding="utf-8") as f:
|
||||
with open(f"./prompts/{guild_data['model']}.txt", "r", encoding="utf-8") as f:
|
||||
prompt = f.read()
|
||||
f.close()
|
||||
# replace the variables in the prompt with the actual values
|
||||
@@ -211,113 +241,33 @@ async def chat_process(self, message):
|
||||
)
|
||||
.replace("[pretend-to-be]", pretend_to_be)
|
||||
)
|
||||
############################## chatGPT and gpt-4 handling ##############################
|
||||
if (
|
||||
model == "chatGPT" or model == "gpt-4"
|
||||
): # if the model is chatGPT, we handle it in a certain way
|
||||
msgs = [] # create the msgs list
|
||||
msgs.append(
|
||||
{"name": "System", "role": "user", "content": prompt}
|
||||
) # add the prompt to the msgs list
|
||||
name = "" # create the name variable
|
||||
for msg in messages: # for each message in the messages list
|
||||
content = msg.content # get the content of the message
|
||||
content = await replace_mentions(
|
||||
content, self.bot
|
||||
) # replace the mentions in the message
|
||||
# if the message is flagged as inappropriate by the OpenAI API, we delete it, send a message and ignore it
|
||||
if await moderate(api_key=api_key, text=content):
|
||||
|
||||
prompt_handlers = {
|
||||
"chatGPT": self.gpt_prompt,
|
||||
"gpt-4": self.gpt_prompt,
|
||||
"davinci": self.davinci_prompt,
|
||||
}
|
||||
prompt_handlers[guild_data["model"]](
|
||||
messages, message, data_dict, prompt, guild_data
|
||||
)
|
||||
|
||||
|
||||
async def check_moderate(self, api_key, message, msg):
|
||||
if await moderate(api_key=api_key, text=msg.content):
|
||||
embed = discord.Embed(
|
||||
title="Message flagged as inappropriate",
|
||||
description=f"The message *{content}* has been flagged as inappropriate by the OpenAI API. This means that if it hadn't been deleted, your openai account would have been banned. Please contact OpenAI support if you think this is a mistake.",
|
||||
description=f"The message *{msg.content}* has been flagged as inappropriate by the OpenAI API. This means that if it hadn't been deleted, your openai account would have been banned. Please contact OpenAI support if you think this is a mistake.",
|
||||
color=discord.Color.brand_red(),
|
||||
)
|
||||
await message.channel.send(
|
||||
f"{msg.author.mention}", embed=embed, delete_after=10
|
||||
)
|
||||
message.delete()
|
||||
else: # if the message is not flagged as inappropriate
|
||||
if msg.author.id == self.bot.user.id:
|
||||
role = "assistant"
|
||||
name = "assistant"
|
||||
else:
|
||||
role = "user"
|
||||
name = msg.author.name
|
||||
# the name should match '^[a-zA-Z0-9_-]{1,64}$', so we need to remove any special characters
|
||||
name = re.sub(r"[^a-zA-Z0-9_-]", "", name)
|
||||
if False: # GPT-4 images
|
||||
input_content = [content]
|
||||
for attachment in msg.attachments:
|
||||
image_bytes = await attachment.read()
|
||||
input_content.append({"image": image_bytes})
|
||||
msgs.append({"role": role, "content": input_content, "name": name})
|
||||
# if there is an attachment, we add it to the message
|
||||
if len(msg.attachments) > 0 and role == "user" and images_enabled == 1:
|
||||
for attachment in msg.attachments:
|
||||
if images_usage >= 6 and premium == 0:
|
||||
images_limit_reached = True
|
||||
elif images_usage >= 30 and premium == 1:
|
||||
images_limit_reached = True
|
||||
if (
|
||||
attachment.url.endswith((".png", ".jpg", ".jpeg", ".gif"))
|
||||
and images_limit_reached == False
|
||||
and os.path.exists(
|
||||
f"./../database/google-vision/results/{attachment.id}.txt"
|
||||
)
|
||||
== False
|
||||
):
|
||||
images_usage += 1
|
||||
analysis = await vision_processing.process(attachment)
|
||||
if analysis != None:
|
||||
content = f"{content} \n\n {analysis}"
|
||||
msgs.append(
|
||||
{
|
||||
"role": role,
|
||||
"content": f"{content}",
|
||||
"name": name,
|
||||
}
|
||||
)
|
||||
# if the attachment is still an image, we can check if there's a file called ./../database/google-vision/results/{attachment.id}.txt, if there is, we add the content of the file to the message
|
||||
elif (
|
||||
attachment.url.endswith((".png", ".jpg", ".jpeg", ".gif"))
|
||||
and os.path.exists(
|
||||
f"./../database/google-vision/results/{attachment.id}.txt"
|
||||
)
|
||||
== True
|
||||
):
|
||||
try:
|
||||
with open(
|
||||
f"./../database/google-vision/results/{attachment.id}.txt",
|
||||
"r",
|
||||
) as f:
|
||||
content = f"{content} \n\n {f.read()}"
|
||||
f.close()
|
||||
msgs.append(
|
||||
{
|
||||
"role": role,
|
||||
"content": f"{content}",
|
||||
"name": name,
|
||||
}
|
||||
)
|
||||
except:
|
||||
msgs.append(
|
||||
{
|
||||
"role": role,
|
||||
"content": f"{content}",
|
||||
"name": name,
|
||||
}
|
||||
)
|
||||
else:
|
||||
msgs.append(
|
||||
{"role": role, "content": f"{content}", "name": name}
|
||||
)
|
||||
c.execute(
|
||||
"UPDATE images SET usage_count = ? WHERE guild_id = ?",
|
||||
(images_usage, message.guild.id),
|
||||
)
|
||||
else:
|
||||
msgs.append({"role": role, "content": f"{content}", "name": name})
|
||||
# 2 easter eggs
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
async def check_easter_egg(self, message, msgs):
|
||||
if message.content.lower().find("undude") != -1:
|
||||
msgs.append(
|
||||
{
|
||||
@@ -339,13 +289,111 @@ async def chat_process(self, message):
|
||||
"https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif"
|
||||
)
|
||||
await message.channel.trigger_typing()
|
||||
return msgs
|
||||
|
||||
|
||||
async def gpt_prompt(self, messages, message, data_dict, prompt, guild_data):
|
||||
msgs = [] # create the msgs list
|
||||
msgs.append(
|
||||
{"name": "System", "role": "user", "content": prompt}
|
||||
) # add the prompt to the msgs list
|
||||
name = "" # create the name variable
|
||||
for msg in messages: # for each message in the messages list
|
||||
content = msg.content # get the content of the message
|
||||
content = await replace_mentions(
|
||||
content, self.bot
|
||||
) # replace the mentions in the message
|
||||
# if the message is flagged as inappropriate by the OpenAI API, we delete it, send a message and ignore it
|
||||
if await self.check_moderate(data_dict["api_key"], message, msg):
|
||||
continue # ignore the message
|
||||
content = await replace_mentions(content, self.bot)
|
||||
prompt += f"{msg.author.name}: {content}\n"
|
||||
if msg.author.id == self.bot.user.id:
|
||||
role = "assistant"
|
||||
name = "assistant"
|
||||
else:
|
||||
role = "user"
|
||||
name = msg.author.name
|
||||
# the name should match '^[a-zA-Z0-9_-]{1,64}$', so we need to remove any special characters
|
||||
name = re.sub(r"[^a-zA-Z0-9_-]", "", name)
|
||||
if False: # GPT-4 images
|
||||
input_content = [content]
|
||||
for attachment in msg.attachments:
|
||||
image_bytes = await attachment.read()
|
||||
input_content.append({"image": image_bytes})
|
||||
msgs.append({"role": role, "content": input_content, "name": name})
|
||||
|
||||
# if there is an attachment, we add it to the message
|
||||
if (
|
||||
len(msg.attachments) > 0
|
||||
and role == "user"
|
||||
and data_dict["images_enabled"] == 1
|
||||
):
|
||||
for attachment in msg.attachments:
|
||||
path = f"./../database/google-vision/results/{attachment.id}.txt"
|
||||
if images_usage >= 6 and guild_data["premium"] == 0:
|
||||
images_limit_reached = True
|
||||
elif images_usage >= 30 and guild_data["premium"] == 1:
|
||||
images_limit_reached = True
|
||||
if (
|
||||
attachment.url.endswith((".png", ".jpg", ".jpeg", ".gif"))
|
||||
and images_limit_reached == False
|
||||
and os.path.exists(path) == False
|
||||
):
|
||||
images_usage += 1
|
||||
analysis = await vision_processing.process(attachment)
|
||||
if analysis != None:
|
||||
content = f"{content} \n\n {analysis}"
|
||||
msgs.append(
|
||||
{
|
||||
"role": role,
|
||||
"content": f"{content}",
|
||||
"name": name,
|
||||
}
|
||||
)
|
||||
# if the attachment is still an image, we can check if there's a file called ./../database/google-vision/results/{attachment.id}.txt, if there is, we add the content of the file to the message
|
||||
elif attachment.url.endswith(
|
||||
(".png", ".jpg", ".jpeg", ".gif")
|
||||
) and os.path.exists(path):
|
||||
try:
|
||||
with open(
|
||||
path,
|
||||
"r",
|
||||
) as f:
|
||||
content = f"{content} \n\n {f.read()}"
|
||||
except:
|
||||
debug(f"Error while reading {path}")
|
||||
finally:
|
||||
msgs.append(
|
||||
{
|
||||
"role": role,
|
||||
"content": f"{content}",
|
||||
"name": name,
|
||||
}
|
||||
)
|
||||
f.close()
|
||||
|
||||
else:
|
||||
msgs.append(
|
||||
{"role": role, "content": f"{content}", "name": name}
|
||||
)
|
||||
curs_data.execute(
|
||||
"UPDATE images SET usage_count = ? WHERE guild_id = ?",
|
||||
(images_usage, message.guild.id),
|
||||
)
|
||||
else:
|
||||
msgs.append({"role": role, "content": f"{content}", "name": name})
|
||||
|
||||
# 2 easter eggs
|
||||
msgs = await self.check_easter_egg(message, msgs)
|
||||
|
||||
if model == "chatGPT":
|
||||
model = "gpt-3.5-turbo" # if the model is chatGPT, we set the model to gpt-3.5-turbo
|
||||
response = ""
|
||||
should_break = True
|
||||
for x in range(10):
|
||||
try:
|
||||
openai.api_key = api_key
|
||||
openai.api_key = data_dict["api_key"]
|
||||
response = await openai.ChatCompletion.acreate(
|
||||
model=model,
|
||||
temperature=2,
|
||||
@@ -384,48 +432,27 @@ async def chat_process(self, message):
|
||||
f"```diff\n-Warning: You have reached the image limit for this server. You can upgrade to premium to get more images recognized. More info in our server: https://discord.gg/sxjHtmqrbf```",
|
||||
delete_after=10,
|
||||
)
|
||||
# -----------------------------------------Davinci------------------------------------------------------------------------------------------
|
||||
|
||||
elif (
|
||||
model == "davinci"
|
||||
): # if the model is davinci or gpt-4, we handle it in a certain way
|
||||
|
||||
async def davinci_prompt(self, messages, message, data_dict, prompt, guild_data):
|
||||
for msg in messages:
|
||||
content = msg.content
|
||||
if await moderate(api_key=api_key, text=msg.content):
|
||||
embed = discord.Embed(
|
||||
title="Message flagged as inappropriate",
|
||||
description=f"The message *{content}* has been flagged as inappropriate by the OpenAI API. This means that if it hadn't been deleted, your openai account would have been banned. Please contact OpenAI support if you think this is a mistake.",
|
||||
color=discord.Color.brand_red(),
|
||||
)
|
||||
await message.channel.send(
|
||||
f"{msg.author.mention}", embed=embed, delete_after=10
|
||||
)
|
||||
message.delete()
|
||||
else:
|
||||
if not await self.check_moderate(data_dict["api_key"], message, msg):
|
||||
content = await replace_mentions(content, self.bot)
|
||||
prompt += f"{msg.author.name}: {content}\n"
|
||||
if message.content.lower().find("undude") != -1:
|
||||
prompt += "System: Undude detected. Botator is now mad. He will start talking in capital letters.\n"
|
||||
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'
|
||||
await asyncio.sleep(1)
|
||||
await message.channel.send(
|
||||
"https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif"
|
||||
)
|
||||
await message.channel.trigger_typing()
|
||||
prompt.append(await check_easter_egg(message, prompt))
|
||||
prompt = prompt + f"\n{self.bot.user.name}:"
|
||||
response = ""
|
||||
for _ in range(10):
|
||||
try:
|
||||
openai.api_key = api_key
|
||||
openai.api_key = data_dict["api_key"]
|
||||
response = await openai.Completion.acreate(
|
||||
engine="text-davinci-003",
|
||||
prompt=str(prompt),
|
||||
max_tokens=int(max_tokens),
|
||||
max_tokens=int(data_dict["max_tokens"]),
|
||||
top_p=1,
|
||||
temperature=float(temperature),
|
||||
frequency_penalty=float(frequency_penalty),
|
||||
presence_penalty=float(presence_penalty),
|
||||
temperature=float(data_dict["temperature"]),
|
||||
frequency_penalty=float(data_dict["frequency_penalty"]),
|
||||
presence_penalty=float(data_dict["presence_penalty"]),
|
||||
stop=[
|
||||
" Human:",
|
||||
" AI:",
|
||||
|
||||
Reference in New Issue
Block a user