| """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.""" | |
| async def introspect(self, location_ref: str) -> Source: | |
| ... | |