new quality save layer
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user