code: def get_new_model_failure_blocks(self, with_header=True):
      if self.prev_ci_artifacts is None:
          return {}
  
      sorted_dict = sorted(
          self.model_results.items(), key=lambda t: t[0]
      )
  
      prev_model_results = {}
      if (
          "prev_ci_results" in self.prev_ci_artifacts
          and "model_results.json"
          in self.prev_ci_artifacts["prev_ci_results"]
      ):
          prev_model_results = json.loads(
              self.prev_ci_artifacts["prev_ci_results"][
                  "model_results.json"
              ]
          )
  
      all_failure_lines = {}
      for job, job_result in sorted_dict:
          if len(job_result["failures"]):
              devices = sorted(
                  job_result["failures"].keys(), reverse=True
              )
              for device in devices:
                  failures = job_result["failures"][device]
                  prev_error_lines = {}
                  if (
                      job in prev_model_results
                      and device in prev_model_results[job]["failures"]
                  ):
                      prev_error_lines = {
                          error["line"]
                          for error in prev_model_results[job][
                              "failures"
                          ][device]
                      }
  
                  url = None
                  if (
                      job_result["job_link"] is not None
                      and job_result["job_link"][device] is not None
                  ):
                      url = job_result["job_link"][device]
  
                  for idx, error in enumerate(failures):
                      if error["line"] in prev_error_lines:
                          continue
  
                      new_text = f'{error["line"]}\n\n'
  
                      if new_text not in all_failure_lines:
                          all_failure_lines[new_text] = []
  
                      all_failure_lines[new_text].append(
                          f"<{url}|{device}>"
                          if url is not None
                          else device
                      )
  
      MAX_ERROR_TEXT = (
          3000
          - len("[Truncated]")
          - len("```New model failures```\n\n")
      )
      failure_text = ""
      for line, devices in all_failure_lines.items():
          new_text = failure_text + f"{'|'.join(devices)} gpu\n{line}"
          if len(new_text) > MAX_ERROR_TEXT:
              # `failure_text` here has length <= 3000
              failure_text = failure_text + "[Truncated]"
              break
          # `failure_text` here has length <= MAX_ERROR_TEXT
          failure_text = new_text
  
      blocks = []
      if failure_text:
          if with_header:
              blocks.append(
                  {
                      "type": "header",
                      "text": {
                          "type": "plain_text",
                          "text": "New model failures",
                          "emoji": True,
                      },
                  }
              )
          else:
              failure_text = f"*New model failures*\n\n{failure_text}"
          blocks.append(
              {
                  "type": "section",
                  "text": {"type": "mrkdwn", "text": failure_text},
              }
          )
  
      return blocks
  
imports: import ast
  import collections
  import functools
  import json
  import operator
  import os
  import re
  import sys
  import time
  from typing import Dict, List, Optional, Union
  import requests
  from get_ci_error_statistics import get_job_links
  from get_previous_daily_ci import get_last_daily_ci_reports
  from slack_sdk import WebClient
label_desc: Use image node_id 17 for calling the Message obj's underlying member method code with example usage: obj.get_new_model_failure_blocks(with_header) and returns: blocks, dict