dexteredep's picture
Improve house recommendations
4a1f3ff
"""
Data models for Visualization Agent
Self-contained models for independent deployment
"""
from __future__ import annotations
from typing import Optional, List, Literal, Dict, Any
from pydantic import BaseModel, Field
# Input Types
BuildingType = Literal[
"residential_single_family",
"residential_multi_family",
"residential_high_rise",
"commercial_office",
"commercial_retail",
"industrial_warehouse",
"institutional_school",
"institutional_hospital",
"infrastructure_bridge",
"mixed_use"
]
RiskLevel = Literal["CRITICAL", "HIGH", "MODERATE", "LOW"]
# Base Models
class Coordinates(BaseModel):
"""Geographic coordinates"""
latitude: float
longitude: float
class LocationInfo(BaseModel):
"""Location information"""
name: str
coordinates: Coordinates
administrative_area: str
# Risk Assessment Models (needed for input)
class HazardDetail(BaseModel):
"""Detailed information about a specific hazard"""
status: str
description: str
distance: Optional[str] = None
direction: Optional[str] = None
severity: Optional[str] = None
class SeismicHazards(BaseModel):
"""Seismic hazard information"""
active_fault: HazardDetail
ground_shaking: HazardDetail
liquefaction: HazardDetail
tsunami: HazardDetail
earthquake_induced_landslide: HazardDetail
fissure: HazardDetail
ground_rupture: HazardDetail
class VolcanicHazards(BaseModel):
"""Volcanic hazard information"""
active_volcano: HazardDetail
potentially_active_volcano: HazardDetail
inactive_volcano: HazardDetail
ashfall: HazardDetail
pyroclastic_flow: HazardDetail
lahar: HazardDetail
lava: HazardDetail
ballistic_projectile: HazardDetail
base_surge: HazardDetail
volcanic_tsunami: HazardDetail
class HydroHazards(BaseModel):
"""Hydrometeorological hazard information"""
flood: HazardDetail
rain_induced_landslide: HazardDetail
storm_surge: HazardDetail
severe_winds: HazardDetail
class HazardData(BaseModel):
"""Complete hazard data from risk assessment"""
seismic: SeismicHazards
volcanic: VolcanicHazards
hydrometeorological: HydroHazards
class RiskSummary(BaseModel):
"""Summary of overall risk assessment"""
overall_risk_level: RiskLevel
total_hazards_assessed: int
high_risk_count: int
moderate_risk_count: int
critical_hazards: List[str] = Field(default_factory=list)
llm_analysis: Optional[str] = None
class FacilityInfo(BaseModel):
"""Critical facilities information from risk assessment"""
schools: Dict[str, Any] | List[Dict[str, Any]] = Field(default_factory=lambda: {})
hospitals: Dict[str, Any] | List[Dict[str, Any]] = Field(default_factory=lambda: {})
road_networks: Dict[str, Any] | List[Dict[str, Any]] = Field(default_factory=lambda: [])
class Metadata(BaseModel):
"""Metadata for data sources"""
timestamp: str
source: str
cache_status: str
ttl: int
class RiskData(BaseModel):
"""Complete risk assessment data"""
success: bool
summary: RiskSummary
location: LocationInfo
hazards: HazardData
facilities: FacilityInfo
metadata: Metadata
# Construction Recommendations Models (needed for input)
class RecommendationDetail(BaseModel):
"""Detailed construction recommendation"""
hazard_type: str
recommendation: str
rationale: str
source_url: Optional[str] = None
class BuildingCodeReference(BaseModel):
"""Building code reference"""
code_name: str
section: str
requirement: str
class Recommendations(BaseModel):
"""Construction recommendations"""
general_guidelines: List[str] = Field(default_factory=list)
seismic_recommendations: List[RecommendationDetail] = Field(default_factory=list)
volcanic_recommendations: List[RecommendationDetail] = Field(default_factory=list)
hydrometeorological_recommendations: List[RecommendationDetail] = Field(default_factory=list)
priority_actions: List[str] = Field(default_factory=list)
building_codes: List[BuildingCodeReference] = Field(default_factory=list)
# House Specifications Models
FoundationType = Literal["shallow", "deep_pile", "raft", "combined", "elevated"]
RoofType = Literal["pitched", "flat", "hip", "gable"]
MaterialType = Literal["reinforced_concrete", "steel_frame", "wood", "composite", "masonry"]
class StructuralFeature(BaseModel):
"""Structural feature specification"""
feature_name: str
specification: str
justification: str
class HouseSpecifications(BaseModel):
"""House specifications for construction"""
number_of_floors: int
primary_material: MaterialType
foundation_type: FoundationType
foundation_depth_meters: float
roof_type: RoofType
wall_thickness_mm: int
reinforcement_details: str
structural_features: List[StructuralFeature] = Field(default_factory=list)
compliance_codes: List[str] = Field(default_factory=list)
decision_rationale: str
# Visualization-specific Models
class VisualizationData(BaseModel):
"""Generated visualization data"""
image_base64: str # Base64-encoded PNG image
prompt_used: str # The prompt that generated the image
model_version: str # Gemini model version used
generation_timestamp: str # ISO format timestamp
image_format: str # "PNG"
resolution: str # "1024x1024"
features_included: List[str] # List of disaster-resistant features shown
class VisualizationRequest(BaseModel):
"""Request for visualization generation"""
risk_data: RiskData
building_type: BuildingType
recommendations: Optional[Recommendations] = None
class VisualizationResponse(BaseModel):
"""Agent response format"""
success: bool
visualization_data: Optional[VisualizationData] = None
error: Optional[ErrorDetail] = None
# Error Handling Models
class ErrorDetail(BaseModel):
"""Error detail information"""
code: str
message: str
details: Optional[Dict[str, Any]] = None
retry_possible: bool = False
class ErrorResponse(BaseModel):
"""Error response structure"""
success: bool = False
error: Optional[ErrorDetail] = None
partial_results: Optional[Dict[str, Any]] = None
# Image Generation Models (Pydantic versions for API validation)
class ImageConfig(BaseModel):
"""Configuration for image generation parameters"""
model: str = "gemini-2.5-flash-image" # or "gemini-3-pro-image-preview"
aspect_ratio: str = "16:9" # 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9
image_size: str = "1K" # 1K, 2K, 4K (4K only for gemini-3-pro-image-preview)
use_search: bool = False # Enable Google Search grounding
output_format: str = "png"
class VisualizationGenerationRequest(BaseModel):
"""Input data for image generation (API request format)"""
prompt: str
construction_data: Optional[Dict[str, Any]] = None
config: Optional[ImageConfig] = None
class VisualizationGenerationResponse(BaseModel):
"""Output data from image generation (API response format)"""
success: bool
image_path: Optional[str] = None
image_base64: Optional[str] = None
text_response: Optional[str] = None
error: Optional[Dict[str, Any]] = None