Added /setup, max queryes, ...

This commit is contained in:
Paillat
2022-11-27 12:21:02 +01:00
parent 5512ca5adf
commit edfe0b96e7

View File

@@ -9,176 +9,168 @@ def debug(message):
logging.info(message) logging.info(message)
#create a database called "database.db" if the database does not exist, else connect to it #create a database called "database.db" if the database does not exist, else connect to it
conn = sqlite3.connect('database.db') conn = sqlite3.connect('data.db')
c = conn.cursor() c = conn.cursor()
# Create table called "data" if it does not exist with the following columns: guild_id, channel_id, api_key, is_active # Create table called "data" if it does not exist with the following columns: guild_id, channel_id, api_key, is_active, max_tokens, temperature, frequency_penalty, presence_penalty, uses_count_today, prompt_size
c.execute('''CREATE TABLE IF NOT EXISTS data (guild_id text, channel_id text, api_key text, is_active boolean)''') c.execute('''CREATE TABLE IF NOT EXISTS data (guild_id text, channel_id text, api_key text, is_active boolean, max_tokens integer, temperature real, frequency_penalty real, presence_penalty real)''')
Intents =discord.Intents.all() # enable all intents Intents =discord.Intents.all() # enable all intents
Intents.members = True Intents.members = True
bot = discord.Bot(intents=Intents.all()) bot = discord.Bot(intents=Intents.all())
#create a command called "setchannel" #create a command called "setup" that takes 2 arguments: the channel id and the api key
@bot.command() @bot.command()
async def setchannel(ctx, channel: discord.TextChannel): @discord.commands.option(name="channel_id", description="The channel id", required=True)
# Check if the bot has the "Manage Channels" permission @discord.commands.option(name="api_key", description="The api key", required=True)
if ctx.author.guild_permissions.manage_channels: async def setup(ctx, channel: discord.TextChannel, api_key):
# Check if the channel is already set #check if the api key is valid
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,)) openai.api_key = api_key
if c.fetchone() is None: try:
# Insert the channel id into the database openai.Completion.create(engine="davinci", prompt="Hello world", max_tokens=1)
c.execute("INSERT INTO data VALUES (?, ?, ?, ?)", (ctx.guild.id, channel.id, None, False)) except:
conn.commit() await ctx.respond("Invalid api key", ephemeral=True)
await ctx.respond("Channel set!",ephemeral=True) return
else: #check if the channel is valid
await ctx.respond("Channel already set!",ephemeral=True) if channel is None:
else: await ctx.respond("Invalid channel id", ephemeral=True)
await ctx.respond("You do not have the permission to do that!",ephemeral=True) return
#create a command called "setkey" #check if the guild is already in the database
@bot.command() c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
async def setkey(ctx, key):
# Check if the bot has the "Manage Channels" permission
if ctx.author.guild_permissions.manage_channels:
# Check if the channel is already set
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,))
if c.fetchone() is not None: if c.fetchone() is not None:
# Insert the api key into the database await ctx.respond("This server is already setup", ephemeral=True)
c.execute("UPDATE data SET api_key = ? WHERE guild_id = ?", (key, ctx.guild.id)) return
#add the guild to the database
c.execute("INSERT INTO data VALUES (?, ?, ?, ?, ?, ?, ?, ?)", (ctx.guild.id, channel.id, api_key, False, 150, 0.5, 0.5, 0.5))
conn.commit() conn.commit()
await ctx.respond("Key set!",ephemeral=True) await ctx.send("The guild has been added to the database")
else: #create a command called "enable" taht only admins can use
await ctx.respond("Channel not set!",ephemeral=True)
else:
await ctx.respond("You do not have the permission to do that!",ephemeral=True)
#create a command called "enable"
@bot.command() @bot.command()
@discord.commands.has_permissions(administrator=True)
async def enable(ctx): async def enable(ctx):
# Check if the bot has the "Manage Channels" permission #check if the guild is in the database
if ctx.author.guild_permissions.manage_channels: c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
# Check if the channel is already set if c.fetchone() is None:
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,)) await ctx.respond("This server is not setup", ephemeral=True)
if c.fetchone() is not None: return
# Check if the api key is already set #enable the guild
c.execute("SELECT api_key FROM data WHERE guild_id = ?", (ctx.guild.id,))
if c.fetchone() is not None:
# Set is_active to True
c.execute("UPDATE data SET is_active = ? WHERE guild_id = ?", (True, ctx.guild.id)) c.execute("UPDATE data SET is_active = ? WHERE guild_id = ?", (True, ctx.guild.id))
conn.commit() conn.commit()
await ctx.respond("Enabled!", ephemeral=True) await ctx.send("The guild has been enabled")
else: #create a command called "disable" that only admins can use
await ctx.respond("Key not set!", ephemeral=True)
else:
await ctx.respond("Channel not set!", ephemeral=True)
else:
await ctx.respond("You do not have the permission to do that!", ephemeral=True)
#create a command called "disable"
@bot.command() @bot.command()
@discord.commands.has_permissions(administrator=True)
async def disable(ctx): async def disable(ctx):
# Check if the bot has the "Manage Channels" permission #check if the guild is in the database
if ctx.author.guild_permissions.manage_channels: c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
# Check if the channel is already set if c.fetchone() is None:
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,)) await ctx.respond("This server is not setup", ephemeral=True)
if c.fetchone() is not None: return
# Check if the api key is already set #disable the guild
c.execute("SELECT api_key FROM data WHERE guild_id = ?", (ctx.guild.id,))
if c.fetchone() is not None:
# Set is_active to false
c.execute("UPDATE data SET is_active = ? WHERE guild_id = ?", (False, ctx.guild.id)) c.execute("UPDATE data SET is_active = ? WHERE guild_id = ?", (False, ctx.guild.id))
conn.commit() conn.commit()
await ctx.respond("Disabled!", ephemeral=True) await ctx.send("The guild has been disabled")
else: #create a command called "advanced" that only admins can use, wich sets the advanced settings up: max_tokens, temperature, frequency_penalty, presence_penalty, prompt_size
await ctx.respond("Key not set!", ephemeral=True)
else:
await ctx.respond("Channel not set!", ephemeral=True)
else:
await ctx.respond("You do not have the permission to do that!", ephemeral=True)
#create a command called "delete" to delete the channel and api key from the database
@bot.command() @bot.command()
@discord.commands.has_permissions(administrator=True)
#set the first argument: max_tokens, with a default value of 150
@discord.commands.option(name="max_tokens", description="The max tokens", required=False)
#set the second argument: temperature, with a default value of 0.5
@discord.commands.option(name="temperature", description="The temperature", required=False)
#set the third argument: frequency_penalty, with a default value of 0.5
@discord.commands.option(name="frequency_penalty", description="The frequency penalty", required=False)
#set the fourth argument: presence_penalty, with a default value of 0.5
@discord.commands.option(name="presence_penalty", description="The presence penalty", required=False)
#set the fifth argument: prompt_size, with a default value of 5
@discord.commands.option(name="prompt_size", description="The number of messages to use as a prompt", required=False)
async def advanced(ctx, max_tokens=150, temperature=0.5, frequency_penalty=0.5, presence_penalty=0.5, prompt_size=5):
#check if the guild is in the database
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
if c.fetchone() is None:
await ctx.respond("This server is not setup, please run /setup", ephemeral=True)
return
#update the advanced settings
c.execute("UPDATE data SET max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?", (max_tokens, temperature, frequency_penalty, presence_penalty, prompt_size, ctx.guild.id))
conn.commit()
await ctx.respond("The advanced settings have been updated", ephemeral=True)
#create a command called "delete" that only admins can use wich deletes the guild id, the api key, the channel id and the advanced settings from the database
@bot.command()
@discord.commands.has_permissions(administrator=True)
async def delete(ctx): async def delete(ctx):
# Check if the bot has the "Manage Channels" permission #check if the guild is in the database
if ctx.author.guild_permissions.manage_channels: c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
# Check if the channel is already set if c.fetchone() is None:
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,)) await ctx.respond("This server is not setup", ephemeral=True)
if c.fetchone() is not None: return
# Delete the channel and api key from the database #delete the guild from the database
c.execute("DELETE FROM data WHERE guild_id = ?", (ctx.guild.id,)) c.execute("DELETE FROM data WHERE guild_id = ?", (ctx.guild.id,))
conn.commit() conn.commit()
await ctx.respond("Deleted!", ephemeral=True) await ctx.send("The guild has been deleted from the database")
else:
await ctx.respond("Channel not set!", ephemeral=True)
else:
await ctx.respond("You do not have the permission to do that!", ephemeral=True)
#create a command called "info" to get the channel and api key from the database
@bot.command() @bot.command()
async def info(ctx): async def help(ctx):
# Check if the bot has the "administrator" permission embed = discord.Embed(title="Help", description="Here is the help page", color=0x00ff00)
if ctx.author.guild_permissions.administrator: embed.add_field(name="/setup", value="Setup the bot", inline=False)
# Check if the channel is already set embed.add_field(name="/enable", value="Enable the bot", inline=False)
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,)) embed.add_field(name="/disable", value="Disable the bot", inline=False)
if c.fetchone() is not None: embed.add_field(name="/advanced", value="Set the advanced settings", inline=False)
# Get the channel and api key from the database embed.add_field(name="/delete", value="Delete all your data from our server", inline=False)
c.execute("SELECT channel_id, api_key FROM data WHERE guild_id = ?", (ctx.guild.id,)) embed.add_field(name="/help", value="Show this message", inline=False)
channel_id, api_key = c.fetchone() await ctx.respond(embed=embed, ephemeral=True)
await ctx.respond(f"Channel: {channel_id}, api key: {api_key}", ephemeral=True) #when a message is sent into a channel check if the guild is in the database and if the bot is enabled
else:
await ctx.respond("Channel not set!", ephemeral=True)
else:
await ctx.respond("You do not have the permission to do that!", ephemeral=True)
# when a message is sent in a channel, check if the channel is in the database for the guild, and if it is, and if it is not, check if the channel is active, and if it is, check if the user is a bot, and if it is not, send the message to openai with the 5 last messages from the channel as the prompt
@bot.event @bot.event
async def on_message(message): async def on_message(message):
debug(message) #check if the message is from a bot
# Check if the channel is in the database for the guild and if the message has been sent in that channel if message.author.bot:
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (message.guild.id,)) return
channel = c.fetchone() #check if the guild is in the database
debug(channel[0]) c.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
debug(message.channel.id) if c.fetchone() is None:
if channel is not None and str(message.channel.id) == str(channel[0]): return
debug("Channel is in database") #check if the bot is enabled
# Check if the channel is active
c.execute("SELECT is_active FROM data WHERE guild_id = ?", (message.guild.id,)) c.execute("SELECT is_active FROM data WHERE guild_id = ?", (message.guild.id,))
if c.fetchone() == (True,): if c.fetchone()[0] == False:
debug("Channel is active") return
# Check if the user is a bot #check if the message has been sent in the channel set in the database
if not message.author.bot: c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (message.guild.id,))
debug("User is not a bot") if str(message.channel.id) != str(c.fetchone()[0]):
# Get the api key from the database return
#get the api key from the database
c.execute("SELECT api_key FROM data WHERE guild_id = ?", (message.guild.id,)) c.execute("SELECT api_key FROM data WHERE guild_id = ?", (message.guild.id,))
api_key = c.fetchone()[0] api_key = c.fetchone()[0]
# Get the 5 last messages from the channel #get the advanced settings from the database
messages = await message.channel.history(limit=5).flatten() c.execute("SELECT max_tokens, temperature, frequency_penalty, presence_penalty, prompt_size FROM data WHERE guild_id = ?", (message.guild.id,))
# Create the prompt with the 5 last messages and the message sent by the user goint at the line after each message, adding HUMAN: before the messages taht were not sent by the bot and AI: before the messages that were sent by the bot max_tokens, temperature, frequency_penalty, presence_penalty, prompt_size = c.fetchone()
messages = await message.channel.history(limit=prompt_size).flatten()
messages.reverse()
prompt = "" prompt = ""
for m in messages: for msg in messages:
#add at the beginning of the prompt and not at the end to have the messages in the right order if msg.author.bot:
if m.author.bot: prompt += f"AI: {msg.content}\n"
prompt = f"AI: {m.content}\n" + prompt
else: else:
prompt = m.author.display_name + ": " + m.content + "\n" + prompt prompt += f"{msg.author.display_name}: {msg.content}\n"
#prompt = f"HUMAN: {m.content}\n" + prompt prompt = f"This is a conversation with an AI. Only the {prompt_size} last messages are used as a prompt. The AI will continue the conversation. The AI is very intelligent and smart. \n\n" + prompt
#add AI: at the end of the prompt #send the request to the api
prompt += "AI:" debug("Sending request to the api")
prompt = "This is a conversation with an AI. Only the last 5 messages are taken as a prompt. \n \n" + prompt
debug(prompt) debug(prompt)
# prompt += f"HUMAN: {message.content}"
#set the api key
openai.api_key = api_key openai.api_key = api_key
# Send the prompt to openai
response = openai.Completion.create( response = openai.Completion.create(
engine="text-davinci-002", engine="text-davinci-002",
prompt=prompt, prompt=str(prompt),
temperature=0.9, max_tokens=int(max_tokens),
max_tokens=512,
top_p=1, top_p=1,
frequency_penalty=0, temperature=float(temperature),
presence_penalty=0.6, frequency_penalty=float(frequency_penalty),
stop=["\n", " Human:", " AI:"] presence_penalty=float(presence_penalty),
stop=[" Human:", " AI:"]
) )
# Send the response to the channel #send the response
if response["choices"][0] ["text"] != "": if response["choices"][0] ["text"] != "":
await message.channel.send(response["choices"][0]["text"]) await message.channel.send(response["choices"][0]["text"])
else: else:
# If the response is empty, send a message saying that the response is empty await message.channel.send("The AI is not sure what to say (the response was empty)")
await message.channel.send("I don't know what to say (response is empty)") debug("The response was empty")
debug("The response has been sent")
#get the message content
# add a slash command called "say" that sends a message to the channel # add a slash command called "say" that sends a message to the channel
@bot.slash_command() @bot.slash_command()
async def say(ctx, message: str): async def say(ctx, message: str):