from __future__ import annotations from pydantic import BaseModel, HttpUrl, Field from typing import List, Optional, Tuple, Literal, Dict from datetime import datetime class SourceMeta(BaseModel): jurisdiction: Literal["HK", "EU", "ICAO", "SESAR", "ASTM", "ISO", "OTHER"] = "OTHER" authority: Optional[str] = None collection: Optional[str] = None canonical_id: Optional[str] = None title: Optional[str] = None lang: str = "en" version: Optional[str] = None effective_date: Optional[datetime] = None publication_date: Optional[datetime] = None retrieved_at: datetime = Field(default_factory=datetime.utcnow) url: HttpUrl media_type: Literal["application/pdf", "text/html", "application/xhtml+xml", "text/plain"] etag: Optional[str] = None last_modified: Optional[str] = None sha256: Optional[str] = None pages: Optional[int] = None notes: Optional[str] = None class Node(BaseModel): node_id: str path: List[str] label: str title: Optional[str] = None page_span: Optional[Tuple[int, int]] = None text: str html: Optional[str] = None numbering: Optional[str] = None children: List["Node"] = Field(default_factory=list) node_hash: Optional[str] = None Node.model_rebuild() class Chunk(BaseModel): source: SourceMeta node_id: str chunk_id: str path: List[str] text: str html: Optional[str] = None page_span: Optional[Tuple[int, int]] = None token_count: int heading_breadcrumb: Optional[str] = None numbering: Optional[str] = None citations_in: Optional[List[Dict[str, str]]] = None tags: Optional[List[str]] = None concepts: Optional[List[str]] = None