from typing import List, Dict, Optional, Union from dataclasses import dataclass, field from pydantic import BaseModel import re from deepeval.test_case import ( LLMTestCase, ) from deepeval.prompt import Prompt class Contestant(BaseModel): name: str test_case: LLMTestCase hyperparameters: Optional[Dict[str, Union[str, int, float, Prompt]]] = None model_config = {"arbitrary_types_allowed": True} @dataclass class ArenaTestCase: contestants: List[Contestant] multimodal: bool = field(default=False) def __post_init__(self): contestant_names = [contestant.name for contestant in self.contestants] if len(contestant_names) != len(set(contestant_names)): raise ValueError("All contestant names must be unique.") cases = [contestant.test_case for contestant in self.contestants] ref_input = cases[0].input for case in cases[1:]: if case.input != ref_input: raise ValueError("All contestants must have the same 'input'.") ref_expected = cases[0].expected_output for case in cases[1:]: if case.expected_output != ref_expected: raise ValueError( "All contestants must have the same 'expected_output'." ) for contestant in self.contestants: if contestant.test_case.multimodal: self.multimodal = True class Arena: test_cases: List[ArenaTestCase]