File size: 2,129 Bytes
5143557 eed1cab 5143557 eed1cab 5143557 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | """Core models and protocol for DataForge repairers."""
from __future__ import annotations
from typing import Literal, Protocol
from pydantic import BaseModel, Field
from dataforge.detectors.base import Issue, Schema
from dataforge.table import TableLike
from dataforge.transactions.txn import CellFix
ProvenanceLiteral = Literal["deterministic", "llm_cache", "llm_live"]
AttemptStatusLiteral = Literal[
"accepted",
"denied",
"escalated",
"rejected",
"unknown",
"attempted_not_fixed",
]
class ProposedFix(BaseModel):
"""A repair proposal emitted by a repairer.
Args:
fix: The cell mutation to apply.
reason: Human-readable explanation of why this repair is proposed.
confidence: Repair confidence in the range [0.0, 1.0].
provenance: Where the proposed value came from.
"""
fix: CellFix
reason: str = Field(min_length=1)
confidence: float = Field(ge=0.0, le=1.0)
provenance: ProvenanceLiteral
model_config = {"frozen": True}
class RepairAttempt(BaseModel):
"""Recorded outcome for one issue-repair attempt."""
issue: Issue
attempt_number: int = Field(ge=1)
fix: ProposedFix | None = None
status: AttemptStatusLiteral
reason: str = Field(min_length=1)
unsat_core: tuple[str, ...] = Field(default_factory=tuple)
model_config = {"frozen": True}
class RetryContext(BaseModel):
"""Hints passed back to a repairer after a failed attempt."""
issue: Issue
previous_attempts: tuple[RepairAttempt, ...] = Field(default_factory=tuple)
rejected_values: frozenset[str] = Field(default_factory=frozenset)
hints: tuple[str, ...] = Field(default_factory=tuple)
model_config = {"frozen": True}
class Repairer(Protocol):
"""Structural protocol implemented by every repairer."""
def propose(
self,
issue: Issue,
df: TableLike,
schema: Schema | None,
retry_context: RetryContext | None = None,
) -> ProposedFix | None:
"""Return a repair proposal for an issue, or ``None`` if unavailable."""
... # pragma: no cover
|