ai-study-assistant / features /summarizer.py
MonishRaman's picture
Upload 31 files
af25a2a verified
Raw
History Blame Contribute Delete
4.81 kB
"""
Summarizer Feature - Generates summaries of study notes
"""
from typing import Tuple
from config import LLM_PROVIDER
from core.llm_engine import LLMEngine
from core.prompt_builder import PromptBuilder
from core.validator import InputValidator, ContentValidator
from core.utils import log_event, format_summary
class Summarizer:
"""Generates summaries of notes and content."""
def __init__(self, llm_provider: str = LLM_PROVIDER):
"""
Initialize summarizer.
Args:
llm_provider: LLM provider to use
"""
self.engine = LLMEngine(llm_provider)
self.prompt_builder = PromptBuilder()
self.validator = InputValidator()
def summarize(
self,
text: str,
mode: str = "normal",
max_length: int = 500,
quality_check: bool = True
) -> Tuple[bool, str]:
"""
Generate a summary of the text.
Args:
text: Text to summarize
mode: Prompt mode (normal, detailed, teacher, exam)
max_length: Maximum summary length
quality_check: Whether to validate output quality
Returns:
Tuple of (success, summary_text)
"""
# Validate input
is_valid, msg = self.validator.validate_input(text)
if not is_valid:
log_event("VALIDATION_ERROR", f"Summarizer: {msg}")
return False, msg
# Build prompt
try:
prompt = self.prompt_builder.build_summary_prompt(
text,
mode=mode,
max_length=max_length
)
log_event("PROMPT_BUILT", "Summary prompt ready")
except Exception as e:
log_event("PROMPT_ERROR", f"Error building prompt: {str(e)}")
return False, f"Error building prompt: {str(e)}"
# Generate summary
success, summary = self.engine.generate(prompt, max_tokens=max_length)
if not success:
log_event("SUMMARY_ERROR", summary)
return False, summary
if not isinstance(summary, str):
summary = str(summary)
summary = summary.strip()
if not summary:
log_event("SUMMARY_ERROR", "Empty summary from model")
return False, "Summary generation failed: empty response from model."
# Retry once if summary is too short.
if not ContentValidator.is_acceptable_summary(summary, min_chars=80):
log_event("SUMMARY_RETRY", "Summary too short, retrying with higher max tokens")
retry_tokens = max(max_length + 200, 300)
success_retry, summary_retry = self.engine.generate(prompt, max_tokens=retry_tokens)
if success_retry and isinstance(summary_retry, str) and summary_retry.strip():
summary = summary_retry.strip()
# Quality check
if quality_check:
is_acceptable = ContentValidator.is_acceptable_summary(summary, min_chars=80)
if not is_acceptable:
log_event("QUALITY_CHECK_FAILED", "Summary too short")
return False, "Summary generated but quality is low. Please try again with more input text."
quality_score = ContentValidator.estimate_quality(summary)
log_event("QUALITY_SCORE", f"Summary quality: {quality_score:.2f}")
# Format summary
formatted_summary = format_summary(summary)
log_event("SUMMARY_SUCCESS", f"Summary generated ({len(formatted_summary)} chars)")
return True, formatted_summary
def quick_summary(self, text: str) -> Tuple[bool, str]:
"""
Generate a quick 1-2 line summary.
Args:
text: Text to summarize
Returns:
Tuple of (success, summary)
"""
return self.summarize(text, mode="exam", max_length=200)
def detailed_summary(self, text: str) -> Tuple[bool, str]:
"""
Generate a detailed summary with context.
Args:
text: Text to summarize
Returns:
Tuple of (success, summary)
"""
return self.summarize(text, mode="detailed", max_length=1000)
def educational_summary(self, text: str) -> Tuple[bool, str]:
"""
Generate a summary suitable for learning.
Args:
text: Text to summarize
Returns:
Tuple of (success, summary)
"""
return self.summarize(text, mode="teacher", max_length=800)