From 74c20eb387cff3a8aefd464cd2e89570345e565d Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:05:18 +0530 Subject: [PATCH 01/13] Add `/chatgpt` command to let users communicate with ChatGPT --- cogs/utils.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cogs/utils.py b/cogs/utils.py index f17d83f5..3869cda0 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -8,12 +8,14 @@ import framework.isobot.embedengine from discord import option, ApplicationContext from discord.ext import commands +from chatgpt import ChatGPT from cogs.economy import get_wallet, get_bank, get_user_networth, get_user_count from cogs.levelling import get_level, get_xp from cogs.afk import get_presence # Variables color = discord.Color.random() +openai = ChatGPT() # Commands class Utils(commands.Cog): @@ -117,6 +119,18 @@ async def status(self, ctx: ApplicationContext): localembed.add_field(name="Release Notes", value="[latest](https://github.com/PyBotDevs/isobot/releases/latest)") localembed.set_footer(text=f"Requested by {ctx.author.name}", icon_url=ctx.author.avatar_url) await ctx.respond(embed=localembed) + + @commands.slash_command( + name="chatgpt", + description="Talk to ChatGPT and get a response back." + ) + @option(name="message", description="What do you want to send to ChatGPT?", type=str) + async def chatgpt(ctx: ApplicationContext, message: str): + response = openai.generate_response(message) + localembed = discord.Embed(description=f"```\n{response}\n```", color=discord.Color.random()) + localembed.set_author(name="ChatGPT", icon_url="https://static.vecteezy.com/system/resources/previews/021/608/790/original/chatgpt-logo-chat-gpt-icon-on-black-background-free-vector.jpg") + localembed.set_footer(text="Powered by OpenAI") + await ctx.respond(embed=localembed) # Cog Initialization def setup(bot): bot.add_cog(Utils(bot)) From 0a98f07443c3ca98ddf35f9e7d0440c844dfb162 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:07:22 +0530 Subject: [PATCH 02/13] Add `/chatgpt` command to commands db --- config/commands.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/commands.json b/config/commands.json index ce87ffb2..ee50592c 100644 --- a/config/commands.json +++ b/config/commands.json @@ -688,5 +688,15 @@ "usable_by": "everyone", "disabled": false, "bugged": false + }, + "chatgpt": { + "name": "ChatGPT", + "description": "Talk to ChatGPT and get a response back.", + "type": "general utilities", + "cooldown": 1, + "args": ["message"], + "usable_by": "everyone", + "disabled": false, + "bugged": false } } From 9f21764c6a7373b931dbc6ce8cd2fe30f7df08fe Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:08:45 +0530 Subject: [PATCH 03/13] Add 1 second cooldown to `/chatgpt` This is implemented to prevent ratelimit errors with the OpenAI API. --- cogs/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/utils.py b/cogs/utils.py index 3869cda0..04f187bd 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -125,6 +125,7 @@ async def status(self, ctx: ApplicationContext): description="Talk to ChatGPT and get a response back." ) @option(name="message", description="What do you want to send to ChatGPT?", type=str) + @commands.cooldown(1, 1, commands.BucketType.user) async def chatgpt(ctx: ApplicationContext, message: str): response = openai.generate_response(message) localembed = discord.Embed(description=f"```\n{response}\n```", color=discord.Color.random()) From 3671c95a2152e23b3e4fcc33d49764c92b905a52 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:29:47 +0530 Subject: [PATCH 04/13] Change ChatGPT library from `chatgpt` to `openai` Turns out that the `chatgpt` library is completely outdated, so I have to use the `openai` library as an alternative. Seems legit. --- cogs/utils.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cogs/utils.py b/cogs/utils.py index 04f187bd..aa45b1f2 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -5,17 +5,18 @@ import os import psutil import math +import openai import framework.isobot.embedengine from discord import option, ApplicationContext from discord.ext import commands -from chatgpt import ChatGPT from cogs.economy import get_wallet, get_bank, get_user_networth, get_user_count from cogs.levelling import get_level, get_xp from cogs.afk import get_presence # Variables color = discord.Color.random() -openai = ChatGPT() +openai.api_key = os.getenv("chatgpt_API_KEY") +chatgpt_conversation = [{"role": "system", "content": "You are a intelligent assistant."}] # Commands class Utils(commands.Cog): @@ -127,8 +128,11 @@ async def status(self, ctx: ApplicationContext): @option(name="message", description="What do you want to send to ChatGPT?", type=str) @commands.cooldown(1, 1, commands.BucketType.user) async def chatgpt(ctx: ApplicationContext, message: str): - response = openai.generate_response(message) - localembed = discord.Embed(description=f"```\n{response}\n```", color=discord.Color.random()) + chatgpt_conversation.append({"role": "user", "content": message}) + _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation) + _reply = _chat.choices[0].message.content + chatgpt_conversation.append({"role": "assistant", "content": reply}) + localembed = discord.Embed(description=f"```\n{_reply}\n```", color=discord.Color.random()) localembed.set_author(name="ChatGPT", icon_url="https://static.vecteezy.com/system/resources/previews/021/608/790/original/chatgpt-logo-chat-gpt-icon-on-black-background-free-vector.jpg") localembed.set_footer(text="Powered by OpenAI") await ctx.respond(embed=localembed) From ef770bcf9b7382a7421846846683672853ae1e59 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:36:05 +0530 Subject: [PATCH 05/13] Add missing `self` keyword in `chatgpt()` --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index aa45b1f2..22192b2a 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -127,7 +127,7 @@ async def status(self, ctx: ApplicationContext): ) @option(name="message", description="What do you want to send to ChatGPT?", type=str) @commands.cooldown(1, 1, commands.BucketType.user) - async def chatgpt(ctx: ApplicationContext, message: str): + async def chatgpt(self, ctx: ApplicationContext, message: str): chatgpt_conversation.append({"role": "user", "content": message}) _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation) _reply = _chat.choices[0].message.content From 36dacde611499f9f6936edae3b736768e170f392 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:37:50 +0530 Subject: [PATCH 06/13] Fix typo in `_reply` variable --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index 22192b2a..a522ae27 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -131,7 +131,7 @@ async def chatgpt(self, ctx: ApplicationContext, message: str): chatgpt_conversation.append({"role": "user", "content": message}) _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation) _reply = _chat.choices[0].message.content - chatgpt_conversation.append({"role": "assistant", "content": reply}) + chatgpt_conversation.append({"role": "assistant", "content": _reply}) localembed = discord.Embed(description=f"```\n{_reply}\n```", color=discord.Color.random()) localembed.set_author(name="ChatGPT", icon_url="https://static.vecteezy.com/system/resources/previews/021/608/790/original/chatgpt-logo-chat-gpt-icon-on-black-background-free-vector.jpg") localembed.set_footer(text="Powered by OpenAI") From a003dec27012e3ff8913a9184da1a015f40fccd8 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:42:23 +0530 Subject: [PATCH 07/13] Fix messed-up markdown in ChatGPT response embed --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index a522ae27..e057cdd0 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -132,7 +132,7 @@ async def chatgpt(self, ctx: ApplicationContext, message: str): _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation) _reply = _chat.choices[0].message.content chatgpt_conversation.append({"role": "assistant", "content": _reply}) - localembed = discord.Embed(description=f"```\n{_reply}\n```", color=discord.Color.random()) + localembed = discord.Embed(description=f"{_reply}", color=discord.Color.random()) localembed.set_author(name="ChatGPT", icon_url="https://static.vecteezy.com/system/resources/previews/021/608/790/original/chatgpt-logo-chat-gpt-icon-on-black-background-free-vector.jpg") localembed.set_footer(text="Powered by OpenAI") await ctx.respond(embed=localembed) From ac09b1c09356cfa4a898c406d2e281acd205d627 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 13:43:27 +0530 Subject: [PATCH 08/13] Trigger response `defer()` while processing a ChatGPT response --- cogs/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/utils.py b/cogs/utils.py index e057cdd0..41c75d29 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -128,6 +128,7 @@ async def status(self, ctx: ApplicationContext): @option(name="message", description="What do you want to send to ChatGPT?", type=str) @commands.cooldown(1, 1, commands.BucketType.user) async def chatgpt(self, ctx: ApplicationContext, message: str): + await ctx.defer() chatgpt_conversation.append({"role": "user", "content": message}) _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation) _reply = _chat.choices[0].message.content From cb8aec66486831601fc359ba7e0aebfc68397a57 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 15:10:25 +0530 Subject: [PATCH 09/13] Link conversations to user ids instead of linking globally --- cogs/utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cogs/utils.py b/cogs/utils.py index 41c75d29..89d89073 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -16,7 +16,7 @@ # Variables color = discord.Color.random() openai.api_key = os.getenv("chatgpt_API_KEY") -chatgpt_conversation = [{"role": "system", "content": "You are a intelligent assistant."}] +chatgpt_conversation = list() # Commands class Utils(commands.Cog): @@ -128,11 +128,12 @@ async def status(self, ctx: ApplicationContext): @option(name="message", description="What do you want to send to ChatGPT?", type=str) @commands.cooldown(1, 1, commands.BucketType.user) async def chatgpt(self, ctx: ApplicationContext, message: str): + if str(ctx.author.id) not in chatgpt_conversation: chatgpt_conversation[str(ctx.author.id)] = [{"role": "system", "content": "You are a intelligent assistant."}] await ctx.defer() - chatgpt_conversation.append({"role": "user", "content": message}) - _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation) + chatgpt_conversation[str(ctx.author.id)].append({"role": "user", "content": message}) + _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation[str(ctx.author.id)]) _reply = _chat.choices[0].message.content - chatgpt_conversation.append({"role": "assistant", "content": _reply}) + chatgpt_conversation[str(ctx.author.id)].append({"role": "assistant", "content": _reply}) localembed = discord.Embed(description=f"{_reply}", color=discord.Color.random()) localembed.set_author(name="ChatGPT", icon_url="https://static.vecteezy.com/system/resources/previews/021/608/790/original/chatgpt-logo-chat-gpt-icon-on-black-background-free-vector.jpg") localembed.set_footer(text="Powered by OpenAI") From 00eb54ce0bf1955b17008842c6fffbf23ef794b4 Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 15:15:48 +0530 Subject: [PATCH 10/13] Fix type error while defining `chatgpt_conversation` --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index 89d89073..a9913308 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -16,7 +16,7 @@ # Variables color = discord.Color.random() openai.api_key = os.getenv("chatgpt_API_KEY") -chatgpt_conversation = list() +chatgpt_conversation = dict() # Commands class Utils(commands.Cog): From 06436d9a3c427e93adbdb2e9ef03bccd2f10e84d Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 15:33:48 +0530 Subject: [PATCH 11/13] Replace ChatGPT author embed icon url because previous url was broken --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index a9913308..79a540d5 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -135,7 +135,7 @@ async def chatgpt(self, ctx: ApplicationContext, message: str): _reply = _chat.choices[0].message.content chatgpt_conversation[str(ctx.author.id)].append({"role": "assistant", "content": _reply}) localembed = discord.Embed(description=f"{_reply}", color=discord.Color.random()) - localembed.set_author(name="ChatGPT", icon_url="https://static.vecteezy.com/system/resources/previews/021/608/790/original/chatgpt-logo-chat-gpt-icon-on-black-background-free-vector.jpg") + localembed.set_author(name="ChatGPT", icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/ChatGPT_logo.svg/1200px-ChatGPT_logo.svg.png") localembed.set_footer(text="Powered by OpenAI") await ctx.respond(embed=localembed) From 605aa4f07d798f7f5464d3c4fdc0560b85dc035d Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 16:04:36 +0530 Subject: [PATCH 12/13] Add OpenAI error handling for `/chatgpt` command --- cogs/utils.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cogs/utils.py b/cogs/utils.py index 79a540d5..317b27bd 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -130,10 +130,15 @@ async def status(self, ctx: ApplicationContext): async def chatgpt(self, ctx: ApplicationContext, message: str): if str(ctx.author.id) not in chatgpt_conversation: chatgpt_conversation[str(ctx.author.id)] = [{"role": "system", "content": "You are a intelligent assistant."}] await ctx.defer() - chatgpt_conversation[str(ctx.author.id)].append({"role": "user", "content": message}) - _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation[str(ctx.author.id)]) - _reply = _chat.choices[0].message.content - chatgpt_conversation[str(ctx.author.id)].append({"role": "assistant", "content": _reply}) + try: + chatgpt_conversation[str(ctx.author.id)].append({"role": "user", "content": message}) + _chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=chatgpt_conversation[str(ctx.author.id)]) + _reply = _chat.choices[0].message.content + chatgpt_conversation[str(ctx.author.id)].append({"role": "assistant", "content": _reply}) + except openai.error.RateLimitError: return await ctx.respond("The OpenAI API is currently being rate-limited. Try again after some time.", ephemeral=True) + except openai.error.ServiceUnavailableError: return await ctx.respond("The ChatGPT service is currently down.\nTry again after some time, or check it's status at https://status.openai.com", ephemeral=True) + except openai.error.APIError: return await ctx.respond("ChatGPT encountered an internal error. Please try again.", ephemeral=True) + except openai.error.Timeout: return await ctx.respond("Your request timed out. Please try again, or wait for a while.", ephemeral=True) localembed = discord.Embed(description=f"{_reply}", color=discord.Color.random()) localembed.set_author(name="ChatGPT", icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/ChatGPT_logo.svg/1200px-ChatGPT_logo.svg.png") localembed.set_footer(text="Powered by OpenAI") From 23ecdffcadc055a44ead3fe554cbc6ddcf4ac8fe Mon Sep 17 00:00:00 2001 From: snipe_blaze <72265661+notsniped@users.noreply.github.com> Date: Fri, 26 May 2023 16:06:20 +0530 Subject: [PATCH 13/13] Fix some grammar --- cogs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils.py b/cogs/utils.py index 317b27bd..fa4365eb 100644 --- a/cogs/utils.py +++ b/cogs/utils.py @@ -136,7 +136,7 @@ async def chatgpt(self, ctx: ApplicationContext, message: str): _reply = _chat.choices[0].message.content chatgpt_conversation[str(ctx.author.id)].append({"role": "assistant", "content": _reply}) except openai.error.RateLimitError: return await ctx.respond("The OpenAI API is currently being rate-limited. Try again after some time.", ephemeral=True) - except openai.error.ServiceUnavailableError: return await ctx.respond("The ChatGPT service is currently down.\nTry again after some time, or check it's status at https://status.openai.com", ephemeral=True) + except openai.error.ServiceUnavailableError: return await ctx.respond("The ChatGPT service is currently unavailable.\nTry again after some time, or check it's status at https://status.openai.com", ephemeral=True) except openai.error.APIError: return await ctx.respond("ChatGPT encountered an internal error. Please try again.", ephemeral=True) except openai.error.Timeout: return await ctx.respond("Your request timed out. Please try again, or wait for a while.", ephemeral=True) localembed = discord.Embed(description=f"{_reply}", color=discord.Color.random())