(
self, response: str, schema: ResponseSchema
)
| 430 | """ |
| 431 | |
| 432 | def validate( |
| 433 | self, response: str, schema: ResponseSchema |
| 434 | ) -> ValidationResult: |
| 435 | if not response or not response.strip(): |
| 436 | return ValidationResult( |
| 437 | passed=False, |
| 438 | failure_mode=FailureMode.CONSTRAINT_VIOLATION, |
| 439 | message="Response is empty.", |
| 440 | score=0.0, |
| 441 | ) |
| 442 | |
| 443 | if schema.must_be_json: |
| 444 | result = self._check_json(response, schema.required_keys) |
| 445 | if not result.passed: |
| 446 | return result |
| 447 | |
| 448 | if schema.max_length and len(response) > schema.max_length: |
| 449 | return ValidationResult( |
| 450 | passed=False, |
| 451 | failure_mode=FailureMode.CONSTRAINT_VIOLATION, |
| 452 | message=( |
| 453 | f"Response too long: {len(response)} chars " |
| 454 | f"(max {schema.max_length})." |
| 455 | ), |
| 456 | score=round(schema.max_length / len(response), 3), |
| 457 | ) |
| 458 | |
| 459 | if schema.min_length and len(response) < schema.min_length: |
| 460 | return ValidationResult( |
| 461 | passed=False, |
| 462 | failure_mode=FailureMode.CONSTRAINT_VIOLATION, |
| 463 | message=( |
| 464 | f"Response too short: {len(response)} chars " |
| 465 | f"(min {schema.min_length})." |
| 466 | ), |
| 467 | score=0.0, |
| 468 | ) |
| 469 | |
| 470 | for phrase in schema.forbidden_phrases: |
| 471 | if phrase.lower() in response.lower(): |
| 472 | return ValidationResult( |
| 473 | passed=False, |
| 474 | failure_mode=FailureMode.CONSTRAINT_VIOLATION, |
| 475 | message=f"Forbidden phrase found: '{phrase}'", |
| 476 | score=0.0, |
| 477 | ) |
| 478 | |
| 479 | score = self._quality_score(response, schema) |
| 480 | return ValidationResult(passed=True, score=score) |
| 481 | |
| 482 | def _check_json( |
| 483 | self, response: str, required_keys: List[str] |
nothing calls this directly
no test coverage detected