docstr: :param agent_parameters: A AgentParameters class instance with all the agent parameters
docstr_tok: [":","param","agent_parameters",":","A","AgentParameters","class","instance","with","all","the","agent","parameters"]
code: def __init__(
      self,
      agent_parameters: AgentParameters,
      parent: Union["LevelManager", "CompositeAgent"] = None,
  ):
      """
      :param agent_parameters: A AgentParameters class instance with all the agent parameters
      """
      super().__init__()
      # use seed
      if agent_parameters.task_parameters.seed is not None:
          random.seed(agent_parameters.task_parameters.seed)
          np.random.seed(agent_parameters.task_parameters.seed)
      else:
          # we need to seed the RNG since the different processes are initialized with the same parent seed
          random.seed()
          np.random.seed()
  
      self.ap = agent_parameters
      self.task_id = self.ap.task_parameters.task_index
      self.is_chief = self.task_id == 0
      self.shared_memory = (
          type(agent_parameters.task_parameters)
          == DistributedTaskParameters
          and self.ap.memory.shared_memory
      )
      if self.shared_memory:
          self.shared_memory_scratchpad = (
              self.ap.task_parameters.shared_memory_scratchpad
          )
      self.parent = parent
      self.parent_level_manager = None
      # TODO this needs to be sorted out. Why the duplicates for the agent's name?
      self.full_name_id = (
          agent_parameters.full_name_id
      ) = self.name = agent_parameters.name
  
      if (
          type(agent_parameters.task_parameters)
          == DistributedTaskParameters
      ):
          screen.log_title(
              "Creating agent - name: {} task id: {} (may take up to 30 seconds due to "
              "tensorflow wake up time)".format(
                  self.full_name_id, self.task_id
              )
          )
      else:
          screen.log_title(
              "Creating agent - name: {}".format(self.full_name_id)
          )
      self.imitation = False
      self.agent_logger = Logger()
      self.agent_episode_logger = EpisodeLogger()
  
      # get the memory
      # - distributed training + shared memory:
      #   * is chief?  -> create the memory and add it to the scratchpad
      #   * not chief? -> wait for the chief to create the memory and then fetch it
      # - non distributed training / not shared memory:
      #   * create memory
      memory_name = self.ap.memory.path.split(":")[1]
      self.memory_lookup_name = self.full_name_id + "." + memory_name
      if self.shared_memory and not self.is_chief:
          self.memory = self.shared_memory_scratchpad.get(
              self.memory_lookup_name
          )
      else:
          # modules
          self.memory = (
              dynamic_import_and_instantiate_module_from_params(
                  self.ap.memory
              )
          )
  
          if hasattr(self.ap.memory, "memory_backend_params"):
              self.memory_backend = get_memory_backend(
                  self.ap.memory.memory_backend_params
              )
  
              if (
                  self.ap.memory.memory_backend_params.run_type
                  != "trainer"
              ):
                  self.memory.set_memory_backend(self.memory_backend)
  
          if self.shared_memory and self.is_chief:
              self.shared_memory_scratchpad.add(
                  self.memory_lookup_name, self.memory
              )
  
      # set devices
      if (
          type(agent_parameters.task_parameters)
          == DistributedTaskParameters
      ):
          self.has_global = True
          self.replicated_device = (
              agent_parameters.task_parameters.device
          )
          self.worker_device = "/job:worker/task:{}".format(
              self.task_id
          )
          if agent_parameters.task_parameters.use_cpu:
              self.worker_device += "/cpu:0"
          else:
              self.worker_device += "/device:GPU:0"
      else:
          self.has_global = False
          self.replicated_device = None
          if agent_parameters.task_parameters.use_cpu:
              self.worker_device = Device(DeviceType.CPU)
          else:
              self.worker_device = [
                  Device(DeviceType.GPU, i)
                  for i in range(
                      agent_parameters.task_parameters.num_gpu
                  )
              ]
  
      # filters
      self.input_filter = self.ap.input_filter
      self.input_filter.set_name("input_filter")
      self.output_filter = self.ap.output_filter
      self.output_filter.set_name("output_filter")
      self.pre_network_filter = self.ap.pre_network_filter
      self.pre_network_filter.set_name("pre_network_filter")
  
      device = (
          self.replicated_device
          if self.replicated_device
          else self.worker_device
      )
  
      # TODO-REMOVE This is a temporary flow dividing to 3 modes. To be converged to a single flow once distributed tf
      #  is removed, and Redis is used for sharing data between local workers.
      # Filters MoW will be split between different configurations
      # 1. Distributed coach synchrnization type (=distributed across multiple nodes) - Redis based data sharing + numpy arithmetic backend
      # 2. Distributed TF (=distributed on a single node, using distributed TF) - TF for both data sharing and arithmetic backend
      # 3. Single worker (=both TF and Mxnet) - no data sharing needed + numpy arithmetic backend
  
      if (
          hasattr(self.ap.memory, "memory_backend_params")
          and self.ap.algorithm.distributed_coach_synchronization_type
      ):
          self.input_filter.set_device(
              device,
              memory_backend_params=self.ap.memory.memory_backend_params,
              mode="numpy",
          )
          self.output_filter.set_device(
              device,
              memory_backend_params=self.ap.memory.memory_backend_params,
              mode="numpy",
          )
          self.pre_network_filter.set_device(
              device,
              memory_backend_params=self.ap.memory.memory_backend_params,
              mode="numpy",
          )
      elif (
          type(agent_parameters.task_parameters)
          == DistributedTaskParameters
          and agent_parameters.task_parameters.framework_type
          == Frameworks.tensorflow
      ):
          self.input_filter.set_device(device, mode="tf")
          self.output_filter.set_device(device, mode="tf")
          self.pre_network_filter.set_device(device, mode="tf")
      else:
          self.input_filter.set_device(device, mode="numpy")
          self.output_filter.set_device(device, mode="numpy")
          self.pre_network_filter.set_device(device, mode="numpy")
  
      # initialize all internal variables
      self._phase = RunPhase.HEATUP
      self.total_shaped_reward_in_current_episode = 0
      self.total_reward_in_current_episode = 0
      self.total_steps_counter = 0
      self.running_reward = None
      self.training_iteration = 0
      self.training_epoch = 0
      self.last_target_network_update_step = 0
      self.last_training_phase_step = 0
      self.current_episode = self.ap.current_episode = 0
      self.curr_state = {}
      self.current_hrl_goal = None
      self.current_episode_steps_counter = 0
      self.episode_running_info = {}
      self.last_episode_evaluation_ran = 0
      self.running_observations = []
      self.agent_logger.set_current_time(self.current_episode)
      self.exploration_policy = None
      self.networks = {}
      self.last_action_info = None
      self.running_observation_stats = None
      self.running_reward_stats = None
      self.accumulated_rewards_across_evaluation_episodes = 0
      self.accumulated_shaped_rewards_across_evaluation_episodes = 0
      self.num_successes_across_evaluation_episodes = 0
      self.num_evaluation_episodes_completed = 0
      self.current_episode_buffer = Episode(
          discount=self.ap.algorithm.discount,
          n_step=self.ap.algorithm.n_step,
      )
      # TODO: add agents observation rendering for debugging purposes (not the same as the environment rendering)
  
      # environment parameters
      self.spaces = None
      self.in_action_space = self.ap.algorithm.in_action_space
  
      # signals
      self.episode_signals = []
      self.step_signals = []
      self.loss = self.register_signal("Loss")
      self.curr_learning_rate = self.register_signal("Learning Rate")
      self.unclipped_grads = self.register_signal("Grads (unclipped)")
      self.reward = self.register_signal(
          "Reward",
          dump_one_value_per_episode=False,
          dump_one_value_per_step=True,
      )
      self.shaped_reward = self.register_signal(
          "Shaped Reward",
          dump_one_value_per_episode=False,
          dump_one_value_per_step=True,
      )
      self.discounted_return = self.register_signal("Discounted Return")
      if isinstance(self.in_action_space, GoalsSpace):
          self.distance_from_goal = self.register_signal(
              "Distance From Goal", dump_one_value_per_step=True
          )
  
      # batch rl
      self.ope_manager = (
          OpeManager() if self.ap.is_batch_rl_training else None
      )
  
imports: import copy
  import random
  from collections import OrderedDict
  from typing import Dict, List, Union, Tuple
  import numpy
  from six.moves import range
  from rl_coach.agents.agent_interface import AgentInterface
  from rl_coach.architectures.network_wrapper import NetworkWrapper
  from rl_coach.base_parameters import AgentParameters, Device, DeviceType, DistributedTaskParameters, Frameworks
  from rl_coach.core_types import RunPhase, PredictionType, EnvironmentEpisodes, ActionType, Batch, Episode, StateType
  from rl_coach.core_types import Transition, ActionInfo, TrainingSteps, EnvironmentSteps, EnvResponse
  from rl_coach.logger import screen, Logger, EpisodeLogger
  from rl_coach.memories.episodic.episodic_experience_replay import EpisodicExperienceReplay
  from rl_coach.saver import SaverCollection
  from rl_coach.spaces import SpacesDefinition, VectorObservationSpace, GoalsSpace, AttentionActionSpace
  from rl_coach.utils import Signal, force_list
  from rl_coach.utils import dynamic_import_and_instantiate_module_from_params
  from rl_coach.memories.backend.memory_impl import get_memory_backend
  from rl_coach.core_types import TimeTypes
  from rl_coach.off_policy_evaluators.ope_manager import OpeManager
  from rl_coach.core_types import PickledReplayBuffer, CsvDataset
label_desc: Use image node_id 1 to create a new Agent object from inherited base classes: AgentInterface with example: obj = Agent(agent_parameters, parent)