@ -26,39 +26,56 @@ class Report:
self . color = None
self . organization = None
self . type = None
self . marked : bool = None
self . blockage : bool = None
self . marked = None
self . blockage = None
self . area_description = None
self . contact_person_phone_number = False
self . contact_person_name = False
self . contact_person_phone_number = None
self . contact_person_name = None
self . at_the_location : bool = None
self . coordinates = None
self . woreda = None
self . info_groups = [
[ " description " , " color " , " size " , " shape " ] ,
[ " description " ] ,
[ " color " , " size " , " shape " ] ,
[ " at_the_location " ] ,
#['coordinates'],
[ " image " ] ,
[ " location " , " area_description " ] ,
[ " woreda " ] ,
[ " location " ] ,
[ " area_description " ] ,
[ " incident " ] ,
[ " blockage " , " marked " ] ,
[ " contact_person_name " , " contact_person_phone_number " ] ,
[ " organization " , " name " , " role " ] ,
]
self . info_explicit = [
" name " ,
" contact_person_name " ,
" contact_person_phone_number " ,
]
self . info_professional = [ " organization " , " role " , " type " ]
self . descriptions = {
" description " : " A general description of the object. " ,
" at_the_location " : " If the person reporting is still where the object was found. (True or False) " ,
" incident " : " Has there been an incident related to the object? " ,
" name " : " The name of the person reporting. " ,
" role " : " The role or occupation of the person reporting. " ,
" location " : " The location of the object. " , # TODO Add more details
" woreda " : " The woreda where the object was found. " ,
" location " : " The closest city or village to where the object was found. " , # TODO Add more details
" coordinates " : " The coordinates of the person reporting. " ,
" image " : " A picture of the object. " ,
" size " : " The size of the object. " ,
" shape " : " The shape of the object. " ,
" color " : " The color of the object. " ,
" organization " : " The organization of the person reporting. " ,
" type " : " The type of the object. " ,
" marked " : " Is the object marked? " ,
" blockage " : " Is the object blocking anything? " ,
" area_description " : " A description of the area where the object is located. " ,
" contact_person_phone_number " : " The phone number of the contact person. " ,
" contact_person_name " : " The name of the contact person. " ,
" type " : " The type of the object. " ,
}
self . looking_for : list = self . info_groups [ 0 ]
@ -93,11 +110,13 @@ class BaseBot:
]
data = { " model " : " gpt-3.5-turbo " , " messages " : messages }
# Print the last message in yellow
last_message = messages [ - 1 ] [ " content " ]
print ( " \n \033 [94m " + last_message + " \033 [0m \n " )
response = requests . post ( self . url , headers = self . headers , json = data ) . json ( )
pprint ( response )
answer = response [ " choices " ] [ 0 ] [ " message " ]
print ( " \033 [95m " + answer [ " content " ] + " \033 [0m " )
@ -122,6 +141,7 @@ class Chatbot(BaseBot):
for group in report . info_groups :
if not group_found :
for info in group :
print ( " # " , info , getattr ( report , info ) )
if getattr ( report , info ) is None :
group_found = True
looking_for . append ( info )
@ -139,20 +159,25 @@ class Chatbot(BaseBot):
if looking_for == [ " image " ] :
question = " image "
else :
prompt = f " Formulate a question asking for the following information: { looking_for } "
general_bot . memory . append ( { " role " : " user " , " content " : prompt } )
question = general_bot . generate ( prompt ) [ " content " ]
general_bot . memory = None
description_dict = { }
for i in looking_for :
description_dict [ i ] = report . descriptions [ i ]
# Give the bot examles of how to ask for the information
general_bot . memory = [
{
" role " : " user " ,
" content " : ' Formulate a question asking for the following information: [ " name " , " age " ] ' ,
" content " : """ I ' m looking for the information in this disctionary:
{ ' description ' : ' If the person reporting is still where the object was found? ' }
Formulate a question asking for the information in the dictionary . """ ,
} ,
{
" role " : " assistant " ,
" content " : " Can you tell me about the name and age of what you ' ve found?" ,
" content " : f " Are you still at the place where object was found?" ,
} ,
]
# If we know what the object is, we can ask about it.
if report . object is not None :
general_bot . memory . insert (
0 ,
@ -162,12 +187,19 @@ class Chatbot(BaseBot):
+ f " The object found might be { report . object } . " ,
} ,
)
general_bot . memory [ 2 ] [ " content " ] = f " Can you tell me about the name and age of the { report . object } ? "
general_bot . memory [ 2 ] [ " content " ] = f " Are you still at the place where the { report . object } was found? "
prompt = f " Formulate a question asking for the following information: { looking_for } "
general_bot . memory . append ( { " role " : " user " , " content " : prompt } )
object_string = ' '
if report . object is not None :
object_string = f " The object found is { report . object } . "
prompt = f """ I ' m looking for the information about an object. { object_string } . The information needed is described in this disctionary:
{ description_dict }
Formulate a question asking for the information in the dictionary . """
question = general_bot . generate ( prompt ) [ " content " ]
general_bot . memory = None
general_bot . memory = [ ]
return question
else :
@ -234,7 +266,7 @@ class CheckerBot(BaseBot):
return answered
def check_for_info ( self , user_message , report : Report , looking_for : list , n_try = 0 ) :
def check_for_info ( self , user_message , report : Report , question : str , looking_for : list , n_try = 0 ) - > dict :
if report . object is None :
@ -264,7 +296,7 @@ class CheckerBot(BaseBot):
]
self . memory = messages
result = self . generate ( user_message ) [ " content " ]
self . memory = None
self . memory = [ ]
if result not in [ " null " , " None " , " " , " Unknown " ] :
print ( " Object: " , result )
@ -274,10 +306,17 @@ class CheckerBot(BaseBot):
for info in looking_for :
if getattr ( report , info ) is None :
info_dict [ info ] = report . descriptions [ info ]
# If the bot asks for a description, it should also check for color, size and shape.
if looking_for == [ " description " ] :
for i in [ " color " , " size " , " shape " ] :
info_dict [ i ] = report . descriptions [ i ]
prompt = f """ "
This is a message from a user : ''' {user_message} ''' \n
This is a dict describing what info I want : \n \n { info_dict } \n \n \
Take a look at the message and create a dictionary with the information that is requested . \
A user was asked ''' {question} '''
This is the answer from the user : ''' {user_message} ''' \n
This is a dictionary describing what info I want : \n \n { info_dict } \n \n \
Take a look at the message along with the question and create a dictionary with the information that is requested . \
There might not be information available in the mesasge for all fields . \
If you can ' t find information for a certain field, fill that with a python null value ( " None " or " null " ).
Do not include any explanations , only provide a RFC8259 compliant JSON response following this format without deviation . \
@ -291,23 +330,32 @@ class CheckerBot(BaseBot):
result [ " content " ]
) # Parse the string back into a dictionary
for key , value in json_content . items ( ) :
if value not in [ " null " , " None " , " " , " Unknown " ] :
if value not in [ " null " , " None " , " " , " Unknown " , None ] :
setattr ( report , key , value )
else : # Don't ask for these again.
if (
key in [ " shape " , " size " , " color " , " marked " , " blockage " ]
and key in looking_for
) :
setattr ( report , key , " Unknown " )
except :
try :
result_content = result_content [
result_content . find ( " { " ) : result_content . rfind ( " } " ) + 1
]
json_content = json . loads (
result [ " content " ]
) # Parse the string back into a dictionary
for key , value in json_content . items ( ) :
if value not in [ " null " , " None " , " " , " Unknown " ] :
setattr ( report , key , value )
except :
if n_try > 3 :
return False
self . check_for_info ( user_message , report , looking_for , n_try = n_try )
self . check_for_info ( user_message , report , looking_for = looking_for , question = question , n_try = n_try )
return json_content
@ -435,13 +483,20 @@ if __name__ == "__main__":
send ( botstrings . first_instructions , check = False )
else :
if chatbot . informations_requested :
question = ' '
for i in chatbot . memory :
if i [ " role " ] == " assistant " :
question = i [ " content " ]
print ( ' QUESTION: ' , question )
answered = checker_bot . check_answer (
user_input , chatbot . memory [ - 1 ] [ " content " ] , chatbot
)
if answered :
# Ask for information and send that message to the report
result = checker_bot . check_for_info (
user_input , report , report . looking_for
user_input , report , looking_for = report . looking_for , question = question
)
if result :
pprint ( result )