class_docstr: A CritiqueClient that creates tasks for workers on Surge AI.
  
  Surge AI concepts:
  
  - A **project** contains **instructions** and **questions**, which are templates that can contain
    placeholders.
  - A **task** is created in a project and contains **fields** that are interpolated into the
    placeholders in the project's instructions and questions templates to instantiate the actual instructions
    and questions in the task.
  - A **task response** is a response to a task by a single worker and contains answers to all the questions
    in the task.
  
  Mapping of HELM concepts to Surge AI concepts:
  
  - A `CritiqueTaskTemplate` maps to a **project**.
  - A `CritiqueQuestionTemplate` maps to a **question** template in a project.
  - A `CritiqueRequest` maps to a **task**
      - `CritiqueRequest.template` indicates which **project** the task should be created in.
      - `CritiqueRequest.fields` provides the fields that are interpolated into the placeholders in the
        projects' instructions and questions templates.
  - A `CritiqueResponse` maps to a **task response**.
  - A `CritiqueRequestResult` maps to a list of **task responses** across multiple workers for a task.
docstr: Create a task on Surge AI and fetch responses from Surge AI if available.
  
  Returns CritiqueRequestResult if worker answers are complete, or None otherwise.
  The intended use is to call it once to create the task, wait a while, and then call it
  later to fetch answers.
  
  First, attempt to find a Surge AI project for the template. If one exists, reuse that project.
  Otherwise, create a new project using the template.
  
  Second, attempt to find a Surge AI task inside this project for the fields. If one exists,
  reuse that task. Otherwise, create a new task inside the project using the fields.
  
  Finally, check if responses are available by checking if the number of workers who have responded
  is equal to the requested number of workers. If so, return those responses.
  
  This method is idempotent, because projects and tasks are not created if they already exist.
  
  The cache will store the mappings from template to Surge AI Project ID and from fields to Surge AI
  question ID. If the cache is deleted, the mappings will be lost, and this method will not be able
  to fetch results from the previous projects and tasks, and will have to create new projects and tasks.
  Note that worker responses are currently not cached.
docstr_tok: ["Create","a","task","on","Surge","AI","and","fetch","responses","from","Surge","AI","if","available",".","Returns","CritiqueRequestResult","if","worker","answers","are","complete",",","or","None","otherwise",".","The","intended","use","is","to","call","it","once","to","create","the","task",",","wait","a","while",",","and","then","call","it","later","to","fetch","answers",".","First",",","attempt","to","find","a","Surge","AI","project","for","the","template",".","If","one","exists",",","reuse","that","project",".","Otherwise",",","create","a","new","project","using","the","template",".","Second",",","attempt","to","find","a","Surge","AI","task","inside","this","project","for","the","fields",".","If","one","exists",",","reuse","that","task",".","Otherwise",",","create","a","new","task","inside","the","project","using","the","fields",".","Finally",",","check","if","responses","are","available","by","checking","if","the","number","of","workers","who","have","responded","is","equal","to","the","requested","number","of","workers",".","If","so",",","return","those","responses",".","This","method","is","idempotent",",","because","projects","and","tasks","are","not","created","if","they","already","exist",".","The","cache","will","store","the","mappings","from","template","to","Surge","AI","Project","ID","and","from","fields","to","Surge","AI","question","ID",".","If","the","cache","is","deleted",",","the","mappings","will","be","lost",",","and","this","method","will","not","be","able","to","fetch","results","from","the","previous","projects","and","tasks",",","and","will","have","to","create","new","projects","and","tasks",".","Note","that","worker","responses","are","currently","not","cached","."]
code: def make_critique_request(
      self, request: CritiqueRequest
  ) -> CritiqueRequestResult:
      """Create a task on Surge AI and fetch responses from Surge AI if available.
  
      Returns CritiqueRequestResult if worker answers are complete, or None otherwise.
      The intended use is to call it once to create the task, wait a while, and then call it
      later to fetch answers.
  
      First, attempt to find a Surge AI project for the template. If one exists, reuse that project.
      Otherwise, create a new project using the template.
  
      Second, attempt to find a Surge AI task inside this project for the fields. If one exists,
      reuse that task. Otherwise, create a new task inside the project using the fields.
  
      Finally, check if responses are available by checking if the number of workers who have responded
      is equal to the requested number of workers. If so, return those responses.
  
      This method is idempotent, because projects and tasks are not created if they already exist.
  
      The cache will store the mappings from template to Surge AI Project ID and from fields to Surge AI
      question ID. If the cache is deleted, the mappings will be lost, and this method will not be able
      to fetch results from the previous projects and tasks, and will have to create new projects and tasks.
      Note that worker responses are currently not cached."""
      project_id = self._get_or_create_surge_project(request.template)
      task_id = self._get_or_create_task(project_id, request.fields)
      worker_responses = self._get_worker_responses(
          task_id, request.template.questions
      )
      return CritiqueRequestResult(worker_responses)
  
imports: from abc import ABC, abstractmethod
  import random
  import threading
  from typing import Dict, List, Union
  from cattrs import unstructure
  import surge
  from surge import questions
  from helm.common.hierarchical_logger import hlog
  from helm.common.cache import Cache, CacheConfig
  from helm.common.critique_request import CritiqueQuestionTemplate, CritiqueRequest, CritiqueRequestResult, CritiqueTaskTemplate, CritiqueResponse, QuestionType
label_desc: Use image node_id 6 for calling the SurgeAICritiqueClient obj's underlying member method code with example usage: obj.make_critique_request(request) and returns: CritiqueRequestResult