from typing import NamedTuple from urllib.parse import urlparse, parse_qs from mlagents_envs.base_env import AgentId, GroupId GlobalGroupId = str GlobalAgentId = str class BehaviorIdentifiers(NamedTuple): """ BehaviorIdentifiers is a named tuple of the identifiers that uniquely distinguish an agent encountered in the trainer_controller. The named tuple consists of the fully qualified behavior name, the name of the brain name (corresponds to trainer in the trainer controller) and the team id. In the future, this can be extended to support further identifiers. """ behavior_id: str brain_name: str team_id: int @staticmethod def from_name_behavior_id(name_behavior_id: str) -> "BehaviorIdentifiers": """ Parses a name_behavior_id of the form name?team=0 into a BehaviorIdentifiers NamedTuple. This allows you to access the brain name and team id of an agent :param name_behavior_id: String of behavior params in HTTP format. :returns: A BehaviorIdentifiers object. """ parsed = urlparse(name_behavior_id) name = parsed.path ids = parse_qs(parsed.query) team_id: int = 0 if "team" in ids: team_id = int(ids["team"][0]) return BehaviorIdentifiers( behavior_id=name_behavior_id, brain_name=name, team_id=team_id ) def create_name_behavior_id(name: str, team_id: int) -> str: """ Reconstructs fully qualified behavior name from name and team_id :param name: brain name :param team_id: team ID :return: name_behavior_id """ return name + "?team=" + str(team_id) def get_global_agent_id(worker_id: int, agent_id: AgentId) -> GlobalAgentId: """ Create an agent id that is unique across environment workers using the worker_id. """ return f"agent_{worker_id}-{agent_id}" def get_global_group_id(worker_id: int, group_id: GroupId) -> GlobalGroupId: """ Create a group id that is unique across environment workers when using the worker_id. """ return f"group_{worker_id}-{group_id}"