moved most functions out of essentials and into chatgpt
moved chatgpt on_message functions out of sparkytron3000 into chatgpt made sparky ignore python imports if they start with _ renamed essentials to _essentials to stop import
This commit is contained in:
parent
edd3bd5093
commit
be04b5f203
3 changed files with 115 additions and 138 deletions
|
|
@ -2,6 +2,9 @@
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
|
import random
|
||||||
|
import asyncio
|
||||||
|
import discord
|
||||||
from discord.ext import commands, tasks
|
from discord.ext import commands, tasks
|
||||||
|
|
||||||
class ChatGPT(commands.Cog):
|
class ChatGPT(commands.Cog):
|
||||||
|
|
@ -22,6 +25,8 @@ class ChatGPT(commands.Cog):
|
||||||
os.mkdir(self.data_dir)
|
os.mkdir(self.data_dir)
|
||||||
if not os.path.exists(self.data_dir + "config"):
|
if not os.path.exists(self.data_dir + "config"):
|
||||||
os.mkdir(self.data_dir + "config")
|
os.mkdir(self.data_dir + "config")
|
||||||
|
if not os.path.exists(self.data_dir + "logs"):
|
||||||
|
os.mkdir(self.data_dir + "logs")
|
||||||
except:
|
except:
|
||||||
print("AsyncOpenAI failed to make directories")
|
print("AsyncOpenAI failed to make directories")
|
||||||
|
|
||||||
|
|
@ -282,6 +287,113 @@ class ChatGPT(commands.Cog):
|
||||||
|
|
||||||
self.save_to_db(reminders_path,data)
|
self.save_to_db(reminders_path,data)
|
||||||
|
|
||||||
|
async def log_chat_and_get_history(self, ctx, logfile, channel_vars):
|
||||||
|
#todo: ctx is actually a message, make this obv
|
||||||
|
log_line = ''
|
||||||
|
log_line += ctx.content
|
||||||
|
log_line = ctx.author.name + ": " + log_line +"\n"
|
||||||
|
chat_history = ""
|
||||||
|
print("Logging: " + log_line, end="")
|
||||||
|
with open(logfile, "a", encoding="utf-8") as f:
|
||||||
|
f.write(log_line)
|
||||||
|
with open(logfile, "r", encoding="utf-8") as f:
|
||||||
|
for line in (f.readlines() [-int(channel_vars["chat_history_len"]):]):
|
||||||
|
chat_history += line
|
||||||
|
return chat_history
|
||||||
|
|
||||||
|
async def react_to_msg(self, ctx, react):
|
||||||
|
#todo ctx is actually a message, make this obv
|
||||||
|
def is_emoji(string):
|
||||||
|
if len(string) == 1:
|
||||||
|
# Range of Unicode codepoints for emojis
|
||||||
|
if 0x1F300 <= ord(string) <= 0x1F6FF:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
if react:
|
||||||
|
if not random.randint(0,10) and ctx.author.id != 1097302679836971038:
|
||||||
|
#todo above line is do not react to self, make this work programatically
|
||||||
|
system_msg = "Send only an emoji as a discord reaction to the following chat message"
|
||||||
|
message = ctx.content[0]
|
||||||
|
headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': f'Bearer {os.getenv("openai.api_key")}',
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"model": "gpt-3.5-turbo",
|
||||||
|
"messages": [{"role": "system", "content": system_msg}, {"role": "user", "content": message}]
|
||||||
|
}
|
||||||
|
|
||||||
|
url = "https://api.openai.com/v1/chat/completions"
|
||||||
|
|
||||||
|
try:
|
||||||
|
async with self.bot.http_session.post(url, headers=headers, json=data) as resp:
|
||||||
|
response_data = await resp.json()
|
||||||
|
reaction = response_data['choices'][0]['message']['content'].strip()
|
||||||
|
if is_emoji(reaction):
|
||||||
|
await ctx.add_reaction(reaction)
|
||||||
|
else:
|
||||||
|
await ctx.add_reaction("😓")
|
||||||
|
except Exception as error:
|
||||||
|
print("Some error happened while trying to react to a message")
|
||||||
|
|
||||||
|
async def chat_response(self, ctx, channel_vars, chat_history_string):
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
prompt = f"You are a {channel_vars['personality']} chat bot named Sparkytron 3000 created by @phixxy.com. Your personality should be {channel_vars['personality']}. You are currently in a {channel_vars['channel_topic']} chatroom. The message history is: {chat_history_string}"
|
||||||
|
headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': f'Bearer {os.getenv("openai.api_key")}',
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"model": "gpt-3.5-turbo",
|
||||||
|
"messages": [{"role": "user", "content": prompt}]
|
||||||
|
}
|
||||||
|
|
||||||
|
url = "https://api.openai.com/v1/chat/completions"
|
||||||
|
|
||||||
|
try:
|
||||||
|
async with self.bot.http_session.post(url, headers=headers, json=data) as resp:
|
||||||
|
response_data = await resp.json()
|
||||||
|
response = response_data['choices'][0]['message']['content']
|
||||||
|
if "Sparkytron 3000:" in response[0:17]:
|
||||||
|
response = response.replace("Sparkytron 3000:", "")
|
||||||
|
max_len = 1999
|
||||||
|
if len(response) > max_len:
|
||||||
|
messages=[response[y-max_len:y] for y in range(max_len, len(response)+max_len,max_len)]
|
||||||
|
else:
|
||||||
|
messages=[response]
|
||||||
|
for message in messages:
|
||||||
|
await ctx.channel.send(message)
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
print("Problem with chat_response in chatgpt")
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_reaction_add(reaction, user):
|
||||||
|
if not random.randint(0,9):
|
||||||
|
message = reaction.message
|
||||||
|
emoji = reaction.emoji
|
||||||
|
await message.add_reaction(emoji)
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_message(self, message: discord.Message):
|
||||||
|
# Log Chat
|
||||||
|
# Todo, make a logging cog to handle this stuff later
|
||||||
|
logfile = f"{self.data_dir}logs/{message.channel.id}.log"
|
||||||
|
channel_vars = await self.get_channel_config(message.channel.id)
|
||||||
|
chat_history_string = await self.log_chat_and_get_history(message, logfile, channel_vars)
|
||||||
|
# Emoji Reaction
|
||||||
|
await self.react_to_msg(message, channel_vars["react_to_msgs"])
|
||||||
|
# Chat Response
|
||||||
|
if channel_vars["chat_enabled"] and not message.author.bot:
|
||||||
|
if message.content and message.content[0] != "!":
|
||||||
|
await self.chat_response(message, channel_vars, chat_history_string)
|
||||||
|
elif not message.content:
|
||||||
|
await self.chat_response(message, channel_vars, chat_history_string)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
await bot.add_cog(ChatGPT(bot))
|
await bot.add_cog(ChatGPT(bot))
|
||||||
|
|
@ -3,10 +3,8 @@ from discord.ext import commands, tasks
|
||||||
from discord.utils import get
|
from discord.utils import get
|
||||||
import shutil
|
import shutil
|
||||||
import json
|
import json
|
||||||
import random
|
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import asyncio
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
|
|
@ -42,115 +40,6 @@ async def handle_error(error):
|
||||||
f.write(log_line)
|
f.write(log_line)
|
||||||
return error
|
return error
|
||||||
|
|
||||||
|
|
||||||
def create_channel_config(filepath):
|
|
||||||
config_dict = {
|
|
||||||
"personality":"average",
|
|
||||||
"channel_topic":"casual",
|
|
||||||
"chat_enabled":False,
|
|
||||||
"commands_enabled":True,
|
|
||||||
"chat_history_len":5,
|
|
||||||
"look_at_images":False,
|
|
||||||
"react_to_msgs":False,
|
|
||||||
"ftp_enabled":False
|
|
||||||
}
|
|
||||||
|
|
||||||
with open(filepath,"w") as f:
|
|
||||||
json.dump(config_dict,f)
|
|
||||||
print("Wrote config variables to file.")
|
|
||||||
|
|
||||||
async def get_channel_config(channel_id):
|
|
||||||
filepath = "channels/config/{0}.json".format(str(channel_id))
|
|
||||||
if not os.path.exists(filepath):
|
|
||||||
create_channel_config(filepath)
|
|
||||||
with open(filepath, "r") as f:
|
|
||||||
config_dict = json.loads(f.readline())
|
|
||||||
return config_dict
|
|
||||||
|
|
||||||
|
|
||||||
async def react_to_msg(ctx, react):
|
|
||||||
def is_emoji(string):
|
|
||||||
if len(string) == 1:
|
|
||||||
# Range of Unicode codepoints for emojis
|
|
||||||
if 0x1F300 <= ord(string) <= 0x1F6FF:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
if react:
|
|
||||||
if not random.randint(0,10) and ctx.author.id != 1097302679836971038:
|
|
||||||
system_msg = "Send only an emoji as a discord reaction to the following chat message"
|
|
||||||
message = ctx.content[0]
|
|
||||||
headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': f'Bearer {os.getenv("openai.api_key")}',
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"model": "gpt-3.5-turbo",
|
|
||||||
"messages": [{"role": "system", "content": system_msg}, {"role": "user", "content": message}]
|
|
||||||
}
|
|
||||||
|
|
||||||
url = "https://api.openai.com/v1/chat/completions"
|
|
||||||
|
|
||||||
try:
|
|
||||||
async with bot.http_session.post(url, headers=headers, json=data) as resp:
|
|
||||||
response_data = await resp.json()
|
|
||||||
reaction = response_data['choices'][0]['message']['content'].strip()
|
|
||||||
if is_emoji(reaction):
|
|
||||||
await ctx.add_reaction(reaction)
|
|
||||||
else:
|
|
||||||
await ctx.add_reaction("😓")
|
|
||||||
except Exception as error:
|
|
||||||
print("Some error happened while trying to react to a message")
|
|
||||||
await handle_error(error)
|
|
||||||
|
|
||||||
async def log_chat_and_get_history(ctx, logfile, channel_vars):
|
|
||||||
log_line = ''
|
|
||||||
log_line += ctx.content
|
|
||||||
log_line = ctx.author.name + ": " + log_line +"\n"
|
|
||||||
chat_history = ""
|
|
||||||
print("Logging: " + log_line, end="")
|
|
||||||
with open(logfile, "a", encoding="utf-8") as f:
|
|
||||||
f.write(log_line)
|
|
||||||
with open(logfile, "r", encoding="utf-8") as f:
|
|
||||||
for line in (f.readlines() [-int(channel_vars["chat_history_len"]):]):
|
|
||||||
chat_history += line
|
|
||||||
return chat_history
|
|
||||||
|
|
||||||
|
|
||||||
async def chat_response(ctx, channel_vars, chat_history_string):
|
|
||||||
async with ctx.channel.typing():
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
prompt = f"You are a {channel_vars['personality']} chat bot named Sparkytron 3000 created by @phixxy.com. Your personality should be {channel_vars['personality']}. You are currently in a {channel_vars['channel_topic']} chatroom. The message history is: {chat_history_string}"
|
|
||||||
headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': f'Bearer {os.getenv("openai.api_key")}',
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"model": "gpt-3.5-turbo",
|
|
||||||
"messages": [{"role": "user", "content": prompt}]
|
|
||||||
}
|
|
||||||
|
|
||||||
url = "https://api.openai.com/v1/chat/completions"
|
|
||||||
|
|
||||||
try:
|
|
||||||
async with bot.http_session.post(url, headers=headers, json=data) as resp:
|
|
||||||
response_data = await resp.json()
|
|
||||||
response = response_data['choices'][0]['message']['content']
|
|
||||||
if "Sparkytron 3000:" in response[0:17]:
|
|
||||||
response = response.replace("Sparkytron 3000:", "")
|
|
||||||
max_len = 1999
|
|
||||||
if len(response) > max_len:
|
|
||||||
messages=[response[y-max_len:y] for y in range(max_len, len(response)+max_len,max_len)]
|
|
||||||
else:
|
|
||||||
messages=[response]
|
|
||||||
for message in messages:
|
|
||||||
await ctx.channel.send(message)
|
|
||||||
|
|
||||||
except Exception as error:
|
|
||||||
await handle_error(error)
|
|
||||||
|
|
||||||
async def folder_setup():
|
async def folder_setup():
|
||||||
# Only tmp, extensions and data are supported, all other folders only exist for backwards compatibility and will be removed soon!
|
# Only tmp, extensions and data are supported, all other folders only exist for backwards compatibility and will be removed soon!
|
||||||
folder_names = ["tmp", "extensions", "data", "channels","channels/config", "channels/logs"]
|
folder_names = ["tmp", "extensions", "data", "channels","channels/config", "channels/logs"]
|
||||||
|
|
@ -201,43 +90,19 @@ async def on_ready():
|
||||||
await delete_all_files("tmp/", folders_made)
|
await delete_all_files("tmp/", folders_made)
|
||||||
# Import plugins from extensions folder
|
# Import plugins from extensions folder
|
||||||
for plugin_file in os.listdir('extensions/'):
|
for plugin_file in os.listdir('extensions/'):
|
||||||
if plugin_file != '__init__.py' and plugin_file[-3:] == '.py':
|
if plugin_file[0] != '_' and plugin_file[-3:] == '.py':
|
||||||
await bot.load_extension(f'extensions.{plugin_file[:-3]}')
|
await bot.load_extension(f'extensions.{plugin_file[:-3]}')
|
||||||
print('We have logged in as {0.user}'.format(bot))
|
print('We have logged in as {0.user}'.format(bot))
|
||||||
task_loop.start()
|
task_loop.start()
|
||||||
|
|
||||||
@bot.event
|
|
||||||
async def on_reaction_add(reaction, user):
|
|
||||||
if not random.randint(0,9):
|
|
||||||
message = reaction.message
|
|
||||||
emoji = reaction.emoji
|
|
||||||
await message.add_reaction(emoji)
|
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_message(ctx):
|
async def on_message(ctx):
|
||||||
#log stuff
|
# Don't allow commands in DMs for now
|
||||||
logfile = "channels/logs/{0}.log".format(str(ctx.channel.id))
|
|
||||||
channel_vars = await get_channel_config(ctx.channel.id)
|
|
||||||
chat_history_string = await log_chat_and_get_history(ctx, logfile, channel_vars)
|
|
||||||
|
|
||||||
#handle non-text channels (dms, etc)
|
|
||||||
if ctx.channel.type.value != 0 and ctx.author.id != 242018983241318410:
|
if ctx.channel.type.value != 0 and ctx.author.id != 242018983241318410:
|
||||||
#This used to notify the user it cannot respond in this channel, but that spammed threads
|
#This used to notify the user it cannot respond in this channel, but that spammed threads
|
||||||
return
|
return
|
||||||
|
|
||||||
await react_to_msg(ctx, channel_vars["react_to_msgs"]) #emoji reactions
|
|
||||||
|
|
||||||
if channel_vars["commands_enabled"] or (ctx.author.id == 242018983241318410 and ctx.content[0] == "?"):
|
|
||||||
await bot.process_commands(ctx)
|
await bot.process_commands(ctx)
|
||||||
if not channel_vars["commands_enabled"]:
|
|
||||||
await ctx.channel.send("This command only ran because you set it to allow to run even when commands are disabled")
|
|
||||||
|
|
||||||
if channel_vars["chat_enabled"] and not ctx.author.bot:
|
|
||||||
if ctx.content and ctx.content[0] != "!":
|
|
||||||
await chat_response(ctx, channel_vars, chat_history_string)
|
|
||||||
elif not ctx.content:
|
|
||||||
await chat_response(ctx, channel_vars, chat_history_string)
|
|
||||||
|
|
||||||
|
|
||||||
bot.run(discord_token)
|
bot.run(discord_token)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue