Spaces:
Paused
Paused
File size: 6,527 Bytes
88bdcff |
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
"""Pydantic output models for FDAM AI Pipeline.
Contains vision analysis results, calculation outputs, and final assessment output.
"""
from typing import Optional
from pydantic import BaseModel, Field
from .input import (
AssessmentInput,
BoundingBox,
ConditionLevel,
MaterialCategory,
MaterialType,
Priority,
SampleType,
ZoneType,
)
# --- Vision Analysis Output ---
class ZoneAnalysis(BaseModel):
"""Zone classification from vision analysis."""
classification: ZoneType
confidence: float = Field(..., ge=0, le=1)
reasoning: str
class ConditionAnalysis(BaseModel):
"""Condition assessment from vision analysis."""
level: ConditionLevel
confidence: float = Field(..., ge=0, le=1)
reasoning: str
class DetectedMaterial(BaseModel):
"""Material detected in image by vision model."""
type: MaterialType
category: MaterialCategory
confidence: float = Field(..., ge=0, le=1)
location_description: Optional[str] = None
bounding_box: Optional[BoundingBox] = None
class CombustionIndicators(BaseModel):
"""Combustion particle indicators from vision analysis."""
soot_visible: bool = False
soot_pattern: Optional[str] = None
char_visible: bool = False
char_description: Optional[str] = None
ash_visible: bool = False
ash_description: Optional[str] = None
class SamplingRecommendation(BaseModel):
"""Recommended sampling location from vision analysis."""
description: str
sample_type: SampleType
priority: Priority
class VisionAnalysisResult(BaseModel):
"""Complete vision analysis result for a single image.
Matches the VISION_OUTPUT_SCHEMA from the technical spec.
"""
zone: ZoneAnalysis
condition: ConditionAnalysis
materials: list[DetectedMaterial] = Field(default_factory=list)
combustion_indicators: CombustionIndicators
structural_concerns: list[str] = Field(default_factory=list)
access_issues: list[str] = Field(default_factory=list)
recommended_sampling_locations: list[SamplingRecommendation] = Field(default_factory=list)
flags_for_review: list[str] = Field(default_factory=list)
# --- Calculation Results ---
class RoomAreaSummary(BaseModel):
"""Area summary for a single room."""
floor_area: float
surface_area: float
volume: float
class SurfaceAreas(BaseModel):
"""Surface area calculations by various groupings."""
by_type: dict[str, float] = Field(default_factory=dict)
by_disposition: dict[str, float] = Field(default_factory=dict)
by_zone: dict[str, float] = Field(default_factory=dict)
by_room: dict[str, RoomAreaSummary] = Field(default_factory=dict)
total_floor_sf: float = 0
total_surface_sf: float = 0
total_volume_cf: float = 0
class AirFiltration(BaseModel):
"""Air filtration calculation results per NADCA ACR 2021."""
total_volume_cf: float
required_ach: int = 4
unit_cfm: int = 2000
units_required: int
calculation: str
standard_reference: str = "NADCA ACR 2021, Section 3.6"
class SampleDensity(BaseModel):
"""Sample density recommendations per FDAM 2.3."""
total_sf: float
size_category: str
surface_types_count: int
surface_types: list[str] = Field(default_factory=list)
tape_lifts_per_type: str
surface_wipes_per_type: str
recommended_tape_lifts: int
recommended_surface_wipes: int
ceiling_deck_note: Optional[str] = None
control_samples_recommended: bool = True
control_sample_note: str = "Control samples from unaffected areas recommended for baseline comparison"
class LaborEstimate(BaseModel):
"""Labor hour estimates by task."""
hepa_vacuum: float = 0
wet_wipe: float = 0
dry_sponge: float = 0
power_wash: float = 0
scrubber: float = 0
removal: float = 0
hvac_cleaning: float = 0
total_hours: float = 0
class EquipmentRequirements(BaseModel):
"""Equipment requirements for the project."""
air_scrubbers: int = 0
hepa_vacuums: int = 0
negative_air_machines: int = 0
dehumidifiers: int = 0
notes: list[str] = Field(default_factory=list)
class RegulatoryFlag(BaseModel):
"""Regulatory flag for potential hazards."""
flag_type: str
description: str
recommendation: str
reference: str
class RegulatoryFlags(BaseModel):
"""Regulatory flags based on construction era and facility type."""
lead_paint_flag: Optional[RegulatoryFlag] = None
acm_flag: Optional[RegulatoryFlag] = None
other_flags: list[RegulatoryFlag] = Field(default_factory=list)
class CalculationResults(BaseModel):
"""All calculation results from FDAM logic engine."""
surface_areas: SurfaceAreas
air_filtration: AirFiltration
sample_density: SampleDensity
labor_estimate: LaborEstimate
equipment: EquipmentRequirements
regulatory_flags: RegulatoryFlags
# --- Document Output ---
class GeneratedDocuments(BaseModel):
"""Generated document outputs."""
cleaning_specification_md: str = Field(..., description="Cleaning Specification / SOW in Markdown")
sampling_plan_md: Optional[str] = Field(None, description="Sampling plan recommendations in Markdown")
confidence_report_md: Optional[str] = Field(None, description="Confidence report in Markdown")
# --- Confidence Report ---
class FlaggedItem(BaseModel):
"""Item flagged for professional review."""
type: str
room: Optional[str] = None
surface: Optional[str] = None
image_id: Optional[str] = None
confidence: Optional[float] = None
recommendation: str
class ConfidenceReport(BaseModel):
"""Confidence report for assessment."""
flagged_items: list[FlaggedItem] = Field(default_factory=list)
overall_confidence: float = Field(..., ge=0, le=1)
review_required: bool = False
# --- Complete Assessment Output ---
class AssessmentOutput(BaseModel):
"""Complete output from FDAM AI assessment pipeline."""
# Original input (with AI-enriched fields)
input: AssessmentInput
# Vision analysis results (by image ID)
vision_results: dict[str, VisionAnalysisResult] = Field(default_factory=dict)
# Calculation results
calculations: CalculationResults
# Generated documents
documents: GeneratedDocuments
# Confidence report
confidence_report: ConfidenceReport
# Processing metadata
processing_time_seconds: Optional[float] = None
model_versions: dict[str, str] = Field(default_factory=dict)
|