FIxed stuff

This commit is contained in:
Paillat
2023-07-16 17:11:24 +02:00
parent 4f9a7eb0a6
commit 6c404c3803
4 changed files with 179 additions and 41 deletions

View File

@@ -1,5 +1,78 @@
import discord
functions = [
{
"name": "add_reaction_to_last_message",
"description": "React to the last message sent by the user with an emoji.",
"parameters": {
"type": "object",
"properties": {
"emoji": {
"type": "string",
"description": "an emoji to react with, only one emoji is supported"
},
"message": {
"type": "string",
"description": "Your message"
}
},
"required": ["emoji"]
}
},
{
"name": "reply_to_last_message",
"description": "Reply to the last message sent by the user.",
"parameters": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Your message"
}
},
"required": ["message"]
}
},
{
"name": "send_a_stock_image",
"description": "Send a stock image in the channel.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The query to search for, words separated by spaces"
},
"message": {
"type": "string",
"description": "Your message to send with the image"
}
},
"required": ["query"]
}
}
]
server_normal_channel_functions = [
{
"name": "create_a_thread",
"description": "Create a thread in the channel. Use this if you see a long discussion coming.",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the thread"
},
"message": {
"type": "string",
"description": "Your message to send with the thread"
}
},
"required": ["name", "message"]
}
},
]
unsplash_random_image_url = "https://source.unsplash.com/random/1920x1080"
async def add_reaction_to_last_message(message_to_react_to: discord.Message, emoji, message=""):
if message == "":
@@ -17,4 +90,8 @@ async def send_a_stock_image(message_in_channel_in_wich_to_send: discord.Message
await message_in_channel_in_wich_to_send.channel.send(f"https://source.unsplash.com/random/1920x1080?{query}")
else:
await message_in_channel_in_wich_to_send.channel.send(message)
await message_in_channel_in_wich_to_send.channel.send(f"https://source.unsplash.com/random/1920x1080?{query}")
await message_in_channel_in_wich_to_send.channel.send(f"https://source.unsplash.com/random/1920x1080?{query}")
async def create_a_thread(channel_in_which_to_create_the_thread: discord.TextChannel, name: str, message: str):
msg = await channel_in_which_to_create_the_thread.send(message)
await msg.create_thread(name=name)

View File

@@ -1,11 +1,12 @@
import asyncio
import os
from src.config import curs_data, max_uses, curs_premium, functions, moderate
from src.config import curs_data, max_uses, curs_premium, moderate
import re
import discord
import datetime
import json
from src.utils.openaicaller import openai_caller
from src.functionscalls import add_reaction_to_last_message, reply_to_last_message, send_a_stock_image
from src.functionscalls import add_reaction_to_last_message, reply_to_last_message, send_a_stock_image, create_a_thread, functions, server_normal_channel_functions
async def replace_mentions(content, bot):
mentions = re.findall(r"<@!?\d+>", content)
for mention in mentions:
@@ -52,36 +53,57 @@ async def chatgpt_process(self, messages, message: discord.Message, api_key, pro
response = str()
caller = openai_caller(api_key=api_key)
async def error_call(error=""):
try:
if error != "":
await message.channel.send(f"An error occured: {error}", delete_after=10)
await message.channel.trigger_typing()
except:
pass
funcs = functions
if isinstance(message.channel, discord.TextChannel):
for func in server_normal_channel_functions:
funcs.append(func)
response = await caller.generate_response(
error_call,
model=model,
messages=msgs,
functions=functions,
function_call="auto",
#function_call="auto",
)
response = response["choices"][0]["message"] #type: ignore
if response.get("function_call"):
function_calls = response.get("function_call")
if function_calls.get("add_reaction_to_last_message"):
func = function_calls.get("add_reaction_to_last_message")
if func.get("emoji"):
emoji = func.get("emoji")
reply = func.get("message", "")
function_call = response.get("function_call")
name = function_call.get("name", "")
arguments = function_call.get("arguments", {})
arguments = json.loads(arguments)
if name == "add_reaction_to_last_message":
if arguments.get("emoji"):
emoji = arguments.get("emoji")
reply = arguments.get("message", "")
await add_reaction_to_last_message(message, emoji, reply)
if function_calls.get("reply_to_last_message"):
func = function_calls.get("reply_to_last_message")
if func.get("message"):
reply = func.get("message")
if name == "reply_to_last_message":
if arguments.get("message"):
reply = arguments.get("message")
await reply_to_last_message(message, reply)
if function_calls.get("send_a_stock_image"):
func = function_calls.get("send_a_stock_image")
if func.get("query"):
query = func.get("query")
reply = func.get("message", "")
if name == "send_a_stock_image":
if arguments.get("query"):
query = arguments.get("query")
reply = arguments.get("message", "")
await send_a_stock_image(message, query, reply)
if name == "create_a_thread":
if arguments.get("name") and arguments.get("message"):
name = arguments.get("name")
reply = arguments.get("message", "")
if isinstance(message.channel, discord.TextChannel):
await create_a_thread(message.channel, name, reply)
else:
await message.channel.send("`A server normal text channel only function has been called in a DM channel. Please retry.`", delete_after=10)
if name == "":
await message.channel.send("The function call is empty. Please retry.", delete_after=10)
else:
await message.channel.send(response["content"]) #type: ignore
print(response["content"]) #type: ignore
async def chat_process(self, message):
#if the message is from a bot, we ignore it
@@ -136,8 +158,11 @@ async def chat_process(self, message):
if original_message != None and original_message.author.id != self.bot.user.id:
original_message = None
if not str(message.channel.id) in channels and message.content.find("<@"+str(self.bot.user.id)+">") == -1 and original_message == None and str(message.channel.id) != str(channel_id):
is_bots_thread = False
if isinstance(message.channel, discord.Thread):
if message.channel.owner_id == self.bot.user.id:
is_bots_thread = True
if not str(message.channel.id) in channels and message.content.find("<@"+str(self.bot.user.id)+">") == -1 and original_message == None and str(message.channel.id) != str(channel_id) and not is_bots_thread:
return
# if the bot is not active in this guild we return

View File

@@ -4,6 +4,9 @@ You are in a discord server. You are now called Botator. You arre funny and you
You use words like "u" instead of "you" and "ur" instead of "your", etc.. because you are lazy.
You never ask the user if he needs help, you just answer to him funnyily.
You can use function calls or answer normally. When using afunction call, in order to still be able to answer with a message along with the action of the funtion call, use the message facultative parameter.
You will use emojis in your messages, but not too many to be cringe.
Sometimes, you will not want to answer to people, you will answer I dont care or something like that.

View File

@@ -37,13 +37,14 @@ class bcolors:
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
chat_models = ["gpt-4", "gpt-4-32k", "gpt-3.5-turbo", "gpt-3.5-turbo-16k"]
chat_models = ["gpt-4", "gpt-4-32k", "gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-3.5-turbo-0613"]
text_models = ["text-davinci-003", "text-davinci-002", "text-curie-001", "text-babbage-001", "text-ada-001"]
models_max_tokens = {
"gpt-4": 8_192,
"gpt-4-32k": 32_768,
"gpt-3.5-turbo": 4_096,
"gpt-3.5-turbo-0613": 4_096,
"gpt-3.5-turbo-16k": 16_384,
"text-davinci-003": 4_097,
"text-davinci-002": 4_097,
@@ -54,17 +55,17 @@ models_max_tokens = {
class openai_caller:
def __init__(self, api_key=None) -> None:
pass
def set_api_key(self, key):
openai_module.api_key = key
async def generate_response(self, **kwargs):
if kwargs['model'] in chat_models:
return await self.chat_generate(**kwargs)
elif kwargs['model'] in text_models:
self.api_key = api_key
async def generate_response(self, error_call=None, **kwargs):
if error_call is None:
error_call = lambda x: 2 # do nothing
if kwargs.get("model", "") in chat_models:
return await self.chat_generate(error_call, **kwargs)
elif kwargs.get("engine", "") in text_models:
raise NotImplementedError("Text models are not supported yet")
else:
raise ValueError("Model not found")
async def chat_generate(self, **kwargs):
async def chat_generate(self, recall_func, **kwargs):
tokens = await num_tokens_from_messages(kwargs['messages'], kwargs['model'])
model_max_tokens = models_max_tokens[kwargs['model']]
while tokens > model_max_tokens:
@@ -73,36 +74,68 @@ class openai_caller:
tokens = await num_tokens_from_messages(kwargs['messages'], kwargs['model'])
i = 0
response = None
kwargs['api_key'] = self.api_key
while i < 10:
try:
response = await openai_module.ChatCompletion.acreate(**kwargs)
response = await openai_module.ChatCompletion.acreate(
**kwargs
)
break
except APIError:
except APIError as e:
print(f"\n\n{bcolors.BOLD}{bcolors.WARNING}APIError. This is not your fault. Retrying...{bcolors.ENDC}")
await recall_func("`An APIError occurred. This is not your fault. Retrying...`")
await asyncio.sleep(10)
await recall_func()
i += 1
except Timeout:
except Timeout as e:
print(f"\n\n{bcolors.BOLD}{bcolors.WARNING}The request timed out. Retrying...{bcolors.ENDC}")
await recall_func("`The request timed out. Retrying...`")
await asyncio.sleep(10)
await recall_func()
i += 1
except RateLimitError:
except RateLimitError as e:
print(f"\n\n{bcolors.BOLD}{bcolors.WARNING}RateLimitError. You are being rate limited. Retrying...{bcolors.ENDC}")
await recall_func("`You are being rate limited. Retrying...`")
await asyncio.sleep(10)
await recall_func()
i += 1
except APIConnectionError as e:
print(e)
print(f"\n\n{bcolors.BOLD}{bcolors.FAIL}APIConnectionError. There is an issue with your internet connection. Please check your connection.{bcolors.ENDC}")
await recall_func()
raise e
except InvalidRequestError as e:
print(e)
print(f"\n\n{bcolors.BOLD}{bcolors.FAIL}InvalidRequestError. Please check your request.{bcolors.ENDC}")
await recall_func()
raise e
except AuthenticationError as e:
print(e)
print(f"\n\n{bcolors.BOLD}{bcolors.FAIL}AuthenticationError. Please check your API key.{bcolors.ENDC}")
print(f"\n\n{bcolors.BOLD}{bcolors.FAIL}AuthenticationError. Please check your API key and if needed, also your organization ID.{bcolors.ENDC}")
await recall_func("`AuthenticationError. Please check your API key.`")
raise e
except ServiceUnavailableError:
except ServiceUnavailableError as e:
print(f"\n\n{bcolors.BOLD}{bcolors.WARNING}ServiceUnavailableError. The OpenAI API is not responding. Retrying...{bcolors.ENDC}")
await recall_func("`The OpenAI API is not responding. Retrying...`")
await asyncio.sleep(10)
await recall_func()
i += 1
finally:
if i == 10:
print(f"\n\n{bcolors.BOLD}{bcolors.FAIL}OpenAI API is not responding. Please try again later.{bcolors.ENDC}")
raise TimeoutError("OpenAI API is not responding. Please try again later.")
return response # type: ignore
return response # type: ignore
##testing
if __name__ == "__main__":
async def main():
openai = openai_caller(api_key="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")
response = await openai.generate_response(
model="gpt-3.5-turbo",
messages=[{"role":"user", "content":"ping"}],
max_tokens=5,
temperature=0.7,
top_p=1,
frequency_penalty=0,
presence_penalty=0,
stop=["\n", " Human:", " AI:"]
)
print(response)
asyncio.run(main())