code: def split_online_stream(
      original_stream: Iterable[DatasetExperience],
      experience_size: int,
      shuffle: bool = True,
      drop_last: bool = False,
      experience_split_strategy: Optional[
          Callable[
              [DatasetExperience[TCLDataset], int],
              Iterable[OnlineCLExperience[TCLDataset]],
          ]
      ] = None,
      access_task_boundaries: bool = False,
  ) -> CLStream[DatasetExperience[TCLDataset]]:
      """Split a stream of large batches to create an online stream of small
      mini-batches.
  
      The resulting stream can be used for Online Continual Learning (OCL)
      scenarios (or data-incremental, or other online-based settings).
  
      For efficiency reasons, the resulting stream is an iterator, generating
      experience on-demand.
  
      :param original_stream: The stream with the original data.
      :param experience_size: The size of the experience, as an int. Ignored
          if `custom_split_strategy` is used.
      :param shuffle: If True, experiences will be split by first shuffling
          instances in each experience. This will use the default PyTorch
          random number generator at its current state. Defaults to False.
          Ignored if `experience_split_strategy` is used.
      :param drop_last: If True, if the last experience doesn't contain
          `experience_size` instances, then the last experience will be dropped.
          Defaults to False. Ignored if `experience_split_strategy` is used.
      :param experience_split_strategy: A function that implements a custom
          splitting strategy. The function must accept an experience and return
          an experience's iterator. Defaults to None, which means
          that the standard splitting strategy will be used (which creates
          experiences of size `experience_size`).
          A good starting to understand the mechanism is to look at the
          implementation of the standard splitting function
          :func:`fixed_size_experience_split`.
      :return: A lazy online stream with experiences of size `experience_size`.
      """
  
      if experience_split_strategy is None:
          # functools.partial is a more compact option
          # However, MyPy does not understand what a partial is -_-
          def default_online_split_wrapper(e, e_sz):
              return _default_online_split(
                  shuffle, drop_last, access_task_boundaries, e, e_sz
              )
  
          split_strategy = default_online_split_wrapper
      else:
          split_strategy = experience_split_strategy
  
      def exps_iter():
          for exp in original_stream:
              for sub_exp in split_strategy(exp, experience_size):
                  yield sub_exp
  
      stream_name: str = (
          getattr(original_stream, "name", "train") + "_online"
      )
      return CLStream(
          name=stream_name,
          exps_iter=exps_iter(),
          set_stream_info=True,
      )
  
imports: from functools import partial
  import random
  from typing import Callable, Generator, Generic, Iterable, List, Optional, TypeVar, Union, Protocol
  from typing_extensions import Literal
  import warnings
  from avalanche.benchmarks.utils.data import AvalancheDataset
  from avalanche.benchmarks.utils.utils import concat_datasets
  import torch
  from torch.distributions.categorical import Categorical
  from torch.utils.data import Sampler
  from .deprecated.benchmark_wrapper_utils import wrap_stream
  from .generic_scenario import CLStream, CLScenario
  from .dataset_scenario import DatasetExperience
label_desc: Use image node_id 2 for calling a global function with example usage: split_online_stream(original_stream, experience_size, shuffle, drop_last, experience_split_strategy, access_task_boundaries) and returns: CLStream, _default_online_split