BuddyMath / domain /risk_engine.py
dotandru's picture
Fix: Clean production deployment with sse-starlette
9d29c62
Raw
History Blame Contribute Delete
2.5 kB
# domain/risk_engine.py
import logging
from typing import Dict, Any, List
from .curriculum_classifier import CurriculumClassifier
logger = logging.getLogger(__name__)
class CognitiveRiskEngine:
"""
V6.1 Phase 4: Risk Scoring
Evaluates the cognitive risk of a proposal based on AST complexity,
step count, retries, and symbolic stability.
"""
WEIGHTS = {
"ast_complexity": 0.30,
"reasoning_depth": 0.20,
"retry_penalty": 0.25,
"symbolic_instability": 0.25
}
@classmethod
def calculate_risk_score(cls,
math_input: str,
draft_steps: List[Dict[str, Any]],
retry_count: int,
validation_errors: int) -> Dict[str, Any]:
"""
Calculates the Cognitive Risk Score (CRS) between 0.0 and 1.0.
"""
# 1. AST Complexity (normalized 0-1)
# We reuse CurriculumClassifier's internal complexity estimation if possible,
# but here we normalize it against a ceiling of 20.
raw_complexity = CurriculumClassifier.estimate_complexity(math_input)
ast_risk = min(raw_complexity / 20.0, 1.0)
# 2. Reasoning Depth (normalized 0-1)
# 10 steps is considered high depth for our MVP
depth_risk = min(len(draft_steps) / 10.0, 1.0)
# 3. Retry Penalty
# 0 retries = 0.0, 1 retry = 1.0 (since max retry is 1 in V6.1)
retry_risk = 1.0 if retry_count > 0 else 0.0
# 4. Symbolic Instability
# Based on validation failures during the process
instability_risk = min(validation_errors / 5.0, 1.0)
# Weighted Final Score
crs = (ast_risk * cls.WEIGHTS["ast_complexity"] +
depth_risk * cls.WEIGHTS["reasoning_depth"] +
retry_risk * cls.WEIGHTS["retry_penalty"] +
instability_risk * cls.WEIGHTS["symbolic_instability"])
result = {
"risk_score": round(crs, 3),
"features": {
"ast_risk": round(ast_risk, 3),
"depth_risk": round(depth_risk, 3),
"retry_risk": retry_risk,
"instability_risk": round(instability_risk, 3)
}
}
logger.info(f"🧠 [RISK_ENGINE] Calculated CRS: {result['risk_score']} (AST: {ast_risk}, Depth: {depth_risk}, Retry: {retry_risk})")
return result