""" Pydantic models and state definitions for the Polymer Datasheet Agent. """ from __future__ import annotations import uuid from datetime import datetime from typing import Any, Literal, Optional from pydantic import BaseModel, Field # ── LangGraph State ────────────────────────────────────────────────────────── class AgentState(BaseModel): """State that flows through the LangGraph workflow.""" # Input input_mode: Literal["search", "upload"] = "search" manufacturer: str = "" polymer_family: str = "" grade: str = "" uploaded_text: str = "" # Raw text from uploaded PDF/file # Search phase search_queries: list[str] = Field(default_factory=list) search_results: list[dict[str, Any]] = Field(default_factory=list) raw_content: str = "" # Aggregated raw text from web/upload # Parsing phase parsed_datasheet: Optional[DatasheetRecord] = None parsing_errors: list[str] = Field(default_factory=list) # Output status: str = "pending" message: str = "" # ── Datasheet Record ───────────────────────────────────────────────────────── class DatasheetRecord(BaseModel): """A single parsed polymer datasheet stored in the database.""" id: str = Field(default_factory=lambda: str(uuid.uuid4())) created_at: str = Field(default_factory=lambda: datetime.now().isoformat()) # General material_name: str = "" trade_name: str = "" manufacturer: str = "" polymer_family: str = "" grade: str = "" description: str = "" processing_method: str = "" features: str = "" applications: str = "" source_url: str = "" # Mechanical tensile_strength_mpa: str = "" tensile_modulus_mpa: str = "" elongation_at_break_pct: str = "" flexural_strength_mpa: str = "" flexural_modulus_mpa: str = "" impact_strength_charpy_kj_m2: str = "" impact_strength_izod_j_m: str = "" hardness_shore_d: str = "" hardness_rockwell: str = "" compressive_strength_mpa: str = "" # Thermal melting_temperature_c: str = "" glass_transition_temperature_c: str = "" heat_deflection_temperature_c: str = "" vicat_softening_temperature_c: str = "" continuous_service_temperature_c: str = "" thermal_conductivity_w_mk: str = "" coefficient_of_thermal_expansion_um_mk: str = "" flammability_rating: str = "" # Physical density_g_cm3: str = "" melt_flow_index_g_10min: str = "" water_absorption_pct: str = "" moisture_absorption_pct: str = "" specific_gravity: str = "" transparency: str = "" color: str = "" # Electrical dielectric_strength_kv_mm: str = "" dielectric_constant: str = "" volume_resistivity_ohm_cm: str = "" surface_resistivity_ohm: str = "" dissipation_factor: str = "" # Chemical Resistance acid_resistance: str = "" alkali_resistance: str = "" solvent_resistance: str = "" uv_resistance: str = "" weatherability: str = "" # Regulatory fda_approved: str = "" rohs_compliant: str = "" reach_compliant: str = "" ul94_rating: str = "" def to_flat_dict(self) -> dict[str, str]: """Return all fields as a flat dict for database storage.""" return self.model_dump() # ── Search Result ──────────────────────────────────────────────────────────── class SearchResult(BaseModel): """One web search result from Tavily.""" title: str = "" url: str = "" content: str = "" raw_content: str = "" score: float = 0.0