ALwrity version 0.5.6

This commit is contained in:
ajaysi
2025-08-22 14:08:54 +05:30
parent 3f2f4d7b8c
commit 5d8d1cfb73
113 changed files with 28164 additions and 2968 deletions

View File

@@ -0,0 +1,24 @@
"""
Quality Gates Package for Calendar Generation Framework
Individual modules for each quality gate category to ensure separation of concerns
and maintainability as the framework grows.
"""
from .quality_gate_manager import QualityGateManager
from .content_uniqueness_gate import ContentUniquenessGate
from .content_mix_gate import ContentMixGate
from .chain_context_gate import ChainContextGate
from .calendar_structure_gate import CalendarStructureGate
from .enterprise_standards_gate import EnterpriseStandardsGate
from .kpi_integration_gate import KPIIntegrationGate
__all__ = [
"QualityGateManager",
"ContentUniquenessGate",
"ContentMixGate",
"ChainContextGate",
"CalendarStructureGate",
"EnterpriseStandardsGate",
"KPIIntegrationGate"
]

View File

@@ -0,0 +1,29 @@
"""Calendar Structure Quality Gate - Validates calendar structure and duration control."""
import logging
from typing import Dict, Any
from datetime import datetime
logger = logging.getLogger(__name__)
class CalendarStructureGate:
def __init__(self):
self.name = "calendar_structure"
self.description = "Validates calendar structure and duration control"
self.pass_threshold = 0.8
self.validation_criteria = ["Structure completeness", "Duration appropriateness"]
async def validate(self, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
try:
validation_result = {
"gate_name": self.name, "passed": False, "score": 0.8,
"issues": [], "recommendations": [], "timestamp": datetime.utcnow().isoformat()
}
validation_result["passed"] = validation_result["score"] >= self.pass_threshold
return validation_result
except Exception as e:
return {"gate_name": self.name, "passed": False, "score": 0.0, "error": str(e)}
def __str__(self) -> str:
return f"CalendarStructureGate(threshold={self.pass_threshold})"

View File

@@ -0,0 +1,29 @@
"""Chain Context Quality Gate - Validates chain step context understanding."""
import logging
from typing import Dict, Any
from datetime import datetime
logger = logging.getLogger(__name__)
class ChainContextGate:
def __init__(self):
self.name = "chain_context"
self.description = "Validates chain step context understanding"
self.pass_threshold = 0.85
self.validation_criteria = ["Step context preservation", "Data flow continuity"]
async def validate(self, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
try:
validation_result = {
"gate_name": self.name, "passed": False, "score": 0.85,
"issues": [], "recommendations": [], "timestamp": datetime.utcnow().isoformat()
}
validation_result["passed"] = validation_result["score"] >= self.pass_threshold
return validation_result
except Exception as e:
return {"gate_name": self.name, "passed": False, "score": 0.0, "error": str(e)}
def __str__(self) -> str:
return f"ChainContextGate(threshold={self.pass_threshold})"

View File

@@ -0,0 +1,154 @@
"""
Content Mix Quality Gate
Validates content mix balance and distribution across different
content types and themes.
"""
import logging
from typing import Dict, Any, List
from datetime import datetime
logger = logging.getLogger(__name__)
class ContentMixGate:
"""Quality gate for content mix balance and distribution."""
def __init__(self):
self.name = "content_mix"
self.description = "Validates content mix balance and distribution"
self.pass_threshold = 0.8
self.validation_criteria = [
"Balanced content types",
"Appropriate content mix ratios",
"Theme distribution",
"Content variety"
]
async def validate(self, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
"""Validate content mix in calendar data."""
try:
logger.info(f"Validating content mix for step: {step_name or 'general'}")
validation_result = {
"gate_name": self.name,
"passed": False,
"score": 0.0,
"issues": [],
"recommendations": [],
"timestamp": datetime.utcnow().isoformat()
}
content_items = self._extract_content_items(calendar_data)
if not content_items:
validation_result["issues"].append("No content items found")
return validation_result
# Check content type balance
type_balance_score = self._check_content_type_balance(content_items)
# Check theme distribution
theme_distribution_score = self._check_theme_distribution(content_items)
# Check content variety
variety_score = self._check_content_variety(content_items)
# Calculate overall score
overall_score = (type_balance_score + theme_distribution_score + variety_score) / 3
validation_result["score"] = overall_score
validation_result["passed"] = overall_score >= self.pass_threshold
if not validation_result["passed"]:
validation_result["recommendations"].extend([
"Balance content types across educational, thought leadership, and promotional",
"Ensure even distribution across content themes",
"Increase content variety and formats"
])
return validation_result
except Exception as e:
logger.error(f"Error in content mix validation: {e}")
return {
"gate_name": self.name,
"passed": False,
"score": 0.0,
"error": str(e),
"recommendations": ["Fix content mix validation system"]
}
def _extract_content_items(self, calendar_data: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Extract content items from calendar data."""
content_items = []
if "daily_schedule" in calendar_data:
for day_data in calendar_data["daily_schedule"].values():
if isinstance(day_data, dict) and "content" in day_data:
content_items.extend(day_data["content"])
return content_items
def _check_content_type_balance(self, content_items: List[Dict[str, Any]]) -> float:
"""Check balance of content types."""
type_counts = {"educational": 0, "thought_leadership": 0, "promotional": 0}
for item in content_items:
if isinstance(item, dict):
content_type = item.get("type", "educational")
type_counts[content_type] = type_counts.get(content_type, 0) + 1
total = sum(type_counts.values())
if total == 0:
return 0.0
# Ideal ratios: 40% educational, 30% thought leadership, 30% promotional
ideal_ratios = {"educational": 0.4, "thought_leadership": 0.3, "promotional": 0.3}
actual_ratios = {k: v/total for k, v in type_counts.items()}
balance_score = 1.0
for content_type, ideal_ratio in ideal_ratios.items():
actual_ratio = actual_ratios.get(content_type, 0)
deviation = abs(actual_ratio - ideal_ratio)
balance_score -= deviation * 0.5 # Penalty for deviation
return max(0.0, balance_score)
def _check_theme_distribution(self, content_items: List[Dict[str, Any]]) -> float:
"""Check distribution of content themes."""
theme_counts = {}
for item in content_items:
if isinstance(item, dict):
theme = item.get("theme", "general")
theme_counts[theme] = theme_counts.get(theme, 0) + 1
if not theme_counts:
return 0.0
total = sum(theme_counts.values())
max_count = max(theme_counts.values())
# Calculate distribution evenness
evenness = 1.0 - (max_count / total - 1/len(theme_counts))
return max(0.0, evenness)
def _check_content_variety(self, content_items: List[Dict[str, Any]]) -> float:
"""Check variety of content formats."""
formats = set()
for item in content_items:
if isinstance(item, dict):
format_type = item.get("format", "article")
formats.add(format_type)
# More formats = higher variety score
variety_score = min(1.0, len(formats) / 5) # Cap at 5 formats
return variety_score
def __str__(self) -> str:
return f"ContentMixGate(threshold={self.pass_threshold})"
def __repr__(self) -> str:
return f"ContentMixGate(name={self.name}, threshold={self.pass_threshold})"

View File

@@ -0,0 +1,246 @@
"""
Content Uniqueness Quality Gate
Validates content uniqueness and prevents duplicate content
in calendar generation.
"""
import logging
from typing import Dict, Any, List, Set
from datetime import datetime
logger = logging.getLogger(__name__)
class ContentUniquenessGate:
"""
Quality gate for content uniqueness and duplicate prevention.
"""
def __init__(self):
self.name = "content_uniqueness"
self.description = "Validates content uniqueness and prevents duplicate content"
self.pass_threshold = 0.9
self.validation_criteria = [
"No duplicate content topics",
"Unique content titles",
"Diverse content themes",
"No keyword cannibalization"
]
async def validate(self, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
"""
Validate content uniqueness in calendar data.
Args:
calendar_data: Calendar data to validate
step_name: Optional step name for context
Returns:
Validation result
"""
try:
logger.info(f"Validating content uniqueness for step: {step_name or 'general'}")
validation_result = {
"gate_name": self.name,
"passed": False,
"score": 0.0,
"issues": [],
"recommendations": [],
"timestamp": datetime.utcnow().isoformat()
}
# Extract content items from calendar data
content_items = self._extract_content_items(calendar_data)
if not content_items:
validation_result["issues"].append("No content items found for validation")
validation_result["recommendations"].append("Ensure calendar contains content items")
return validation_result
# Check for duplicate topics
duplicate_topics = self._check_duplicate_topics(content_items)
if duplicate_topics:
validation_result["issues"].extend(duplicate_topics)
# Check for duplicate titles
duplicate_titles = self._check_duplicate_titles(content_items)
if duplicate_titles:
validation_result["issues"].extend(duplicate_titles)
# Check content diversity
diversity_score = self._calculate_diversity_score(content_items)
# Check keyword cannibalization
keyword_issues = self._check_keyword_cannibalization(content_items)
if keyword_issues:
validation_result["issues"].extend(keyword_issues)
# Calculate overall score
base_score = 1.0
penalty_per_issue = 0.1
total_penalties = len(validation_result["issues"]) * penalty_per_issue
final_score = max(0.0, base_score - total_penalties)
# Apply diversity bonus
final_score = (final_score + diversity_score) / 2
validation_result["score"] = final_score
validation_result["passed"] = final_score >= self.pass_threshold
# Generate recommendations
if not validation_result["passed"]:
validation_result["recommendations"].extend([
"Review and remove duplicate content topics",
"Ensure unique content titles",
"Increase content theme diversity",
"Avoid keyword cannibalization"
])
logger.info(f"Content uniqueness validation: {'PASSED' if validation_result['passed'] else 'FAILED'} (score: {final_score:.2f})")
return validation_result
except Exception as e:
logger.error(f"Error in content uniqueness validation: {e}")
return {
"gate_name": self.name,
"passed": False,
"score": 0.0,
"error": str(e),
"recommendations": ["Fix content uniqueness validation system"]
}
def _extract_content_items(self, calendar_data: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Extract content items from calendar data."""
content_items = []
# Extract from daily schedule
if "daily_schedule" in calendar_data:
for day_data in calendar_data["daily_schedule"].values():
if isinstance(day_data, dict) and "content" in day_data:
content_items.extend(day_data["content"])
# Extract from weekly themes
if "weekly_themes" in calendar_data:
for theme_data in calendar_data["weekly_themes"].values():
if isinstance(theme_data, dict) and "content" in theme_data:
content_items.extend(theme_data["content"])
# Extract from content recommendations
if "content_recommendations" in calendar_data:
content_items.extend(calendar_data["content_recommendations"])
return content_items
def _check_duplicate_topics(self, content_items: List[Dict[str, Any]]) -> List[str]:
"""Check for duplicate content topics."""
issues = []
topics = []
for item in content_items:
if isinstance(item, dict):
topic = item.get("topic", item.get("title", ""))
if topic:
topics.append(topic.lower().strip())
# Find duplicates
seen_topics = set()
duplicate_topics = set()
for topic in topics:
if topic in seen_topics:
duplicate_topics.add(topic)
else:
seen_topics.add(topic)
for topic in duplicate_topics:
issues.append(f"Duplicate topic found: {topic}")
return issues
def _check_duplicate_titles(self, content_items: List[Dict[str, Any]]) -> List[str]:
"""Check for duplicate content titles."""
issues = []
titles = []
for item in content_items:
if isinstance(item, dict):
title = item.get("title", "")
if title:
titles.append(title.lower().strip())
# Find duplicates
seen_titles = set()
duplicate_titles = set()
for title in titles:
if title in seen_titles:
duplicate_titles.add(title)
else:
seen_titles.add(title)
for title in duplicate_titles:
issues.append(f"Duplicate title found: {title}")
return issues
def _calculate_diversity_score(self, content_items: List[Dict[str, Any]]) -> float:
"""Calculate content diversity score."""
if not content_items:
return 0.0
# Extract themes/categories
themes = set()
for item in content_items:
if isinstance(item, dict):
theme = item.get("theme", item.get("category", ""))
if theme:
themes.add(theme.lower().strip())
# Calculate diversity based on number of unique themes
total_items = len(content_items)
unique_themes = len(themes)
if total_items == 0:
return 0.0
# Diversity score: more themes = higher score, but not too many
diversity_ratio = unique_themes / total_items
optimal_ratio = 0.3 # 30% unique themes is optimal
if diversity_ratio <= optimal_ratio:
return diversity_ratio / optimal_ratio
else:
# Penalize too much diversity (might indicate lack of focus)
return max(0.0, 1.0 - (diversity_ratio - optimal_ratio))
def _check_keyword_cannibalization(self, content_items: List[Dict[str, Any]]) -> List[str]:
"""Check for keyword cannibalization."""
issues = []
keywords = []
for item in content_items:
if isinstance(item, dict):
item_keywords = item.get("keywords", [])
if isinstance(item_keywords, list):
keywords.extend([kw.lower().strip() for kw in item_keywords])
# Find keyword frequency
keyword_freq = {}
for keyword in keywords:
keyword_freq[keyword] = keyword_freq.get(keyword, 0) + 1
# Check for overused keywords
for keyword, frequency in keyword_freq.items():
if frequency > 3: # More than 3 uses of same keyword
issues.append(f"Potential keyword cannibalization: '{keyword}' used {frequency} times")
return issues
def __str__(self) -> str:
return f"ContentUniquenessGate(threshold={self.pass_threshold})"
def __repr__(self) -> str:
return f"ContentUniquenessGate(name={self.name}, threshold={self.pass_threshold}, criteria={len(self.validation_criteria)})"

View File

@@ -0,0 +1,29 @@
"""Enterprise Standards Quality Gate - Validates enterprise-level content standards."""
import logging
from typing import Dict, Any
from datetime import datetime
logger = logging.getLogger(__name__)
class EnterpriseStandardsGate:
def __init__(self):
self.name = "enterprise_standards"
self.description = "Validates enterprise-level content standards"
self.pass_threshold = 0.9
self.validation_criteria = ["Professional quality", "Brand compliance", "Industry standards"]
async def validate(self, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
try:
validation_result = {
"gate_name": self.name, "passed": False, "score": 0.9,
"issues": [], "recommendations": [], "timestamp": datetime.utcnow().isoformat()
}
validation_result["passed"] = validation_result["score"] >= self.pass_threshold
return validation_result
except Exception as e:
return {"gate_name": self.name, "passed": False, "score": 0.0, "error": str(e)}
def __str__(self) -> str:
return f"EnterpriseStandardsGate(threshold={self.pass_threshold})"

View File

@@ -0,0 +1,29 @@
"""KPI Integration Quality Gate - Validates content strategy KPI integration."""
import logging
from typing import Dict, Any
from datetime import datetime
logger = logging.getLogger(__name__)
class KPIIntegrationGate:
def __init__(self):
self.name = "kpi_integration"
self.description = "Validates content strategy KPI integration"
self.pass_threshold = 0.85
self.validation_criteria = ["KPI alignment", "Measurement framework", "Goal tracking"]
async def validate(self, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
try:
validation_result = {
"gate_name": self.name, "passed": False, "score": 0.85,
"issues": [], "recommendations": [], "timestamp": datetime.utcnow().isoformat()
}
validation_result["passed"] = validation_result["score"] >= self.pass_threshold
return validation_result
except Exception as e:
return {"gate_name": self.name, "passed": False, "score": 0.0, "error": str(e)}
def __str__(self) -> str:
return f"KPIIntegrationGate(threshold={self.pass_threshold})"

View File

@@ -0,0 +1,205 @@
"""
Quality Gate Manager
Manages all quality gates and provides comprehensive quality validation
for calendar generation.
"""
import logging
from typing import Dict, Any, List, Optional
from datetime import datetime
from .content_uniqueness_gate import ContentUniquenessGate
from .content_mix_gate import ContentMixGate
from .chain_context_gate import ChainContextGate
from .calendar_structure_gate import CalendarStructureGate
from .enterprise_standards_gate import EnterpriseStandardsGate
from .kpi_integration_gate import KPIIntegrationGate
logger = logging.getLogger(__name__)
class QualityGateManager:
"""
Manages all quality gates and provides comprehensive quality validation.
"""
def __init__(self):
"""Initialize the quality gate manager."""
self.gates = {
"content_uniqueness": ContentUniquenessGate(),
"content_mix": ContentMixGate(),
"chain_context": ChainContextGate(),
"calendar_structure": CalendarStructureGate(),
"enterprise_standards": EnterpriseStandardsGate(),
"kpi_integration": KPIIntegrationGate()
}
logger.info(f"Initialized QualityGateManager with {len(self.gates)} gates")
async def validate_all_gates(self, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
"""
Validate all quality gates against calendar data.
Args:
calendar_data: Calendar data to validate
step_name: Optional step name for context-specific validation
Returns:
Comprehensive validation results
"""
try:
logger.info(f"Validating all quality gates for step: {step_name or 'general'}")
validation_results = {
"timestamp": datetime.utcnow().isoformat(),
"step_name": step_name,
"gates": {},
"overall_score": 0.0,
"passed_gates": 0,
"failed_gates": 0,
"recommendations": []
}
total_score = 0.0
passed_count = 0
failed_count = 0
all_recommendations = []
# Validate each gate
for gate_name, gate in self.gates.items():
try:
gate_result = await gate.validate(calendar_data, step_name)
validation_results["gates"][gate_name] = gate_result
total_score += gate_result.get("score", 0.0)
if gate_result.get("passed", False):
passed_count += 1
else:
failed_count += 1
# Collect recommendations
recommendations = gate_result.get("recommendations", [])
all_recommendations.extend(recommendations)
except Exception as e:
logger.error(f"Error validating gate {gate_name}: {e}")
validation_results["gates"][gate_name] = {
"passed": False,
"score": 0.0,
"error": str(e),
"recommendations": [f"Fix validation error in {gate_name} gate"]
}
failed_count += 1
# Calculate overall score
validation_results["overall_score"] = total_score / len(self.gates) if self.gates else 0.0
validation_results["passed_gates"] = passed_count
validation_results["failed_gates"] = failed_count
validation_results["recommendations"] = all_recommendations
logger.info(f"Quality validation completed: {passed_count} passed, {failed_count} failed, overall score: {validation_results['overall_score']:.2f}")
return validation_results
except Exception as e:
logger.error(f"Error in quality gate validation: {e}")
return {
"timestamp": datetime.utcnow().isoformat(),
"step_name": step_name,
"error": str(e),
"overall_score": 0.0,
"passed_gates": 0,
"failed_gates": len(self.gates),
"recommendations": ["Fix quality gate validation system"]
}
async def validate_specific_gate(self, gate_name: str, calendar_data: Dict[str, Any], step_name: str = None) -> Dict[str, Any]:
"""
Validate a specific quality gate.
Args:
gate_name: Name of the gate to validate
calendar_data: Calendar data to validate
step_name: Optional step name for context-specific validation
Returns:
Validation result for the specific gate
"""
try:
if gate_name not in self.gates:
raise ValueError(f"Unknown quality gate: {gate_name}")
gate = self.gates[gate_name]
result = await gate.validate(calendar_data, step_name)
logger.info(f"Gate {gate_name} validation: {'PASSED' if result.get('passed') else 'FAILED'} (score: {result.get('score', 0.0):.2f})")
return result
except Exception as e:
logger.error(f"Error validating gate {gate_name}: {e}")
return {
"passed": False,
"score": 0.0,
"error": str(e),
"recommendations": [f"Fix validation error in {gate_name} gate"]
}
def get_gate_info(self, gate_name: str = None) -> Dict[str, Any]:
"""
Get information about quality gates.
Args:
gate_name: Optional specific gate name
Returns:
Gate information
"""
if gate_name:
if gate_name not in self.gates:
return {"error": f"Unknown gate: {gate_name}"}
gate = self.gates[gate_name]
return {
"name": gate_name,
"description": gate.description,
"criteria": gate.validation_criteria,
"threshold": gate.pass_threshold
}
return {
"total_gates": len(self.gates),
"gates": {
name: {
"description": gate.description,
"threshold": gate.pass_threshold
}
for name, gate in self.gates.items()
}
}
def get_validation_summary(self) -> Dict[str, Any]:
"""
Get a summary of all quality gates.
Returns:
Quality gate summary
"""
return {
"total_gates": len(self.gates),
"gate_categories": list(self.gates.keys()),
"description": "Comprehensive quality validation for calendar generation",
"thresholds": {
name: gate.pass_threshold for name, gate in self.gates.items()
}
}
def __str__(self) -> str:
"""String representation of the quality gate manager."""
return f"QualityGateManager(gates={len(self.gates)})"
def __repr__(self) -> str:
"""Detailed string representation of the quality gate manager."""
return f"QualityGateManager(gates={list(self.gates.keys())})"