from __future__ import annotations from dataclasses import dataclass, field from typing import Literal, Optional AnchorKind = Literal["slide", "page", "heading"] @dataclass(frozen=True) class Anchor: """Exact, immutable pointer back to where text came from.""" file: str # e.g. "heap-sort.pptx" kind: AnchorKind # "slide" | "page" | "heading" locator: str # slide/page number as str, or heading text label: str # human-readable, e.g. 'heap-sort.pptx — slide 12 ("Heap Sort")' is_notes: bool = False # True for PPTX speaker-notes blocks @dataclass class ParsedBlock: """One structural unit (a slide, a page, a heading-section) as plain text.""" text: str anchor: Anchor title: Optional[str] = None has_text: bool = True # False => no extractable text (flag for OCR in Phase 2) @dataclass class Chunk: """A retrievable unit; inherits its block's anchor.""" id: str file: str anchor: Anchor title: Optional[str] text: str concepts: list[str] = field(default_factory=list)