Represents a learned error pattern.
| 24 | |
| 25 | |
| 26 | class ErrorPattern: |
| 27 | """Represents a learned error pattern.""" |
| 28 | |
| 29 | def __init__(self, error_type: str, error_message: str, fix: str, |
| 30 | success: bool, context: Dict = None): |
| 31 | self.error_type = error_type |
| 32 | self.error_message = error_message |
| 33 | self.fix = fix |
| 34 | self.success = success |
| 35 | self.context = context or {} |
| 36 | self.created_at = datetime.now().isoformat() |
| 37 | self.times_seen = 1 |
| 38 | self.times_fixed = 1 if success else 0 |
| 39 | |
| 40 | def to_dict(self) -> Dict: |
| 41 | return { |
| 42 | "error_type": self.error_type, |
| 43 | "error_message": self.error_message, |
| 44 | "fix": self.fix, |
| 45 | "success": self.success, |
| 46 | "context": self.context, |
| 47 | "created_at": self.created_at, |
| 48 | "times_seen": self.times_seen, |
| 49 | "times_fixed": self.times_fixed, |
| 50 | } |
| 51 | |
| 52 | @classmethod |
| 53 | def from_dict(cls, data: Dict) -> "ErrorPattern": |
| 54 | pattern = cls( |
| 55 | error_type=data["error_type"], |
| 56 | error_message=data["error_message"], |
| 57 | fix=data.get("fix", ""), |
| 58 | success=data.get("success", False), |
| 59 | context=data.get("context", {}), |
| 60 | ) |
| 61 | pattern.created_at = data.get("created_at", pattern.created_at) |
| 62 | pattern.times_seen = data.get("times_seen", 1) |
| 63 | pattern.times_fixed = data.get("times_fixed", 0) |
| 64 | return pattern |
| 65 | |
| 66 | def similarity_score(self, other: "ErrorPattern") -> float: |
| 67 | """Calculate similarity to another error pattern.""" |
| 68 | score = 0.0 |
| 69 | |
| 70 | # Same error type is strong signal |
| 71 | if self.error_type == other.error_type: |
| 72 | score += 0.4 |
| 73 | |
| 74 | # Similar error messages |
| 75 | msg_similarity = self._string_similarity( |
| 76 | self.error_message.lower(), |
| 77 | other.error_message.lower() |
| 78 | ) |
| 79 | score += msg_similarity * 0.4 |
| 80 | |
| 81 | # Same file type context |
| 82 | if self.context.get("file_ext") == other.context.get("file_ext"): |
| 83 | score += 0.2 |
no outgoing calls
no test coverage detected