"""Shared data structures for the model preference compiler.""" from __future__ import annotations from dataclasses import asdict, dataclass, field from pathlib import Path from typing import Any @dataclass(frozen=True) class Signal: name: str prompt_ids: tuple[str, ...] normalized_score: float | None level: str confidence: str raw_scores: dict[str, float] def to_dict(self) -> dict[str, Any]: return asdict(self) @dataclass class BodyBlock: id: str kind: str text: str start_line: int end_line: int start_offset: int end_offset: int parent_heading: str | None = None heading_level: int | None = None list_depth: int = 0 protected_spans: list[tuple[int, int]] = field(default_factory=list) @dataclass(frozen=True) class Annotation: type: str block_id: str quote: str confidence: float source: str antecedent_quote: str | None = None def to_dict(self) -> dict[str, Any]: return asdict(self) @dataclass class Operation: type: str signal: str annotation_type: str | None = None block_id: str | None = None quote: str | None = None target_section: str | None = None replacement: str | None = None source_quotes: list[str] = field(default_factory=list) def to_dict(self) -> dict[str, Any]: return asdict(self) @dataclass class AnnotationResult: annotations: list[Annotation] = field(default_factory=list) used: bool = False model: str | None = None accepted: int = 0 rejected: int = 0 error: str | None = None def to_dict(self) -> dict[str, Any]: return { "used": self.used, "model": self.model, "accepted": self.accepted, "rejected": self.rejected, "error": self.error, } @dataclass(frozen=True) class SourceRef: block_id: str quote: str def to_dict(self) -> dict[str, str]: return asdict(self) @dataclass(frozen=True) class SemanticRewriteUnit: kind: str target_section: str | None source_refs: tuple[SourceRef, ...] replacement: str confidence: float def to_dict(self) -> dict[str, Any]: return { "kind": self.kind, "target_section": self.target_section, "source_refs": [item.to_dict() for item in self.source_refs], "replacement": self.replacement, "confidence": self.confidence, } @dataclass class SemanticPlanResult: units: list[SemanticRewriteUnit] = field(default_factory=list) used: bool = False model: str | None = None transport_attempts: int = 0 request_variant: str | None = None accepted: int = 0 rejected: int = 0 rejection_reasons: list[str] = field(default_factory=list) semantic_rounds: int = 0 provider_request_count: int = 0 initial_proposed: int = 0 initial_accepted: int = 0 initial_rejected: int = 0 initial_rejection_reasons: list[str] = field(default_factory=list) repair_attempted: bool = False repair_proposed: int = 0 repair_accepted: int = 0 repair_rejected: int = 0 repair_rejection_reasons: list[str] = field(default_factory=list) repair_transport_attempts: int = 0 repair_request_variant: str | None = None repair_error: str | None = None applied: int = 0 skipped: int = 0 skip_reasons: list[str] = field(default_factory=list) error: str | None = None def to_dict(self) -> dict[str, Any]: return { "used": self.used, "model": self.model, "transport_attempts": self.transport_attempts, "request_variant": self.request_variant, "accepted": self.accepted, "rejected": self.rejected, "rejection_reasons": list(self.rejection_reasons), "semantic_rounds": self.semantic_rounds, "provider_request_count": self.provider_request_count, "initial": { "proposed": self.initial_proposed, "accepted": self.initial_accepted, "rejected": self.initial_rejected, "rejection_reasons": list(self.initial_rejection_reasons), }, "repair": { "attempted": self.repair_attempted, "proposed": self.repair_proposed, "accepted": self.repair_accepted, "rejected": self.repair_rejected, "rejection_reasons": list(self.repair_rejection_reasons), "transport_attempts": self.repair_transport_attempts, "request_variant": self.repair_request_variant, "error": self.repair_error, }, "applied": self.applied, "skipped": self.skipped, "skip_reasons": list(self.skip_reasons), "error": self.error, "units": [unit.to_dict() for unit in self.units], } @dataclass class GuardResult: passed: bool checks: dict[str, bool] failures: list[str] = field(default_factory=list) def to_dict(self) -> dict[str, Any]: return asdict(self) @dataclass(frozen=True) class CompileResult: output_dir: Path | None report: dict[str, Any] skill_name: str