from datetime import datetime from typing import Literal from pydantic import BaseModel, Field, ConfigDict # Stub locale di _YamlModel (in the reference implementation vive in mschema/models.py). # Qui serve solo come base con populate_by_name; mschema/ sara' portato nel Task A9. class _YamlModel(BaseModel): model_config = ConfigDict(populate_by_name=True) class SessionManifest(_YamlModel): id: str created_at: datetime status: Literal["open", "closed", "finalized"] = "open" question: str database: str db_schema: str = Field(alias="schema") # D12/D15: autore della sessione (auth) e versione del workflow usato. author: str | None = None summary: str | None = None updated_at: datetime | None = None updated_by: str | None = None schema_version: int | None = None class Candidate(BaseModel): kind: Literal["table", "column"] name: str signals: dict = {} evidence: list[str] = [] decision: Literal["promoted", "excluded", "pending"] = "pending" decision_seq: int | None = None # D14a: valori citati nella domanda ancorati a questa colonna/tabella. grounded_values: list[dict] = [] class Join(BaseModel): from_: str = Field(alias="from") to: str source: str = "" decision: Literal["promoted", "excluded", "pending"] = "promoted" decision_seq: int | None = None model_config = {"populate_by_name": True} class ExcludedItem(BaseModel): kind: Literal["table", "column"] name: str decision_seq: int | None = None class SchemaLinking(BaseModel): question: str candidates: list[Candidate] = [] joins: list[Join] = [] excluded: list[ExcludedItem] = [] open_questions: list[str] = [] # D14b: formule di concetto approvate, parte dello schema-linking. concept_formulas: list[dict] = [] model_config = {"extra": "forbid"}