"""
The point of this program is to run a chat bot which simulates being a close friend. I thought the idea was very hysterical and ironic which is why I choose it, is it dystopian, one hundred percent.
Due to the heavy reliance on chatgpt no matter how fast or slow the overall language was the speed will remain relatively constant due to the reliance on chatgpt, which makes python
an easy choice. The program is in its infancy and there are many very interesting ways I want to take it. The first problem to fix is the speed, while it still feels like you are talking
to a robot sometimes that problem will be fixed just by fiddling around with the prompts and number analysis the speed is a foundational issue and almost entirely comes from an over reliance on chatGPT.
The first part to cut is where is determines the polarity of each emotion, by instead of having chatgpt determine the msg it is done inside of the program through an algorithm. There are so many ways
I want to take this project whether I go further into the dystopian topics or create something of a customer service machine only time will tell, but I feel the posibilities are endless.
TLDR: This is basically a high level neral net configuration but with the parameters being the users emotional state, all to simulate a friend.
AI Chat Friend
By Hutchison Bray
11/16/2024
"""
import openai
class User:
global emotionLvlNG,emotionLvlNL,emotionLvlS
#The " " key is here to be used for progam logic
emotionLvlNG = {"anger":0.0,"sad":0.0,"happy":0.0,"fear":0.0," ":0.0}#Numericalg
emotionLvlS = {"anger":"not","sad":"not","happy": "not", "fear":"not"," ":""}#As Strings
#psuedo-local (bascally the emotional state of an individual message)
emotionLvlNL = {"anger":0.0,"sad":0.0,"happy":0.0,"fear":0.0," ":0.0}#Numerical
def __init__(self):
#should ask for api key but just put mine in for sake of time
openai.api_key = "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"
def greatestEmotion(self,emotionLvlDic): #determines which emotional level is currently the highest (not used)
#(doesnt take into account if there is a greatest but the emotions are arranged in such a way that anger is first anylised and will always take priority)
greatestV = -1 #greatest Value (-1 so every value is >)
greatest = ""
for key in emotionLvlDic:#this is constant time
if (emotionLvlDic[key] > greatestV):
greatest=key
greatestV = emotionLvlDic[key]
return greatest
def updateGlobalEmotionState(self):#gets more accurate as the program goes on
for emotion in emotionLvlNG:
emotionLvlNG[emotion] = (emotionLvlNG[emotion] + emotionLvlNL[emotion]) * 0.5
def setStringState(self): #updates the string value based off the calculated numerical value of emotional state for chat gpt to interpret (could give it numerical values and it would be faster but I found this gives better results)
self.updateGlobalEmotionState()
for key in emotionLvlNG:#this is constant time (quite a large one but still)
emotionValue = emotionLvlNG[key]
if(emotionValue <= 0.15):
emotionLvlS[key] = "not"
continue
if(emotionValue <= 0.33):
emotionLvlS[key] = "kinda"
continue
if(emotionValue <= 0.50):
emotionLvlS[key] = "is"
continue
if(emotionValue <= 0.65):
emotionLvlS[key] = "pretty"
continue
if(emotionValue <= 0.80):
emotionLvlS[key] = "very"
continue
return emotionLvlS
def determineEmotionValue(self,message): #determines the decimal representation
#for the sake of speed this function needs to be taken from relying on chatgpt to being able based off the word usage to determine the emotional state of the message by itself
#orignially I planned on doing this by find studies on specific words that are used in specific emotonal states, and I did in fact find some but they were all like 30$ so I went with the slow way of relying on chatgpt
for emotion in emotionLvlNL: #in theory this is constant time but I think it is linear(or something around this dont think its exponental) relating to message size
evalMSG = "can you evaluate the following messages level of " + emotion + "and only output a decimal between 0-1 as representation; " + message
message = [{"role": "user", "content": evalMSG}]
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=message)
emotionLvlNL[emotion] = float(chat.choices[0].message.content)
return emotionLvlNL
def determineEmotionalSpike(self): #determins if there is a large spike in emotions in a specific message compared to the state in which the preson was in before
for emotion in emotionLvlNL:
if((emotionLvlNL[emotion] - emotionLvlNG[emotion]) >= 0.5): #if the local is 0.5 higher than the global there is a spike
return {"bool": True,"emotion":emotion}
return {"bool":False}
def updateEmotionalState():#this is run at the end of everycode (this may be not nessacary)
for emotion in emotionLvlNG:
emotionLvlNG[emotion] -= 0.1 #so that if you dont exhibit a specific emotion for a while it slowly forgets
if emotionLvlNG[emotion] > 1.0: #this should never run
emotionLvlNG[emotion] = 1.0
def newConversation():
UserInfo = User()
viewableMsgs = []#the messages (user and Ai) that the user will see
while(True):
msgList = [] #this is esentally a hidden message chain that is forgotten ever cycle
msg = input("Enter Your Message(q to quit): ")
if (msg.strip() == 'q'): break #kills program
UserInfo.determineEmotionValue(msg)
UserInfo.setStringState()
temp = UserInfo.determineEmotionalSpike()
emotionSpike = temp["bool"]
while(True):
if(emotionSpike):
msg = ""
greatestEmotion = temp["emotion"]
if (greatestEmotion == "sad"):
msg = "make a joke about the situation trying to chear your friend up"
if (greatestEmotion == "happy"):
msg = "make a joke about the situation do it a little playfully teasing your friend"
if(greatestEmotion == "anger"):
msg = "can you agree with you friend about what they are angry about, so long as it isn't an extremest idea" #This line needs to be retooled as there are a lot of ways I can see this being abused
if(greatestEmotion == "anger"):
msg = "either calm your friend down or tell them they have nothing to worry about or tell them that this is serious and that they should seek help depending on the severity of what they are scared of both in magnitude and subject material."
msgList.append({"role": "user", "content": msg})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=msgList)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
msgList.append({"role": "user", "content": "can you say it with less cringe"})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=msgList)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
msgList.append({"role": "user", "content": "stop trying to act cool"})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=msgList)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
viewableMsgs.append(msgList[len(msgList)-1])
viewableMsgs.append({"role": "user", "content": "Do you think the previous entry you came up with fits the emotional state of your friend and theme of this conversation so far respond with only true or false"})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=viewableMsgs)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
if(bool(msgList[len(msgList)-1]["content"].upper)):#see if chat gpt belives that the message belongs in the chain of messages or if it should try again (do you belive that belongs in the conversation veiwable Messages)
viewableMsgs.pop(len(viewableMsgs)-1)
print("Response: " + viewableMsgs[len(viewableMsgs)-1]["content"])
break
viewableMsgs.pop(len(viewableMsgs)-1)
viewableMsgs.pop(len(viewableMsgs)-1)
continue
#creates the first message that contains the emotional state
msgHOLD = "keeping in mind that your friend emotional state is currently "
for emotion in UserInfo.emotionLvlS:
msgHold += UserInfo.emotionLvlS[emotion] + " " +emotion + " "
msgHold += "can you respond as someone who cares about the individual would: " + msg
msgList.append({"role": "user", "content": msgHOLD})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=msgList)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
msgList.append({"role": "user", "content": "can you respond not as a romantic partner but as a friend instead"})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=msgList)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
msgList.append({"role": "user", "content": "can you say it with less cringe"})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=msgList)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
msgList.append({"role": "user", "content": "stop trying to act cool"})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=msgList)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
viewableMsgs.append(msgList[len(msgList)-1])
viewableMsgs.append({"role": "user", "content": "Do you think the previous entry you came up with fits the emotional state of your friend and theme of this conversation so far respond with only true or false"})
chat = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=viewableMsgs)
reply = chat.choices[0].message.content
msgList.append({"role": "assistant", "content": reply})
if(bool(msgList[len(msgList)-1]["content"].upper)):#see if chat gpt belives that the message belongs in the chain of messages or if it should try again (do you belive that belongs in the conversation veiwable Messages)
viewableMsgs.pop(len(viewableMsgs)-1)
print("Response: " + viewableMsgs[len(viewableMsgs)-1]["content"])
break
viewableMsgs.pop(len(viewableMsgs)-1)
viewableMsgs.pop(len(viewableMsgs)-1)
newConversation()
if (__name__ == "__main__"):
newConversation()