class_docstr: Util to build SampleBatches for each policy in a multi-agent env.
  
  Input data is per-agent, while output data is per-policy. There is an M:N
  mapping between agents and policies. We retain one local batch builder
  per agent. When an agent is done, then its local batch is appended into the
  corresponding policy batch for the agent's policy.
code: def try_build_truncated_episode_multi_agent_batch(
      self,
  ) -> List[Union[MultiAgentBatch, SampleBatch]]:
      batches = []
      # Loop through ongoing episodes and see whether their length plus
      # what's already in the policy collectors reaches the fragment-len
      # (abiding to the unit used: env-steps or agent-steps).
      for episode_id, episode in self.episodes.items():
          # Measure batch size in env-steps.
          if self.count_steps_by == "env_steps":
              built_steps = (
                  episode.batch_builder.env_steps
                  if episode.batch_builder
                  else 0
              )
              ongoing_steps = self.episode_steps[episode_id]
          # Measure batch-size in agent-steps.
          else:
              built_steps = (
                  episode.batch_builder.agent_steps
                  if episode.batch_builder
                  else 0
              )
              ongoing_steps = self.agent_steps[episode_id]
  
          # Reached the fragment-len -> We should build an MA-Batch.
          if (
              built_steps + ongoing_steps
              >= self.rollout_fragment_length
          ):
              if self.count_steps_by == "env_steps":
                  assert (
                      built_steps + ongoing_steps
                      == self.rollout_fragment_length
                  )
              # If we reached the fragment-len only because of `episode_id`
              # (still ongoing) -> postprocess `episode_id` first.
              if built_steps < self.rollout_fragment_length:
                  self.postprocess_episode(episode, is_done=False)
              # If there is a builder for this episode,
              # build the MA-batch and add to return values.
              if episode.batch_builder:
                  batch = self._build_multi_agent_batch(episode=episode)
                  batches.append(batch)
              # No batch-builder:
              # We have reached the rollout-fragment length w/o any agent
              # steps! Warn that the environment may never request any
              # actions from any agents.
              elif log_once("no_agent_steps"):
                  logger.warning(
                      "Your environment seems to be stepping w/o ever "
                      "emitting agent observations (agents are never "
                      "requested to act)!"
                  )
  
      return batches
  
imports: import collections
  from gymnasium.spaces import Space
  import logging
  import numpy
  import tree
  from typing import Dict, List, Optional, Tuple, TYPE_CHECKING, Union
  from ray.rllib.env.base_env import _DUMMY_AGENT_ID
  from ray.rllib.evaluation.collectors.sample_collector import SampleCollector
  from ray.rllib.evaluation.collectors.agent_collector import AgentCollector
  from ray.rllib.evaluation.episode import Episode
  from ray.rllib.policy.policy import Policy
  from ray.rllib.policy.policy_map import PolicyMap
  from ray.rllib.policy.sample_batch import SampleBatch, MultiAgentBatch, concat_samples
  from ray.rllib.utils.annotations import override, PublicAPI
  from ray.rllib.utils.debug import summarize
  from ray.rllib.utils.framework import try_import_tf, try_import_torch
  from ray.rllib.utils.spaces.space_utils import get_dummy_batch_for_space
  from ray.rllib.utils.typing import AgentID, EpisodeID, EnvID, PolicyID, TensorType, ViewRequirementsDict
  from ray.util.debug import log_once
label_desc: Use image node_id 10 for calling the SimpleListCollector obj's underlying member method code with example usage: obj.try_build_truncated_episode_multi_agent_batch() and returns: batches