Source code for ralph.mcp.artifacts.smoke_test_result

"""Structured smoke_test_result artifact validation helpers."""

from __future__ import annotations

from typing import TYPE_CHECKING

from pydantic import ConfigDict, Field, ValidationError, model_validator

if TYPE_CHECKING:
    from pathlib import Path

from ralph.mcp.artifacts.smoke_test_result_validation_error import SmokeTestResultValidationError
from ralph.mcp.artifacts.store import get_artifact
from ralph.pydantic_compat import RalphBaseModel

SMOKE_TEST_RESULT_ARTIFACT_TYPE = "smoke_test_result"


class SmokeTestResult(RalphBaseModel):
    """Validated schema for a smoke_test_result artifact."""

    model_config = ConfigDict(extra="forbid")

    status: str = Field(..., min_length=1)
    summary: str = Field(..., min_length=1)
    output_file: str = Field(..., min_length=1)
    observed_working: list[str] = Field(default_factory=list)
    observed_breaks: list[str] = Field(default_factory=list)
    headless_guide_checks: list[str] = Field(default_factory=list)

    @model_validator(mode="after")
    def validate_status_requirements(self) -> SmokeTestResult:
        if self.status not in {"passed", "failed", "partial"}:
            raise ValueError("status must be one of: passed, failed, partial")
        if self.status == "failed" and not self.observed_breaks:
            raise ValueError("failed smoke_test_result artifacts must include observed_breaks")
        if not self.headless_guide_checks:
            raise ValueError("smoke_test_result artifacts must include headless_guide_checks")
        return self


[docs] def normalize_smoke_test_result_content(content: dict[str, object]) -> dict[str, object]: """Validate and normalize a raw smoke_test_result content dict.""" try: validated = SmokeTestResult.model_validate(content) return validated.model_dump(mode="python", exclude_none=True) except ValidationError as exc: raise SmokeTestResultValidationError(str(exc)) from exc
[docs] def read_smoke_test_result_artifact(repo_root: Path) -> dict[str, object] | None: """Read the persisted smoke_test_result artifact content from the workspace.""" artifact_dir = repo_root / ".agent" / "artifacts" try: artifact = get_artifact(artifact_dir, SMOKE_TEST_RESULT_ARTIFACT_TYPE) except Exception: return None payload = artifact.content return {str(key): value for key, value in payload.items()}
__all__ = [ "SMOKE_TEST_RESULT_ARTIFACT_TYPE", "SmokeTestResultValidationError", "normalize_smoke_test_result_content", "read_smoke_test_result_artifact", ]