"""Pydantic request/response models for the LM-Gambit API.""" from __future__ import annotations from typing import Dict, List, Optional from pydantic import BaseModel, Field class ProviderSummary(BaseModel): name: str is_default: bool = False class ModelSummary(BaseModel): id: str display_name: str class ModelListResponse(BaseModel): provider: str models: List[ModelSummary] class TestPrompt(BaseModel): """A single question in the suite. ``title`` is derived from the first non-empty line of ``prompt`` by the engine, so it is read-only here and returned for display purposes only. """ filename: str title: str prompt: str class TestSuiteResponse(BaseModel): tests: List[TestPrompt] directory: str class TestDraft(BaseModel): """One question as submitted by the suite builder form.""" prompt: str = Field(min_length=1) class SaveSuiteRequest(BaseModel): tests: List[TestDraft] class RunMetrics(BaseModel): tokens_per_second: float = 0.0 total_tokens: int = 0 time_to_first_token: float = 0.0 stop_reason: str = "N/A" class RunRequest(BaseModel): provider: str model_id: str temperature: float = Field(default=0.1, ge=0.0, le=2.0) filenames: Optional[List[str]] = Field( default=None, description="Subset of test filenames to run. Omit to run the whole suite.", ) class RunSummary(BaseModel): average_tokens_per_second: float = 0.0 average_time_to_first_token: float = 0.0 total_tokens: int = 0 passed: int = 0 failed: int = 0 overall_score: Optional[float] = None graded: int = 0 class PluginSummary(BaseModel): name: str slug: str version: str description: str path: str enabled: bool hooks: List[str] = [] error: Optional[str] = None class RunResponse(BaseModel): id: str status: str provider: str model_id: str model_label: str temperature: float total: int completed: int started_at: float finished_at: Optional[float] = None report_name: Optional[str] = None error: Optional[str] = None summary: RunSummary = RunSummary() class PlaygroundRequest(BaseModel): provider: str model_id: str prompt: str = Field(min_length=1) temperature: float = Field(default=0.1, ge=0.0, le=2.0) class PlaygroundResponse(BaseModel): response: Optional[str] = None error: Optional[str] = None metrics: Optional[RunMetrics] = None elapsed: float = 0.0 class ReportSummary(BaseModel): name: str model_label: str size_bytes: int modified_at: float class ReportDetail(ReportSummary): content: str class ModelPathEntry(BaseModel): nickname: str = "" path: str class SettingsResponse(BaseModel): default_provider: str default_temperature: float local_model_paths: List[ModelPathEntry] tests_dir: str results_dir: str models_dir: str class SettingsUpdate(BaseModel): default_provider: Optional[str] = None default_temperature: Optional[float] = Field(default=None, ge=0.0, le=2.0) local_model_paths: Optional[List[ModelPathEntry]] = None class SystemInfo(BaseModel): version: str engine_architecture: str engine_runtime: str template_ok: bool python_version: str metrics: Dict[str, str] = {}