class_docstr: Generaes the utterances for a single character only.
  
  The label will be the silent token if that character doesn't speak that round. This
  is an abstract class: do NOT use directly!
class_docstr_tok: ["Generaes","the","utterances","for","a","single","character","only",".","The","label","will","be","the","silent","token","if","that","character","does","n't","speak","that","round",".","This","is","an","abstract","class",":","do","NOT","use","directly","!"]
code: def setup_data(self, datafile: str) -> List[Message]:
      episode_needs_reset = False
  
      for utt, new_episode in super().setup_data(datafile):
          # checking if we need to skip this round because of the speaker tier
          if (
              utt["speaker_worker_tier"]
              not in self.speaker_quality_tiers
          ):
              continue
  
          if new_episode:
              last_speaker_trun = -1
              turn_num = 0
          else:
              turn_num += 1
  
          is_silence_turn = not self.is_this_speaker_turn(utt)
          if (
              is_silence_turn
              and self.silence_token_dropout
              and random.random() < self.silence_token_dropout
          ):
              if new_episode:
                  # We keep this to reset the episode next round around.
                  episode_needs_reset = True
              continue
  
          if episode_needs_reset:
              # Setting new episode because we missed the original one due to silence drop out.
              episode_needs_reset = False
              new_episode = True
  
          ret = copy.deepcopy(utt)
          context = ret["full_context"][(last_speaker_trun + 1) :]
  
          if not context:
              context = (
                  [self.silence_token]
                  if turn_num > 0
                  else [self.start_token]
              )
  
          if last_speaker_trun < 0:
              # Only adding the extra context on the first episode that will get yielded
              ret["text"] = self.utterance_delimiter.join(
                  self.get_extra_context_before(ret) + context
              )
          else:
              ret["text"] = self.utterance_delimiter.join(context)
  
          last_speaker_trun = turn_num
          # Setting the speaker to the current speaker.
          # Even if the speaker doesn't speak, the silence term is this speaker's action.
          ret["speaker"] = get_speaker_name_from_index(
              utt, self.get_speaker_index()
          )
  
          # Adding the prompot to the temp_history for not keeping it in the full history.
          # There is also an extra \n to make the format more alike the other teachers.
          ret["temp_history"] = "\n".join(
              [""] + self.get_extra_context_after(ret)
          )
          if is_silence_turn:
              ret["label"] = self.generate_silence_label(ret["speaker"])
          else:
              last_speaker_trun += 1
  
          yield ret, new_episode
  
imports: from abc import ABC, abstractclassmethod
  import copy
  import jsonlines
  import random
  import os
  from typing import Any, Dict, List, Optional, Set, Tuple
  from parlai.core.message import Message
  from parlai.core.metrics import ExactMatchMetric, F1Metric
  from parlai.core.opt import Opt
  from parlai.core.params import ParlaiParser
  from parlai.core.teachers import DialogTeacher
  from parlai.core.torch_classifier_agent import ConfusionMatrixMetric
  from parlai.utils.data import DatatypeHelper
  from parlai.tasks.light_multiparty.build import build, DATASET_NAME
label_desc: Use image node_id 6 for calling the SingleSpeakerTeacher obj's underlying member method code with example usage: obj.setup_data(datafile) without return types