diff --git a/examples/st_game/README.md b/examples/st_game/README.md index 28c4efec4..114f7f672 100644 --- a/examples/st_game/README.md +++ b/examples/st_game/README.md @@ -17,6 +17,8 @@ # updated This can be used to achieve docking of simulation data without changing the GA code. Otherwise, the GA code must be modified to adapt to the MG output path. +If you don't want to start from 0, copy other simulation directories under `generative_agents/environment/frontend_server/storage/` to `examples/st_game/storage`, and select a directory named `fork_sim_code`. + ### Backend service startup The execution entry is `python3 run_st_game.py "Host a open lunch party at 13:00 pm" "base_the_ville_isabella_maria_klaus" "test_sim" 10` or diff --git a/examples/st_game/README_CN.md b/examples/st_game/README_CN.md index 4e1b3f439..84470f5c2 100644 --- a/examples/st_game/README_CN.md +++ b/examples/st_game/README_CN.md @@ -14,7 +14,9 @@ # 更新为 STORAGE_PATH = Path("{path/to/ga/storage}") TEMP_STORAGE_PATH = Path("{path/to/ga/temp_storage}") ``` -这样可用实现不改变GA代码情况下,实现仿真数据的对接。不然得修改GA的代码来适配MG的输出路径。 +这样可用实现不改变GA代码情况下,实现仿真数据的对接。不然得修改GA的代码来适配MG的输出路径。 + +如果你不想从0开始启动,拷贝`generative_agents/environment/frontend_server/storage/`下的其他仿真目录到`examples/st_game/storage`,并选择一个目录名作为`fork_sim_code`。 ### 后端服务启动 执行入口为:`python3 run_st_game.py "Host a open lunch party at 13:00 pm" "base_the_ville_isabella_maria_klaus" "test_sim" 10` diff --git a/examples/st_game/memory/scratch.py b/examples/st_game/memory/scratch.py index 1c30f1829..6fc687901 100644 --- a/examples/st_game/memory/scratch.py +++ b/examples/st_game/memory/scratch.py @@ -11,7 +11,6 @@ from pydantic import ( Field, field_serializer, field_validator, - model_validator, ) from metagpt.utils.common import read_json_file, write_json_file @@ -68,11 +67,11 @@ class Scratch(BaseModel): act_duration: Optional[int] = Field(default=None) act_description: Optional[str] = Field(default=None) act_pronunciatio: Optional[str] = Field(default=None) - act_event: tuple[str, Optional[str], Optional[str]] = (None, None, None) + act_event: list[Optional[str]] = [None, None, None] act_obj_description: Optional[str] = Field(default=None) act_obj_pronunciatio: Optional[str] = Field(default=None) - act_obj_event: tuple[Optional[str], Optional[str], Optional[str]] = (None, None, None) + act_obj_event: list[Optional[str]] = [None, None, None] chatting_with: Optional[str] = Field(default=None) chat: Optional[str] = Field(default=None) @@ -80,15 +79,7 @@ class Scratch(BaseModel): chatting_end_time: Optional[datetime] = Field(default=None) act_path_set: bool = False - planned_path: list[str] = Field(default=[]) - - @model_validator(mode="after") - @classmethod - def check_values(cls, values): - if "name" in values: - values["act_event"] = (values["name"], None, None) - values["act_obj_event"] = (values["name"], None, None) - return values + planned_path: list[list[int]] = Field(default=[]) @field_validator("curr_time", "act_start_time", "chatting_end_time", mode="before") @classmethod @@ -103,7 +94,7 @@ class Scratch(BaseModel): return time_filed @classmethod - def set_scratch_path(cls, f_saved: Path): + def init_scratch_from_path(cls, f_saved: Path): scratch_load = read_json_file(f_saved) scratch = Scratch(**scratch_load) return scratch @@ -253,21 +244,21 @@ class Scratch(BaseModel): def get_curr_event(self): if not self.act_address: - return (self.name, None, None) + return self.name, None, None else: return self.act_event def get_curr_event_and_desc(self): if not self.act_address: - return (self.name, None, None, None) + return self.name, None, None, None else: - return (self.act_event[0], self.act_event[1], self.act_event[2], self.act_description) + return self.act_event[0], self.act_event[1], self.act_event[2], self.act_description def get_curr_obj_event_and_desc(self): if not self.act_address: - return ("", None, None, None) + return "", None, None, None else: - return (self.act_address, self.act_obj_event[1], self.act_obj_event[2], self.act_obj_description) + return self.act_address, self.act_obj_event[1], self.act_obj_event[2], self.act_obj_description def add_new_action( self, diff --git a/examples/st_game/roles/st_role.py b/examples/st_game/roles/st_role.py index af4188733..d5dd994f9 100644 --- a/examples/st_game/roles/st_role.py +++ b/examples/st_game/roles/st_role.py @@ -153,7 +153,7 @@ class STRole(Role): self.rc.spatial_memory.set_mem_path(f_saved=sp_mem_saved) scratch_f_saved = self.role_storage_path.joinpath("bootstrap_memory/scratch.json") - self.rc.scratch = Scratch.set_scratch_path(f_saved=scratch_f_saved) + self.rc.scratch = Scratch.init_scratch_from_path(f_saved=scratch_f_saved) logger.info(f"Role: {self.name} loaded role's memory from {str(self.role_storage_path)}") diff --git a/examples/st_game/run_st_game.py b/examples/st_game/run_st_game.py index 09ae8f0ec..304bf24ba 100644 --- a/examples/st_game/run_st_game.py +++ b/examples/st_game/run_st_game.py @@ -24,7 +24,6 @@ async def startup( ): town = StanfordTown() logger.info("StanfordTown init environment") - print(f"{fork_sim_code}\t{sim_code}{temp_storage_path}\t{investment}\t{n_round}") # copy `storage/{fork_sim_code}` to `storage/{sim_code}` copy_folder(str(STORAGE_PATH.joinpath(fork_sim_code)), str(STORAGE_PATH.joinpath(sim_code))) @@ -71,9 +70,9 @@ def main( """ Args: idea: idea works as an `inner voice` to the first agent. - fork_sim_code: old simulation name to start with + fork_sim_code: old simulation name to start with, choose one inside `generative_agents/environment/frontend_server/storage/` sim_code: new simulation name to save simulation result - temp_storage_path: generative_agents storage path inside `environment/frontend_server` to + temp_storage_path: generative_agents temp_storage path inside `environment/frontend_server` to interact. investment: the investment of running agents n_round: rounds to run agents """