ritik99's picture
Upload 14 files
c7b88cf
import random
from utils.text_generation import generate, get_rating
import networkx as nx
class Agent:
"""
A class to represent an individual agent in a simulation similar to The Sims.
Attributes:
-----------
name : str
The name of the agent.
description : str
A brief description of the agent.
location : str
The current location of the agent in the simulated environment.
memories : list
A list of memories the agent has about their interactions.
compressed_memories : list
A list of compressed memories that summarize the agent's experiences.
plans : str
The agent's daily plans, generated at the beginning of each day.
Methods:
--------
plan(global_time, town_people, prompt_meta):
Generates the agent's daily plan.
execute_action(other_agents, location, global_time, town_areas, prompt_meta):
Executes the agent's action based on their current situation and interactions with other agents.
update_memories(other_agents, global_time, action_results):
Updates the agent's memories based on their interactions with other agents.
compress_memories(memory_ratings, global_time, MEMORY_LIMIT=10):
Compresses the agent's memories to a more manageable and relevant set.
rate_locations(locations, town_areas, global_time, prompt_meta):
Rates different locations in the simulated environment based on the agent's preferences and experiences.
"""
def __init__(self, name, description, starting_location, world_graph, use_openai):
self.name = name
self.description = description
self.location = starting_location
self.memory_ratings = []
self.memories = []
self.compressed_memories = []
self.plans = ""
self.world_graph = world_graph
self.use_openai = use_openai
def __repr__(self):
return f"Agent({self.name}, {self.description}, {self.location})"
def plan(self, global_time, prompt_meta):
"""
Generates the agent's daily plan.
Parameters:
-----------
global_time : int
The current time in the simulation.
prompt_meta : str
The prompt used to generate the plan.
"""
prompt = "You are {}. The following is your description: {} You just woke up. What is your goal for today? Write it down in an hourly basis, starting at {}:00. Write only one or two very short sentences. Be very brief. Use at most 50 words.".format(self.name, self.description, str(global_time))
self.plans = generate(prompt_meta.format(prompt), self.use_openai)
def execute_action(self, other_agents, location, global_time, town_areas, prompt_meta):
"""Executes the agent's action based on their current situation and interactions with other agents.
Parameters:
-----------
other_agents : list
A list of other Agent objects in the simulation.
location : Location
The current Location object where the agent is located.
global_time : int
The current time in the simulation.
town_areas : dict
A dictionary of Location objects representing different areas in the simulated environment.
prompt_meta : str
The prompt used to generate the action.
Returns:
--------
action : str
The action executed by the agent.
"""
people = [agent.name for agent in other_agents if agent.location == location]
prompt = "You are {}. Your plans are: {}. You are currently in {} with the following description: {}. It is currently {}:00. The following people are in this area: {}. You can interact with them.".format(self.name, self.plans, location.name, town_areas[location.name], str(global_time), ', '.join(people))
people_description = [f"{agent.name}: {agent.description}" for agent in other_agents if agent.location == location.name]
prompt += ' You know the following about people: ' + '. '.join(people_description)
prompt += "What do you do in the next hour? Use at most 10 words to explain."
action = generate(prompt_meta.format(prompt), self.use_openai)
return action
def update_memories(self, other_agents, global_time, action_results):
"""
Updates the agent's memories based on their interactions with other agents.
Parameters:
-----------
other_agents : list
A list of other Agent objects in the simulation.
global_time : int
The current time in the simulation.
action_results : dict
A dictionary of the results of each agent's action.
"""
for agent in other_agents:
if agent.location == self.location:
self.memories.append('[Time: {}. Person: {}. Memory: {}]\n'.format(str(global_time), agent.name, action_results[agent.name]))
def compress_memories(self, global_time, MEMORY_LIMIT=10):
"""
Compresses the agent's memories to a more manageable and relevant set.
Parameters:
-----------
global_time : int
The current time in the simulation.
MEMORY_LIMIT : int, optional
The maximum number of memories to compress. Default is 10.
Returns:
--------
memory_string : str
The compressed memory string.
"""
memories_sorted = sorted(self.memory_ratings, key=lambda x: x[1], reverse=True)
relevant_memories = memories_sorted[:MEMORY_LIMIT]
memory_string_to_compress = '.'.join([a[0] for a in relevant_memories])
return '[Recollection at Time {}:00: {}]'.format(str(global_time), memory_string_to_compress)
def rate_memories(self, locations, global_time, prompt_meta):
"""
Rates the agent's memories based on their relevance and importance.
Parameters:
-----------
locations : Locations
The Locations object representing different areas in the simulated environment.
global_time : int
The current time in the simulation.
prompt_meta : str
The prompt used to rate the memories.
Returns:
--------
memory_ratings : list
A list of tuples representing the memory, its rating, and the generated response.
"""
memory_ratings = []
for memory in self.memories:
prompt = "You are {}. Your plans are: {}. You are currently in {}. It is currently {}:00. You observe the following: {}. Give a rating, between 1 and 5, to how much you care about this.".format(self.name, self.plans, locations.get_location(self.location), str(global_time), memory)
res = generate(prompt_meta.format(prompt), self.use_openai)
rating = get_rating(res)
max_attempts = 2
current_attempt = 0
while rating is None and current_attempt < max_attempts:
rating = get_rating(res)
current_attempt += 1
if rating is None:
rating = 0
memory_ratings.append((memory, rating, res))
self.memory_ratings = memory_ratings
return memory_ratings
def rate_locations(self, locations, global_time, prompt_meta):
"""
Rates different locations in the simulated environment based on the agent's preferences and experiences.
Parameters:
-----------
locations : Locations
The Locations object representing different areas in the simulated environment.
global_time : int
The current time in the simulation.
prompt_meta : str
The prompt used to rate the locations.
Returns:
--------
place_ratings : list
A list of tuples representing the location, its rating, and the generated response.
"""
place_ratings = []
for location in locations.locations.values():
prompt = "You are {}. Your plans are: {}. It is currently {}:00. You are currently at {}. How likely are you to go to {} next?".format(self.name, self.plans, str(global_time), locations.get_location(self.location), location.name)
res = generate(prompt_meta.format(prompt), self.use_openai)
rating = get_rating(res)
max_attempts = 2
current_attempt = 0
while rating is None and current_attempt < max_attempts:
rating = get_rating(res)
current_attempt += 1
if rating is None:
rating = 0
place_ratings.append((location.name, rating, res))
self.place_ratings = place_ratings
return sorted(place_ratings, key=lambda x: x[1], reverse=True)
def move(self, new_location_name):
if new_location_name == self.location:
return self.location
try:
path = nx.shortest_path(self.world_graph, source=self.location, target=new_location_name)
self.location = new_location_name
except nx.NetworkXNoPath:
print(f"No path found between {self.location} and {new_location_name}")
return self.location
return self.location