new quality save layer

This commit is contained in:
2026-02-12 14:17:36 +01:00
parent 7c69302b33
commit 1ebf50ab04
16 changed files with 2256 additions and 30 deletions

View File

@@ -16,6 +16,10 @@ from src.agents import (
PostClassifierAgent,
PostTypeAnalyzerAgent,
)
from src.agents.grammar_checker import GrammarCheckAgent
from src.agents.style_validator import StyleValidator
from src.agents.readability_checker import ReadabilityChecker
from src.agents.quality_refiner import QualityRefinerAgent
from src.database.models import PostType
@@ -31,11 +35,16 @@ class WorkflowOrchestrator:
self.critic = CriticAgent()
self.post_classifier = PostClassifierAgent()
self.post_type_analyzer = PostTypeAnalyzerAgent()
# New quality check agents
self.grammar_checker = GrammarCheckAgent()
self.style_validator = StyleValidator()
self.readability_checker = ReadabilityChecker()
self.quality_refiner = QualityRefinerAgent()
self._all_agents = [
self.profile_analyzer, self.topic_extractor, self.researcher,
self.writer, self.critic, self.post_classifier, self.post_type_analyzer
]
logger.info("WorkflowOrchestrator initialized")
logger.info("WorkflowOrchestrator initialized with quality check & refiner agents")
def _set_tracking(self, operation: str, user_id: Optional[str] = None,
company_id: Optional[str] = None):
@@ -669,6 +678,7 @@ class WorkflowOrchestrator:
iteration=iteration,
max_iterations=max_iterations
)
critic_feedback_list.append(critic_result)
approved = critic_result.get("approved", False)
@@ -692,7 +702,53 @@ class WorkflowOrchestrator:
if iteration < max_iterations:
logger.info("Post needs revision, continuing...")
# === POST-CRITIC QUALITY POLISH ===
# Simple approach: Analyze quality, then one final LLM polish
if settings.quality_refiner_enabled:
logger.info("=== Running Quality Analysis & Polish ===")
# Run quality checks (analysis only, no score changes)
quality_checks = await self._run_quality_checks(current_post, example_post_texts)
# Log quality metrics (for transparency)
grammar_errors = quality_checks['grammar_check'].get('error_count', 0)
style_similarity = quality_checks['style_check'].get('avg_similarity', 1.0)
readability_passed = quality_checks['readability_check'].get('passed', True)
logger.info(f"Quality Analysis:")
logger.info(f" Grammar: {grammar_errors} errors")
logger.info(f" Style: {style_similarity:.1%} similarity")
logger.info(f" Readability: {'' if readability_passed else '⚠️'}")
# Check if polish is needed
needs_polish = (
grammar_errors > 0 or
style_similarity < 0.75 or
not readability_passed
)
if needs_polish:
logger.info("Quality issues detected, running final polish...")
polished_post = await self.quality_refiner.final_polish(
post=current_post,
quality_checks=quality_checks,
profile_analysis=profile_analysis.full_analysis,
example_posts=example_post_texts
)
current_post = polished_post
logger.info("✅ Post polished (Formatierung erhalten)")
else:
logger.info("✅ No quality issues, skipping polish")
# Store quality info in critic result (for reference)
final_critic_result = critic_feedback_list[-1] if critic_feedback_list else {}
final_critic_result["quality_checks"] = quality_checks
final_critic_result["quality_polished"] = needs_polish
# === END QUALITY POLISH ===
# All new posts start as draft - user moves them via Kanban board
# IMPORTANT: Keep original critic score!
final_score = critic_feedback_list[-1].get("overall_score", 0) if critic_feedback_list else 0
status = "draft"
@@ -717,11 +773,53 @@ class WorkflowOrchestrator:
"final_post": current_post,
"iterations": iteration,
"approved": approved,
"final_score": critic_feedback_list[-1].get("overall_score", 0) if critic_feedback_list else 0,
"final_score": final_score,
"writer_versions": writer_versions,
"critic_feedback": critic_feedback_list
}
async def _run_quality_checks(
self,
post: str,
example_posts: List[str]
) -> Dict[str, Any]:
"""
Run all quality checks on a post.
Args:
post: Post text to check
example_posts: Reference posts for style comparison
Returns:
Dictionary with all quality check results
"""
# Grammar Check
grammar_result = await self.grammar_checker.process(
text=post,
auto_correct=False # Don't auto-correct here, refiner will do it
)
# Style Similarity Check
style_result = await self.style_validator.process(
generated_text=post,
reference_texts=example_posts,
threshold=0.75
)
# Readability Check
readability_result = await self.readability_checker.process(
text=post,
target_grade=10.0,
target_flesch=60.0,
max_sentence_length=20
)
return {
"grammar_check": grammar_result,
"style_check": style_result,
"readability_check": readability_result
}
async def _extract_recurring_feedback(self, user_id: UUID) -> Dict[str, Any]:
"""
Extract recurring feedback patterns from past generated posts.