class_docstr:     Client for the Anthropic models (https://arxiv.org/abs/2204.05862).
      They use their own tokenizer.
      Here are a list of bugs that we deal with in this client:
      - The prompt must contains anthropic.HUMAN_PROMPT ('
  
  Human:') and anthropic.AI_PROMPT ('
  
  Assistant:')
      - The completions is often too verbose, so we add the PROMPT_ANSWER_START to the prompt.
      TODO(#1521): Remove this when we have a better way to do prompt engineering.
      - The completions often start with a colon, space, or newline, so we remove it. This means
      that we need to query more tokens than necessary to ensure that the completion does not start
      with a colon, space, or newline. We query `max_tokens + ADDITIONAL_TOKENS` tokens and then
      remove the excess tokens at the end of the completion.
      TODO(#1512): Once we have a good way to post-process the completion, move this logic to the
      post-processing.
      - The API sometimes returns "Prompt must contain anthropic.AI_PROMPT". This is a bug related to the
      window_service that does not properly truncate some prompts.  It is caused by the suffix being truncated.
      - The API sometimes return Prompt length + max_tokens exceeds max (9192). This is something we do not
      handle yet (we have not limit on prompt length + max_tokens). TODO(#1520): Fix this.
      
code: def make_request(self, request: Request) -> RequestResult:
      if request.max_tokens > AnthropicClient.MAX_COMPLETION_LENGTH:
          raise ValueError(
              "The value for `max_tokens` exceeds the currently supported maximum "
              f"({request.max_tokens} > {AnthropicClient.MAX_COMPLETION_LENGTH})."
          )
      if request.max_tokens == 0 and not request.echo_prompt:
          raise ValueError(
              "echo_prompt must be True when max_tokens=0."
          )
  
      raw_request = {
          "prompt": request.prompt,
          "stop_sequences": request.stop_sequences,
          "model": request.model_engine,
          "max_tokens_to_sample": request.max_tokens,
          "temperature": request.temperature,
          "top_p": request.top_p,
          "top_k": request.top_k_per_token,
      }
  
      completions: List[Sequence] = []
  
      # `num_completions` is not supported, so instead make `num_completions` separate requests.
      for completion_index in range(request.num_completions):
          try:
  
              def do_it():
                  result = self._send_request(raw_request)
                  assert (
                      "completion" in result
                  ), f"Invalid response: {result}"
                  return result
  
              # We need to include the engine's name to differentiate among requests made for different model
              # engines since the engine name is not included in the request itself.
              # In addition, we want to make `request.num_completions` fresh
              # requests, cache key should contain the completion_index.
              # Echoing the original prompt is not officially supported by Anthropic. We instead prepend the
              # completion with the prompt when `echo_prompt` is true, so keep track of it in the cache key.
              cache_key = Client.make_cache_key(
                  {
                      "completion_index": completion_index,
                      **raw_request,
                  },
                  request,
              )
  
              response, cached = self.cache.get(
                  cache_key, wrap_request_time(do_it)
              )
          except Exception as error:
              if "Prompt must contain anthropic.AI_PROMPT" in str(
                  error
              ):
                  return RequestResult(
                      success=False,
                      cached=False,
                      error=response["error"],
                      completions=[],
                      embedding=[],
                      error_flags=ErrorFlags(
                          is_retriable=False, is_fatal=False
                      ),
                  )
              if "exceeds max (" in str(error):
                  return RequestResult(
                      success=False,
                      cached=False,
                      error=response["error"],
                      completions=[],
                      embedding=[],
                      error_flags=ErrorFlags(
                          is_retriable=False, is_fatal=False
                      ),
                  )
              return RequestResult(
                  success=False,
                  cached=False,
                  error=str(error),
                  completions=[],
                  embedding=[],
              )
  
          # Post process the completion.
          response["completion"] = self._filter_completion(
              response["completion"], request.max_tokens
          )
  
          # The Anthropic API doesn't support echo. If `echo_prompt` is true, combine the prompt and completion.
          text: str = (
              request.prompt + response["completion"]
              if request.echo_prompt
              else response["completion"]
          )
          # The Anthropic API doesn't return us tokens or logprobs, so we tokenize ourselves.
          tokenization_result: TokenizationRequestResult = self.tokenize(
              # Anthropic uses their own tokenizer
              TokenizationRequest(text, tokenizer=request.model_engine)
          )
  
          # Log probs are not currently not supported by the Anthropic, so set to 0 for now.
          tokens: List[Token] = [
              Token(text=str(text), logprob=0, top_logprobs={})
              for text in tokenization_result.raw_tokens
          ]
  
          completion = Sequence(
              text=response["completion"], logprob=0, tokens=tokens
          )
          # See NOTE() in _filter_completion() to understand why warnings are printed for truncation.
          # TODO(#1512): Fix this with post-processing.
          sequence = truncate_sequence(
              completion, request, print_warning=True
          )
          completions.append(sequence)
  
      return RequestResult(
          success=True,
          cached=cached,
          request_time=response["request_time"],
          request_datetime=response["request_datetime"],
          completions=completions,
          embedding=[],
      )
  
imports: from typing import Any, Dict, List, Optional
  import json
  import requests
  import time
  import urllib.parse
  import websocket
  import anthropic
  from helm.common.cache import Cache, CacheConfig
  from helm.common.hierarchical_logger import htrack_block, hlog
  from helm.common.request import EMBEDDING_UNAVAILABLE_REQUEST_RESULT, Request, RequestResult, Sequence, Token, ErrorFlags
  from helm.common.tokenization_request import TokenizationRequest, TokenizationRequestResult, DecodeRequest, DecodeRequestResult, TokenizationToken
  from .client import Client, wrap_request_time, truncate_sequence
  from transformers import PreTrainedTokenizerBase, PreTrainedTokenizerFast
  from dataclasses import asdict
label_desc: Use image node_id 4 for calling the AnthropicClient obj's underlying member method code with example usage: obj.make_request(request) and returns: RequestResult, result, RequestResult, RequestResult, RequestResult