from backend.graph.state import BrainState from backend.sse import emit def _score_confidence(skill: dict, contradictions: list) -> float: """Math-based confidence scoring per the CLAUDE.md formula.""" base = 0.5 source_count = len(skill.get("evidence", [])) if source_count >= 3: base += 0.25 elif source_count == 2: base += 0.15 elif source_count == 1: base += 0.05 base += 0.15 skill_id = skill.get("id", "") has_contradiction = any( c.get("id", "").startswith(skill_id.split("_")[0]) or skill_id in str(c.get("domain", "")) for c in contradictions ) if not has_contradiction: base += 0.10 return round(min(base, 1.0), 2) async def score_confidence(state: BrainState) -> dict: job_id = state["job_id"] skills = state.get("skills_with_evidence", []) contradictions = state.get("contradictions", []) print(f"[{job_id}] Node score_confidence: scoring {len(skills)} skills") await emit( job_id, "stage", {"name": "SCORING_CONFIDENCE", "detail": f"Scoring {len(skills)} skills"}, ) final_skills = [] for skill in skills: skill["confidence"] = _score_confidence(skill, contradictions) final_skills.append(skill) avg_conf = round( sum(s.get("confidence", 0) for s in final_skills) / max(len(final_skills), 1), 2 ) await emit( job_id, "stage", { "name": "SCORING_DONE", "detail": f"Average confidence: {avg_conf} across {len(final_skills)} skills", }, ) print(f"[{job_id}] score_confidence: avg confidence {avg_conf}") return {"final_skills": final_skills}