from typing import Any, Dict, Optional from pydantic import BaseModel, Field, field_validator class CurrentState(BaseModel): last_action_code: str = "desconhecido" last_route: str = "desconhecido" last_task_status: str = "desconhecido" metadata: Dict[str, Any] = Field(default_factory=dict) class AnalyzeRequest(BaseModel): last_customer_message: str = Field(..., min_length=1) previous_context: str = "" current_state: CurrentState = Field(default_factory=CurrentState) source: Optional[str] = "manual" conversation_id: Optional[str] = None contact_id: Optional[str] = None @field_validator("last_customer_message") @classmethod def _non_blank_customer_message(cls, value: str) -> str: if not str(value or "").strip(): raise ValueError("last_customer_message não pode estar vazio") return value class ActionDecision(BaseModel): action_code: str note: str = "" confidence: float = Field(ge=0.0, le=1.0, default=0.0) customer_intent: str = "" evidence: str = "" needs_human_review: bool = False history_used: bool = False payment_intent: Optional[str] = None class ActionResult(BaseModel): action_code: str route: str action_required: bool = False action: str note: str = "" safe_to_post: bool = False class UsageInfo(BaseModel): id: Optional[str] = None model: Optional[str] = None provider: Optional[str] = None prompt_tokens: int = 0 completion_tokens: int = 0 total_tokens: int = 0 cost: float = 0.0 class AnalyzeResponse(BaseModel): app: str = "ClientFlow" model: str action_decision: ActionDecision action_result: ActionResult usage: UsageInfo needs_review: bool = False action_run_id: Optional[str] = None message_id: Optional[str] = None task_id: Optional[str] = None