diff --git a/examples/st_game/actions/agent_chat_sum_rel.py b/examples/st_game/actions/agent_chat_sum_rel.py index c6cfda806..ae092602b 100644 --- a/examples/st_game/actions/agent_chat_sum_rel.py +++ b/examples/st_game/actions/agent_chat_sum_rel.py @@ -5,7 +5,6 @@ from metagpt.logs import logger from metagpt.schema import Message -from examples.st_game.roles.st_role import STRole from examples.st_game.actions.st_action import STAction @@ -29,8 +28,8 @@ class AgentChatSumRel(STAction): def _func_fail_default_resp(self) -> str: pass - def run(self, init_role: STRole, target_role: STRole, statements: str) -> str: - def create_prompt_input(init_role: STRole, target_role: STRole, statements: str) -> str: + def run(self, init_role: "STRole", target_role: "STRole", statements: str) -> str: + def create_prompt_input(init_role: "STRole", target_role: "STRole", statements: str) -> str: prompt_input = [statements, init_role.name, target_role.name] return prompt_input diff --git a/examples/st_game/actions/decide_to_talk.py b/examples/st_game/actions/decide_to_talk.py index f8df51d26..e7e3cdd39 100644 --- a/examples/st_game/actions/decide_to_talk.py +++ b/examples/st_game/actions/decide_to_talk.py @@ -5,7 +5,6 @@ from metagpt.logs import logger from metagpt.schema import Message -from examples.st_game.roles.st_role import STRole from examples.st_game.actions.st_action import STAction @@ -29,9 +28,9 @@ class DecideToTalk(STAction): def _func_fail_default_resp(self) -> str: return "yes" - def run(self, init_role: STRole, target_role: STRole, retrieved: dict, *args, **kwargs) -> bool: + def run(self, init_role: "STRole", target_role: "STRole", retrieved: dict, *args, **kwargs) -> bool: """Run action""" - def create_prompt_input(init_role: STRole, target_role: STRole, retrieved: dict) -> str: + def create_prompt_input(init_role: "STRole", target_role: "STRole", retrieved: dict) -> str: scratch = init_role._rc.scratch target_scratch = target_role._rc.scratch last_chat = init_role._rc.memory.get_last_chat(target_role.name) diff --git a/examples/st_game/actions/gen_action_details.py b/examples/st_game/actions/gen_action_details.py index a734315db..a28116111 100644 --- a/examples/st_game/actions/gen_action_details.py +++ b/examples/st_game/actions/gen_action_details.py @@ -8,7 +8,6 @@ import random from metagpt.logs import logger from metagpt.schema import Message -from ..roles.st_role import STRole from ..maze import Maze from .st_action import STAction @@ -35,7 +34,7 @@ class GenActionSector(STAction): fs = ("kitchen") return fs - def run(self, role: STRole, maze: Maze, act_desp: str): + def run(self, role: "STRole", maze: Maze, act_desp: str): def create_prompt_input(role, maze, act_desp): act_world = f"{maze.access_tile(role.scratch.curr_tile)['world']}" @@ -122,7 +121,7 @@ class GenActionArena(STAction): fs = ("kitchen") return fs - def run(self, role: STRole, maze: Maze, act_desp: str, act_world: str, act_sector: str): + def run(self, role: "STRole", maze: Maze, act_desp: str, act_world: str, act_sector: str): def create_prompt_input(role, maze, act_desp, act_world, act_sector): prompt_input = [] # prompt_input += [role.scratch.get_str_name()] @@ -185,7 +184,7 @@ class GenActionObject(STAction): fs = ("bed") return fs - def run(self, role: STRole, act_desp: str, temp_address: str): + def run(self, role: "STRole", act_desp: str, temp_address: str): def create_prompt_input(role, act_desp, temp_address): prompt_input = [] @@ -231,7 +230,7 @@ class GenPronunciatio(STAction): fs = "😋" return fs - def run(self, role: STRole, act_desp: str): + def run(self, role: "STRole", act_desp: str): def create_prompt_input(act_desp): if "(" in act_desp: act_desp = act_desp.split("(")[-1].split(")")[0] @@ -271,7 +270,7 @@ class GenEventTriple(STAction): fs = (role.name, "is", "idle") return fs - def run(self, role: STRole, act_desp: str): + def run(self, role: "STRole", act_desp: str): def create_prompt_input(role, act_desp): if "(" in act_desp: act_desp = act_desp.split("(")[-1].split(")")[0] @@ -309,7 +308,7 @@ class GenActObjDescription(STAction): fs = f"{act_game_object} is idle" return fs - def run(self, role: STRole, act_game_object: str, act_desp: str): + def run(self, role: "STRole", act_game_object: str, act_desp: str): def create_prompt_input(act_game_object, act_desp, role): prompt_input = [act_game_object, role.name, @@ -349,7 +348,7 @@ class GenObjEventTriple(STAction): fs = (act_game_object, "is", "idle") return fs - def run(self, role: STRole, act_game_object, act_obj_desp): + def run(self, role: "STRole", act_game_object, act_obj_desp): def create_prompt_input(act_game_object, act_obj_desp): prompt_input = [act_game_object, act_obj_desp, @@ -385,7 +384,7 @@ class GenActionDetails(STAction): return fs def run(self, - role: STRole, + role: "STRole", act_desp: str, act_dura): maze = role._rc.env.maze diff --git a/examples/st_game/actions/gen_daily_schedule.py b/examples/st_game/actions/gen_daily_schedule.py index 47dc54482..31c6778cd 100644 --- a/examples/st_game/actions/gen_daily_schedule.py +++ b/examples/st_game/actions/gen_daily_schedule.py @@ -7,9 +7,9 @@ import datetime from metagpt.logs import logger from metagpt.schema import Message -from ..roles.st_role import STRole from .st_action import STAction + class GenDailySchedule(STAction): def __init__(self, name="GenDailySchedule", context: list[Message] = None, llm=None): super().__init__(name, context, llm) @@ -41,7 +41,7 @@ class GenDailySchedule(STAction): 'go to bed at 11:00 pm'] return fs - def run(self, role: STRole, wake_up_hour: str): + def run(self, role: "STRole", wake_up_hour: str): def create_prompt_input(role, wake_up_hour): prompt_input = [] prompt_input += [role.scratch.get_str_iss()] diff --git a/examples/st_game/actions/gen_hourly_schedule.py b/examples/st_game/actions/gen_hourly_schedule.py index b823dae01..8b3dd358a 100644 --- a/examples/st_game/actions/gen_hourly_schedule.py +++ b/examples/st_game/actions/gen_hourly_schedule.py @@ -9,9 +9,9 @@ import string from metagpt.logs import logger from metagpt.schema import Message -from ..roles.st_role import STRole from .st_action import STAction + def get_random_alphanumeric(i=6, j=6): """ Returns a random alpha numeric strength that has the length of somewhere @@ -27,6 +27,7 @@ def get_random_alphanumeric(i=6, j=6): x = ''.join(random.choices(string.ascii_letters + string.digits, k=k)) return x + class GenHourlySchedule(STAction): def __init__(self, name="GenHourlySchedule", context: list[Message] = None, llm=None): super().__init__(name, context, llm) @@ -48,11 +49,11 @@ class GenHourlySchedule(STAction): fs = "asleep" return fs - def _generate_schedule_for_given_hour(self, role: STRole, - curr_hour_str, - p_f_ds_hourly_org, - hour_str, - intermission2): + def _generate_schedule_for_given_hour(self, role: "STRole", + curr_hour_str, + p_f_ds_hourly_org, + hour_str, + intermission2=None): def create_prompt_input(persona, curr_hour_str, p_f_ds_hourly_org, @@ -102,19 +103,19 @@ class GenHourlySchedule(STAction): return prompt_input - wake_up_hour = int(wake_up_hour) prompt_template = "generate_hourly_schedule_v2.txt" prompt_input = create_prompt_input(role, curr_hour_str, - p_f_ds_hourly_org, - hour_str, - intermission2) + p_f_ds_hourly_org, + hour_str, + intermission2) + logger.info(f"Role: {role.name} _generate_schedule_for_given_hour prompt_input: {prompt_input}") prompt = self.generate_prompt_with_tmpl_filename(prompt_input, prompt_template) self.fail_default_resp = self._func_fail_default_resp() output = self._run_v1(prompt) return output - def run(self, role: STRole, wake_up_hour: str): + def run(self, role: "STRole", wake_up_hour: str): hour_str = ["00:00 AM", "01:00 AM", "02:00 AM", "03:00 AM", "04:00 AM", "05:00 AM", "06:00 AM", "07:00 AM", "08:00 AM", "09:00 AM", "10:00 AM", "11:00 AM", "12:00 PM", "01:00 PM", "02:00 PM", @@ -131,8 +132,8 @@ class GenHourlySchedule(STAction): n_m1_activity += ["sleeping"] wake_up_hour -= 1 else: - n_m1_activity += [self._generate_schedule_for_given_hour( - role, curr_hour_str, n_m1_activity, hour_str)[0]] + n_m1_activity += [self._generate_schedule_for_given_hour( + role, curr_hour_str, n_m1_activity, hour_str)] # Step 1. Compressing the hourly schedule to the following format: # The integer indicates the number of hours. They should add up to 24. diff --git a/examples/st_game/actions/gen_iter_chat_utt.py b/examples/st_game/actions/gen_iter_chat_utt.py index b3e67e7c6..5b3bb47a8 100644 --- a/examples/st_game/actions/gen_iter_chat_utt.py +++ b/examples/st_game/actions/gen_iter_chat_utt.py @@ -5,7 +5,6 @@ from metagpt.logs import logger from metagpt.schema import Message -from examples.st_game.roles.st_role import STRole from examples.st_game.actions.st_action import STAction from examples.st_game.utils.utils import extract_first_json_dict from examples.st_game.maze import Maze @@ -45,9 +44,9 @@ class GenIterChatUTT(STAction): cleaned_dict["end"] = False return cleaned_dict - def run(self, maze: Maze, init_role: STRole, target_role: STRole, retrieved: dict, curr_context: str, + def run(self, maze: Maze, init_role: "STRole", target_role: "STRole", retrieved: dict, curr_context: str, curr_chat: list[str], *args, **kwargs) -> dict: - def create_prompt_input(maze: Maze, init_role: STRole, target_role: STRole, + def create_prompt_input(maze: Maze, init_role: "STRole", target_role: "STRole", retrieved: dict, curr_context: str, curr_chat: list[str]): role = init_role scratch = role._rc.scratch diff --git a/examples/st_game/actions/new_decomp_schedule.py b/examples/st_game/actions/new_decomp_schedule.py index f38bb56cc..a1ff2d39e 100644 --- a/examples/st_game/actions/new_decomp_schedule.py +++ b/examples/st_game/actions/new_decomp_schedule.py @@ -7,7 +7,6 @@ import datetime from metagpt.logs import logger from metagpt.schema import Message -from examples.st_game.roles.st_role import STRole from examples.st_game.actions.st_action import STAction @@ -86,7 +85,7 @@ class NewDecompSchedule(STAction): return ret def run(self, - role: STRole, + role: "STRole", main_act_dur: int, truncated_act_dur: int, start_time_hour: datetime, @@ -95,7 +94,7 @@ class NewDecompSchedule(STAction): inserted_act_dur: int, *args, **kwargs): - def create_prompt_input(role: STRole, + def create_prompt_input(role: "STRole", main_act_dur: int, truncated_act_dur: int, start_time_hour: datetime, diff --git a/examples/st_game/actions/run_reflect_action.py b/examples/st_game/actions/run_reflect_action.py index cd3d38664..900b70e16 100644 --- a/examples/st_game/actions/run_reflect_action.py +++ b/examples/st_game/actions/run_reflect_action.py @@ -140,7 +140,7 @@ class AgentEventTriple(STAction): output = self._run_v1(prompt) output = (role.scratch.name, output[0], output[1]) - logger.info(f"Run action: {self.__class__.__name__} with result: {output}") + logger.info(f"Role: {role.name} Run action: {self.__class__.__name__} with result: {output}") return output diff --git a/examples/st_game/actions/task_decomp.py b/examples/st_game/actions/task_decomp.py index 13bd01727..3a17f98ac 100644 --- a/examples/st_game/actions/task_decomp.py +++ b/examples/st_game/actions/task_decomp.py @@ -7,7 +7,6 @@ import datetime from metagpt.logs import logger from metagpt.schema import Message -from ..roles.st_role import STRole from ..actions.st_action import STAction @@ -82,13 +81,9 @@ class TaskDecomp(STAction): return fs def run(self, - role: STRole, + role: "STRole", main_act_dur: int, truncated_act_dur: int, - start_time_hour: datetime, - end_time_hour: datetime, - inserted_act: str, - inserted_act_dur: int, *args, **kwargs): def create_prompt_input(role, task, duration): @@ -150,13 +145,9 @@ class TaskDecomp(STAction): prompt_input = create_prompt_input(role, main_act_dur, - truncated_act_dur, - start_time_hour, - end_time_hour, - inserted_act, - inserted_act_dur) + truncated_act_dur) prompt = self.generate_prompt_with_tmpl_filename(prompt_input, "task_decomp_v3.txt") - self.fail_default_resp = self._func_fail_default_resp(main_act_dur, truncated_act_dur) + self.fail_default_resp = self._func_fail_default_resp() output = self._run_v1(prompt) return output diff --git a/examples/st_game/actions/wake_up.py b/examples/st_game/actions/wake_up.py index 911c8ebcf..a9fe598fc 100644 --- a/examples/st_game/actions/wake_up.py +++ b/examples/st_game/actions/wake_up.py @@ -7,7 +7,6 @@ import datetime from metagpt.logs import logger from metagpt.schema import Message -from ..roles.st_role import STRole from ..actions.st_action import STAction @@ -31,7 +30,7 @@ class WakeUp(STAction): fs = 8 return fs - def run(self, role: STRole): + def run(self, role: "STRole"): def create_prompt_input(role): prompt_input = [role.scratch.get_str_iss(), role.scratch.get_str_lifestyle(), diff --git a/examples/st_game/memory/agent_memory.py b/examples/st_game/memory/agent_memory.py index 869f94a4d..722246c6b 100644 --- a/examples/st_game/memory/agent_memory.py +++ b/examples/st_game/memory/agent_memory.py @@ -4,12 +4,14 @@ import json from datetime import datetime +from dataclasses import dataclass from metagpt.memory.memory import Memory from metagpt.schema import Message from metagpt.logs import logger +@dataclass(unsafe_hash=True) class BasicMemory(Message): def __init__(self, memory_id: str, memory_count: int, type_count: int, memory_type: str, depth: int, @@ -44,6 +46,7 @@ class BasicMemory(Message): self.predicate: str = predicate # 谓语 self.object: str = object # 宾语 + self.description = content self.embedding_key: str = embedding_key # 内容与self.content一致 self.poignancy: int = poignancy # importance值 self.keywords: list = keywords # keywords @@ -339,3 +342,25 @@ class AgentMemory(Memory): return self.chat_keywords[target_role_name.lower()][0] else: return False + + def retrieve_relevant_thoughts(self, s_content: str, p_content: str, o_content: str) -> set: + contents = [s_content, p_content, o_content] + + ret = [] + for i in contents: + if i in self.thought_keywords: + ret += self.thought_keywords[i.lower()] + + ret = set(ret) + return ret + + def retrieve_relevant_events(self, s_content: str, p_content: str, o_content: str) -> set: + contents = [s_content, p_content, o_content] + + ret = [] + for i in contents: + if i in self.event_keywords: + ret += self.event_keywords[i] + + ret = set(ret) + return ret diff --git a/examples/st_game/plan/converse.py b/examples/st_game/plan/converse.py index c740629ea..e598e792c 100644 --- a/examples/st_game/plan/converse.py +++ b/examples/st_game/plan/converse.py @@ -7,13 +7,12 @@ from typing import Union, Tuple from metagpt.logs import logger from examples.st_game.maze import Maze -from examples.st_game.roles.st_role import STRole from examples.st_game.memory.retrieve import new_agent_retrieve from examples.st_game.actions.agent_chat_sum_rel import AgentChatSumRel from examples.st_game.actions.gen_iter_chat_utt import GenIterChatUTT -def agent_conversation(maze: Maze, init_role: STRole, target_role: STRole) -> list[str]: +def agent_conversation(maze: Maze, init_role: "STRole", target_role: "STRole") -> list[str]: curr_chat = [] logger.info(f"Role: {init_role.name} starts a conversation with Role: {target_role.name}") @@ -72,8 +71,8 @@ def agent_conversation(maze: Maze, init_role: STRole, target_role: STRole) -> li return curr_chat -def generate_summarize_agent_relationship(init_role: STRole, - target_role: STRole, +def generate_summarize_agent_relationship(init_role: "STRole", + target_role: "STRole", retrieved: dict) -> str: all_embedding_keys = list() for key, val in retrieved.items(): diff --git a/examples/st_game/plan/st_plan.py b/examples/st_game/plan/st_plan.py index c9504b20b..2e96aecc4 100644 --- a/examples/st_game/plan/st_plan.py +++ b/examples/st_game/plan/st_plan.py @@ -4,13 +4,13 @@ import random from typing import Union, Tuple -from datetime import datetime +import datetime import math from metagpt.llm import LLM +from metagpt.logs import logger from ..maze import Maze from ..plan.converse import agent_conversation -from ..roles.st_role import STRole from ..actions.decide_to_talk import DecideToTalk from ..actions.summarize_conv import SummarizeConv from ..actions.new_decomp_schedule import NewDecompSchedule @@ -20,16 +20,17 @@ from ..actions.gen_daily_schedule import GenDailySchedule from ..actions.gen_hourly_schedule import GenHourlySchedule from ..actions.gen_action_details import GenActionDetails from ..utils.utils import get_embedding -from ..memory.retrieve import new_retrieve +from ..memory.retrieve import new_agent_retrieve -def plan(role: STRole, maze: Maze, roles: list[STRole], new_day: bool, retrieved: dict): +def plan(role: "STRole", maze: Maze, roles: list["STRole"], new_day: bool, retrieved: dict): # PART 1: Generate the hourly schedule. if new_day: _long_term_planning(role, new_day) # PART 2: If the current action has expired, we want to create a new plan. - if role.scratch.act_check_finished(): + if role.scratch.act_check_finished(): + logger.info("act_check_finished is True") _determine_action(role, maze) # PART 3: If you perceived an event that needs to be responded to (saw @@ -109,7 +110,7 @@ def _should_react(role: "STRole", retrieved: dict, roles: dict): Determines what form of reaction the role should exihibit given the retrieved values. INPUT - role: Current instance whose action we are determining. + role: Current <"STRole"> instance whose action we are determining. retrieved: A dictionary of that were retrieved from the the role's associative memory. This dictionary takes the following form: @@ -118,10 +119,10 @@ def _should_react(role: "STRole", retrieved: dict, roles: dict): ["events"] = [, ...], ["thoughts"] = [, ...] } roles: A dictionary that contains all role names as keys, and the - instance as values. + <"STRole"> instance as values. """ - def lets_talk(init_role: STRole, target_role: STRole, retrieved: dict): + def lets_talk(init_role: "STRole", target_role: "STRole", retrieved: dict): scratch = init_role._rc.scratch target_scratch = target_role._rc.scratch if (not target_scratch.act_address @@ -153,7 +154,7 @@ def _should_react(role: "STRole", retrieved: dict, roles: dict): return False - def lets_react(init_role: STRole, target_role: STRole, retrieved: dict): + def lets_react(init_role: "STRole", target_role: "STRole", retrieved: dict): scratch = init_role._rc.scratch target_scratch = target_role._rc.scratch if (not target_scratch.act_address @@ -215,7 +216,7 @@ def _should_react(role: "STRole", retrieved: dict, roles: dict): return False -def _chat_react(maze: Maze, role: STRole, reaction_mode: str, roles: list[STRole]): +def _chat_react(maze: Maze, role: "STRole", reaction_mode: str, roles: list["STRole"]): # There are two roles -- the role who is initiating the conversation # and the role who is the target. We get the role instances here. init_role = role @@ -262,7 +263,7 @@ def _chat_react(maze: Maze, role: STRole, reaction_mode: str, roles: list[STRole act_obj_event, act_start_time) -def _create_react(role: STRole, inserted_act: str, inserted_act_dur: int, +def _create_react(role: "STRole", inserted_act: str, inserted_act_dur: int, act_address: str, act_event: Tuple, chatting_with: str, chat: list, chatting_with_buffer: dict, chatting_end_time: datetime, act_pronunciatio: str, act_obj_description: str, act_obj_pronunciatio: str, @@ -320,7 +321,7 @@ def _create_react(role: STRole, inserted_act: str, inserted_act_dur: int, act_start_time) -def _wait_react(role: STRole, reaction_mode: str): +def _wait_react(role: "STRole", reaction_mode: str): scratch = role._rc.scratch inserted_act = f'waiting to start {scratch.act_description.split("(")[-1][:-1]}' @@ -345,7 +346,7 @@ def _wait_react(role: STRole, reaction_mode: str): act_pronunciatio, act_obj_description, act_obj_pronunciatio, act_obj_event) -def generate_convo(maze: Maze, init_role: STRole, target_role: STRole) -> Union[list, int]: +def generate_convo(maze: Maze, init_role: "STRole", target_role: "STRole") -> Union[list, int]: curr_loc = maze.access_tile(init_role._rc.scratch.curr_tile) convo = agent_conversation(maze, init_role, target_role) all_utt = "" @@ -360,12 +361,12 @@ def generate_convo(maze: Maze, init_role: STRole, target_role: STRole) -> Union[ return convo, convo_length -def generate_convo_summary(role: STRole, conv: list) -> str: +def generate_convo_summary(role: "STRole", conv: list) -> str: conv_summary = SummarizeConv().run(conv) return conv_summary -def generate_new_decomp_schedule(role: STRole, inserted_act: str, inserted_act_dur: int, +def generate_new_decomp_schedule(role: "STRole", inserted_act: str, inserted_act_dur: int, start_hour: int, end_hour: int): # Step 1: Setting up the core variables for the function. #

is the role whose schedule we are editing right now. @@ -433,7 +434,7 @@ def generate_new_decomp_schedule(role: STRole, inserted_act: str, inserted_act_d inserted_act_dur) -def _long_term_planning(role: STRole, new_day: bool): +def _long_term_planning(role: "STRole", new_day: bool): """ Formulates the role's daily long-term plan if it is the start of a new day. This basically has two components: first, we create the wake-up hour, @@ -445,6 +446,8 @@ def _long_term_planning(role: STRole, new_day: bool): """ # We start by creating the wake up hour for the role. wake_up_hour = WakeUp().run(role) + wake_up_hour = int(wake_up_hour) + logger.info(f"Role: {role.name} long_term_planning, wake_up_hour: {wake_up_hour}") # When it is a new day, we start by creating the daily_req of the role. # Note that the daily_req is a list of strings that describe the role's @@ -454,8 +457,8 @@ def _long_term_planning(role: STRole, new_day: bool): # if this is the start of generation (so there is no previous day's # daily requirement, or if we are on a new day, we want to create a new # set of daily requirements. - role.scratch.daily_req = GenDailySchedule().run(role, - wake_up_hour) + role.scratch.daily_req = GenDailySchedule().run(role, wake_up_hour) + logger.info(f"Role: {role.name} daily requirements: {role.scratch.daily_req}") elif new_day == "New day": revise_identity(role) @@ -466,11 +469,9 @@ def _long_term_planning(role: STRole, new_day: bool): # Based on the daily_req, we create an hourly schedule for the role, # which is a list of todo items with a time duration (in minutes) that # add up to 24 hours. - role.scratch.f_daily_schedule = GenHourlySchedule().run(role, - wake_up_hour) - role.scratch.f_daily_schedule_hourly_org = (role.scratch - .f_daily_schedule[:]) - + role.scratch.f_daily_schedule = GenHourlySchedule().run(role, wake_up_hour) + logger.info(f"Role: {role.name} f_daily_schedule: {role.scratch.f_daily_schedule}") + role.scratch.f_daily_schedule_hourly_org = (role.scratch.f_daily_schedule[:]) # Added March 4 -- adding plan to the memory. thought = f"This is {role.scratch.name}'s plan for {role.scratch.curr_time.strftime('%A %B %d')}:" @@ -492,7 +493,7 @@ def _long_term_planning(role: STRole, new_day: bool): # print("Done sleeping!") -def _determine_action(role: STRole, maze: Maze): +def _determine_action(role: "STRole", maze: Maze): """ Creates the next action sequence for the role. The main goal of this function is to run "add_new_action" on the role's @@ -593,12 +594,12 @@ def _determine_action(role: STRole, maze: Maze): role.scratch.add_new_action(**new_action_details) -def revise_identity(role: STRole): +def revise_identity(role: "STRole"): p_name = role.scratch.name focal_points = [f"{p_name}'s plan for {role.scratch.get_str_curr_date_str()}.", f"Important recent events for {p_name}'s life."] - retrieved = new_retrieve(role, focal_points) + retrieved = new_agent_retrieve(role, focal_points) statements = "[Statements]\n" for key, val in retrieved.items(): diff --git a/examples/st_game/roles/st_role.py b/examples/st_game/roles/st_role.py index 19afcc2d2..8b86e8c93 100644 --- a/examples/st_game/roles/st_role.py +++ b/examples/st_game/roles/st_role.py @@ -37,6 +37,7 @@ from examples.st_game.utils.mg_ga_transform import save_movement, get_role_envir from examples.st_game.actions.inner_voice_action import AgentWhisperThoughtAction from examples.st_game.actions.run_reflect_action import AgentEventTriple from examples.st_game.reflect.reflect import role_reflect +from examples.st_game.plan.st_plan import plan class STRoleContext(RoleContext): @@ -64,6 +65,7 @@ class STRole(Role): self.start_time = datetime.datetime.strptime(f"{start_date}, 00:00:00", "%B %d, %Y, %H:%M:%S") self.curr_time = datetime.datetime.strptime(curr_time, "%B %d, %Y, %H:%M:%S") self.sec_per_step = sec_per_step + self.inner_voice = False self.game_obj_cleanup = dict() @@ -152,6 +154,7 @@ class STRole(Role): thought = generate_inner_thought(whisper) # init scratch curr_time with self.curr_time + self.inner_voice = True self._rc.scratch.curr_time = self.curr_time created = self._rc.scratch.curr_time if self._rc.scratch.curr_time else datetime.datetime.now() @@ -306,20 +309,22 @@ class STRole(Role): return ret_events - def retrieve(self, focus_points, n=30) -> dict: + def retrieve(self, observed: list) -> dict: # TODO retrieve memories from agent_memory - retrieve_memories = new_agent_retrieve(self, focus_points, n) - return retrieve_memories + retrieved = dict() + for event in observed: + retrieved[event.description] = dict() + retrieved[event.description]["curr_event"] = event - async def plan(self): - # TODO make a plan + relevant_events = self._rc.memory.retrieve_relevant_events( + event.subject, event.predicate, event.object) + retrieved[event.description]["events"] = list(relevant_events) - # TODO judge if start a conversation + relevant_thoughts = self._rc.memory.retrieve_relevant_thoughts( + event.subject, event.predicate, event.object) + retrieved[event.description]["thoughts"] = list(relevant_thoughts) - # TODO update plan - - # TODO re-add result into memory - pass + return retrieved def reflect(self): # TODO reflection if meet reflect condition @@ -496,31 +501,42 @@ class STRole(Role): ret = self.update_role_env() if not ret: # TODO add message + logger.info(f"Role: {self.name} update_role_env return False") return DummyMessage() - # TODO observe + new_day = False + if not self.scratch.curr_time or self.inner_voice: + new_day = "First day" + elif (self.scratch.curr_time.strftime('%A %B %d') + != self.curr_time.strftime('%A %B %d')): + new_day = "New day" + logger.info(f"Role: {self.name} {new_day}") + self._rc.scratch.curr_time = self.curr_time + # get maze_env from self._rc.env, and observe env info + observed = self.observe() - # TODO retrieve, use self._rc.memory 's retrieve functions + # use self._rc.memory 's retrieve functions + retrieved = self.retrieve(observed) - # TODO plan - # plan = self.plan() - # - # # TODO reflect - # - # # TODO execute(feed-back into maze_env) - # next_tile, pronunciatio, description = self.execute(plan) - # role_move = { - # "movement": next_tile, - # "pronunciatio": pronunciatio, - # "description": description, - # "chat": self.scratch.chat - # } - # save_movement(self.name, role_move, step=self.step, sim_code=self.sim_code, curr_time=self.curr_time) + plans = plan(self, self._rc.env.maze, self._rc.env.get_roles(), new_day, retrieved) + + self.reflect() + + # feed-back into maze_env + next_tile, pronunciatio, description = self.execute(plans) + role_move = { + "movement": next_tile, + "pronunciatio": pronunciatio, + "description": description, + "chat": self.scratch.chat + } + save_movement(self.name, role_move, step=self.step, sim_code=self.sim_code, curr_time=self.curr_time) # step update logger.info(f"Role: {self.name} run at {self.step} step on {self.curr_time}") self.step += 1 self.curr_time += datetime.timedelta(seconds=self.sec_per_step) + self.inner_voice = False return DummyMessage()