tillu-daemon / app /models /api.py
tillu-AI's picture
upload app/models/api.py
d47f36f verified
"""
API Request/Response Models
"""
from typing import Any, Dict, List, Optional
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, Field, validator
from enum import Enum
class MessageType(str, Enum):
TEXT = "text"
AUDIO = "audio"
IMAGE = "image"
DOCUMENT = "document"
LOCATION = "location"
class MessageRequest(BaseModel):
"""Request model for /api/v1/message endpoint"""
type: MessageType = Field(default=MessageType.TEXT)
text: Optional[str] = None
media_url: Optional[str] = None
location: Optional[Dict[str, float]] = None # {lat, lng}
metadata: Optional[Dict[str, Any]] = Field(default_factory=dict)
client_id: Optional[UUID] = None
@validator("text")
def validate_text_for_text_type(cls, v, values):
if values.get("type") == MessageType.TEXT and not v:
raise ValueError("text is required for text message type")
return v
class ChainMetadata(BaseModel):
"""Metadata about the chain execution"""
chain: str
model: str
latency_ms: int
tokens_used: int
intent_class: Optional[str] = None
personality_mode: Optional[str] = None
class SourceInfo(BaseModel):
"""Source information for responses"""
name: str
url: Optional[str] = None
type: str = "general"
class MessageResponse(BaseModel):
"""Response model for /api/v1/message endpoint"""
response: Dict[str, Any] = Field(..., description="Response content with type and structured data")
personality_mode: str = "sharp"
queued_events: List[Dict[str, Any]] = Field(default_factory=list)
intelligence_packet: Optional[Dict[str, Any]] = None
meta: ChainMetadata
sources: List[SourceInfo] = Field(default_factory=list)
session_id: Optional[UUID] = None
class IntelligencePacket(BaseModel):
"""Compiled intelligence for client consumption"""
packet_type: str # morning_brief, news_digest, etc.
generated_at: datetime
expires_at: Optional[datetime] = None
content: Dict[str, Any]
sources: List[SourceInfo]
class EventResponse(BaseModel):
"""Event in the response queue"""
event_id: UUID
event_type: str
urgency: int = Field(..., ge=1, le=10)
title: str
body: str
tillu_message: str
actions: List[str]
generated_at: datetime
requires_ack: bool = False
class HealthStatus(BaseModel):
"""Health status of a service"""
service: str
status: str # healthy, degraded, down
response_time_ms: Optional[int] = None
last_check: datetime
details: Optional[Dict[str, Any]] = None
class HealthResponse(BaseModel):
"""System health status"""
status: str = "healthy"
version: str
timestamp: datetime
services: List[HealthStatus]
api_limits: Dict[str, Dict[str, Any]] # Provider -> {remaining, reset_time}
queue_depths: Dict[str, int] # Queue name -> count
class MemorySearchRequest(BaseModel):
"""Request for semantic memory search"""
query: str
types: Optional[List[str]] = None # Filter by content type
date_range_start: Optional[datetime] = None
date_range_end: Optional[datetime] = None
limit: int = Field(default=10, ge=1, le=50)
similarity_threshold: float = Field(default=0.75, ge=0.0, le=1.0)
class MemoryItem(BaseModel):
"""Single memory item in search results"""
id: UUID
content: str
content_type: str
category: Optional[str] = None
source_type: Optional[str] = None
confidence_score: float
similarity: float
created_at: datetime
class MemorySearchResponse(BaseModel):
"""Response for memory search"""
query: str
results: List[MemoryItem]
total_found: int
search_time_ms: int
class ClientCapabilities(BaseModel):
"""Client capabilities for registration"""
supports_text: bool = True
supports_audio: bool = False
supports_image: bool = False
supports_document: bool = False
supports_location: bool = False
supports_sse: bool = False
supports_websocket: bool = False
class ClientRegistrationRequest(BaseModel):
"""Request to register a new client"""
client_name: str
client_type: str # whatsapp, web, mobile, api
capabilities: ClientCapabilities = Field(default_factory=ClientCapabilities)
preferences: Optional[Dict[str, Any]] = None
class ClientRegistrationResponse(BaseModel):
"""Response for client registration"""
client_id: UUID
api_key: str
registered_at: datetime
message: str = "Client registered successfully"
class StreamEvent(BaseModel):
"""Event sent via SSE/WebSocket stream"""
event_id: UUID
event_type: str
urgency: int
source_agent: str
content: Dict[str, Any]
personality_mode: str
generated_at: datetime
class AnalyticsResponse(BaseModel):
"""System analytics data"""
period_start: datetime
period_end: datetime
# Interactions
total_interactions: int
avg_response_time_ms: float
interactions_by_chain: Dict[str, int]
# Quality
avg_quality_scores: Dict[str, float]
# API Usage
api_usage: Dict[str, Dict[str, int]]
# Events
events_generated: int
events_by_type: Dict[str, int]
# Memory
knowledge_items: int
memory_searches: int