from datetime import datetime from enum import StrEnum from pydantic import BaseModel, ConfigDict, Field, model_validator class LeaveType(StrEnum): PERSONAL = "PERSONAL" SICK = "SICK" ANNUAL = "ANNUAL" class LeaveDraftSuggestionRequest(BaseModel): text: str = Field(min_length=1, max_length=2000) timezone: str = Field(default="Asia/Shanghai", min_length=1, max_length=64) now: datetime | None = None class LeaveDraftSuggestion(BaseModel): type: LeaveType | None = None startsAt: datetime | None = None endsAt: datetime | None = None reason: str | None = Field(default=None, max_length=2000) assumptions: list[str] = Field(default_factory=list, max_length=10) needsClarification: list[str] = Field(default_factory=list, max_length=10) @model_validator(mode="after") def validate_time_range(self) -> "LeaveDraftSuggestion": if self.startsAt is not None and self.endsAt is not None: if self.startsAt.tzinfo is None or self.endsAt.tzinfo is None: raise ValueError("startsAt and endsAt must include timezone offsets") if self.endsAt <= self.startsAt: raise ValueError("endsAt must be later than startsAt") if self.reason is not None: normalized = self.reason.strip() self.reason = normalized or None return self class LeaveDraftSuggestionResponse(BaseModel): suggestion: LeaveDraftSuggestion model: str requiresUserConfirmation: bool = True class LeaveProgressContext(BaseModel): model_config = ConfigDict(extra="forbid") requestId: str type: LeaveType status: str startsAt: datetime endsAt: datetime activeTaskNames: list[str] = Field(default_factory=list, max_length=20) completedTaskNames: list[str] = Field(default_factory=list, max_length=50) processEnded: bool timelineEventTypes: list[str] = Field(default_factory=list, max_length=50) class LeaveProgressAnswerRequest(BaseModel): question: str = Field(min_length=1, max_length=2000) timezone: str = Field(min_length=1, max_length=64) context: LeaveProgressContext class LeaveProgressAnswerResponse(BaseModel): answer: str = Field(min_length=1, max_length=2000) model: str