| """Shared contract for query executors.""" | |
| from abc import ABC, abstractmethod | |
| from dataclasses import dataclass, field | |
| from sqlalchemy.ext.asyncio import AsyncSession | |
| from src.rag.base import RetrievalResult | |
| class QueryResult: | |
| source_type: str # "database" or "document" | |
| source_id: str # database_client_id or document_id | |
| table_or_file: str | |
| columns: list[str] | |
| rows: list[dict] | |
| row_count: int | |
| metadata: dict = field(default_factory=dict) | |
| # metadata should include "column_types": {"col_name": "dtype"} when available | |
| class BaseExecutor(ABC): | |
| async def execute( | |
| self, | |
| results: list[RetrievalResult], | |
| user_id: str, | |
| db: AsyncSession, | |
| question: str, | |
| limit: int = 100, | |
| ) -> list[QueryResult]: ... | |