class_docstr: Managing class for the acute evaluator process.
  
  Relevant args are parsed in the `setup_args` function above.
class_docstr_tok: ["Managing","class","for","the","acute","evaluator","process",".","Relevant","args","are","parsed","in","the","`","setup_args","`","function","above","."]
docstr: Top up worker task data.
  
  This function is called if ``self.task_queue`` is exhausted but
  task_data for the worker is less than the `tasks_per_unit`.
  
  Make sure that all added tasks have not been seen by the worker.
  
  :param worker_id:
      id for worker
  
  :param task_data:
      list of potential tasks already for worker
  
  :return task_data:
      a list of tasks for a worker to complete
docstr_tok: ["Top","up","worker","task","data",".","This","function","is","called","if","``","self.task_queue","``","is","exhausted","but","task_data","for","the","worker","is","less","than","the","`","tasks_per_unit","`",".","Make","sure","that","all","added","tasks","have","not","been","seen","by","the","worker",".",":","param","worker_id",":","id","for","worker",":","param","task_data",":","list","of","potential","tasks","already","for","worker",":","return","task_data",":","a","list","of","tasks","for","a","worker","to","complete"]
code: def _top_up_task_data(
      self, worker_id: str, task_data: List[Dict[str, Any]]
  ) -> List[PairingsDict]:
      """
      Top up worker task data.
  
      This function is called if ``self.task_queue`` is exhausted but
      task_data for the worker is less than the `tasks_per_unit`.
  
      Make sure that all added tasks have not been seen by the worker.
  
      :param worker_id:
          id for worker
  
      :param task_data:
          list of potential tasks already for worker
  
      :return task_data:
          a list of tasks for a worker to complete
      """
      worker_data = self._get_worker_data(worker_id)
      tasks_still_needed = self.args.blueprint.subtasks_per_unit - len(
          task_data
      )
      tasks_remaining = [
          t_id
          for t_id in range(len(self.desired_tasks))
          if t_id not in worker_data["tasks_completed"]
      ]
      # get any pairings with conversations this worker has not seen to fill this hit
      additional_tasks = [
          t
          for t in tasks_remaining
          if all(
              d_id not in worker_data["conversations_seen"]
              for d_id in self._get_dialogue_ids(self.desired_tasks[t])
          )
      ]
      if tasks_still_needed < len(additional_tasks):
          additional_tasks = random.sample(
              additional_tasks, tasks_still_needed
          )
      worker_data["tasks_completed"].extend(additional_tasks)
  
      for t in additional_tasks:
          worker_data["conversations_seen"].extend(
              self._get_dialogue_ids(self.desired_tasks[t])
          )
          task_data.append(self.desired_tasks[t])
  
      return task_data
  
imports: import json
  import queue
  import random
  from typing import List, Any, Dict, Tuple, Set, TYPE_CHECKING
  from mephisto.utils.logger_core import get_logger
  from mephisto.abstractions.blueprint import SharedTaskState, TaskRunner
  from omegaconf import DictConfig
label_desc: Use image node_id 8 for calling the AcuteEvalRunner obj's underlying member method code with example usage: obj._top_up_task_data(worker_id, task_data) and returns: task_data