ai.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. """AI-related Pydantic schemas (P3-M1)."""
  2. from typing import Optional, List, Dict, Any
  3. from pydantic import BaseModel, Field
  4. class ChatMessage(BaseModel):
  5. """Single chat message."""
  6. role: str = Field(..., description="system/user/assistant")
  7. content: str
  8. class ChatRequest(BaseModel):
  9. """Request body for /api/ai/chat."""
  10. messages: List[ChatMessage]
  11. model: Optional[str] = None
  12. temperature: Optional[float] = None
  13. max_tokens: Optional[int] = Field(default=None, ge=1, le=8192, description="Max output tokens, capped at 8192")
  14. system_prompt: Optional[str] = None
  15. class ChatResponse(BaseModel):
  16. """Response from /api/ai/chat."""
  17. content: str
  18. reasoning_content: Optional[str] = None
  19. model: str
  20. usage: Dict[str, Any] = Field(default_factory=dict)
  21. finish_reason: Optional[str] = None
  22. class AIHealthResponse(BaseModel):
  23. """Response from /api/ai/health."""
  24. status: str
  25. configured: bool
  26. base_url: str
  27. default_model: str
  28. available_models: List[Dict[str, Any]] = Field(default_factory=list)
  29. error: Optional[str] = None
  30. class AICallLogResponse(BaseModel):
  31. """AI call log entry."""
  32. id: int
  33. endpoint: str
  34. model: str
  35. status: str
  36. duration_ms: int
  37. prompt_tokens: int
  38. completion_tokens: int
  39. total_tokens: int
  40. error: Optional[str] = None
  41. created_at: str
  42. class Config:
  43. from_attributes = True
  44. class AIUsageSummary(BaseModel):
  45. """AI usage summary."""
  46. total_calls: int
  47. success_calls: int
  48. failed_calls: int
  49. total_tokens: int
  50. total_prompt_tokens: int
  51. total_completion_tokens: int
  52. total_duration_ms: int