class_docstr: The LevelManager is in charge of managing a level in the hierarchy of control. Each level can have one or more
  CompositeAgents and an environment to control. Its API is double-folded:
      1. Expose services of a LevelManager such as training the level, or stepping it (while behaving according to a
         LevelBehaviorScheme, e.g. as SelfPlay between two identical agents). These methods are implemented in the
         LevelManagerLogic class.
      2. Disguise as appearing as an environment to the upper level control so it will believe it is interacting with
         an environment. This includes stepping through what appears to be a regular environment, setting its phase
         or resetting it. These methods are implemented directly in LevelManager as it inherits from
         EnvironmentInterface.
docstr: A level manager controls a single or multiple composite agents and a single environment.
  The environment can be either a real environment or another level manager behaving as an environment.
  :param agents: a single agent or a dictionary of agents or composite agents to control
  :param environment: an environment or level manager to control
  :param real_environment: the real environment that is is acted upon. if this is None (which it should be for
   the most bottom level), it will be replaced by the environment parameter. For simple RL schemes, where there
   is only a single level of hierarchy, this removes the requirement of defining both the environment and the
   real environment, as they are the same.
  :param steps_limit: the number of time steps to run when stepping the internal components
  :param should_reset_agent_state_after_time_limit_passes: reset the agent after stepping for steps_limit
  :param name: the level's name
  :param spaces_definition: external definition of spaces for when we don't have an environment (e.g. batch-rl)
docstr_tok: ["A","level","manager","controls","a","single","or","multiple","composite","agents","and","a","single","environment",".","The","environment","can","be","either","a","real","environment","or","another","level","manager","behaving","as","an","environment",".",":","param","agents",":","a","single","agent","or","a","dictionary","of","agents","or","composite","agents","to","control",":","param","environment",":","an","environment","or","level","manager","to","control",":","param","real_environment",":","the","real","environment","that","is","is","acted","upon",".","if","this","is","None","(","which","it","should","be","for","the","most","bottom","level",")",",","it","will","be","replaced","by","the","environment","parameter",".","For","simple","RL","schemes",",","where","there","is","only","a","single","level","of","hierarchy",",","this","removes","the","requirement","of","defining","both","the","environment","and","the","real","environment",",","as","they","are","the","same",".",":","param","steps_limit",":","the","number","of","time","steps","to","run","when","stepping","the","internal","components",":","param","should_reset_agent_state_after_time_limit_passes",":","reset","the","agent","after","stepping","for","steps_limit",":","param","name",":","the","level","'s","name",":","param","spaces_definition",":","external","definition","of","spaces","for","when","we","do","n't","have","an","environment","(","e.g",".","batch-rl",")"]
code: def __init__(
      self,
      name: str,
      agents: Union[AgentInterface, Dict[str, AgentInterface]],
      environment: Union["LevelManager", Environment],
      real_environment: Environment = None,
      steps_limit: EnvironmentSteps = EnvironmentSteps(1),
      should_reset_agent_state_after_time_limit_passes: bool = False,
      spaces_definition: SpacesDefinition = None,
  ):
      """
      A level manager controls a single or multiple composite agents and a single environment.
      The environment can be either a real environment or another level manager behaving as an environment.
      :param agents: a single agent or a dictionary of agents or composite agents to control
      :param environment: an environment or level manager to control
      :param real_environment: the real environment that is is acted upon. if this is None (which it should be for
       the most bottom level), it will be replaced by the environment parameter. For simple RL schemes, where there
       is only a single level of hierarchy, this removes the requirement of defining both the environment and the
       real environment, as they are the same.
      :param steps_limit: the number of time steps to run when stepping the internal components
      :param should_reset_agent_state_after_time_limit_passes: reset the agent after stepping for steps_limit
      :param name: the level's name
      :param spaces_definition: external definition of spaces for when we don't have an environment (e.g. batch-rl)
      """
      super().__init__()
  
      if not isinstance(agents, dict):
          # insert the single composite agent to a dictionary for compatibility
          agents = {agents.name: agents}
      if real_environment is None:
          self._real_environment = real_environment = environment
      self.agents = agents
      self.environment = environment
      self.real_environment = real_environment
      self.steps_limit = steps_limit
      self.should_reset_agent_state_after_time_limit_passes = (
          should_reset_agent_state_after_time_limit_passes
      )
      self.full_name_id = self.name = name
      self._phase = RunPhase.HEATUP
      self.reset_required = False
  
      # set self as the parent for all the composite agents
      for agent in self.agents.values():
          agent.parent = self
          agent.parent_level_manager = self
  
      # create all agents in all composite_agents - we do it here so agents will have access to their level manager
      for agent in self.agents.values():
          if isinstance(agent, CompositeAgent):
              agent.create_agents()
  
      if not isinstance(self.steps_limit, EnvironmentSteps):
          raise ValueError(
              "The num consecutive steps for acting must be defined in terms of environment steps"
          )
      self.build(spaces_definition)
  
      # there are cases where we don't have an environment. e.g. in batch-rl or in imitation learning.
      self.last_env_response = (
          self.real_environment.last_env_response
          if self.real_environment
          else None
      )
  
      self.parent_graph_manager = None
  
imports: import copy
  from typing import Union, Dict
  from rl_coach.agents.composite_agent import CompositeAgent
  from rl_coach.agents.agent_interface import AgentInterface
  from rl_coach.core_types import EnvResponse, ActionInfo, RunPhase, ActionType, EnvironmentSteps, Transition
  from rl_coach.environments.environment import Environment
  from rl_coach.environments.environment_interface import EnvironmentInterface
  from rl_coach.saver import SaverCollection
  from rl_coach.spaces import ActionSpace, SpacesDefinition
label_desc: Use image node_id 1 to create a new LevelManager object from inherited base classes: EnvironmentInterface with example: obj = LevelManager(name, agents, environment, real_environment, steps_limit, should_reset_agent_state_after_time_limit_passes, spaces_definition)