class_docstr: LLMFunction for comparisons.
  
  LLMCompareFunction runs an input over a pair of LLMFunctions and compares the
  result.
code: def _call_impl(
      self, inputs: llmfn_input_utils.LLMFunctionInputs | None
  ) -> Sequence[llmfn_outputs.LLMFnOutputEntry]:
      lhs_results = self._lhs_fn(inputs)
      rhs_results = self._rhs_fn(inputs)
  
      # Combine the results.
      outputs: list[llmfn_outputs.LLMFnOutputEntry] = []
      for lhs_entry, rhs_entry in zip(lhs_results, rhs_results):
          if lhs_entry.prompt_num != rhs_entry.prompt_num:
              raise RuntimeError(
                  "Prompt num mismatch: {} vs {}".format(
                      lhs_entry.prompt_num, rhs_entry.prompt_num
                  )
              )
          if lhs_entry.input_num != rhs_entry.input_num:
              raise RuntimeError(
                  "Input num mismatch: {} vs {}".format(
                      lhs_entry.input_num, rhs_entry.input_num
                  )
              )
          if lhs_entry.prompt_vars != rhs_entry.prompt_vars:
              raise RuntimeError(
                  "Prompt vars mismatch: {} vs {}".format(
                      lhs_entry.prompt_vars, rhs_entry.prompt_vars
                  )
              )
  
          # The two functions may have different numbers of results due to
          # options like candidate_count, so we can only compare up to the
          # minimum of the two.
          num_output_rows = min(
              len(lhs_entry.output_rows), len(rhs_entry.output_rows)
          )
          lhs_output_rows = lhs_entry.output_rows[:num_output_rows]
          rhs_output_rows = rhs_entry.output_rows[:num_output_rows]
          output_rows: list[llmfn_output_row.LLMFnOutputRow] = []
          for result_num, lhs_and_rhs_output_row in enumerate(
              zip(lhs_output_rows, rhs_output_rows)
          ):
              lhs_output_row, rhs_output_row = lhs_and_rhs_output_row
  
              # Combine cells from lhs_output_row and rhs_output_row into a
              # single row.
              # Although it is possible for RESULT_NUM (the index of each
              # text_result if a prompt produces multiple text_results) to be
              # different between the left and right sides, we ignore their
              # RESULT_NUM entries and write our own.
              row_data: dict[str, Any] = {
                  llmfn_outputs.ColumnNames.RESULT_NUM: result_num,
                  self._result_name: self._result_compare_fn(
                      lhs_output_row, rhs_output_row
                  ),
              }
              output_row = llmfn_output_row.LLMFnOutputRow(
                  data=row_data, result_type=Any
              )
  
              # Add the prompt vars.
              output_row.add(
                  llmfn_outputs.ColumnNames.PROMPT_VARS,
                  lhs_entry.prompt_vars,
              )
  
              # Add the results from the left-hand side and right-hand side.
              for name, row in [
                  (self._lhs_name, lhs_output_row),
                  (self._rhs_name, rhs_output_row),
              ]:
                  for k, v in row.items():
                      if k != llmfn_outputs.ColumnNames.RESULT_NUM:
                          # We use LLMFnOutputRow.add() because it handles column
                          # name collisions.
                          output_row.add("{}_{}".format(name, k), v)
  
              output_rows.append(output_row)
  
          outputs.append(
              llmfn_outputs.LLMFnOutputEntry(
                  prompt_num=lhs_entry.prompt_num,
                  input_num=lhs_entry.input_num,
                  prompt_vars=lhs_entry.prompt_vars,
                  output_rows=self._run_post_processing_cmds(
                      lhs_output_rows=lhs_output_rows,
                      rhs_output_rows=rhs_output_rows,
                      results=output_rows,
                  ),
              )
          )
      return outputs
  
imports: from __future__ import annotations
  import abc
  import dataclasses
  from typing import AbstractSet, Any, Callable, Iterable, Mapping, Optional, Sequence, Union
  from google.generativeai.notebook.lib import llmfn_input_utils
  from google.generativeai.notebook.lib import llmfn_output_row
  from google.generativeai.notebook.lib import llmfn_outputs
  from google.generativeai.notebook.lib import llmfn_post_process
  from google.generativeai.notebook.lib import llmfn_post_process_cmds
  from google.generativeai.notebook.lib import model
  from google.generativeai.notebook.lib import prompt_utils
label_desc: Use image node_id 4 for calling the LLMCompareFunction obj's underlying member method code with example usage: obj._call_impl(inputs) and returns: outputs