"""Pydantic schemas for KB Accelerator.""" from typing import Any, Literal, Optional from uuid import UUID from pydantic import BaseModel, Field # ── Requests ── class KBUploadTextRequest(BaseModel): """Upload KB article via text paste.""" content: str = Field(..., min_length=10, max_length=500_000) title: Optional[str] = Field(None, min_length=1, max_length=255) target_type: Optional[Literal["troubleshooting", "procedural"]] = Field( None, description="Target flow type. If omitted, AI decides." ) class KBNodeEditRequest(BaseModel): """Edit a specific KB import node during review.""" operation: Literal[ "approve", "reject", "edit", "delete", "regenerate", "insert_after" ] content: Optional[dict[str, Any]] = Field( None, description="Updated node content (required for 'edit' and 'insert_after')" ) guidance: Optional[str] = Field( None, max_length=2000, description="User guidance for 'regenerate' operation", ) class KBCommitRequest(BaseModel): """Optional overrides when committing a KB import to the flow library.""" name: Optional[str] = Field(None, min_length=1, max_length=255) description: Optional[str] = Field(None, max_length=2000) category_id: Optional[UUID] = None # ── Responses ── class KBImportNodeResponse(BaseModel): """A single generated node in a KB import.""" id: UUID kb_import_id: UUID node_order: int node_type: str content: dict[str, Any] parent_node_id: Optional[UUID] = None source_excerpt: Optional[str] = None confidence_score: float user_edited: bool user_approved: bool model_config = {"from_attributes": True} class KBUploadResponse(BaseModel): """Response after uploading a KB article.""" id: UUID status: str source_format: str class KBImportResponse(BaseModel): """Full KB import detail with nodes.""" id: UUID account_id: UUID created_by: UUID source_filename: Optional[str] = None source_format: str source_text: str source_metadata: Optional[dict[str, Any]] = None target_type: str status: str confidence_avg: Optional[float] = None error_message: Optional[str] = None processing_time_ms: Optional[int] = None ai_tokens_input: Optional[int] = None ai_tokens_output: Optional[int] = None tree_id: Optional[UUID] = None nodes: list[KBImportNodeResponse] = [] created_at: str updated_at: str model_config = {"from_attributes": True} class KBImportSummary(BaseModel): """Lightweight import item for list view.""" id: UUID source_filename: Optional[str] = None source_format: str target_type: str status: str confidence_avg: Optional[float] = None node_count: int = 0 created_at: str model_config = {"from_attributes": True} class KBImportListResponse(BaseModel): """Paginated list of KB imports.""" items: list[KBImportSummary] total: int skip: int limit: int class KBCommitResponse(BaseModel): """Response after committing a KB import to the flow library.""" tree_id: UUID import_id: UUID tree_type: str class KBQuotaResponse(BaseModel): """Current KB Accelerator entitlements and usage for the user's account.""" plan: str kb_accelerator_enabled: bool lifetime_conversions_used: int lifetime_conversions_limit: Optional[int] = None allowed_formats: list[str] detailed_analysis: bool conversational_refinement: bool step_library_matching: bool history_limit: Optional[int] = None can_convert: bool