"""Typed, serializable failures used across the v3 workflow.""" from __future__ import annotations from dataclasses import dataclass, field from enum import StrEnum from typing import Any class ErrorCode(StrEnum): CANCELLED = "CANCELLED" AUTHOR_FORMAT_INVALID = "AUTHOR_FORMAT_INVALID" AUTHOR_DECISION_REJECTED = "AUTHOR_DECISION_REJECTED" STALE_WORKING_HEAD = "STALE_WORKING_HEAD" FAILED_AUTHOR_FORMAT = "FAILED_AUTHOR_FORMAT" RUNTIME_PRECONDITION_FAILED = "RUNTIME_PRECONDITION_FAILED" RUNTIME_CONTRACT_INVALID = "RUNTIME_CONTRACT_INVALID" CANDIDATE_BUILD_FAILED = "CANDIDATE_BUILD_FAILED" CANDIDATE_REVIEW_REJECTED = "CANDIDATE_REVIEW_REJECTED" VERIFIER_UNAVAILABLE = "VERIFIER_UNAVAILABLE" CLAIM_VERIFICATION_FAILED = "CLAIM_VERIFICATION_FAILED" MODEL_STRUCTURED_OUTPUT_UNSUPPORTED = "MODEL_STRUCTURED_OUTPUT_UNSUPPORTED" MODEL_PROTOCOL_CHECK_PENDING = "MODEL_PROTOCOL_CHECK_PENDING" AUTHOR_TRANSPORT_UNAVAILABLE = "AUTHOR_TRANSPORT_UNAVAILABLE" REVIEW_SERVICE_UNAVAILABLE = "REVIEW_SERVICE_UNAVAILABLE" RENDER_SERVICE_UNAVAILABLE = "RENDER_SERVICE_UNAVAILABLE" STORAGE_FAILURE = "STORAGE_FAILURE" CALL_BUDGET_EXHAUSTED = "CALL_BUDGET_EXHAUSTED" REQUIREMENTS_SPEC_INVALID = "REQUIREMENTS_SPEC_INVALID" NO_PROGRESS_LIMIT = "NO_PROGRESS_LIMIT" RUNTIME_EXECUTION_FAILURE = "RUNTIME_EXECUTION_FAILURE" BEST_EFFORT_COMPLETED = "BEST_EFFORT_COMPLETED" FAILED_INTERNAL = "FAILED_INTERNAL" WAITING_FOR_USER = "WAITING_FOR_USER" @dataclass(frozen=True, slots=True) class WorkflowError: """An expected domain rejection, never a free-form exception channel.""" code: ErrorCode message: str field_errors: tuple[dict[str, Any], ...] = () retryable: bool = False details: dict[str, Any] = field(default_factory=dict) def payload(self) -> dict[str, Any]: return { "code": self.code.value, "message": self.message, "field_errors": list(self.field_errors), "retryable": self.retryable, "details": self.details, }