File size: 1,728 Bytes
a688aff | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 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}
|