from datetime import datetime, timezone from enum import Enum from pydantic import BaseModel, Field class JobStatus(str, Enum): PENDING = "pending" QUEUED = "queued" PREPROCESSING = "preprocessing" TRAINING = "training" COMPLETED = "completed" EVALUATING = "evaluating" EVALUATION_DONE = "evaluation_done" FAILED = "failed" CANCELLED = "cancelled" @property def is_terminal(self) -> bool: return self in (self.COMPLETED, self.FAILED, self.CANCELLED, self.EVALUATION_DONE) class TrainingJob(BaseModel): id: str model_id: str model_type: str peft_method: str dataset_id: str config: dict = Field(default_factory=dict) status: JobStatus = JobStatus.PENDING progress: float = 0.0 current_epoch: int = 0 current_step: int = 0 total_steps: int = 0 loss: float | None = None adapter_path: str | None = None error_message: str | None = None created_at: str = Field(default_factory=lambda: datetime.now(timezone.utc).isoformat()) started_at: str | None = None finished_at: str | None = None