from __future__ import annotations from dataclasses import dataclass from typing import Protocol class QuoteStateLike(Protocol): pending_image_urls: list pending_requirements: list quote_phase: str quote_ready_turns: int @dataclass class QuoteStateMachine: delay_turns: int = 1 def refresh(self, state: QuoteStateLike, phase_hint: str = "") -> None: if phase_hint in {"idle", "collecting", "ready_to_quote", "waiting_result"}: state.quote_phase = phase_hint if phase_hint == "idle": state.quote_ready_turns = 0 return if not state.pending_image_urls: state.quote_phase = "idle" state.quote_ready_turns = 0 return if state.quote_phase in {"ready_to_quote", "waiting_result"}: return state.quote_phase = "collecting" def mark_ready(self, state: QuoteStateLike) -> None: if state.quote_phase != "ready_to_quote": state.quote_phase = "ready_to_quote" state.quote_ready_turns = max(0, int(self.delay_turns)) def should_defer_batch_quote(self, state: QuoteStateLike, mark_ready: bool = False) -> bool: if mark_ready and state.quote_phase != "ready_to_quote": self.mark_ready(state) if state.quote_phase == "ready_to_quote" and state.quote_ready_turns > 0: state.quote_ready_turns -= 1 return True return False