# Cidadão.AI Backend API Data Structures This document provides a comprehensive reference for all Pydantic models, request/response schemas, and data structures used in the Cidadão.AI backend API that a frontend application would need to implement. ## Table of Contents 1. [Chat API Models](#chat-api-models) 2. [WebSocket Models](#websocket-models) 3. [Investigation Models](#investigation-models) 4. [Authentication Models](#authentication-models) 5. [Agent Models](#agent-models) 6. [Pagination Models](#pagination-models) 7. [Error Response Format](#error-response-format) --- ## Chat API Models ### ChatRequest ```python class ChatRequest(BaseModel): """Chat message request""" message: str # min_length=1, max_length=1000 session_id: Optional[str] = None context: Optional[Dict[str, Any]] = None ``` ### ChatResponse ```python class ChatResponse(BaseModel): """Chat message response""" session_id: str agent_id: str agent_name: str message: str confidence: float suggested_actions: Optional[List[str]] = None requires_input: Optional[Dict[str, str]] = None metadata: Dict[str, Any] = {} ``` ### QuickAction ```python class QuickAction(BaseModel): """Quick action suggestion""" id: str label: str icon: str action: str ``` ### Stream Response Format (SSE) ```javascript // Server-Sent Events format for /api/v1/chat/stream data: {"type": "start", "timestamp": "2025-01-19T12:00:00Z"} data: {"type": "detecting", "message": "Analisando sua mensagem..."} data: {"type": "intent", "intent": "investigate", "confidence": 0.92} data: {"type": "agent_selected", "agent_id": "zumbi", "agent_name": "Zumbi dos Palmares"} data: {"type": "chunk", "content": "Olá! Sou Zumbi dos Palmares..."} data: {"type": "complete", "suggested_actions": ["start_investigation", "learn_more"]} data: {"type": "error", "message": "Erro ao processar mensagem"} ``` --- ## WebSocket Models ### WebSocketMessage ```python class WebSocketMessage(BaseModel): """WebSocket message structure""" type: str # Message type data: Dict[str, Any] = {} timestamp: datetime = Field(default_factory=datetime.utcnow) id: str = Field(default_factory=lambda: str(uuid4())) ``` ### WebSocket Connection URL ``` ws://localhost:8000/api/v1/ws/chat/{session_id}?token={jwt_token} ``` ### WebSocket Message Types #### Client to Server ```javascript // Send chat message { "type": "chat_message", "data": { "message": "Investigar contratos do Ministério da Saúde", "context": {} } } // Subscribe to investigation { "type": "subscribe_investigation", "data": { "investigation_id": "123e4567-e89b-12d3-a456-426614174000" } } // Unsubscribe from investigation { "type": "unsubscribe_investigation", "data": { "investigation_id": "123e4567-e89b-12d3-a456-426614174000" } } // Keep alive ping { "type": "ping", "data": {} } ``` #### Server to Client ```javascript // Connection established { "type": "connection", "data": { "status": "connected", "session_id": "abc123", "message": "Conectado ao Cidadão.AI em tempo real" }, "timestamp": "2025-01-19T12:00:00Z", "id": "msg123" } // Agent response { "type": "agent_response", "data": { "agent_id": "zumbi", "agent_name": "Zumbi dos Palmares", "message": "Encontrei 15 anomalias nos contratos...", "confidence": 0.92, "metadata": { "processing_time_ms": 1250, "anomalies_found": 15 } } } // Investigation update { "type": "investigation_update", "data": { "investigation_id": "123e4567", "status": "processing", "progress": 0.75, "current_phase": "analyzing_patterns", "anomalies_detected": 12 } } // Error message { "type": "error", "data": { "code": "PROCESSING_ERROR", "message": "Failed to process request", "details": {} } } // Pong response { "type": "pong", "data": {} } ``` --- ## Investigation Models ### InvestigationRequest ```python class InvestigationRequest(BaseModel): """Request model for starting an investigation""" query: str # Investigation query or focus area data_source: str = "contracts" # One of: contracts, expenses, agreements, biddings, servants filters: Dict[str, Any] = {} anomaly_types: List[str] = ["price", "vendor", "temporal", "payment"] include_explanations: bool = True stream_results: bool = False ``` ### InvestigationResponse ```python class InvestigationResponse(BaseModel): """Response model for investigation results""" investigation_id: str status: str query: str data_source: str started_at: datetime completed_at: Optional[datetime] = None anomalies_found: int total_records_analyzed: int results: List[Dict[str, Any]] summary: str confidence_score: float processing_time: float ``` ### AnomalyResult ```python class AnomalyResult(BaseModel): """Individual anomaly result""" anomaly_id: str type: str # price, vendor, temporal, payment, duplicate, pattern severity: str # low, medium, high, critical confidence: float description: str explanation: str affected_records: List[Dict[str, Any]] suggested_actions: List[str] metadata: Dict[str, Any] ``` ### InvestigationStatus ```python class InvestigationStatus(BaseModel): """Investigation status response""" investigation_id: str status: str # started, processing, completed, failed progress: float # 0.0 to 1.0 current_phase: str records_processed: int anomalies_detected: int estimated_completion: Optional[datetime] = None ``` --- ## Authentication Models ### LoginRequest ```python class LoginRequest(BaseModel): email: str # EmailStr password: str ``` ### LoginResponse ```python class LoginResponse(BaseModel): access_token: str refresh_token: str token_type: str = "bearer" expires_in: int # seconds user: { "id": str, "email": str, "name": str, "role": str, "is_active": bool } ``` ### RefreshRequest ```python class RefreshRequest(BaseModel): refresh_token: str ``` ### RefreshResponse ```python class RefreshResponse(BaseModel): access_token: str token_type: str = "bearer" expires_in: int # seconds ``` ### RegisterRequest ```python class RegisterRequest(BaseModel): email: str # EmailStr password: str name: str role: Optional[str] = "analyst" ``` ### UserResponse ```python class UserResponse(BaseModel): id: str email: str name: str role: str is_active: bool created_at: datetime last_login: Optional[datetime] = None ``` ### Authorization Header ``` Authorization: Bearer {access_token} ``` --- ## Agent Models ### AgentMessage ```python class AgentMessage(BaseModel): """Message passed between agents""" sender: str # Agent that sent the message recipient: str # Agent that should receive the message action: str # Action to perform payload: Dict[str, Any] = {} context: Dict[str, Any] = {} timestamp: datetime message_id: str requires_response: bool = True ``` ### AgentResponse ```python class AgentResponse(BaseModel): """Response from an agent""" agent_name: str status: str # IDLE, PROCESSING, COMPLETED, ERROR, REFLECTING result: Optional[Any] = None error: Optional[str] = None metadata: Dict[str, Any] = {} timestamp: datetime processing_time_ms: Optional[float] = None ``` ### Available Agents ```javascript const AGENTS = { abaporu: { name: "Abaporu", role: "Orquestrador" }, zumbi: { name: "Zumbi dos Palmares", role: "Investigador" }, anita: { name: "Anita Garibaldi", role: "Analista" }, tiradentes: { name: "Tiradentes", role: "Relator" }, machado: { name: "Machado de Assis", role: "Textual" }, dandara: { name: "Dandara", role: "Justiça Social" }, drummond: { name: "Carlos Drummond de Andrade", role: "Comunicação" } } ``` --- ## Pagination Models ### CursorPaginationRequest ```python class CursorPaginationRequest(BaseModel): """Request parameters for cursor pagination""" cursor: Optional[str] = None # Base64 encoded cursor limit: int = 20 # min=1, max=100 direction: str = "next" # next or prev ``` ### CursorPaginationResponse ```python class CursorPaginationResponse(BaseModel): """Response with cursor pagination metadata""" items: List[T] next_cursor: Optional[str] = None prev_cursor: Optional[str] = None has_more: bool = False total_items: Optional[int] = None metadata: Dict[str, Any] = {} ``` ### Cursor Format ```javascript // Cursor is base64 encoded JSON { "t": "2025-01-19T12:00:00Z", // timestamp "i": "123e4567", // id "d": "next" // direction } ``` --- ## Error Response Format All API errors follow this standardized format: ### HTTP Exception Response ```javascript { "status": "error", "status_code": 400, // HTTP status code "error": { "error": "HTTPException", "message": "Invalid request data", "details": {} } } ``` ### Application Error Response ```javascript { "status": "error", "status_code": 500, "error": { "error": "InternalServerError", "message": "An unexpected error occurred", "details": { "error_type": "DatabaseConnectionError" // Only in development } } } ``` ### Custom Exception Format (CidadaoAIError) ```javascript { "error": "AgentExecutionError", // Error code "message": "Agent failed to execute task", "details": { "agent": "zumbi", "action": "investigate", "error": "Connection timeout" } } ``` --- ## Common HTTP Status Codes - `200 OK` - Success - `201 Created` - Resource created - `400 Bad Request` - Invalid request data - `401 Unauthorized` - Missing or invalid authentication - `403 Forbidden` - Insufficient permissions - `404 Not Found` - Resource not found - `422 Unprocessable Entity` - Validation error - `429 Too Many Requests` - Rate limit exceeded - `500 Internal Server Error` - Server error --- ## API Base URLs ### Development ``` http://localhost:8000/api/v1 ws://localhost:8000/api/v1/ws ``` ### Production (HuggingFace Spaces) ``` https://neural-thinker-cidadao-ai-backend.hf.space/api/v1 wss://neural-thinker-cidadao-ai-backend.hf.space/api/v1/ws ``` --- ## TypeScript Interface Examples For TypeScript frontend implementations, here are the equivalent interfaces: ```typescript // Chat interfaces interface ChatRequest { message: string; session_id?: string; context?: Record; } interface ChatResponse { session_id: string; agent_id: string; agent_name: string; message: string; confidence: number; suggested_actions?: string[]; requires_input?: Record; metadata: Record; } // WebSocket interfaces interface WebSocketMessage { type: string; data: Record; timestamp: string; id: string; } // Investigation interfaces interface InvestigationRequest { query: string; data_source?: 'contracts' | 'expenses' | 'agreements' | 'biddings' | 'servants'; filters?: Record; anomaly_types?: string[]; include_explanations?: boolean; stream_results?: boolean; } // Error interface interface ErrorResponse { status: 'error'; status_code: number; error: { error: string; message: string; details: Record; }; } ``` --- ## Notes for Frontend Developers 1. **Authentication**: All authenticated endpoints require the `Authorization: Bearer {token}` header 2. **WebSocket**: Connect with JWT token as query parameter for authentication 3. **Pagination**: Use cursor-based pagination for chat history and large datasets 4. **Error Handling**: Always check for error responses and handle appropriately 5. **SSE Streaming**: For real-time responses, use EventSource API with `/api/v1/chat/stream` 6. **Rate Limiting**: Respect rate limits indicated in response headers 7. **Timestamp Format**: All timestamps are in ISO 8601 format (UTC) 8. **IDs**: All entity IDs are UUIDs in string format