Merge pull request #86 from Kav-K/slight-clean

housekeeping, bugfixes
Kaveen Kumarasinghe 2 years ago committed by GitHub
commit d544599574
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -37,8 +37,7 @@ class DrawDallEService(discord.Cog, name="DrawDallEService"):
self.message_queue = message_queue self.message_queue = message_queue
self.deletion_queue = deletion_queue self.deletion_queue = deletion_queue
self.converser_cog = converser_cog self.converser_cog = converser_cog
print("Draw service initialized")
print("Draw service init")
async def encapsulated_send( async def encapsulated_send(
self, self,

@ -29,6 +29,9 @@ if sys.platform == "win32":
else: else:
separator = "/" separator = "/"
"""
Get the user key service if it is enabled.
"""
USER_INPUT_API_KEYS = EnvService.get_user_input_api_keys() USER_INPUT_API_KEYS = EnvService.get_user_input_api_keys()
USER_KEY_DB = None USER_KEY_DB = None
if USER_INPUT_API_KEYS: if USER_INPUT_API_KEYS:
@ -38,6 +41,11 @@ if USER_INPUT_API_KEYS:
USER_KEY_DB = SqliteDict("user_key_db.sqlite") USER_KEY_DB = SqliteDict("user_key_db.sqlite")
print("Retrieved/created the user key database") print("Retrieved/created the user key database")
"""
Obtain the Moderation table and the General table, these are two SQLite tables that contain
information about the server that are used for persistence and to auto-restart the moderation service.
"""
MOD_DB = None MOD_DB = None
GENERAL_DB = None GENERAL_DB = None
try: try:
@ -64,12 +72,23 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
pinecone_service, pinecone_service,
): ):
super().__init__() super().__init__()
self.GLOBAL_COOLDOWN_TIME = 0.25
# Environment
self.data_path = data_path self.data_path = data_path
self.debug_channel = None self.debug_channel = None
# Services and models
self.bot = bot self.bot = bot
self._last_member_ = None self.usage_service = usage_service
self.conversation_threads = {} self.model = model
self.DAVINCI_ROLES = ["admin", "Admin", "GPT", "gpt"] self.deletion_queue = deletion_queue
# Data specific to all text based GPT interactions
self.users_to_interactions = defaultdict(list)
self.redo_users = {}
# Conversations-specific data
self.END_PROMPTS = [ self.END_PROMPTS = [
"end", "end",
"end conversation", "end conversation",
@ -77,21 +96,20 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
"that's all", "that's all",
"that'll be all", "that'll be all",
] ]
self.last_used = {}
self.GLOBAL_COOLDOWN_TIME = 0.25
self.usage_service = usage_service
self.model = model
self.summarize = self.model.summarize_conversations
self.deletion_queue = deletion_queue
self.users_to_interactions = defaultdict(list)
self.redo_users = {}
self.awaiting_responses = [] self.awaiting_responses = []
self.awaiting_thread_responses = [] self.awaiting_thread_responses = []
self.conversation_threads = {}
self.summarize = self.model.summarize_conversations
# Moderation service data
self.moderation_queues = {} self.moderation_queues = {}
self.moderation_alerts_channel = EnvService.get_moderations_alert_channel() self.moderation_alerts_channel = EnvService.get_moderations_alert_channel()
self.moderation_enabled_guilds = [] self.moderation_enabled_guilds = []
self.moderation_tasks = {} self.moderation_tasks = {}
self.moderations_launched = [] self.moderations_launched = []
# Pinecone data
self.pinecone_service = pinecone_service self.pinecone_service = pinecone_service
try: try:
@ -206,19 +224,15 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
) )
await member.send(content=None, embed=welcome_embed) await member.send(content=None, embed=welcome_embed)
@discord.Cog.listener()
async def on_member_remove(self, member):
pass
@discord.Cog.listener() @discord.Cog.listener()
async def on_ready(self): async def on_ready(self):
self.debug_channel = self.bot.get_guild(self.DEBUG_GUILD).get_channel( self.debug_channel = self.bot.get_guild(self.DEBUG_GUILD).get_channel(
self.DEBUG_CHANNEL self.DEBUG_CHANNEL
) )
print("The debug channel was acquired")
# Check moderation service for each guild # Check moderation service for each guild
for guild in self.bot.guilds: for guild in self.bot.guilds:
print("Checking moderation service for guild " + guild.name)
await self.check_and_launch_moderations(guild.id) await self.check_and_launch_moderations(guild.id)
await self.bot.sync_commands( await self.bot.sync_commands(
@ -230,7 +244,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
check_guilds=[], check_guilds=[],
delete_existing=True, delete_existing=True,
) )
print(f"The debug channel was acquired and commands registered") print(f"Commands synced")
@add_to_group("system") @add_to_group("system")
@discord.slash_command( @discord.slash_command(
@ -268,7 +282,10 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
for thread in guild.threads: for thread in guild.threads:
thread_name = thread.name.lower() thread_name = thread.name.lower()
if "with gpt" in thread_name or "closed-gpt" in thread_name: if "with gpt" in thread_name or "closed-gpt" in thread_name:
try:
await thread.delete() await thread.delete()
except:
pass
await ctx.respond("All conversation threads have been deleted.") await ctx.respond("All conversation threads have been deleted.")
# TODO: add extra condition to check if multi is enabled for the thread, stated in conversation_threads # TODO: add extra condition to check if multi is enabled for the thread, stated in conversation_threads
@ -276,8 +293,6 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
cond1 = ( cond1 = (
channel_id channel_id
in self.conversation_threads in self.conversation_threads
# and user_id in self.conversation_thread_owners
# and channel_id == self.conversation_thread_owners[user_id]
) )
# If the trimmed message starts with a Tilde, then we want to not contribute this to the conversation # If the trimmed message starts with a Tilde, then we want to not contribute this to the conversation
try: try:
@ -305,6 +320,9 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
"Only the conversation starter can end this.", delete_after=5 "Only the conversation starter can end this.", delete_after=5
) )
return return
# TODO Possible bug here, if both users have a conversation active and one user tries to end the other, it may
# allow them to click the end button on the other person's thread and it will end their own convo.
self.conversation_threads.pop(channel_id) self.conversation_threads.pop(channel_id)
if isinstance(ctx, discord.ApplicationContext): if isinstance(ctx, discord.ApplicationContext):
@ -395,6 +413,11 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
value="Optimize an image prompt for use with DALL-E2, Midjourney, SD, etc.", value="Optimize an image prompt for use with DALL-E2, Midjourney, SD, etc.",
inline=False, inline=False,
) )
embed.add_field(
name="/system moderations",
value="The automatic moderations service",
inline=False,
)
embed.add_field(name="/help", value="See this help text", inline=False) embed.add_field(name="/help", value="See this help text", inline=False)
await ctx.respond(embed=embed) await ctx.respond(embed=embed)
@ -603,9 +626,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
await response_message.edit(content="Redoing prompt 🔄...") await response_message.edit(content="Redoing prompt 🔄...")
edited_content = after.content edited_content = after.content
# If the user is conversing, we need to get their conversation history, delete the last
# "<username>:" message, create a new <username>: section with the new prompt, and then set the prompt to
# the new prompt, then send that new prompt as the new prompt.
if after.channel.id in self.conversation_threads: if after.channel.id in self.conversation_threads:
# Remove the last two elements from the history array and add the new <username>: prompt # Remove the last two elements from the history array and add the new <username>: prompt
self.conversation_threads[ self.conversation_threads[
@ -645,7 +666,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
self.moderation_queues[guild_id], 1, 1, moderations_channel self.moderation_queues[guild_id], 1, 1, moderations_channel
) )
) )
print("Launched the moderations service") print("Launched the moderations service for guild " + str(guild_id))
self.moderations_launched.append(guild_id) self.moderations_launched.append(guild_id)
return moderations_channel return moderations_channel
@ -653,8 +674,6 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
@discord.Cog.listener() @discord.Cog.listener()
async def on_message(self, message): async def on_message(self, message):
# Get the message from context
if message.author == self.bot.user: if message.author == self.bot.user:
return return
@ -682,9 +701,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
await self.end_conversation(message) await self.end_conversation(message)
return return
# GPT3 command
if conversing: if conversing:
# Extract all the text after the !g and use it as the prompt.
user_api_key = None user_api_key = None
if USER_INPUT_API_KEYS: if USER_INPUT_API_KEYS:
user_api_key = await GPT3ComCon.get_user_api_key( user_api_key = await GPT3ComCon.get_user_api_key(
@ -697,9 +714,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
await self.check_conversation_limit(message) await self.check_conversation_limit(message)
# We want to have conversationality functionality. To have gpt3 remember context, we need to append the conversation/prompt # If the user is in a conversation thread
# history to the prompt. We can do this by checking if the user is in the conversating_users dictionary, and if they are,
# we can append their history to the prompt.
if message.channel.id in self.conversation_threads: if message.channel.id in self.conversation_threads:
# Since this is async, we don't want to allow the user to send another prompt while a conversation # Since this is async, we don't want to allow the user to send another prompt while a conversation
@ -799,7 +814,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
try: try:
# This is the EMBEDDINGS CASE # Pinecone is enabled, we will create embeddings for this conversation.
if self.pinecone_service and ctx.channel.id in self.conversation_threads: if self.pinecone_service and ctx.channel.id in self.conversation_threads:
# The conversation_id is the id of the thread # The conversation_id is the id of the thread
conversation_id = ctx.channel.id conversation_id = ctx.channel.id
@ -815,8 +830,6 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
) )
new_prompt = new_prompt.encode("ascii", "ignore").decode() new_prompt = new_prompt.encode("ascii", "ignore").decode()
# print("Creating embedding for ", prompt)
# Print the current timestamp
timestamp = int( timestamp = int(
str(datetime.datetime.now().timestamp()).replace(".", "") str(datetime.datetime.now().timestamp()).replace(".", "")
) )
@ -835,7 +848,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
) )
# Create and upsert the embedding for the conversation id, prompt, timestamp # Create and upsert the embedding for the conversation id, prompt, timestamp
embedding = await self.pinecone_service.upsert_conversation_embedding( await self.pinecone_service.upsert_conversation_embedding(
self.model, self.model,
conversation_id, conversation_id,
new_prompt, new_prompt,
@ -845,8 +858,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
embedding_prompt_less_author = await self.model.send_embedding_request( embedding_prompt_less_author = await self.model.send_embedding_request(
prompt_less_author, custom_api_key=custom_api_key prompt_less_author, custom_api_key=custom_api_key
) # Use the version of ) # Use the version of the prompt without the author's name for better clarity on retrieval.
# the prompt without the author's name for better clarity on retrieval.
# Now, build the new prompt by getting the X most similar with pinecone # Now, build the new prompt by getting the X most similar with pinecone
similar_prompts = self.pinecone_service.get_n_similar( similar_prompts = self.pinecone_service.get_n_similar(
@ -901,7 +913,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
tokens = self.usage_service.count_tokens(new_prompt) tokens = self.usage_service.count_tokens(new_prompt)
# Summarize case # No pinecone, we do conversation summarization for long term memory instead
elif ( elif (
id in self.conversation_threads id in self.conversation_threads
and tokens > self.model.summarize_threshold and tokens > self.model.summarize_threshold
@ -1157,10 +1169,6 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
await ctx.defer() await ctx.defer()
# CONVERSE Checks here TODO
# Send the request to the model
# If conversing, the prompt to send is the history, otherwise, it's just the prompt
await self.encapsulated_send( await self.encapsulated_send(
user.id, user.id,
prompt, prompt,

@ -107,12 +107,21 @@ class ImgPromptOptimizer(discord.Cog, name="ImgPromptOptimizer"):
) )
return return
# If the response_message is > 75 words, concatenate to the last 70th word
# TODO Temporary workaround until prompt is adjusted to make the optimized prompts shorter.
try:
if len(response_text.split()) > 75:
response_text = " ".join(response_text.split()[-70:])
except:
pass
response_message = await ctx.respond( response_message = await ctx.respond(
response_text.replace("Optimized Prompt:", "") response_text.replace("Optimized Prompt:", "")
.replace("Output Prompt:", "") .replace("Output Prompt:", "")
.replace("Output:", "") .replace("Output:", "")
) )
self.converser_cog.users_to_interactions[user.id] = [] self.converser_cog.users_to_interactions[user.id] = []
self.converser_cog.users_to_interactions[user.id].append( self.converser_cog.users_to_interactions[user.id].append(
response_message.id response_message.id

@ -24,7 +24,7 @@ from models.openai_model import Model
from models.usage_service_model import UsageService from models.usage_service_model import UsageService
from models.env_service_model import EnvService from models.env_service_model import EnvService
__version__ = "5.1" __version__ = "5.1.1"
""" """
The pinecone service is used to store and retrieve conversation embeddings. The pinecone service is used to store and retrieve conversation embeddings.

Loading…
Cancel
Save