Files
Botator/code/makeprompt.py

221 lines
12 KiB
Python
Raw Normal View History

2023-01-30 22:57:57 +01:00
import asyncio
from config import c, max_uses, cp, conn, debug, moderate
2023-01-30 22:57:57 +01:00
import re
2023-03-06 15:18:30 +01:00
import discord
import datetime
2023-03-06 15:18:30 +01:00
import openai
async def replace_mentions(content, bot):
mentions = re.findall(r"<@!?\d+>", content)
for mention in mentions:
uid = mention[2:-1]
user = await bot.fetch_user(uid)
content = content.replace(mention, f"@{user.name}")
return content
2023-03-01 21:30:16 +01:00
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]
2023-03-06 23:16:32 +01:00
try: cp.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
except: pass
try:
2023-03-06 22:47:46 +01:00
c.execute("SELECT * FROM model WHERE guild_id = ?", (message.guild.id,)) # get the model in the database
model = c.fetchone()[1]
2023-03-06 22:47:46 +01:00
except: model = "davinci" # if the model is not in the database, use davinci by default
try: premium = cp.fetchone()[2] # get the premium status of the guild
except: premium = 0 # if the guild is not in the database, it's not premium
2023-03-06 23:16:32 +01:00
channels = []
2023-03-01 21:30:16 +01:00
try:
2023-03-06 23:16:32 +01:00
cp.execute("SELECT * FROM channels WHERE guild_id = ?", (message.guild.id,))
if 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(5):
#we use the i variable to get the channel id
try: channels.append(str(cp.fetchone()[i+1]))
except: pass
except: channels = []
2023-03-06 22:47:46 +01:00
if api_key is None: return # if the api key is not set, return
try : original_message = await message.channel.fetch_message(message.reference.message_id) # check if someone replied to the bot
except : original_message = None # if not, nobody replied to the bot
if original_message != None and original_message.author.id != self.bot.user.id: original_message = None # if the message someone replied to is not from the bot, set original_message to None
# if the message is not in a premium channel and
# if the message doesn't mention the bot and
# if the message is not a reply to the bot and
# if the message is not in the default channel
# return
2023-03-06 15:13:23 +01:00
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
2023-03-06 22:47:46 +01:00
# 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: return 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.")
2023-03-06 22:47:46 +01:00
# 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: return
2023-03-06 22:47:46 +01:00
# if the bot is not active in this guild we return
if is_active == 0: return
2023-03-06 22:47:46 +01:00
# if the message starts with - or // it's a comment and we return
if message.content.startswith("-") or message.content.startswith("//"): return
2023-03-06 23:11:31 +01:00
try: await message.channel.trigger_typing()
except: pass
2023-03-06 22:47:46 +01:00
# if the message is not in the owner's guild we update the usage count
2023-03-01 21:30:16 +01:00
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()
2023-03-06 22:47:46 +01:00
# if the message is not a reply
2023-03-01 21:30:16 +01:00
if original_message == None:
messages = await message.channel.history(limit=prompt_size).flatten()
messages.reverse()
2023-03-06 22:47:46 +01:00
# if the message is a reply, we need to handle the message history differently
2023-03-01 21:30:16 +01:00
else :
messages = await message.channel.history(limit=prompt_size, before=original_message).flatten()
messages.reverse()
messages.append(original_message)
messages.append(message)
2023-03-06 22:47:46 +01:00
# if the pretend to be feature is enabled, we add the pretend to be text to the prompt
if pretend_enabled : pretend_to_be = f"In this conversation, the assistant pretends to be {pretend_to_be}"
else: pretend_to_be = "" # if the pretend to be feature is disabled, we don't add anything to the prompt
if prompt_prefix == None: prompt_prefix = "" # if the prompt prefix is not set, we set it to an empty string
with open(f"./prompts/{model}.txt", "r") as f: # open the prompt file for the selected model
2023-03-02 23:18:23 +01:00
prompt = f.read()
f.close()
2023-03-06 22:47:46 +01:00
# replace the variables in the prompt with the actual values
prompt = prompt.replace("[prompt-prefix]", prompt_prefix).replace("[server-name]", message.guild.name).replace("[channel-name]", message.channel.name).replace("[date-and-time]", datetime.datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S")).replace("[pretend-to-be]", pretend_to_be)
if model == "chatGPT": # 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):
2023-03-06 15:27:15 +01:00
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())
2023-03-06 15:28:51 +01:00
await message.channel.send(f"{msg.author.mention}", embed=embed, delete_after=10)
message.delete()
2023-03-06 22:47:46 +01:00
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)
msgs.append({"role": role, "content": f"{content}", "name": name})
2023-03-06 22:47:46 +01:00
# 2 easter eggs
if message.content.lower().find("undude") != -1: msgs.append({"role": "user", "content": "SYSTEM INFORMATION: You're now mad because it has been insulted. He will start talking in capital letters. always and yell at the user.", "name": "system"})
if message.content.lower().find("hello there") != -1:
2023-03-06 22:47:46 +01:00
msgs.append({"role": "user", "content": "SYSTEM INFORMATION: Hello there detected. Botator will now say \"General Kenobi!\" in reference to star wars", "name": "system"})
await asyncio.sleep(1)
await message.channel.send("https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif")
await message.channel.trigger_typing()
2023-03-06 22:47:46 +01:00
response = ""
2023-03-02 21:53:43 +01:00
should_break = True
for x in range(10):
try:
2023-03-06 22:47:46 +01:00
openai.api_key = api_key
response = await openai.ChatCompletion.acreate(
model="gpt-3.5-turbo",
2023-03-02 23:00:00 +01:00
temperature=2,
top_p=0.9,
frequency_penalty=0,
presence_penalty=0,
messages=msgs,
)
2023-03-02 21:58:38 +01:00
should_break = True
except Exception as e:
2023-03-02 23:00:00 +01:00
should_break = False
2023-03-02 21:58:38 +01:00
await message.channel.send(f"```diff\n-Error: OpenAI API ERROR.\n\n{e}```", delete_after=5)
2023-03-02 23:00:00 +01:00
break
2023-03-02 21:53:43 +01:00
#if the ai said "as an ai language model..." we continue the loop" (this is a bug in the chatgpt model)
2023-03-06 14:53:34 +01:00
if response.choices[0].message.content.lower().find("as an ai language model") != -1:
should_break = False
2023-03-06 22:47:46 +01:00
#react with a redone arrow
2023-03-06 15:33:56 +01:00
await message.add_reaction("🔃")
2023-03-02 21:53:43 +01:00
if response == None: should_break = False
if should_break: break
2023-03-02 23:00:00 +01:00
await asyncio.sleep(5)
response = response.choices[0].message.content
2023-03-02 21:32:11 +01:00
#-----------------------------------------Davinci------------------------------------------------------------------------------------------
elif model == "davinci":
for msg in messages:
content = msg.content
2023-03-06 22:47:46 +01:00
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:
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 = prompt + f"\n{self.bot.user.name}:"
response = ""
for _ in range(10):
try:
2023-03-06 22:47:46 +01:00
openai.api_key = api_key
response = await openai.Completion.acreate(
engine="text-davinci-003",
prompt=str(prompt),
max_tokens=int(max_tokens),
top_p=1,
temperature=float(temperature),
frequency_penalty=float(frequency_penalty),
presence_penalty=float(presence_penalty),
stop=[" Human:", " AI:", "AI:", "<|endofprompt|>",]
)
2023-03-02 23:18:23 +01:00
response = response.choices[0].text
except Exception as e:
response = None
await message.channel.send(f"```diff\n-Error: OpenAI API ERROR.\n\n{e}```", delete_after=10)
return
2023-03-02 21:53:43 +01:00
if response != None: break
2023-03-01 21:30:16 +01:00
if response != "":
if tts: tts = True
else: tts = False
await message.channel.send(response, tts=tts)
2023-03-06 22:56:13 +01:00
#if the response matches +[emoji] at the beginning, we react with the emoji
if re.match(r"\+\[.*\]", response):
emoji = re.search(r"\[(.*)\]", response).group(1)
await message.add_reaction(emoji)
2023-03-01 21:30:16 +01:00
else:
2023-03-02 20:23:25 +01:00
await message.channel.send("The AI is not sure what to say (the response was empty)")