Source code for ralph.recovery.classifier

"""Failure classification: categorize exceptions for intelligent attribution."""

from __future__ import annotations

from dataclasses import dataclass

from ralph.recovery.classified_failure import ClassifiedFailure
from ralph.recovery.failure_category import FailureCategory
from ralph.recovery.failure_classifier import (
    SESSION_NOT_FOUND_SUBSTRINGS,
    FailureClassifier,
    is_missing_artifact_message,
)

__all__ = [
    "SESSION_NOT_FOUND_SUBSTRINGS",
    "ClassifiedFailure",
    "FailureCategory",
    "FailureClassifier",
    "FailureContext",
    "is_missing_artifact_message",
    "is_retryable_without_budget",
]


[docs] @dataclass(frozen=True) class FailureContext: """Context for a failure event passed to RecoveryController.handle.""" phase: str agent: str | None = None retry_in_session: bool = False classified_failure: ClassifiedFailure | None = None
[docs] def is_retryable_without_budget(failure: ClassifiedFailure) -> bool: """Return True if this failure should retry without debiting the agent budget. Environmental, artifact-validation, and ambiguous failures retry without counting. Agent and user_config failures consume budget. """ return not failure.counts_against_budget