2023-01-30 22:57:57 +01:00
import asyncio
2023-03-02 21:53:43 +01:00
from config import c , max_uses , cp , conn , debug
2023-01-30 22:57:57 +01:00
import re
import openai
2023-02-09 20:13:54 +01:00
import datetime
2023-03-01 23:46:54 +01:00
async def replace_mentions ( content , bot ) :
mentions = re . findall ( r " <@!? \ d+> " , content )
for mention in mentions :
uid = mention [ 2 : - 1 ]
user = await bot . fetch_user ( uid )
content = content . replace ( mention , f " @ { user . name } " )
return content
2023-03-01 21:30:16 +01:00
async def chat_process ( self , message ) :
if message . author . bot :
return
try : c . execute ( " SELECT * FROM data WHERE guild_id = ? " , ( message . guild . id , ) )
except :
return
data = c . fetchone ( )
channel_id = data [ 1 ]
api_key = data [ 2 ]
is_active = data [ 3 ]
max_tokens = data [ 4 ]
temperature = data [ 5 ]
frequency_penalty = data [ 6 ]
presence_penalty = data [ 7 ]
uses_count_today = data [ 8 ]
prompt_size = data [ 9 ]
prompt_prefix = data [ 10 ]
tts = data [ 11 ]
pretend_to_be = data [ 12 ]
pretend_enabled = data [ 13 ]
try : cp . execute ( " SELECT * FROM data WHERE guild_id = ? " , ( message . guild . id , ) )
except : pass
2023-03-01 23:46:54 +01:00
try :
c . execute ( " SELECT * FROM model WHERE guild_id = ? " , ( message . guild . id , ) )
model = c . fetchone ( ) [ 1 ]
except : model = " davinci "
2023-03-01 21:30:16 +01:00
try : premium = cp . fetchone ( ) [ 2 ]
except : premium = 0
channels = [ ]
try :
cp . execute ( " SELECT * FROM channels WHERE guild_id = ? " , ( message . guild . id , ) )
if premium : channels = cp . fetchone ( ) [ 1 : ]
except : channels = [ ]
if api_key is None :
return
2023-03-01 23:46:54 +01:00
if uses_count_today > = max_uses and premium == 0 : return await message . channel . send ( f " The bot has been used more than { str ( max_uses ) } times in the last 24 hours in this guild. Please try again in 24h. " )
elif uses_count_today > = max_uses * 5 and premium == 1 : return
if is_active == 0 : return
if message . content . startswith ( " - " ) or message . content . startswith ( " // " ) : return
2023-03-01 21:30:16 +01:00
try : original_message = await message . channel . fetch_message ( message . reference . message_id )
except : original_message = None
2023-03-01 23:46:54 +01:00
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 ) : return
if original_message != None and message . guild . id == 1050769643180146749 and message . author . id != 707196665668436019 : return
2023-03-01 21:30:16 +01:00
await message . channel . trigger_typing ( )
if message . guild . id != 1021872219888033903 :
c . execute ( " UPDATE data SET uses_count_today = uses_count_today + 1 WHERE guild_id = ? " , ( message . guild . id , ) )
conn . commit ( )
if original_message == None :
messages = await message . channel . history ( limit = prompt_size ) . flatten ( )
messages . reverse ( )
else :
messages = await message . channel . history ( limit = prompt_size , before = original_message ) . flatten ( )
messages . reverse ( )
messages . append ( original_message )
messages . append ( message )
if pretend_enabled : pretend_to_be = f " In this conversation, the assistant pretends to be { pretend_to_be } "
else : pretend_to_be = " "
2023-03-01 23:46:54 +01:00
if prompt_prefix == None : prompt_prefix = " "
2023-03-02 21:32:11 +01:00
prompt = " "
2023-03-01 23:46:54 +01:00
if model == " chatGPT " :
2023-03-02 21:34:16 +01:00
# we open the chatGPT prompt file located in the ./prompts/chatGPT.txt file
with open ( " ./prompts/chatGPT.txt " , " r " ) as f :
prompt = f . read ( )
f . close ( )
# we replace the variables in the prompt file with the variables we have
prompt = prompt . replace ( " [server-name] " , message . guild . name )
prompt = prompt . replace ( " [channel-name] " , message . channel . name )
prompt = prompt . replace ( " [date-and-time] " , datetime . datetime . utcnow ( ) . strftime ( " %d / % m/ % Y % H: % M: % S " ) ) # this is the gmt+1 time. If we want the gmt 0 time, we need to do: datetime.datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S")
prompt = prompt . replace ( " [pretend-to-be] " , pretend_to_be )
prompt = prompt . replace ( " [prompt-prefix] " , prompt_prefix )
2023-03-01 23:46:54 +01:00
msgs = [ ]
if prompt_prefix != " " : prompt = f " \n { prompt } \n { prompt_prefix } "
else : prompt = f " \n { prompt } "
2023-03-02 21:32:11 +01:00
msgs . append ( { " role " : " system " , " content " : prompt , " name " : " system " } )
2023-03-02 18:04:27 +01:00
name = " "
2023-03-01 23:46:54 +01:00
for msg in messages :
content = msg . content
content = await replace_mentions ( content , self . bot )
if msg . author . id == self . bot . user . id :
role = " assistant "
2023-03-02 18:04:27 +01:00
name = " assistant "
2023-03-01 23:46:54 +01:00
else :
role = " user "
2023-03-02 18:04:27 +01:00
name = msg . author . name
msgs . append ( { " role " : role , " content " : f " { content } " , " name " : name } )
2023-03-01 23:46:54 +01:00
if message . content . lower ( ) . find ( " undude " ) != - 1 :
# prompt += "System: Undude detected. Botator is now mad. He will start talking in capital letters.\n"
2023-03-02 18:04:27 +01:00
msgs . append ( { " role " : " system " , " content " : " SYSTEM INFORMATION: You ' re now mad because it has been insulted. He will start talking in capital letters. always and yell at the user. " , " name " : " system " } )
2023-03-01 23:46:54 +01:00
if message . content . lower ( ) . find ( " hello there " ) != - 1 :
# prompt += "System: Hello there detected. Botator will now say \"General Kenobi!\"\n in reference to star wars\n"
2023-03-02 18:04:27 +01:00
msgs . append ( { " role " : " system " , " content " : " SYSTEM INFORMATION: Hello there detected. Botator will now say \" General Kenobi! \" in reference to star wars " , " name " : " system " } )
2023-03-01 23:46:54 +01:00
await asyncio . sleep ( 1 )
await message . channel . send ( " https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif " )
await message . channel . trigger_typing ( )
openai . api_key = api_key
response = " "
2023-03-02 21:53:43 +01:00
should_break = True
for x in range ( 10 ) :
2023-03-01 23:46:54 +01:00
try :
response = await openai . ChatCompletion . acreate (
model = " gpt-3.5-turbo " ,
max_tokens = int ( max_tokens ) ,
messages = msgs ,
)
2023-03-02 21:58:38 +01:00
should_break = True
2023-03-01 23:46:54 +01:00
except Exception as e :
2023-03-02 21:58:38 +01:00
should_break = FalseS
await message . channel . send ( f " ```diff \n -Error: OpenAI API ERROR. \n \n { e } ``` " , delete_after = 5 )
2023-03-01 23:46:54 +01:00
break
2023-03-02 21:53:43 +01:00
#if the ai said "as an ai language model..." we continue the loop" (this is a bug in the chatgpt model)
if response . choices [ 0 ] . message . content . lower ( ) . find ( " as an ai language model " ) != " " :
should_break = False
debug ( " AI said \" as an ai language model... \" . Continuing loop. " )
if response == None : should_break = False
if should_break : break
asyncio . sleep ( 5 )
2023-03-01 23:46:54 +01:00
response = response . choices [ 0 ] . message . content
2023-03-02 21:32:11 +01:00
#-----------------------------------------Davinci------------------------------------------------------------------------------------------
2023-03-01 23:46:54 +01:00
elif model == " davinci " :
2023-03-02 18:04:27 +01:00
prompt = f ''' Server name: { message . guild . name } . Channel name: { message . channel . name } .
The assistant is called Botator . { pretend_to_be } . { prompt_prefix }
Botator is an AI and a regular Discord user . He types casually , uses a lot of emojis in each message . Botator has many niche interests . Botator talks normally and is sentient . Botator is really funny and has a good humor . Botator is intelligent . Botator often uses internet shorthand like " lol " and " bruh " . He uses " bruh " a lot .
The date and time is : { datetime . datetime . now ( ) . strftime ( ' %d / % m/ % Y % H: % M: % S ' ) } UTC . The assistant can surely tell the time to te users when asked . '''
2023-03-01 23:46:54 +01:00
prompt = f " { prompt } <|endofprompt|> "
for msg in messages :
content = msg . content
content = await replace_mentions ( content , self . bot )
prompt + = f " { msg . author . name } : { content } \n "
if message . content . lower ( ) . find ( " undude " ) != - 1 :
prompt + = " System: Undude detected. Botator is now mad. He will start talking in capital letters. \n "
if message . content . lower ( ) . find ( " hello there " ) != - 1 :
prompt + = " System: Hello there detected. Botator will now say \" General Kenobi! \" \n in reference to star wars \n "
await asyncio . sleep ( 1 )
await message . channel . send ( " https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif " )
await message . channel . trigger_typing ( )
prompt = prompt + f " \n { self . bot . user . name } : "
openai . api_key = api_key
response = " "
for _ in range ( 10 ) :
try :
response = await openai . Completion . acreate (
engine = " text-davinci-003 " ,
prompt = str ( prompt ) ,
max_tokens = int ( max_tokens ) ,
top_p = 1 ,
temperature = float ( temperature ) ,
frequency_penalty = float ( frequency_penalty ) ,
presence_penalty = float ( presence_penalty ) ,
stop = [ " Human: " , " AI: " , " AI: " , " <|endofprompt|> " , ]
)
except Exception as e :
response = None
await message . channel . send ( f " ```diff \n -Error: OpenAI API ERROR. \n \n { e } ``` " , delete_after = 10 )
return
2023-03-02 21:53:43 +01:00
if response != None : break
2023-03-01 21:30:16 +01:00
if response != " " :
if tts : tts = True
else : tts = False
await message . channel . send ( response , tts = tts )
else :
2023-03-02 20:23:25 +01:00
await message . channel . send ( " The AI is not sure what to say (the response was empty) " )