code: def generate_episodes(
      tag_reader: Any,
      episode_metadata_fn: Callable[
          [Dict[str, Any]], Optional[Dict[str, Any]]
      ] = lambda x: x,
      step_fn: Callable[[Dict[str, Any]], Dict[str, Any]] = lambda x: x,
  ) -> Generator[Dict[str, Any], None, None]:
      """Generates episodes by reading them from the tag_reader.
  
      Args:
        tag_reader: Envlogger reader (envlogger.Reader).
        episode_metadata_fn: function to process the episode metadata. If it returns
          None, the episode is skipped.
        step_fn: function that gets an RLDS step and returns the processed step.
  
      Yields:
        A dictionary representing one episode, including metadata and steps. Steps
        are represented by a nested dictionary where each nested field is a list.
      """
      for index, episode_metadata in enumerate(
          tag_reader.episode_metadata()
      ):
          episode = tag_reader.episodes[index]
          episode_dict = get_episode_dict(
              episode, episode_metadata, episode_metadata_fn, step_fn
          )
          if episode_dict:
              yield episode_dict
  
file_path: datasets/tensorflow_datasets/rlds/envlogger_reader.py
imports: from typing import Any, Callable, Dict, Generator, List, Optional, Sequence, Tuple, Union
  import numpy
  from tensorflow_datasets.core.utils import tree_utils
label_desc: Use image node_id 4 for calling a global function with example usage: generate_episodes(tag_reader, episode_metadata_fn, step_fn) without return types