Configuration for the overall LLM setup, including ensembles.
| 117 | |
| 118 | @dataclass |
| 119 | class LLMConfig(LLMModelConfig): |
| 120 | """Configuration for the overall LLM setup, including ensembles.""" |
| 121 | |
| 122 | # Default API configuration (can be overridden by individual models) |
| 123 | api_base: str = "https://api.openai.com/v1" |
| 124 | |
| 125 | # Default generation parameters |
| 126 | system_message: Optional[str] = "system_message" |
| 127 | temperature: float = 0.7 |
| 128 | top_p: float = 0.95 |
| 129 | max_tokens: int = 4096 |
| 130 | |
| 131 | # Default request parameters |
| 132 | timeout: int = 60 |
| 133 | retries: int = 3 |
| 134 | retry_delay: int = 5 |
| 135 | |
| 136 | # N-model configuration for the evolution LLM ensemble |
| 137 | models: List[LLMModelConfig] = field(default_factory=list) |
| 138 | |
| 139 | # N-model configuration for the evaluator LLM ensemble |
| 140 | evaluator_models: List[LLMModelConfig] = field(default_factory=lambda: []) |
| 141 | |
| 142 | # Backward compatibility for simpler two-model setups |
| 143 | primary_model: str = None |
| 144 | primary_model_weight: float = None |
| 145 | secondary_model: str = None |
| 146 | secondary_model_weight: float = None |
| 147 | |
| 148 | # Reasoning parameters (inherited from LLMModelConfig but can be overridden at this level) |
| 149 | reasoning_effort: Optional[str] = None |
| 150 | |
| 151 | def __post_init__(self): |
| 152 | """Post-initialization to set up model configurations and handle backward compatibility.""" |
| 153 | super().__post_init__() # Resolve ${VAR} in api_key at the LLMConfig level |
| 154 | |
| 155 | # Handle backward compatibility for primary_model/secondary_model settings |
| 156 | if self.primary_model: |
| 157 | primary_model = LLMModelConfig( |
| 158 | name=self.primary_model, weight=self.primary_model_weight or 1.0 |
| 159 | ) |
| 160 | self.models.append(primary_model) |
| 161 | |
| 162 | if self.secondary_model: |
| 163 | # Create secondary model only if weight is specified and > 0, or if not specified (defaults to 0.2) |
| 164 | if self.secondary_model_weight is None or self.secondary_model_weight > 0: |
| 165 | secondary_model = LLMModelConfig( |
| 166 | name=self.secondary_model, |
| 167 | weight=( |
| 168 | self.secondary_model_weight |
| 169 | if self.secondary_model_weight is not None |
| 170 | else 0.2 |
| 171 | ), |
| 172 | ) |
| 173 | self.models.append(secondary_model) |
| 174 | |
| 175 | # Validate that at least one model is configured if any model-related settings are present |
| 176 | if ( |