from datetime import datetime from typing import Optional from pydantic import BaseModel, Field, field_serializer class BugFixPullRequest(BaseModel): title: str number: int merge_commit_sha: Optional[str] branch: str minor_version: Optional[str] = None fixed_version: Optional[str] = None has_release: bool = False class BugIssue(BaseModel): title: str number: int state: str body: str labels: list[str] affect_versions: Optional[list[str]] = None fixed_versions: Optional[list[str]] = None fixed_prs: Optional[list[BugFixPullRequest]] = None class TicketComment(BaseModel): body: str internal: Optional[bool] = None author: str created: datetime updated_author: str updated: datetime @field_serializer("created") def serialize_created(self, created: datetime) -> str: return created.isoformat() @field_serializer("updated") def serialize_updated(self, updated: datetime) -> str: return updated.isoformat() class MentionGitHubIssueLink(BaseModel): owner: str repo: str number: int url: str def __hash__(self): return hash((self.owner, self.repo, self.number)) def __eq__(self, other): return ( self.owner == other.owner and self.repo == other.repo and self.number == other.number ) def __ne__(self, other): return not self.__eq__(other) def __str__(self): return f"https://github.com/{self.owner}/{self.repo}/issues/{self.number}" class MentionGitHubIssue(BaseModel): link: MentionGitHubIssueLink title: str body: str state: str labels: list[str] affect_versions: Optional[list[str]] fixed_prs: Optional[list[BugFixPullRequest]] fixed_versions: Optional[list[str]] class SupportTicket(BaseModel): """A technical support ticket of TiDB on the Jira Service Management system. ## Important Note - The `draft_root_cause` `draft_solution` `draft_workaround` field are the conclusions provided by the other customer engineer who finished the ticket, which may be short or incomplete. """ key: str = Field(description="The jira issue key") link: str = Field(description="The jira issue link") title: str = Field( description="The title of the ticket which is written by the reporter" ) reporter: str = Field( description="The ticket reporter may be a customer (mostly) or another technical support engineer" ) description: str = Field( description="The detailed description of the ticket written by reporter, maybe colloquial" ) versions: list[str] = Field(description="The versions used by the reporter.") components: list[str] = Field( description="The affected components used by the reporter." ) comments: list[TicketComment] = Field( description=""" The comment list serves as a work log for support engineers when diagnosing and resolving user-reported issues. It typically includes: - Information collected from the ticket reporter. - Analytical discussions with other internal staffs. - Final conclusions and proposed solutions. Important Note: During the communication process, there may be speculations such as: - "The issue appears to be similar to GitHub Issue XXX." - "The issue might have been caused by GitHub Issue XXX." Such speculations should not be treated as the final conclusion. Ensure clarity in distinguishing between speculations and definitive resolutions. """ ) mention_github_issues: list[MentionGitHubIssue] = Field( description="The GitHub issues mention in the ticket discussion" ) draft_root_cause: Optional[str] = Field( description="The root cause of the problem on the ticket, provided by another colleague" ) draft_solution: Optional[str] = Field( description="The solution for the ticket, provided by another colleague" ) draft_workaround: Optional[str] = Field( description="The workaround for the ticket, provided by another colleague" )