"""Ultra-minimal Pydantic models for pure Mem0 API.""" from typing import List, Optional, Dict, Any from pydantic import BaseModel, Field import re # Constants for input validation MAX_MESSAGE_LENGTH = 50000 # ~12k tokens max per message MAX_QUERY_LENGTH = 10000 # ~2.5k tokens max per query MAX_USER_ID_LENGTH = 100 # Reasonable user ID length MAX_MEMORY_ID_LENGTH = 100 # Memory IDs are typically UUIDs MAX_CONTEXT_MESSAGES = 100 # Max conversation context messages USER_ID_PATTERN = r"^[a-zA-Z0-9_\-\.@]+$" # Alphanumeric with common separators # Request Models class ChatMessage(BaseModel): """Chat message structure.""" role: str = Field( ..., max_length=20, description="Message role (user, assistant, system)" ) content: str = Field( ..., max_length=MAX_MESSAGE_LENGTH, description="Message content" ) class ChatRequest(BaseModel): """Ultra-minimal chat request.""" message: str = Field(..., max_length=MAX_MESSAGE_LENGTH, description="User message") user_id: Optional[str] = Field( "default", max_length=MAX_USER_ID_LENGTH, pattern=USER_ID_PATTERN, description="User identifier (alphanumeric, _, -, ., @)", ) agent_id: Optional[str] = Field( None, max_length=MAX_USER_ID_LENGTH, description="Agent identifier" ) run_id: Optional[str] = Field( None, max_length=MAX_USER_ID_LENGTH, description="Run identifier" ) context: Optional[List[ChatMessage]] = Field( None, max_length=MAX_CONTEXT_MESSAGES, description="Previous conversation context (max 100 messages)", ) metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata") class MemoryAddRequest(BaseModel): """Request to add memories with hierarchy support - open-source compatible.""" messages: List[ChatMessage] = Field( ..., max_length=MAX_CONTEXT_MESSAGES, description="Messages to process (max 100 messages)", ) user_id: Optional[str] = Field( "default", max_length=MAX_USER_ID_LENGTH, pattern=USER_ID_PATTERN, description="User identifier", ) agent_id: Optional[str] = Field( None, max_length=MAX_USER_ID_LENGTH, description="Agent identifier" ) run_id: Optional[str] = Field( None, max_length=MAX_USER_ID_LENGTH, description="Run identifier" ) metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata") class MemorySearchRequest(BaseModel): """Request to search memories with hierarchy filtering.""" query: str = Field(..., max_length=MAX_QUERY_LENGTH, description="Search query") user_id: Optional[str] = Field( "default", max_length=MAX_USER_ID_LENGTH, pattern=USER_ID_PATTERN, description="User identifier", ) agent_id: Optional[str] = Field( None, max_length=MAX_USER_ID_LENGTH, description="Agent identifier" ) run_id: Optional[str] = Field( None, max_length=MAX_USER_ID_LENGTH, description="Run identifier" ) limit: int = Field(5, ge=1, le=100, description="Maximum number of results (1-100)") threshold: Optional[float] = Field( None, ge=0.0, le=1.0, description="Minimum relevance score (0-1)" ) filters: Optional[Dict[str, Any]] = Field(None, description="Additional filters") class MemoryUpdateRequest(BaseModel): """Request to update a memory.""" memory_id: str = Field( ..., max_length=MAX_MEMORY_ID_LENGTH, description="Memory ID to update" ) user_id: str = Field( ..., max_length=MAX_USER_ID_LENGTH, pattern=USER_ID_PATTERN, description="User identifier for ownership verification", ) content: str = Field( ..., max_length=MAX_MESSAGE_LENGTH, description="New memory content" ) metadata: Optional[Dict[str, Any]] = Field(None, description="Updated metadata") # Response Models - Ultra-minimal class MemoryItem(BaseModel): """Individual memory item.""" id: str = Field(..., description="Memory unique identifier") memory: str = Field(..., description="Memory content") user_id: Optional[str] = Field(None, description="Associated user ID") agent_id: Optional[str] = Field(None, description="Associated agent ID") run_id: Optional[str] = Field(None, description="Associated run ID") metadata: Optional[Dict[str, Any]] = Field(None, description="Memory metadata") score: Optional[float] = Field( None, description="Relevance score (for search results)" ) created_at: Optional[str] = Field(None, description="Creation timestamp") updated_at: Optional[str] = Field(None, description="Last update timestamp") class MemorySearchResponse(BaseModel): """Memory search results - pure Mem0 structure.""" memories: List[MemoryItem] = Field(..., description="Found memories") total_count: int = Field(..., description="Total number of memories found") query: str = Field(..., description="Original search query") class MemoryAddResponse(BaseModel): """Response from adding memories - pure Mem0 structure.""" added_memories: List[Dict[str, Any]] = Field( ..., description="Memories that were added" ) message: str = Field(..., description="Success message") class GraphRelationship(BaseModel): """Graph relationship structure.""" source: str = Field(..., description="Source entity") relationship: str = Field(..., description="Relationship type") target: str = Field(..., description="Target entity") properties: Optional[Dict[str, Any]] = Field( None, description="Relationship properties" ) class GraphResponse(BaseModel): """Graph relationships - pure Mem0 structure.""" relationships: List[GraphRelationship] = Field( ..., description="Found relationships" ) entities: List[str] = Field(..., description="Unique entities") user_id: str = Field(..., description="User identifier") class HealthResponse(BaseModel): """Health check response.""" status: str = Field(..., description="Service status") services: Dict[str, str] = Field(..., description="Individual service statuses") timestamp: str = Field(..., description="Health check timestamp") class ErrorResponse(BaseModel): """Error response structure.""" error: str = Field(..., description="Error message") detail: Optional[str] = Field(None, description="Detailed error information") status_code: int = Field(..., description="HTTP status code") # Statistics and Monitoring Models class MemoryOperationStats(BaseModel): """Memory operation statistics.""" add: int = Field(..., description="Number of add operations") search: int = Field(..., description="Number of search operations") update: int = Field(..., description="Number of update operations") delete: int = Field(..., description="Number of delete operations") class GlobalStatsResponse(BaseModel): """Global application statistics.""" total_memories: int = Field(..., description="Total memories across all users") total_users: int = Field(..., description="Total number of users") api_calls_today: int = Field(..., description="Total API calls today") avg_response_time_ms: float = Field( ..., description="Average response time in milliseconds" ) memory_operations: MemoryOperationStats = Field( ..., description="Memory operation breakdown" ) uptime_seconds: float = Field(..., description="Application uptime in seconds") class UserStatsResponse(BaseModel): """User-specific statistics.""" user_id: str = Field(..., description="User identifier") memory_count: int = Field(..., description="Number of memories for this user") relationship_count: int = Field( ..., description="Number of graph relationships for this user" ) last_activity: Optional[str] = Field(None, description="Last activity timestamp") api_calls_today: int = Field(..., description="API calls made by this user today") avg_response_time_ms: float = Field( ..., description="Average response time for this user's requests" )