File size: 4,054 Bytes
cb4d01a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""

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