class_docstr: This is the multi-agent version of ExternalEnv.
class_docstr_tok: ["This","is","the","multi-agent","version","of","ExternalEnv","."]
docstr: Record an observation and (off-policy) action taken.
  
  Args:
      episode_id: Episode id returned from start_episode().
      observation_dict: Current environment observation.
      action_dict: Action for the observation.
docstr_tok: ["Record","an","observation","and","(","off-policy",")","action","taken",".","Args",":","episode_id",":","Episode","id","returned","from","start_episode","(",")",".","observation_dict",":","Current","environment","observation",".","action_dict",":","Action","for","the","observation","."]
code: def log_action(
      self,
      episode_id: str,
      observation_dict: MultiAgentDict,
      action_dict: MultiAgentDict,
  ) -> None:
      """Record an observation and (off-policy) action taken.
  
      Args:
          episode_id: Episode id returned from start_episode().
          observation_dict: Current environment observation.
          action_dict: Action for the observation.
      """
  
      episode = self._get(episode_id)
      episode.log_action(observation_dict, action_dict)
  
file_path: ray/python/ray/rllib/env/external_multi_agent_env.py
imports: import uuid
  import gymnasium
  from typing import Optional
  from ray.rllib.utils.annotations import override, PublicAPI
  from ray.rllib.env.external_env import ExternalEnv, _ExternalEnvEpisode
  from ray.rllib.utils.typing import MultiAgentDict
label_desc: Use image node_id 5 for calling the ExternalMultiAgentEnv obj's underlying member method code with example usage: obj.log_action(episode_id, observation_dict, action_dict) without return types