# This file was auto-generated by Fern from our API Definition.

import typing

import pydantic
from ..core.pydantic_utilities import IS_PYDANTIC_V2
from ..core.unchecked_base_model import UncheckedBaseModel
from .assertion_result import AssertionResult
from .test_result_status import TestResultStatus


class TestResult(UncheckedBaseModel):
    """
    Result from running a single test case
    """

    test_name: str = pydantic.Field()
    """
    Name of the test case
    """

    passed: bool = pydantic.Field()
    """
    Whether the test passed overall
    """

    status: TestResultStatus = pydantic.Field()
    """
    Test execution status
    """

    input: typing.Dict[str, typing.Optional[typing.Any]] = pydantic.Field()
    """
    Input data sent to workflow
    """

    expected_output: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None)
    """
    Expected output
    """

    actual_output: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None)
    """
    Actual output from workflow
    """

    latency_ms: int = pydantic.Field()
    """
    Execution time in milliseconds
    """

    metrics: typing.Optional[typing.Dict[str, typing.Optional[float]]] = pydantic.Field(default=None)
    """
    Per-test metrics (e.g., {'similarity': 0.87, 'correctness': 4.5})
    """

    assertion_results: typing.Optional[typing.List[AssertionResult]] = pydantic.Field(default=None)
    """
    [LEGACY] Results for each assertion
    """

    scorer_results: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = pydantic.Field(
        default=None
    )
    """
    Results from scorer execution (list of ScorerResult dicts)
    """

    composite_score: typing.Optional[float] = pydantic.Field(default=None)
    """
    Weighted composite score across all scorers (0-1)
    """

    judge_reasoning: typing.Optional[str] = pydantic.Field(default=None)
    """
    LLM judge explanation
    """

    error_message: typing.Optional[str] = pydantic.Field(default=None)
    """
    Error message if test failed
    """

    error_type: typing.Optional[str] = pydantic.Field(default=None)
    """
    Type of error (timeout, execution_error, etc.)
    """

    error_details: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None)
    """
    Detailed error information from workflow service (includes HTTP response, status codes, etc.)
    """

    metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None)
    """
    Test case metadata passed through
    """

    tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
    """
    Tags from the original test case
    """

    if IS_PYDANTIC_V2:
        model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True)  # type: ignore # Pydantic v2
    else:

        class Config:
            frozen = True
            smart_union = True
            extra = pydantic.Extra.allow
