retry=tenacity.retry_if_exception_type(ValueError),
                                before_sleep=lambda retry_state: print(f"ValueError occurred: {retry_state.outcome.exception()}, retrying..."),
                            ):
                with attempt:
                    action = self._act()
        except tenacity.RetryError as e:
            action = self.random_action()
        return action
Main loop#
def main(agents, env):
    env.reset()
    for name, agent in agents.items():
        agent.reset()
    for agent_name in env.agent_iter():
        observation, reward, termination, truncation, info = env.last()
        obs_message = agents[agent_name].observe(
            observation, reward, termination, truncation, info)
        print(obs_message)
        if termination or truncation:
            action = None
        else:
            action = agents[agent_name].act()
        print(f'Action: {action}')
        env.step(action)
    env.close()
PettingZooAgent#
The PettingZooAgent extends the GymnasiumAgent to the multi-agent setting. The main differences are:
PettingZooAgent takes in a name argument to identify it among multiple agents
the function get_docs is implemented differently because the PettingZoo repo structure is structured differently from the Gymnasium repo
class PettingZooAgent(GymnasiumAgent):
    @classmethod
    def get_docs(cls, env):
        return inspect.getmodule(env.unwrapped).__doc__
    
    def __init__(self, name, model, env):
        super().__init__(model, env)
        self.name = name
        
    def random_action(self):
        action = self.env.action_space(self.name).sample()
        return action
Rock, Paper, Scissors#
rtdocs_stable/api.python.langchain.com/en/stable/use_cases/agent_simulations/petting_zoo.html