Initial upload: CLI Explain Fix project with CI/CD workflow
This commit is contained in:
131
src/cli_explain_fix/explainer.py
Normal file
131
src/cli_explain_fix/explainer.py
Normal file
@@ -0,0 +1,131 @@
|
||||
"""Explanation generation module."""
|
||||
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
from cli_explain_fix.knowledge_base import KnowledgeBase, ErrorExplanation
|
||||
from cli_explain_fix.parser import ParsedError
|
||||
|
||||
|
||||
class Explainer:
|
||||
"""Generator for human-readable error explanations."""
|
||||
|
||||
def __init__(self, knowledge_base: Optional[KnowledgeBase] = None):
|
||||
"""Initialize explainer with optional knowledge base."""
|
||||
self.knowledge_base = knowledge_base or KnowledgeBase()
|
||||
|
||||
def explain(self, parsed_error: ParsedError, verbose: bool = False) -> Dict[str, Any]:
|
||||
"""Generate a complete explanation for a parsed error."""
|
||||
explanation = self.knowledge_base.get_explanation(
|
||||
parsed_error.error_type,
|
||||
parsed_error.language
|
||||
)
|
||||
|
||||
if not explanation:
|
||||
explanation = self.knowledge_base.find_by_pattern(
|
||||
parsed_error.message,
|
||||
parsed_error.language
|
||||
)
|
||||
|
||||
if not explanation:
|
||||
explanation = self.knowledge_base.get_fallback_explanation(
|
||||
parsed_error.error_type,
|
||||
parsed_error.language
|
||||
)
|
||||
|
||||
result: Dict[str, Any] = {
|
||||
'error_type': parsed_error.error_type,
|
||||
'language': parsed_error.language,
|
||||
'summary': self._generate_summary(explanation),
|
||||
'what_happened': explanation.what_happened,
|
||||
'why_happened': explanation.why_happened,
|
||||
'how_to_fix': explanation.how_to_fix,
|
||||
'severity': explanation.severity,
|
||||
}
|
||||
|
||||
if parsed_error.file_name:
|
||||
result['location'] = {
|
||||
'file': parsed_error.file_name,
|
||||
'line': parsed_error.line_number,
|
||||
}
|
||||
|
||||
if parsed_error.stack_frames:
|
||||
result['stack_trace'] = parsed_error.stack_frames
|
||||
|
||||
if explanation.code_snippets:
|
||||
code_examples = self._format_code_examples(explanation.code_snippets)
|
||||
result['code_examples'] = code_examples
|
||||
|
||||
if explanation.documentation_url:
|
||||
result['documentation'] = explanation.documentation_url
|
||||
|
||||
if verbose:
|
||||
result['raw_error'] = parsed_error.raw_input
|
||||
|
||||
return result
|
||||
|
||||
def _generate_summary(self, explanation: ErrorExplanation) -> str:
|
||||
"""Generate a short summary of the explanation."""
|
||||
severity_icons = {
|
||||
'critical': '🔴',
|
||||
'high': '🟠',
|
||||
'medium': '🟡',
|
||||
'low': '🟢',
|
||||
'unknown': '⚪',
|
||||
}
|
||||
icon = severity_icons.get(explanation.severity, '⚪')
|
||||
|
||||
return f"{icon} {explanation.error_type} in {explanation.language}"
|
||||
|
||||
def _format_code_examples(self, code_snippets: list) -> list:
|
||||
"""Format code snippets for display."""
|
||||
formatted = []
|
||||
for snippet in code_snippets:
|
||||
formatted.append({
|
||||
'description': snippet.get('description', ''),
|
||||
'code': snippet.get('code', ''),
|
||||
'language': snippet.get('language', 'text'),
|
||||
})
|
||||
return formatted
|
||||
|
||||
def get_fix_steps(self, parsed_error: ParsedError) -> list:
|
||||
"""Get step-by-step fix instructions."""
|
||||
explanation = self.knowledge_base.get_explanation(
|
||||
parsed_error.error_type,
|
||||
parsed_error.language
|
||||
)
|
||||
|
||||
if not explanation:
|
||||
explanation = self.knowledge_base.get_fallback_explanation(
|
||||
parsed_error.error_type,
|
||||
parsed_error.language
|
||||
)
|
||||
|
||||
return explanation.how_to_fix
|
||||
|
||||
def explain_simple(self, error_type: str, message: str, language: str) -> str:
|
||||
"""Generate a simple text explanation."""
|
||||
explanation = self.knowledge_base.get_explanation(error_type, language)
|
||||
|
||||
if not explanation:
|
||||
explanation = self.knowledge_base.get_fallback_explanation(
|
||||
error_type,
|
||||
language
|
||||
)
|
||||
|
||||
lines = [
|
||||
f"Error: {error_type}",
|
||||
f"Language: {language}",
|
||||
"",
|
||||
"What happened:",
|
||||
explanation.what_happened,
|
||||
"",
|
||||
"Why it happened:",
|
||||
explanation.why_happened,
|
||||
"",
|
||||
"How to fix:",
|
||||
]
|
||||
|
||||
for i, step in enumerate(explanation.how_to_fix, 1):
|
||||
lines.append(f" {i}. {step}")
|
||||
|
||||
return "\n".join(lines)
|
||||
Reference in New Issue
Block a user