""" Bug 数据模型 """ from datetime import datetime from typing import Optional, Any from enum import Enum from pydantic import BaseModel, Field class BugStatus(str, Enum): """Bug 状态""" NEW = "NEW" VERIFYING = "VERIFYING" CANNOT_REPRODUCE = "CANNOT_REPRODUCE" PENDING_FIX = "PENDING_FIX" FIXING = "FIXING" FIXED = "FIXED" FIX_FAILED = "FIX_FAILED" VERIFIED = "VERIFIED" DEPLOYED = "DEPLOYED" class ErrorInfo(BaseModel): """错误信息""" type: str = Field(description="异常类型") message: str = Field(description="错误消息") file_path: Optional[str] = Field(default=None, description="文件路径") line_number: Optional[int] = Field(default=None, description="行号") stack_trace: Optional[list[str]] = Field(default=None, description="堆栈信息") class Bug(BaseModel): """Bug 数据模型""" id: int = Field(description="Bug ID") project_id: str = Field(description="项目ID") environment: str = Field(default="production", description="环境") level: str = Field(default="ERROR", description="日志级别") error: ErrorInfo = Field(description="错误信息") context: Optional[dict[str, Any]] = Field(default=None, description="上下文") status: BugStatus = Field(default=BugStatus.NEW, description="状态") retry_count: int = Field(default=0, description="重试次数") severity: Optional[int] = Field(default=None, description="严重等级 1-10") created_at: Optional[datetime] = Field(default=None, description="创建时间") def format_for_prompt(self) -> str: """格式化为 Prompt 内容""" lines = [ f"## Bug #{self.id}: {self.error.type}", f"- 文件: {self.error.file_path or 'unknown'}", f"- 行号: {self.error.line_number or 'unknown'}", f"- 错误: {self.error.message}", ] if self.error.stack_trace: lines.append("- 堆栈:") lines.append("```") lines.extend(self.error.stack_trace[:10]) # 最多10行 lines.append("```") if self.context: lines.append(f"- 上下文: {self.context}") return "\n".join(lines) class FixResult(BaseModel): """修复结果""" bug_id: int success: bool message: str modified_files: list[str] = Field(default_factory=list) diff: Optional[str] = None class BatchFixResult(BaseModel): """批量修复结果""" project_id: str total: int success_count: int failed_count: int results: list[FixResult] = Field(default_factory=list) class RepairReport(BaseModel): """修复报告(一次批量修复 = 一条报告)""" error_log_ids: list[int] status: BugStatus project_id: str ai_analysis: str fix_plan: str code_diff: str modified_files: list[str] test_output: str test_passed: bool repair_round: int = 1 failure_reason: Optional[str] = None pr_url: Optional[str] = None pr_number: Optional[int] = None branch_name: Optional[str] = None