From 3f1b00a515b9d5ab68cb90ba66efd6b8eb69ad3d Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Fri, 13 Jan 2023 12:02:57 +0000 Subject: [PATCH 1/9] Add missing requirements --- pyproject.toml | 1 + requirements.txt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 52bf578..c430571 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ dependencies = [ "aiofiles", "pinecone-client", "sqlitedict", + "backoff", ] dynamic = ["version"] [project.scripts] diff --git a/requirements.txt b/requirements.txt index 70b386c..e0de98d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,5 @@ transformers==4.25.1 pycord-multicog==1.0.2 aiofiles==22.1.0 pinecone-client==2.1.0 -sqlitedict==2.1.0 \ No newline at end of file +sqlitedict==2.1.0 +backoff==2.2.1 \ No newline at end of file From bec4e3c40a59d05562bd73dcbc6da59e1b423706 Mon Sep 17 00:00:00 2001 From: Hikari Haru Date: Fri, 13 Jan 2023 13:05:20 +0100 Subject: [PATCH 2/9] Bump version Signed-off-by: Hikari Haru --- gpt3discord.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpt3discord.py b/gpt3discord.py index 0e29667..1c24b6e 100644 --- a/gpt3discord.py +++ b/gpt3discord.py @@ -24,7 +24,7 @@ from models.openai_model import Model from models.usage_service_model import UsageService from models.env_service_model import EnvService -__version__ = "5.4" +__version__ = "5.4.1" """ The pinecone service is used to store and retrieve conversation embeddings. From 91e84dddf65a2c6f657bb8883cc6efaec764cae7 Mon Sep 17 00:00:00 2001 From: Alessandro Bellia Date: Fri, 13 Jan 2023 16:28:55 +0100 Subject: [PATCH 3/9] Added the possibility to configure SQLITE db path Now, the SQLITE db path for the user API keys can be configured through the USER_KEY_DB_PATH env variable Signed-off-by: Alessandro Bellia --- README.md | 6 +++++- cogs/gpt_3_commands_and_converser.py | 13 ++++++++++++- models/env_service_model.py | 13 +++++++++++++ sample.env | 5 ++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cd9c260..8e7b0de 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,9 @@ USER_INPUT_API_KEYS="True" Then, restart the bot, and it will set up the system for everyone to input their own API keys. -The bot will use SQLite to store API keys for the users, each user's key will be saved with a USER_ID <> API_KEY mapping in SQLite, and will be persistent across restarts. All the data will be saved in a file called `user_key_db.sqlite` in the current working directory of the bot. +The bot will use SQLite to store API keys for the users, each user's key will be saved with a USER_ID <> API_KEY mapping in SQLite, and will be persistent across restarts. All the data will be saved in a file called `user_key_db.sqlite` in the current working directory of the bot (by default). + +You can configure the location of the sqlite database by changing the `USER_KEY_DB_PATH` variable in your `.env` file (check the `sample.env` file for reference). With this feature enabled, any attempt to use a GPT3 or DALL-E command without a valid API key set for the user will pop up the following modal for them to enter their API key: @@ -239,6 +241,8 @@ GPT_ROLES="openai,gpt" WELCOME_MESSAGE="Hi There! Welcome to our Discord server. We hope you'll enjoy our server and we look forward to engaging with you!" # This is a fallback message if gpt3 fails to generate a welcome message. # This is the channel that auto-moderation alerts will be sent to MODERATIONS_ALERT_CHANNEL="977697652147892304" +# User API key db path configuration. This is where the user API keys will be stored. +USER_KEY_DB_PATH = user_key_db.sqlite ``` **Permissions** diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 7a81d40..3572ef8 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -41,7 +41,18 @@ if USER_INPUT_API_KEYS: print( "This server was configured to enforce user input API keys. Doing the required database setup now" ) - USER_KEY_DB = SqliteDict("user_key_db.sqlite") + # Get USER_KEY_DB from the environment variable + USER_KEY_DB_PATH = EnvService.get_user_key_db_path() + # Check if USER_KEY_DB_PATH is valid + if not USER_KEY_DB_PATH: + print("No user key database path was provided. Defaulting to user_key_db.sqlite") + USER_KEY_DB_PATH = "user_key_db.sqlite" + else: + # append "user_key_db.sqlite" to USER_KEY_DB_PATH if it doesn't already end with .sqlite + if not USER_KEY_DB_PATH.match("*.sqlite"): + # append "user_key_db.sqlite" to USER_KEY_DB_PATH + USER_KEY_DB_PATH = USER_KEY_DB_PATH / "user_key_db.sqlite" + USER_KEY_DB = SqliteDict(USER_KEY_DB_PATH) print("Retrieved/created the user key database") diff --git a/models/env_service_model.py b/models/env_service_model.py index 80caddc..c6f10e7 100644 --- a/models/env_service_model.py +++ b/models/env_service_model.py @@ -1,6 +1,8 @@ import os import sys from pathlib import Path +from typing import Union + from dotenv import load_dotenv @@ -193,3 +195,14 @@ class EnvService: return False except: return False + + @staticmethod + def get_user_key_db_path() -> Union[Path, None]: + try: + user_key_db_path = os.getenv("USER_KEY_DB_PATH") + if user_key_db_path is None: + return None + else: + return Path(user_key_db_path) + except: + return None diff --git a/sample.env b/sample.env index 3bd1ed1..9648ca5 100644 --- a/sample.env +++ b/sample.env @@ -18,4 +18,7 @@ WELCOME_MESSAGE = "Hi There! Welcome to our Discord server. We hope you'll enjoy USER_INPUT_API_KEYS="False" # If True, users must use their own API keys for OpenAI. If False, the bot will use the API key in the .env file. # Moderations Service alert channel, this is where moderation alerts will be sent as a default if enabled -MODERATIONS_ALERT_CHANNEL = "977697652147892304" \ No newline at end of file +MODERATIONS_ALERT_CHANNEL = "977697652147892304" + +# User API key db path configuration. This is where the user API keys will be stored. +USER_KEY_DB_PATH = user_key_db.sqlite \ No newline at end of file From 38b43825115716a1635248d92cfeed9950e0ebaf Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:17:57 +0000 Subject: [PATCH 4/9] Format Python code with psf/black push --- cogs/gpt_3_commands_and_converser.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 3572ef8..1c87f24 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -45,7 +45,9 @@ if USER_INPUT_API_KEYS: USER_KEY_DB_PATH = EnvService.get_user_key_db_path() # Check if USER_KEY_DB_PATH is valid if not USER_KEY_DB_PATH: - print("No user key database path was provided. Defaulting to user_key_db.sqlite") + print( + "No user key database path was provided. Defaulting to user_key_db.sqlite" + ) USER_KEY_DB_PATH = "user_key_db.sqlite" else: # append "user_key_db.sqlite" to USER_KEY_DB_PATH if it doesn't already end with .sqlite From 37f70f35dd0567e3c00eb74a798bdc8e15655f91 Mon Sep 17 00:00:00 2001 From: Kaveen Kumarasinghe Date: Sat, 14 Jan 2023 04:12:03 -0500 Subject: [PATCH 5/9] add space --- cogs/gpt_3_commands_and_converser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 3666f1c..7469716 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -1082,10 +1082,10 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): elif from_edit_command: if codex: response_text = response_text.strip() - response_text = f"***Prompt:{prompt}***\n***Instruction:{instruction}***\n\n```\n{response_text}\n```" + response_text = f"***Prompt: {prompt}***\n***Instruction: {instruction}***\n\n```\n{response_text}\n```" else: response_text = response_text.strip() - response_text = f"***Prompt:{prompt}***\n***Instruction:{instruction}***\n\n{response_text}\n" + response_text = f"***Prompt: {prompt}***\n***Instruction: {instruction}***\n\n{response_text}\n" # If gpt3 tries writing a user mention try to replace it with their name response_text = await self.mention_to_username(ctx, response_text) From d935845f275c4e66213436f5ac05df7be1b92767 Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Sat, 14 Jan 2023 09:25:46 +0000 Subject: [PATCH 6/9] Fixed redouser missing parameters --- cogs/draw_image_generation.py | 2 +- cogs/image_prompt_optimizer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/draw_image_generation.py b/cogs/draw_image_generation.py index d073cbf..5b406a5 100644 --- a/cogs/draw_image_generation.py +++ b/cogs/draw_image_generation.py @@ -177,7 +177,7 @@ class DrawDallEService(discord.Cog, name="DrawDallEService"): ) ) - redo_users[user_id] = RedoUser(prompt, ctx, ctx, result_message) + redo_users[user_id] = RedoUser(prompt=prompt, message=ctx, ctx=ctx, response=response_message, instruction=None, codex=False) self.converser_cog.users_to_interactions[user_id].append( response_message.id diff --git a/cogs/image_prompt_optimizer.py b/cogs/image_prompt_optimizer.py index 33c01a7..5255137 100644 --- a/cogs/image_prompt_optimizer.py +++ b/cogs/image_prompt_optimizer.py @@ -124,7 +124,7 @@ class ImgPromptOptimizer(discord.Cog, name="ImgPromptOptimizer"): ) self.converser_cog.redo_users[user.id] = RedoUser( - final_prompt, ctx, ctx, response_message + prompt=final_prompt, message=ctx, ctx=ctx, response=response_message, instruction=None, codex=False ) self.converser_cog.redo_users[user.id].add_interaction(response_message.id) await response_message.edit( From 08372846343d7818967388a546ad94df703c0fe7 Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Sat, 14 Jan 2023 09:28:47 +0000 Subject: [PATCH 7/9] One more --- cogs/draw_image_generation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/draw_image_generation.py b/cogs/draw_image_generation.py index 5b406a5..e822af7 100644 --- a/cogs/draw_image_generation.py +++ b/cogs/draw_image_generation.py @@ -123,7 +123,7 @@ class DrawDallEService(discord.Cog, name="DrawDallEService"): if from_context: result_message = await ctx.fetch_message(result_message.id) - redo_users[user_id] = RedoUser(prompt, ctx, ctx, result_message) + redo_users[user_id] = RedoUser(prompt=prompt, message=ctx, ctx=ctx, response=response_message, instruction=None, codex=False) else: if not vary: # Editing case From 99bb6200aa554feb092c27faa25700b585142a5c Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 14 Jan 2023 09:36:34 +0000 Subject: [PATCH 8/9] Format Python code with psf/black push --- cogs/draw_image_generation.py | 18 +++++- cogs/gpt_3_commands_and_converser.py | 95 ++++++++++++++++++++-------- cogs/image_prompt_optimizer.py | 7 +- models/openai_model.py | 21 ++++-- 4 files changed, 106 insertions(+), 35 deletions(-) diff --git a/cogs/draw_image_generation.py b/cogs/draw_image_generation.py index e822af7..ef62fb7 100644 --- a/cogs/draw_image_generation.py +++ b/cogs/draw_image_generation.py @@ -123,7 +123,14 @@ class DrawDallEService(discord.Cog, name="DrawDallEService"): if from_context: result_message = await ctx.fetch_message(result_message.id) - redo_users[user_id] = RedoUser(prompt=prompt, message=ctx, ctx=ctx, response=response_message, instruction=None, codex=False) + redo_users[user_id] = RedoUser( + prompt=prompt, + message=ctx, + ctx=ctx, + response=response_message, + instruction=None, + codex=False, + ) else: if not vary: # Editing case @@ -177,7 +184,14 @@ class DrawDallEService(discord.Cog, name="DrawDallEService"): ) ) - redo_users[user_id] = RedoUser(prompt=prompt, message=ctx, ctx=ctx, response=response_message, instruction=None, codex=False) + redo_users[user_id] = RedoUser( + prompt=prompt, + message=ctx, + ctx=ctx, + response=response_message, + instruction=None, + codex=False, + ) self.converser_cog.users_to_interactions[user_id].append( response_message.id diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index b251861..db69848 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -889,14 +889,20 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): edited_request=False, redo_request=False, ): - new_prompt = prompt + "\nGPTie: " if not from_g_command and not from_edit_command else prompt + new_prompt = ( + prompt + "\nGPTie: " + if not from_g_command and not from_edit_command + else prompt + ) from_context = isinstance(ctx, discord.ApplicationContext) if not instruction: - tokens = self.usage_service.count_tokens(new_prompt) - else: - tokens = self.usage_service.count_tokens(new_prompt) + self.usage_service.count_tokens(instruction) + tokens = self.usage_service.count_tokens(new_prompt) + else: + tokens = self.usage_service.count_tokens( + new_prompt + ) + self.usage_service.count_tokens(instruction) try: @@ -1089,9 +1095,9 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): response_text = self.cleanse_response(str(response["choices"][0]["text"])) if from_g_command: - # Append the prompt to the beginning of the response, in italics, then a new line - response_text = response_text.strip() - response_text = f"***{prompt}***\n\n{response_text}" + # Append the prompt to the beginning of the response, in italics, then a new line + response_text = response_text.strip() + response_text = f"***{prompt}***\n\n{response_text}" elif from_edit_command: if codex: response_text = response_text.strip() @@ -1164,21 +1170,34 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): response_message = await ctx.reply( response_text, view=ConversationView( - ctx, self, ctx.channel.id, model, custom_api_key=custom_api_key + ctx, + self, + ctx.channel.id, + model, + custom_api_key=custom_api_key, ), ) elif from_edit_command: response_message = await ctx.respond( response_text, view=ConversationView( - ctx, self, ctx.channel.id, model, from_edit_command, custom_api_key=custom_api_key + ctx, + self, + ctx.channel.id, + model, + from_edit_command, + custom_api_key=custom_api_key, ), ) - else: + else: response_message = await ctx.respond( response_text, view=ConversationView( - ctx, self, ctx.channel.id, model, custom_api_key=custom_api_key + ctx, + self, + ctx.channel.id, + model, + custom_api_key=custom_api_key, ), ) @@ -1190,7 +1209,12 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): ) self.redo_users[ctx.author.id] = RedoUser( - prompt=new_prompt, instruction=instruction, ctx=ctx, message=ctx, response=actual_response_message, codex=codex + prompt=new_prompt, + instruction=instruction, + ctx=ctx, + message=ctx, + response=actual_response_message, + codex=codex, ) self.redo_users[ctx.author.id].add_interaction( actual_response_message.id @@ -1219,7 +1243,9 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): await ctx.send_followup(message) else: await ctx.reply(message) - self.remove_awaiting(ctx.author.id, ctx.channel.id, from_g_command, from_edit_command) + self.remove_awaiting( + ctx.author.id, ctx.channel.id, from_g_command, from_edit_command + ) # Error catching for OpenAI model value errors except ValueError as e: @@ -1227,7 +1253,9 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): await ctx.send_followup(e) else: await ctx.reply(e) - self.remove_awaiting(ctx.author.id, ctx.channel.id, from_g_command, from_edit_command) + self.remove_awaiting( + ctx.author.id, ctx.channel.id, from_g_command, from_edit_command + ) # General catch case for everything except Exception: @@ -1236,7 +1264,9 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): await ctx.send_followup(message) if from_context else await ctx.reply( message ) - self.remove_awaiting(ctx.author.id, ctx.channel.id, from_g_command, from_edit_command) + self.remove_awaiting( + ctx.author.id, ctx.channel.id, from_g_command, from_edit_command + ) traceback.print_exc() try: @@ -1318,6 +1348,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): from_g_command=True, custom_api_key=user_api_key, ) + @add_to_group("gpt") @discord.slash_command( name="edit", @@ -1325,10 +1356,15 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): guild_ids=ALLOWED_GUILDS, ) @discord.option( - name="instruction", description="How you want GPT3 to edit the text", required=True + name="instruction", + description="How you want GPT3 to edit the text", + required=True, ) @discord.option( - name="input", description="The text you want to edit, can be empty", required=False, default="" + name="input", + description="The text you want to edit, can be empty", + required=False, + default="", ) @discord.option( name="temperature", @@ -1347,10 +1383,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): max_value=1, ) @discord.option( - name="codex", - description="Enable codex version", - required=False, - default=False + name="codex", description="Enable codex version", required=False, default=False ) @discord.guild_only() async def edit( @@ -1367,7 +1400,6 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): input = await self.mention_to_username(ctx, input.strip()) instruction = await self.mention_to_username(ctx, instruction.strip()) - user_api_key = None if USER_INPUT_API_KEYS: user_api_key = await GPT3ComCon.get_user_api_key(user.id, ctx) @@ -1795,7 +1827,15 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): class ConversationView(discord.ui.View): - def __init__(self, ctx, converser_cog, id, model, from_edit_command=False, custom_api_key=None): + def __init__( + self, + ctx, + converser_cog, + id, + model, + from_edit_command=False, + custom_api_key=None, + ): super().__init__(timeout=3600) # 1 hour interval to redo. self.converser_cog = converser_cog self.ctx = ctx @@ -1803,7 +1843,12 @@ class ConversationView(discord.ui.View): self.from_edit_command = from_edit_command self.custom_api_key = custom_api_key self.add_item( - RedoButton(self.converser_cog, model, from_edit_command, custom_api_key=self.custom_api_key) + RedoButton( + self.converser_cog, + model, + from_edit_command, + custom_api_key=self.custom_api_key, + ) ) if id in self.converser_cog.conversation_threads: @@ -1890,7 +1935,7 @@ class RedoButton(discord.ui.Button["ConversationView"]): codex=codex, custom_api_key=self.custom_api_key, redo_request=True, - from_edit_command=self.from_edit_command + from_edit_command=self.from_edit_command, ) else: await interaction.response.send_message( diff --git a/cogs/image_prompt_optimizer.py b/cogs/image_prompt_optimizer.py index 5255137..37e9019 100644 --- a/cogs/image_prompt_optimizer.py +++ b/cogs/image_prompt_optimizer.py @@ -124,7 +124,12 @@ class ImgPromptOptimizer(discord.Cog, name="ImgPromptOptimizer"): ) self.converser_cog.redo_users[user.id] = RedoUser( - prompt=final_prompt, message=ctx, ctx=ctx, response=response_message, instruction=None, codex=False + prompt=final_prompt, + message=ctx, + ctx=ctx, + response=response_message, + instruction=None, + codex=False, ) self.converser_cog.redo_users[user.id].add_interaction(response_message.id) await response_message.edit( diff --git a/models/openai_model.py b/models/openai_model.py index e850be0..59b1d9d 100644 --- a/models/openai_model.py +++ b/models/openai_model.py @@ -399,28 +399,35 @@ class Model: max_tries=6, on_backoff=backoff_handler, ) - async def send_edit_request(self, instruction, input=None, temp_override=None, top_p_override=None, codex=False, custom_api_key=None): - + async def send_edit_request( + self, + instruction, + input=None, + temp_override=None, + top_p_override=None, + codex=False, + custom_api_key=None, + ): + # Validate that all the parameters are in a good state before we send the request if len(instruction) < self.prompt_min_length: raise ValueError( "Instruction must be greater than 8 characters, it is currently " + str(len(instruction)) ) - - print(f"The text about to be edited is [{input}] with instructions [{instruction}] codex [{codex}]") print( - f"Overrides -> temp:{temp_override}, top_p:{top_p_override}" + f"The text about to be edited is [{input}] with instructions [{instruction}] codex [{codex}]" ) - + print(f"Overrides -> temp:{temp_override}, top_p:{top_p_override}") + async with aiohttp.ClientSession(raise_for_status=True) as session: payload = { "model": Models.EDIT if codex is False else Models.CODE_EDIT, "input": "" if input is None else input, "instruction": instruction, "temperature": self.temp if temp_override is None else temp_override, - "top_p": self.top_p if top_p_override is None else top_p_override + "top_p": self.top_p if top_p_override is None else top_p_override, } headers = { "Content-Type": "application/json", From 30172f8d3fa7391d538b724bc53bfed2cd50ca7e Mon Sep 17 00:00:00 2001 From: Kaveen Kumarasinghe Date: Sat, 14 Jan 2023 04:40:38 -0500 Subject: [PATCH 9/9] update readme, bump version --- README.md | 14 ++++++-------- gpt3discord.py | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9abef40..53e2e6f 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ SUPPORT SERVER FOR BOT SETUP: https://discord.gg/WvAHXDMS7Q (You can NOT use the

# Recent Notable Updates +- **Edit Requests** - Ask GPT to edit a piece of text with a given instruction using a specific OpenAI edits model! `/gpt edit`! + + - **Automatic retry on API errors** - The bot will automatically retry API requests if they fail due to some issue with OpenAI's APIs, this is becoming increasingly important now as their APIs become under heavy load. @@ -32,9 +35,6 @@ SUPPORT SERVER FOR BOT SETUP: https://discord.gg/WvAHXDMS7Q (You can NOT use the - **Permanent memory with embeddings and PineconeDB finished!** - An initial alpha version of permanent memory is now done! This allows you to chat with GPT3 infinitely and accurately, and save tokens, by using embeddings. *Please read the Permanent Memory section for more information!* -- **Multi-user, group chats with GPT3** - Multiple users can converse with GPT3 in a chat now, and it will know that there are multiple distinct users chatting with it! - - - **AI-BASED SERVER MODERATION** - GPT3Discord now has a built-in AI-based moderation system that can automatically detect and remove toxic messages from your server. This is a great way to keep your server safe and clean, and it's completely automatic and **free**! Check out the commands section to learn how to enable it! @@ -47,6 +47,8 @@ SUPPORT SERVER FOR BOT SETUP: https://discord.gg/WvAHXDMS7Q (You can NOT use the - **DALL-E Image Prompt Optimization** - Given some text that you're trying to generate an image for, the bot will automatically optimize the text to be more DALL-E friendly! `/dalle optimize ` +- **Edit Requests** - Ask GPT to edit a piece of text or code with a given instruction. `/gpt edit ` + - **Redo Requests** - A simple button after the GPT3 response or DALL-E generation allows you to redo the initial prompt you asked. You can also redo conversation messages by just editing your message! - **Automatic AI-Based Server Moderation** - Moderate your server automatically with AI! @@ -182,9 +184,7 @@ USER_INPUT_API_KEYS="True" Then, restart the bot, and it will set up the system for everyone to input their own API keys. -The bot will use SQLite to store API keys for the users, each user's key will be saved with a USER_ID <> API_KEY mapping in SQLite, and will be persistent across restarts. All the data will be saved in a file called `user_key_db.sqlite` in the current working directory of the bot (by default). - -You can configure the location of the sqlite database by changing the `USER_KEY_DB_PATH` variable in your `.env` file (check the `sample.env` file for reference). +The bot will use SQLite to store API keys for the users, each user's key will be saved with a USER_ID <> API_KEY mapping in SQLite, and will be persistent across restarts. All the data will be saved in a file called `user_key_db.sqlite` in the current working directory of the bot. With this feature enabled, any attempt to use a GPT3 or DALL-E command without a valid API key set for the user will pop up the following modal for them to enter their API key: @@ -245,8 +245,6 @@ GPT_ROLES="openai,gpt" WELCOME_MESSAGE="Hi There! Welcome to our Discord server. We hope you'll enjoy our server and we look forward to engaging with you!" # This is a fallback message if gpt3 fails to generate a welcome message. # This is the channel that auto-moderation alerts will be sent to MODERATIONS_ALERT_CHANNEL="977697652147892304" -# User API key db path configuration. This is where the user API keys will be stored. -USER_KEY_DB_PATH = user_key_db.sqlite ``` **Permissions** diff --git a/gpt3discord.py b/gpt3discord.py index 1c24b6e..317e54b 100644 --- a/gpt3discord.py +++ b/gpt3discord.py @@ -24,7 +24,7 @@ from models.openai_model import Model from models.usage_service_model import UsageService from models.env_service_model import EnvService -__version__ = "5.4.1" +__version__ = "6.0" """ The pinecone service is used to store and retrieve conversation embeddings.