from pydantic import field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", extra="ignore", ) google_project_id: str google_location: str = "us-central1" # Runtime de atendimento do product. Mantido separado do runtime de geração # de código do admin_app, que usa AdminSettings próprios. atendimento_model_name: str | None = None atendimento_bundle_model_name: str | None = None atendimento_temperature: float = 0 atendimento_max_output_tokens: int = 768 # Aliases legados mantidos por compatibilidade enquanto o runtime de # atendimento migra para o perfil explícito de atendimento. vertex_model_name: str = "gemini-2.5-pro" vertex_bundle_model_name: str = "gemini-2.5-pro" # Tools database (MySQL) db_host: str = "127.0.0.1" db_port: int = 3306 db_user: str = "root" db_password: str = "" db_name: str = "orquestrador_mock" db_cloud_sql_connection_name: str | None = None # Mock database (MySQL) for fictitious business data mock_db_host: str = "127.0.0.1" mock_db_port: int = 3306 mock_db_user: str = "root" mock_db_password: str = "" mock_db_name: str = "orquestrador_mock" mock_db_cloud_sql_connection_name: str | None = None mock_seed_enabled: bool = True auto_seed_tools: bool = True auto_seed_mock: bool = True environment: str = "production" debug: bool = False # Cloud SQL (legacy Postgres var kept only for backward compatibility in deploy scripts) cloud_sql_connection_name: str | None = None # Parametros de rede legados (mantidos por compatibilidade) run_vpc_connector: str | None = None run_vpc_egress: str = "private-ranges-only" # Telegram satellite telegram_bot_token: str | None = None telegram_polling_timeout: int = 30 telegram_request_timeout: int = 45 # Conversation state backend conversation_state_backend: str = "memory" conversation_state_ttl_minutes: int = 60 # Redis conversation state redis_url: str = "redis://127.0.0.1:6379/0" redis_key_prefix: str = "orquestrador" redis_socket_timeout_seconds: int = 5 # External integrations integrations_enabled: bool = False integration_sync_delivery_enabled: bool = True brevo_api_key: str | None = None brevo_base_url: str = "https://api.brevo.com/v3" brevo_sender_email: str | None = None brevo_sender_name: str = "Orquestrador" brevo_request_timeout_seconds: int = 10 @field_validator("debug", mode="before") @classmethod def parse_debug_aliases(cls, value): if isinstance(value, str): normalized = value.strip().lower() if normalized in {"debug", "development", "dev"}: return True if normalized in {"release", "production", "prod"}: return False return value @field_validator("environment", "conversation_state_backend", mode="before") @classmethod def normalize_runtime_text_settings(cls, value): if isinstance(value, str): return value.strip().lower() return value @field_validator("atendimento_model_name", "atendimento_bundle_model_name", mode="before") @classmethod def normalize_optional_model_names(cls, value): if isinstance(value, str): stripped = value.strip() return stripped or None return value @field_validator("vertex_model_name", "vertex_bundle_model_name", mode="before") @classmethod def normalize_required_model_names(cls, value): if isinstance(value, str): return value.strip() return value @field_validator("atendimento_temperature") @classmethod def validate_atendimento_temperature(cls, value: float) -> float: if value < 0 or value > 2: raise ValueError("atendimento_temperature must be between 0 and 2") return value @field_validator("atendimento_max_output_tokens") @classmethod def validate_atendimento_max_output_tokens(cls, value: int) -> int: if value < 128: raise ValueError("atendimento_max_output_tokens must be >= 128") return value def resolve_atendimento_model_name(self) -> str: configured = str(self.atendimento_model_name or "").strip() if configured: return configured return str(self.vertex_model_name or "").strip() def resolve_atendimento_bundle_model_name(self) -> str: configured = str(self.atendimento_bundle_model_name or "").strip() if configured: return configured legacy = str(self.vertex_bundle_model_name or "").strip() if legacy: return legacy return self.resolve_atendimento_model_name() def build_atendimento_generation_config(self) -> dict[str, int | float]: return { "temperature": float(self.atendimento_temperature), "max_output_tokens": int(self.atendimento_max_output_tokens), } settings = Settings()