code: def completion(
      model: str,
      messages: list,
      api_base: str,
      model_response: ModelResponse,
      print_verbose: Callable,
      logging_obj,
      api_key,
      encoding,
      custom_prompt_dict={},
      optional_params=None,
      litellm_params=None,
      logger_fn=None,
  ):
      # Start a prediction and get the prediction URL
      version_id = model_to_version_id(model)
      ## Load Config
      config = litellm.ReplicateConfig.get_config()
      for k, v in config.items():
          if (
              k not in optional_params
          ):  # completion(top_k=3) > replicate_config(top_k=3) <- allows for dynamic variables to be passed in
              optional_params[k] = v
  
      system_prompt = None
      if (
          optional_params is not None
          and "supports_system_prompt" in optional_params
      ):
          supports_sys_prompt = optional_params.pop(
              "supports_system_prompt"
          )
      else:
          supports_sys_prompt = False
  
      if supports_sys_prompt:
          for i in range(len(messages)):
              if messages[i]["role"] == "system":
                  first_sys_message = messages.pop(i)
                  system_prompt = first_sys_message["content"]
                  break
  
      if model in custom_prompt_dict:
          # check if the model has a registered custom prompt
          model_prompt_details = custom_prompt_dict[model]
          prompt = custom_prompt(
              role_dict=model_prompt_details.get("roles", {}),
              initial_prompt_value=model_prompt_details.get(
                  "initial_prompt_value", ""
              ),
              final_prompt_value=model_prompt_details.get(
                  "final_prompt_value", ""
              ),
              bos_token=model_prompt_details.get("bos_token", ""),
              eos_token=model_prompt_details.get("eos_token", ""),
              messages=messages,
          )
      else:
          prompt = prompt_factory(model=model, messages=messages)
  
      # If system prompt is supported, and a system prompt is provided, use it
      if system_prompt is not None:
          input_data = {
              "prompt": prompt,
              "system_prompt": system_prompt,
              **optional_params,
          }
      # Otherwise, use the prompt as is
      else:
          input_data = {"prompt": prompt, **optional_params}
  
      ## COMPLETION CALL
      ## Replicate Compeltion calls have 2 steps
      ## Step1: Start Prediction: gets a prediction url
      ## Step2: Poll prediction url for response
      ## Step2: is handled with and without streaming
      model_response["created"] = int(
          time.time()
      )  # for pricing this must remain right before calling api
      prediction_url = start_prediction(
          version_id,
          input_data,
          api_key,
          api_base,
          logging_obj=logging_obj,
          print_verbose=print_verbose,
      )
      print_verbose(prediction_url)
  
      # Handle the prediction response (streaming or non-streaming)
      if (
          "stream" in optional_params
          and optional_params["stream"] == True
      ):
          print_verbose("streaming request")
          return handle_prediction_response_streaming(
              prediction_url, api_key, print_verbose
          )
      else:
          result, logs = handle_prediction_response(
              prediction_url, api_key, print_verbose
          )
          model_response[
              "ended"
          ] = (
              time.time()
          )  # for pricing this must remain right after calling api
          ## LOGGING
          logging_obj.post_call(
              input=prompt,
              api_key="",
              original_response=result,
              additional_args={
                  "complete_input_dict": input_data,
                  "logs": logs,
                  "api_base": prediction_url,
              },
          )
  
          print_verbose(f"raw model_response: {result}")
  
          if (
              len(result) == 0
          ):  # edge case, where result from replicate is empty
              result = " "
  
          ## Building RESPONSE OBJECT
          if len(result) > 1:
              model_response["choices"][0]["message"][
                  "content"
              ] = result
  
          # Calculate usage
          prompt_tokens = len(encoding.encode(prompt))
          completion_tokens = len(
              encoding.encode(
                  model_response["choices"][0]["message"].get(
                      "content", ""
                  )
              )
          )
          model_response["model"] = "replicate/" + model
          usage = Usage(
              prompt_tokens=prompt_tokens,
              completion_tokens=completion_tokens,
              total_tokens=prompt_tokens + completion_tokens,
          )
          model_response.usage = usage
          return model_response
  
imports: import os, types
  import json
  import requests
  import time
  from typing import Callable, Optional
  from litellm.utils import ModelResponse, Usage
  import litellm
  import httpx
  from .prompt_templates.factory import prompt_factory, custom_prompt
label_desc: Use image node_id 5 for calling a global function with example usage: completion(model, messages, api_base, model_response, print_verbose, logging_obj, api_key, encoding, custom_prompt_dict, optional_params, litellm_params, logger_fn) and returns: handle_prediction_response_streaming, model_response