Source code for ralph.recovery.budget_state
"""Immutable budget state for a single (phase, agent) pair."""
from __future__ import annotations
from dataclasses import dataclass
[docs]
@dataclass(frozen=True)
class BudgetState:
"""Immutable budget state for a single (phase, agent) pair.
``max_retries`` and ``consumed`` are the only counters needed to
drive every budget decision (exhausted / remaining). A previous
``failures: tuple[ClassifiedFailure, ...]`` accumulator was
removed in wt-024 memory-perf AC-01: it was appended on every
debit, never read for any decision, and retained heavyweight
``ClassifiedFailure`` objects (original_exception + traceback
frames) across an entire run. Repo-wide grep confirmed zero
readers.
"""
max_retries: int
consumed: int = 0
@property
def exhausted(self) -> bool:
return self.consumed >= self.max_retries
@property
def remaining(self) -> int:
return max(0, self.max_retries - self.consumed)