(cls, v, info)
| 228 | |
| 229 | @field_validator("model") |
| 230 | def validate_model_field(cls, v, info): # Renamed to avoid conflict |
| 231 | original_model = v |
| 232 | new_model = v # Default to original value |
| 233 | |
| 234 | logger.debug( |
| 235 | f"📋 MODEL VALIDATION: Original='{original_model}', Preferred='{PREFERRED_PROVIDER}', BIG='{BIG_MODEL}', SMALL='{SMALL_MODEL}'" |
| 236 | ) |
| 237 | |
| 238 | # Remove provider prefixes for easier matching |
| 239 | clean_v = v |
| 240 | if clean_v.startswith("anthropic/"): |
| 241 | clean_v = clean_v[10:] |
| 242 | elif clean_v.startswith("openai/"): |
| 243 | clean_v = clean_v[7:] |
| 244 | elif clean_v.startswith("gemini/"): |
| 245 | clean_v = clean_v[7:] |
| 246 | |
| 247 | # --- Mapping Logic --- START --- |
| 248 | mapped = False |
| 249 | if PREFERRED_PROVIDER == "anthropic": |
| 250 | # Don't remap to big/small models, just add the prefix |
| 251 | new_model = f"anthropic/{clean_v}" |
| 252 | mapped = True |
| 253 | |
| 254 | # Map Haiku to SMALL_MODEL based on provider preference |
| 255 | elif "haiku" in clean_v.lower(): |
| 256 | if PREFERRED_PROVIDER == "google" and SMALL_MODEL in GEMINI_MODELS: |
| 257 | new_model = f"gemini/{SMALL_MODEL}" |
| 258 | mapped = True |
| 259 | else: |
| 260 | new_model = f"openai/{SMALL_MODEL}" |
| 261 | mapped = True |
| 262 | |
| 263 | # Map Sonnet to BIG_MODEL based on provider preference |
| 264 | elif "sonnet" in clean_v.lower(): |
| 265 | if PREFERRED_PROVIDER == "google" and BIG_MODEL in GEMINI_MODELS: |
| 266 | new_model = f"gemini/{BIG_MODEL}" |
| 267 | mapped = True |
| 268 | else: |
| 269 | new_model = f"openai/{BIG_MODEL}" |
| 270 | mapped = True |
| 271 | |
| 272 | # Add prefixes to non-mapped models if they match known lists |
| 273 | elif not mapped: |
| 274 | if clean_v in GEMINI_MODELS and not v.startswith("gemini/"): |
| 275 | new_model = f"gemini/{clean_v}" |
| 276 | mapped = True # Technically mapped to add prefix |
| 277 | elif clean_v in OPENAI_MODELS and not v.startswith("openai/"): |
| 278 | new_model = f"openai/{clean_v}" |
| 279 | mapped = True # Technically mapped to add prefix |
| 280 | # --- Mapping Logic --- END --- |
| 281 | |
| 282 | if mapped: |
| 283 | logger.debug(f"📌 MODEL MAPPING: '{original_model}' ➡️ '{new_model}'") |
| 284 | else: |
| 285 | # If no mapping occurred and no prefix exists, log warning or decide default |
| 286 | if not v.startswith(("openai/", "gemini/", "anthropic/")): |
| 287 | logger.warning( |
nothing calls this directly
no outgoing calls
no test coverage detected