From 02d9f1e3cf55b636da9759ed58d01850d126aeac Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 28 Oct 2023 10:15:45 +0000 Subject: [PATCH] Format Python code with psf/black push --- cogs/code_interpreter_service_cog.py | 116 ++++++++++++++++++--------- cogs/commands.py | 10 +-- cogs/search_service_cog.py | 81 ++++++++++--------- gpt3discord.py | 1 - 4 files changed, 125 insertions(+), 83 deletions(-) diff --git a/cogs/code_interpreter_service_cog.py b/cogs/code_interpreter_service_cog.py index e6f90124..fb8427bd 100644 --- a/cogs/code_interpreter_service_cog.py +++ b/cogs/code_interpreter_service_cog.py @@ -107,12 +107,12 @@ class CodeInterpreterService(discord.Cog, name="CodeInterpreterService"): """Cog containing translation commands and retrieval of translation services""" def __init__( - self, - bot, - gpt_model, - usage_service, - deletion_service, - converser_cog, + self, + bot, + gpt_model, + usage_service, + deletion_service, + converser_cog, ): super().__init__() self.bot = bot @@ -131,7 +131,7 @@ async def paginate_chat_embed(self, response_text): """Given a response text make embed pages and return a list of the pages.""" response_text = [ - response_text[i: i + 3500] for i in range(0, len(response_text), 7000) + response_text[i : i + 3500] for i in range(0, len(response_text), 7000) ] pages = [] first = False @@ -194,7 +194,10 @@ async def on_message(self, message): # If the message channel is in self.chat_agents, then we delegate the message to the agent. if message.channel.id in self.chat_agents: if prompt.lower() in ["stop", "end", "quit", "exit"]: - await message.reply("Ending chat session. You can access the sandbox of this session at https://"+self.sessions[message.channel.id].get_hostname()) + await message.reply( + "Ending chat session. You can access the sandbox of this session at https://" + + self.sessions[message.channel.id].get_hostname() + ) self.sessions[message.channel.id].close() self.chat_agents.pop(message.channel.id) @@ -237,13 +240,15 @@ async def on_message(self, message): # Determine if we have artifacts in the response artifacts_available = "Artifacts: []" not in stdout_output - # Parse the artifact names. After Artifacts: there should be a list in form [] where the artifact names are inside, comma separated inside stdout_output artifact_names = re.findall(r"Artifacts: \[(.*?)\]", stdout_output) # The artifacts list may be formatted like ["'/home/user/artifacts/test2.txt', '/home/user/artifacts/test.txt'"], where its technically 1 element in the list, so we need to split it by comma and then remove the quotes and spaces if len(artifact_names) > 0: artifact_names = artifact_names[0].split(",") - artifact_names = [artifact_name.strip().replace("'", "") for artifact_name in artifact_names] + artifact_names = [ + artifact_name.strip().replace("'", "") + for artifact_name in artifact_names + ] if len(response) > 2000: embed_pages = await self.paginate_chat_embed(response) @@ -251,16 +256,20 @@ async def on_message(self, message): pages=embed_pages, timeout=None, author_check=False, - custom_view=CodeInterpreterDownloadArtifactsView(message, self, self.sessions[message.channel.id], artifact_names) if artifacts_available else None, + custom_view=CodeInterpreterDownloadArtifactsView( + message, self, self.sessions[message.channel.id], artifact_names + ) + if artifacts_available + else None, ) try: await paginator.respond(message) except: response = [ - response[i: i + 1900] for i in range(0, len(response), 1900) + response[i : i + 1900] for i in range(0, len(response), 1900) ] for count, chunk in enumerate(response, start=1): - await message.channel.send(chunk) + await message.channel.send(chunk) else: response = response.replace("\\n", "\n") @@ -270,13 +279,18 @@ async def on_message(self, message): description=response, color=0x808080, ) - await message.reply(embed=response_embed, view=CodeInterpreterDownloadArtifactsView(message, self, self.sessions[message.channel.id], artifact_names) if artifacts_available else None) - + await message.reply( + embed=response_embed, + view=CodeInterpreterDownloadArtifactsView( + message, self, self.sessions[message.channel.id], artifact_names + ) + if artifacts_available + else None, + ) self.thread_awaiting_responses.remove(message.channel.id) class SessionedCodeExecutor: - def __init__(self): try: self.session = DataAnalysis(api_key=E2B_API_KEY) @@ -299,7 +313,14 @@ async def execute_code_async(self, code: str): if len(stdout) > 12000: stdout = stdout[:12000] - return "STDOUT: "+stdout +"\nSTDERR: "+stderr+ "\nArtifacts: " + str([artifact.name for artifact in artifacts]) + return ( + "STDOUT: " + + stdout + + "\nSTDERR: " + + stderr + + "\nArtifacts: " + + str([artifact.name for artifact in artifacts]) + ) def close(self): self.session.close() @@ -320,13 +341,15 @@ def is_sessioned(self): return self.sessioned async def code_interpreter_chat_command( - self, ctx: discord.ApplicationContext, model, + self, + ctx: discord.ApplicationContext, + model, ): embed_title = f"{ctx.user.name}'s code interpreter conversation with GPT" message_embed = discord.Embed( title=embed_title, description=f"The agent is able to execute Python code and manipulate its environment.\nModel: {model}\n\nType `end` to stop the conversation", - color=0xf82c45, + color=0xF82C45, ) message_embed.set_thumbnail(url="https://i.imgur.com/qua6Bya.png") message_embed.set_footer( @@ -342,7 +365,9 @@ async def code_interpreter_chat_command( self.sessions[thread.id] = self.SessionedCodeExecutor() if not self.sessions[thread.id].is_sessioned(): - await thread.send("Failed to start code interpreter session. This may be an issue with E2B. Please try again later.") + await thread.send( + "Failed to start code interpreter session. This may be an issue with E2B. Please try again later." + ) await thread.edit(name="Closed-GPT (Error)") await thread.edit(archived=True) return @@ -357,12 +382,12 @@ async def code_interpreter_chat_command( Tool( name="Install-python-package-tool", func=self.sessions[thread.id].install_python_package, - description=f"This tool installs a python package into the execution environment. The input to the tool is a single python package name (e.g 'numpy'). If you need to install multiple python packages, call this tool multiple times." + description=f"This tool installs a python package into the execution environment. The input to the tool is a single python package name (e.g 'numpy'). If you need to install multiple python packages, call this tool multiple times.", ), Tool( name="Install-system-package-tool", func=self.sessions[thread.id].install_python_package, - description=f"This tool installs a system package into the system environment. The input to the tool is a single package name (e.g 'htop'). If you need to install multiple system packages, call this tool multiple times." + description=f"This tool installs a system package into the system environment. The input to the tool is a single package name (e.g 'htop'). If you need to install multiple system packages, call this tool multiple times.", ), ] @@ -372,10 +397,11 @@ async def code_interpreter_chat_command( "extra_prompt_messages": [MessagesPlaceholder(variable_name="memory")], "system_message": SystemMessage( content="You are an expert programmer that is able to use the tools to your advantage to execute " - "python code. Help the user iterate on their code and test it through execution. Always " - "respond in the specified JSON format. Always provide the full code output when asked for " - "when you execute code. Ensure that all your code is formatted with backticks followed by the " - "markdown identifier of the language that the code is in. For example ```python3 {code} ```. When asked to write code that saves files, always prefix the file with the artifacts/ folder. For example, if asked to create test.txt, in the function call you make to whatever library that creates the file, you would use artifacts/test.txt. Always show the output of code execution explicitly and separately at the end of the rest of your output. You are also able to install system and python packages using your tools. However, the tools can only install one package at a time, if you need to install multiple packages, call the tools multiple times. Always first display your code to the user BEFORE you execute it using your tools. The user should always explicitly ask you to execute code.") + "python code. Help the user iterate on their code and test it through execution. Always " + "respond in the specified JSON format. Always provide the full code output when asked for " + "when you execute code. Ensure that all your code is formatted with backticks followed by the " + "markdown identifier of the language that the code is in. For example ```python3 {code} ```. When asked to write code that saves files, always prefix the file with the artifacts/ folder. For example, if asked to create test.txt, in the function call you make to whatever library that creates the file, you would use artifacts/test.txt. Always show the output of code execution explicitly and separately at the end of the rest of your output. You are also able to install system and python packages using your tools. However, the tools can only install one package at a time, if you need to install multiple packages, call the tools multiple times. Always first display your code to the user BEFORE you execute it using your tools. The user should always explicitly ask you to execute code." + ), } llm = ChatOpenAI(model=model, temperature=0, openai_api_key=OPENAI_API_KEY) @@ -391,20 +417,25 @@ async def code_interpreter_chat_command( self.chat_agents[thread.id] = agent_chain + class CodeInterpreterDownloadArtifactsView(discord.ui.View): def __init__( - self, - ctx, - code_interpreter_cog, - session, - artifact_names, + self, + ctx, + code_interpreter_cog, + session, + artifact_names, ): super().__init__(timeout=None) # No timeout self.code_interpreter_cog = code_interpreter_cog self.ctx = ctx self.session = session self.artifact_names = artifact_names - self.add_item(DownloadButton(self.ctx, self.code_interpreter_cog, self.session, self.artifact_names)) + self.add_item( + DownloadButton( + self.ctx, self.code_interpreter_cog, self.session, self.artifact_names + ) + ) # A view for a follow-up button @@ -418,10 +449,18 @@ def __init__(self, ctx, code_interpreter_cog, session, artifact_names): async def callback(self, interaction: discord.Interaction): """Send the followup modal""" - await interaction.response.send_message("Downloading the artifacts: " + str(self.artifact_names) +". This may take a while.", ephemeral=True, delete_after=120) + await interaction.response.send_message( + "Downloading the artifacts: " + + str(self.artifact_names) + + ". This may take a while.", + ephemeral=True, + delete_after=120, + ) for artifact in self.artifact_names: try: - runner = functools.partial(self.session.download_file, filepath=artifact) + runner = functools.partial( + self.session.download_file, filepath=artifact + ) bytes = await asyncio.get_running_loop().run_in_executor(None, runner) # Save these bytes into a tempfile @@ -429,9 +468,12 @@ async def callback(self, interaction: discord.Interaction): temp.write(bytes) temp.flush() temp.seek(0) - await self.ctx.channel.send(file=discord.File(temp.name, filename=artifact)) + await self.ctx.channel.send( + file=discord.File(temp.name, filename=artifact) + ) os.unlink(temp.name) except: traceback.print_exc() - await self.ctx.channel.send("Failed to download artifact: " + artifact, delete_after=120) - + await self.ctx.channel.send( + "Failed to download artifact: " + artifact, delete_after=120 + ) diff --git a/cogs/commands.py b/cogs/commands.py index 010415c1..47456808 100644 --- a/cogs/commands.py +++ b/cogs/commands.py @@ -95,7 +95,9 @@ def __init__( name="code", description="Code interpreter functionalities", guild_ids=ALLOWED_GUILDS, - checks=[Check.check_index_roles()], # TODO new role checker for code interpreter + checks=[ + Check.check_index_roles() + ], # TODO new role checker for code interpreter ) # @@ -1029,10 +1031,10 @@ async def ask_gpt_action(self, ctx, message: discord.Message): async def draw_action(self, ctx, message: discord.Message): await self.image_draw_cog.draw_action(ctx, message) - """ Code interpreter commands and actions """ + @add_to_group("code") @discord.slash_command( name="chat", @@ -1057,9 +1059,7 @@ async def chat_code( "Code interpretation is disabled on this server.", ephemeral=True ) return - await self.code_interpreter_cog.code_interpreter_chat_command( - ctx, model=model - ) + await self.code_interpreter_cog.code_interpreter_chat_command(ctx, model=model) """ Translation commands and actions diff --git a/cogs/search_service_cog.py b/cogs/search_service_cog.py index 51bdfed6..428e73ff 100644 --- a/cogs/search_service_cog.py +++ b/cogs/search_service_cog.py @@ -208,10 +208,10 @@ def get(self, url: str, **kwargs: Any) -> str: if len(text) < 5: return "This website could not be scraped. I cannot answer this question." if ( - model in Models.CHATGPT_MODELS - and tokens > Models.get_max_tokens(model) - 1000 + model in Models.CHATGPT_MODELS + and tokens > Models.get_max_tokens(model) - 1000 ) or ( - model in Models.GPT4_MODELS and tokens > Models.get_max_tokens(model) - 1000 + model in Models.GPT4_MODELS and tokens > Models.get_max_tokens(model) - 1000 ): with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write(text) @@ -244,12 +244,12 @@ class SearchService(discord.Cog, name="SearchService"): """Cog containing translation commands and retrieval of translation services""" def __init__( - self, - bot, - gpt_model, - usage_service, - deletion_service, - converser_cog, + self, + bot, + gpt_model, + usage_service, + deletion_service, + converser_cog, ): super().__init__() self.bot = bot @@ -263,12 +263,12 @@ def __init__( # Make a mapping of all the country codes and their full country names: async def paginate_embed( - self, response_text, user: discord.Member, original_link=None + self, response_text, user: discord.Member, original_link=None ): """Given a response text make embed pages and return a list of the pages.""" response_text = [ - response_text[i: i + self.EMBED_CUTOFF] + response_text[i : i + self.EMBED_CUTOFF] for i in range(0, len(response_text), self.EMBED_CUTOFF) ] pages = [] @@ -306,7 +306,7 @@ async def paginate_chat_embed(self, response_text): """Given a response text make embed pages and return a list of the pages.""" response_text = [ - response_text[i: i + 3500] for i in range(0, len(response_text), 7000) + response_text[i : i + 3500] for i in range(0, len(response_text), 7000) ] pages = [] first = False @@ -441,7 +441,7 @@ async def on_message(self, message): self.thread_awaiting_responses.remove(message.channel.id) async def search_chat_command( - self, ctx: discord.ApplicationContext, model, search_scope=2 + self, ctx: discord.ApplicationContext, model, search_scope=2 ): embed_title = f"{ctx.user.name}'s internet-connected conversation with GPT" message_embed = discord.Embed( @@ -504,7 +504,8 @@ async def search_chat_command( agent_kwargs = { "extra_prompt_messages": [MessagesPlaceholder(variable_name="memory")], "system_message": SystemMessage( - content="You are a superpowered version of GPT-4 that is able to access the internet. You can use google search to browse the web, you can crawl the web to see the content of specific websites, and in some cases you can also use Wolfram Alpha to perform mathematical operations. Use all of these tools to your advantage.") + content="You are a superpowered version of GPT-4 that is able to access the internet. You can use google search to browse the web, you can crawl the web to see the content of specific websites, and in some cases you can also use Wolfram Alpha to perform mathematical operations. Use all of these tools to your advantage." + ), } llm = ChatOpenAI(model=model, temperature=0, openai_api_key=OPENAI_API_KEY) @@ -521,18 +522,18 @@ async def search_chat_command( self.chat_agents[thread.id] = agent_chain async def search_command( - self, - ctx: discord.ApplicationContext, - query, - search_scope, - nodes, - deep, - response_mode, - model, - multistep=False, - redo=None, - from_followup=None, - followup_user=None, + self, + ctx: discord.ApplicationContext, + query, + search_scope, + nodes, + deep, + response_mode, + model, + multistep=False, + redo=None, + from_followup=None, + followup_user=None, ): """Command handler for the search command""" await ctx.defer() if not redo else None @@ -551,8 +552,8 @@ async def search_command( return if ( - not EnvService.get_google_search_api_key() - or not EnvService.get_google_search_engine_id() + not EnvService.get_google_search_api_key() + or not EnvService.get_google_search_engine_id() ): await ctx.respond( embed=EmbedStatics.get_search_failure_embed( @@ -639,10 +640,10 @@ async def search_command( class SearchView(discord.ui.View): def __init__( - self, - ctx, - search_cog, - response_text, + self, + ctx, + search_cog, + response_text, ): super().__init__(timeout=None) # No timeout self.search_cog = search_cog @@ -729,14 +730,14 @@ async def callback(self, interaction: discord.Interaction): # Build the context context_text = ( - "Original question: " - + query - + "\n" - + "Answer to original: " - + self.response_text - + "\n" - + "Follow-up question: " - + self.children[0].value + "Original question: " + + query + + "\n" + + "Answer to original: " + + self.response_text + + "\n" + + "Follow-up question: " + + self.children[0].value ) # Get the link of the message that the user interacted on diff --git a/gpt3discord.py b/gpt3discord.py index 131260b8..a5a4e00b 100644 --- a/gpt3discord.py +++ b/gpt3discord.py @@ -202,7 +202,6 @@ async def main(): ) print("The Code Interpreter service is enabled.") - bot.add_cog( TranscribeService( bot,