"""Pydantic models for document chunks produced by the segmenter.""" from __future__ import annotations import hashlib from pydantic import BaseModel, Field, computed_field class DocumentChunk(BaseModel): """A contiguous text segment of a source document with offset metadata. The chunk preserves exact source character offsets so that downstream evidence spans can always be mapped back to the original document text. """ chunk_id: str = Field(description="Deterministic ID: {document_id}:{start_char}") document_id: str = Field(description="Parent document identifier") document_type: str = Field(description="Type of document: article, filing, transcript, macro_event") section_path: list[str] = Field(default_factory=list, description="Hierarchical section/heading path") speaker: str | None = Field(default=None, description="Speaker label for transcript chunks") start_char: int = Field(ge=0, description="Start character offset in source document") end_char: int = Field(gt=0, description="End character offset in source document (exclusive)") text: str = Field(min_length=1, description="Chunk text content") overlap_left: int = Field(default=0, ge=0, description="Characters of overlap with previous chunk") overlap_right: int = Field(default=0, ge=0, description="Characters of overlap with next chunk") boilerplate_score: float = Field(default=0.0, ge=0.0, le=1.0, description="Boilerplate likelihood 0.0-1.0") @computed_field # type: ignore[prop-decorator] @property def checksum(self) -> str: """SHA-256 hex digest of the chunk text.""" return hashlib.sha256(self.text.encode("utf-8")).hexdigest()