"""BaseIntrospector — contract for source-specific schema readers. Subclasses produce a Source object with raw schema (names, types, sample values, stats). The planner consumes this directly — descriptions are not LLM-generated. """ from abc import ABC, abstractmethod from ..models import Source # Max sample values stored per column (down from 5 — token cost: sample values # are fed to the planner prompt). Single source of truth for every introspection # path (tabular files + DB), so the cap can never drift between them. SAMPLE_LIMIT = 3 class BaseIntrospector(ABC): """Abstract base. Subclasses: DatabaseIntrospector, TabularIntrospector.""" @abstractmethod async def introspect(self, location_ref: str) -> Source: ...