mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-08 15:05:17 +02:00
fix format
This commit is contained in:
parent
b568b8f4a0
commit
94a04afc72
16 changed files with 89 additions and 62 deletions
|
|
@ -3,6 +3,7 @@
|
|||
# @Desc :
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from metagpt.const import MESSAGE_ROUTE_TO_ALL
|
||||
|
||||
|
||||
|
|
@ -16,11 +17,11 @@ class RoleType(Enum):
|
|||
|
||||
|
||||
class RoleState(Enum):
|
||||
ALIVE = "alive" # the role is alive
|
||||
DEAD = "dead" # killed or poisoned
|
||||
KILLED = "killed" # killed by werewolf or voting
|
||||
POISONED = "poisoned" # killed by poison
|
||||
SAVED = "saved" # saved by antidote
|
||||
ALIVE = "alive" # the role is alive
|
||||
DEAD = "dead" # killed or poisoned
|
||||
KILLED = "killed" # killed by werewolf or voting
|
||||
POISONED = "poisoned" # killed by poison
|
||||
SAVED = "saved" # saved by antidote
|
||||
PROTECTED = "projected" # projected by guard
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# @Desc : werewolf observation/action space and its action definition
|
||||
|
||||
from pydantic import ConfigDict, Field
|
||||
from gymnasium import spaces
|
||||
from pydantic import ConfigDict, Field
|
||||
|
||||
from metagpt.environment.base_env_space import BaseEnvAction, BaseEnvActionType
|
||||
from metagpt.environment.werewolf.const import STEP_INSTRUCTIONS, RoleState
|
||||
|
|
@ -11,10 +11,10 @@ from metagpt.environment.werewolf.const import STEP_INSTRUCTIONS, RoleState
|
|||
|
||||
class EnvActionType(BaseEnvActionType):
|
||||
NONE = 0 # no action to run, just get observation
|
||||
WOLF_KILL = 1 # wolf kill someone
|
||||
VOTE_KILL = 2 # vote kill someone
|
||||
WITCH_POISON = 3 # witch poison someone
|
||||
WITCH_SAVE = 4 # witch save someone
|
||||
WOLF_KILL = 1 # wolf kill someone
|
||||
VOTE_KILL = 2 # vote kill someone
|
||||
WITCH_POISON = 3 # witch poison someone
|
||||
WITCH_SAVE = 4 # witch save someone
|
||||
GUARD_PROTECT = 5 # guard protect someone
|
||||
PROGRESS_STEP = 6 # step increment
|
||||
|
||||
|
|
@ -28,22 +28,25 @@ class EnvAction(BaseEnvAction):
|
|||
|
||||
|
||||
def get_observation_space(player_num: int) -> spaces.Dict:
|
||||
space = spaces.Dict({
|
||||
"step_idx": spaces.Discrete(len(STEP_INSTRUCTIONS)),
|
||||
"player_states": spaces.MultiDiscrete([len(RoleState)] * player_num),
|
||||
"vote_counts": spaces.MultiDiscrete([player_num - 1] * player_num),
|
||||
|
||||
"player_current_dead": None, # TODO
|
||||
"winner": spaces.Text(16),
|
||||
"win_reason": spaces.Text(64)
|
||||
})
|
||||
space = spaces.Dict(
|
||||
{
|
||||
"step_idx": spaces.Discrete(len(STEP_INSTRUCTIONS)),
|
||||
"player_states": spaces.MultiDiscrete([len(RoleState)] * player_num),
|
||||
"vote_counts": spaces.MultiDiscrete([player_num - 1] * player_num),
|
||||
"player_current_dead": None, # TODO
|
||||
"winner": spaces.Text(16),
|
||||
"win_reason": spaces.Text(64),
|
||||
}
|
||||
)
|
||||
return space
|
||||
|
||||
|
||||
def get_action_space() -> spaces.Dict:
|
||||
space = spaces.Dict({
|
||||
"action_type": spaces.Discrete(len(EnvActionType)),
|
||||
"player_name": spaces.Text(16), # the player to do the action
|
||||
"target_player_name": spaces.Text(16) # the target player who take the action
|
||||
})
|
||||
space = spaces.Dict(
|
||||
{
|
||||
"action_type": spaces.Discrete(len(EnvActionType)),
|
||||
"player_name": spaces.Text(16), # the player to do the action
|
||||
"target_player_name": spaces.Text(16), # the target player who take the action
|
||||
}
|
||||
)
|
||||
return space
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ from pydantic import ConfigDict, Field
|
|||
|
||||
from metagpt.environment.base_env import ExtEnv, mark_as_readable, mark_as_writeable
|
||||
from metagpt.environment.base_env_space import BaseEnvObsParams
|
||||
from metagpt.environment.werewolf.const import STEP_INSTRUCTIONS, RoleState, RoleType
|
||||
from metagpt.environment.werewolf.env_space import EnvAction, EnvActionType
|
||||
from metagpt.logs import logger
|
||||
from metagpt.environment.werewolf.const import STEP_INSTRUCTIONS, RoleState, RoleType
|
||||
|
||||
|
||||
class WerewolfExtEnv(ExtEnv):
|
||||
|
|
@ -61,7 +61,6 @@ class WerewolfExtEnv(ExtEnv):
|
|||
return {
|
||||
"game_setup": self.game_setup,
|
||||
"step_idx": self.step_idx,
|
||||
|
||||
"living_players": self.living_players,
|
||||
"werewolf_players": self.werewolf_players,
|
||||
"player_hunted": self.player_hunted,
|
||||
|
|
@ -69,7 +68,7 @@ class WerewolfExtEnv(ExtEnv):
|
|||
"witch_poison_left": self.witch_poison_left,
|
||||
"witch_antidote_left": self.witch_antidote_left,
|
||||
"winner": self.winner,
|
||||
"win_reason": self.win_reason
|
||||
"win_reason": self.win_reason,
|
||||
}
|
||||
|
||||
def step(self, action: EnvAction) -> tuple[dict[str, Any], float, bool, bool, dict[str, Any]]:
|
||||
|
|
@ -271,8 +270,9 @@ class WerewolfExtEnv(ExtEnv):
|
|||
# self.player_hunted = Counter(hunted_all).most_common()[0][0]
|
||||
self.player_hunted = player_name
|
||||
|
||||
def _witch_poison_or_save_someone(self, witch_name: str, player_name: str = None,
|
||||
state: RoleState = RoleState.POISONED):
|
||||
def _witch_poison_or_save_someone(
|
||||
self, witch_name: str, player_name: str = None, state: RoleState = RoleState.POISONED
|
||||
):
|
||||
if not self._check_valid_role(witch_name, RoleType.WITCH.value):
|
||||
return
|
||||
if not self._check_player_continue(player_name):
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ class InstructSpeak(Action):
|
|||
name: str = "InstructSpeak"
|
||||
|
||||
async def run(self, step_idx, living_players, werewolf_players, player_hunted, player_current_dead):
|
||||
instruction_info = STEP_INSTRUCTIONS.get(step_idx, {"content": "Unknown instruction.", "send_to": {},
|
||||
"restricted_to": {}})
|
||||
instruction_info = STEP_INSTRUCTIONS.get(
|
||||
step_idx, {"content": "Unknown instruction.", "send_to": {}, "restricted_to": {}}
|
||||
)
|
||||
content = instruction_info["content"]
|
||||
if "{living_players}" in content and "{werewolf_players}" in content:
|
||||
content = content.format(living_players=living_players, werewolf_players=werewolf_players)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from metagpt.ext.werewolf.actions.common_actions import NighttimeWhispers
|
||||
from metagpt.environment.werewolf.const import RoleActionRes
|
||||
from metagpt.ext.werewolf.actions.common_actions import NighttimeWhispers
|
||||
|
||||
|
||||
class Save(NighttimeWhispers):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import re
|
||||
|
||||
from pydantic import SerializeAsAny, Field
|
||||
from pydantic import Field, SerializeAsAny
|
||||
|
||||
from metagpt.actions.action import Action
|
||||
from metagpt.environment.werewolf.const import RoleState, RoleType
|
||||
from metagpt.ext.werewolf.actions import (
|
||||
ACTIONS,
|
||||
AddNewExperiences,
|
||||
|
|
@ -12,10 +14,8 @@ from metagpt.ext.werewolf.actions import (
|
|||
Speak,
|
||||
)
|
||||
from metagpt.ext.werewolf.schema import RoleExperience, WwMessage
|
||||
from metagpt.environment.werewolf.const import RoleType, RoleState
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles import Role
|
||||
from metagpt.actions.action import Action
|
||||
|
||||
|
||||
class BasePlayer(Role):
|
||||
|
|
@ -129,7 +129,7 @@ class BasePlayer(Role):
|
|||
sent_from=self.name,
|
||||
cause_by=type(todo),
|
||||
send_to={},
|
||||
restricted_to=restricted_to
|
||||
restricted_to=restricted_to,
|
||||
)
|
||||
|
||||
self.experiences.append(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
from metagpt.environment.werewolf.const import RoleType
|
||||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
|
||||
|
||||
class Guard(BasePlayer):
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from metagpt.environment.werewolf.const import RoleType
|
||||
from metagpt.ext.werewolf.actions import Speak
|
||||
from metagpt.ext.werewolf.roles import BasePlayer
|
||||
from metagpt.logs import logger
|
||||
from metagpt.ext.werewolf.schema import WwMessage
|
||||
from metagpt.environment.werewolf.const import RoleType
|
||||
from metagpt.logs import logger
|
||||
|
||||
|
||||
async def _act(self):
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import re
|
||||
from typing import Union
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
|
||||
from metagpt.actions.add_requirement import UserRequirement
|
||||
from metagpt.const import DEFAULT_WORKSPACE_ROOT
|
||||
from metagpt.environment.werewolf.const import STEP_INSTRUCTIONS, RoleType
|
||||
from metagpt.environment.werewolf.const import (
|
||||
STEP_INSTRUCTIONS,
|
||||
RoleActionRes,
|
||||
RoleState,
|
||||
RoleType,
|
||||
)
|
||||
from metagpt.environment.werewolf.env_space import EnvAction, EnvActionType
|
||||
from metagpt.ext.werewolf.actions import Hunt, Poison, Protect, Save, Verify
|
||||
from metagpt.ext.werewolf.actions.moderator_actions import (
|
||||
|
|
@ -12,10 +17,9 @@ from metagpt.ext.werewolf.actions.moderator_actions import (
|
|||
InstructSpeak,
|
||||
ParseSpeak,
|
||||
)
|
||||
from metagpt.logs import logger
|
||||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
from metagpt.ext.werewolf.schema import WwMessage
|
||||
from metagpt.environment.werewolf.const import RoleState, RoleActionRes
|
||||
from metagpt.logs import logger
|
||||
|
||||
|
||||
class Moderator(BasePlayer):
|
||||
|
|
@ -73,11 +77,17 @@ class Moderator(BasePlayer):
|
|||
|
||||
msg_cause_by = latest_msg.cause_by
|
||||
if msg_cause_by == Hunt:
|
||||
self.rc.env.step(EnvAction(action_type=EnvActionType.WOLF_KILL, player_name=latest_msg.send_from,
|
||||
target_player_name=target))
|
||||
self.rc.env.step(
|
||||
EnvAction(
|
||||
action_type=EnvActionType.WOLF_KILL, player_name=latest_msg.send_from, target_player_name=target
|
||||
)
|
||||
)
|
||||
elif msg_cause_by == Protect:
|
||||
self.rc.env.step(EnvAction(action_type=EnvActionType.GUARD_PROTECT, player_name=latest_msg.send_from,
|
||||
target_player_name=target))
|
||||
self.rc.env.step(
|
||||
EnvAction(
|
||||
action_type=EnvActionType.GUARD_PROTECT, player_name=latest_msg.send_from, target_player_name=target
|
||||
)
|
||||
)
|
||||
elif msg_cause_by == Verify:
|
||||
if target in self.werewolf_players:
|
||||
msg_content = f"{target} is a werewolf"
|
||||
|
|
@ -92,8 +102,13 @@ class Moderator(BasePlayer):
|
|||
msg_content = "You have no antidote left and thus can not save the player"
|
||||
restricted_to = {RoleType.MODERATOR.value, RoleType.WITCH.value}
|
||||
else:
|
||||
self.rc.env.step(EnvAction(action_type=EnvActionType.WITCH_SAVE, player_name=latest_msg.send_from,
|
||||
target_player_name=target))
|
||||
self.rc.env.step(
|
||||
EnvAction(
|
||||
action_type=EnvActionType.WITCH_SAVE,
|
||||
player_name=latest_msg.send_from,
|
||||
target_player_name=target,
|
||||
)
|
||||
)
|
||||
elif msg_cause_by == Poison:
|
||||
if RoleActionRes.PASS.value in latest_msg_content.lower():
|
||||
pass
|
||||
|
|
@ -101,8 +116,13 @@ class Moderator(BasePlayer):
|
|||
msg_content = "You have no poison left and thus can not poison the player"
|
||||
restricted_to = {RoleType.MODERATOR.value, RoleType.WITCH.value}
|
||||
else:
|
||||
self.rc.env.step(EnvAction(action_type=EnvActionType.WITCH_POISON, player_name=latest_msg.send_from,
|
||||
target_player_name=target))
|
||||
self.rc.env.step(
|
||||
EnvAction(
|
||||
action_type=EnvActionType.WITCH_POISON,
|
||||
player_name=latest_msg.send_from,
|
||||
target_player_name=target,
|
||||
)
|
||||
)
|
||||
|
||||
return msg_content, restricted_to
|
||||
|
||||
|
|
@ -179,7 +199,7 @@ class Moderator(BasePlayer):
|
|||
sent_from=self.name,
|
||||
cause_by=InstructSpeak,
|
||||
send_to=msg_to_send_to,
|
||||
restricted_to=msg_restricted_to
|
||||
restricted_to=msg_restricted_to,
|
||||
)
|
||||
self.rc.env.step(EnvAction(action_type=EnvActionType.PROGRESS_STEP)) # to update step_idx
|
||||
|
||||
|
|
@ -192,7 +212,7 @@ class Moderator(BasePlayer):
|
|||
sent_from=self.name,
|
||||
cause_by=ParseSpeak,
|
||||
send_to={},
|
||||
restricted_to=msg_restricted_to
|
||||
restricted_to=msg_restricted_to,
|
||||
)
|
||||
|
||||
elif isinstance(todo, AnnounceGameResult):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
from metagpt.environment.werewolf.const import RoleType
|
||||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
|
||||
|
||||
class Seer(BasePlayer):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
from metagpt.environment.werewolf.const import RoleType
|
||||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
|
||||
|
||||
class Villager(BasePlayer):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from metagpt.environment.werewolf.const import RoleType
|
||||
from metagpt.ext.werewolf.actions import Impersonate, Speak
|
||||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
from metagpt.environment.werewolf.const import RoleType
|
||||
|
||||
|
||||
class Werewolf(BasePlayer):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from metagpt.environment.werewolf.const import RoleType
|
||||
from metagpt.ext.werewolf.actions import InstructSpeak, Poison, Save, Speak
|
||||
from metagpt.ext.werewolf.roles.base_player import BasePlayer
|
||||
from metagpt.environment.werewolf.const import RoleType
|
||||
|
||||
|
||||
class Witch(BasePlayer):
|
||||
|
|
|
|||
|
|
@ -23,4 +23,6 @@ class WerewolfGame(Team):
|
|||
def run_project(self, idea):
|
||||
"""Run a project from user instruction."""
|
||||
self.idea = idea
|
||||
self.env.publish_message(WwMessage(role="User", content=idea, cause_by=UserRequirement, restricted_to={"Moderator"}))
|
||||
self.env.publish_message(
|
||||
WwMessage(role="User", content=idea, cause_by=UserRequirement, restricted_to={"Moderator"})
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# @Desc : the unittest of WerewolfExtEnv
|
||||
|
||||
from metagpt.environment.werewolf.werewolf_ext_env import WerewolfExtEnv
|
||||
from metagpt.environment.werewolf.const import RoleState
|
||||
from metagpt.environment.werewolf.werewolf_ext_env import WerewolfExtEnv
|
||||
from metagpt.roles.role import Role
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class TestExperiencesOperation:
|
|||
RoleExperience(
|
||||
profile="Witch",
|
||||
reflection="The game is intense with two players claiming to be the Witch and one claiming to be the Seer. "
|
||||
"Player4's behavior is suspicious.",
|
||||
"Player4's behavior is suspicious.",
|
||||
response="",
|
||||
outcome="",
|
||||
round_id=test_round_id,
|
||||
|
|
@ -26,7 +26,7 @@ class TestExperiencesOperation:
|
|||
RoleExperience(
|
||||
profile="Witch",
|
||||
reflection="The game is in a critical state with only three players left, "
|
||||
"and I need to make a wise decision to save Player7 or not.",
|
||||
"and I need to make a wise decision to save Player7 or not.",
|
||||
response="",
|
||||
outcome="",
|
||||
round_id=test_round_id,
|
||||
|
|
@ -35,7 +35,7 @@ class TestExperiencesOperation:
|
|||
RoleExperience(
|
||||
profile="Seer",
|
||||
reflection="Player1, who is a werewolf, falsely claimed to be a Seer, and Player6, who might be a Witch, "
|
||||
"sided with him. I, as the real Seer, am under suspicion.",
|
||||
"sided with him. I, as the real Seer, am under suspicion.",
|
||||
response="",
|
||||
outcome="",
|
||||
round_id=test_round_id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue