Coverage for src / local_deep_research / advanced_search_system / candidates / base_candidate.py: 27%
37 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
1"""
2Base candidate class for tracking potential answers.
3"""
5from dataclasses import dataclass, field
6from typing import Any, Dict, List
8from ..constraints.base_constraint import Constraint
9from ..evidence.base_evidence import Evidence
12@dataclass
13class Candidate:
14 """A potential answer with supporting evidence."""
16 name: str
17 evidence: Dict[str, Evidence] = field(default_factory=dict)
18 score: float = 0.0
19 metadata: Dict[str, Any] = field(default_factory=dict)
21 def add_evidence(self, constraint_id: str, evidence: Evidence):
22 """Add evidence for a constraint."""
23 self.evidence[constraint_id] = evidence
25 def calculate_score(self, constraints: List[Constraint]) -> float:
26 """Calculate overall score based on evidence and constraints."""
27 if not constraints:
28 return 0.0
30 total_score = 0.0
31 total_weight = 0.0
33 for constraint in constraints:
34 evidence = self.evidence.get(constraint.id)
35 if evidence:
36 score = evidence.confidence * constraint.weight
37 total_score += score
38 total_weight += constraint.weight
40 self.score = total_score / total_weight if total_weight > 0 else 0.0
41 return self.score
43 def get_unverified_constraints(
44 self, constraints: List[Constraint]
45 ) -> List[Constraint]:
46 """Get constraints that don't have evidence yet."""
47 unverified = []
48 for constraint in constraints:
49 if constraint.id not in self.evidence:
50 unverified.append(constraint)
51 return unverified
53 def get_weak_evidence(self, threshold: float = 0.5) -> List[str]:
54 """Get constraint IDs with weak evidence."""
55 weak = []
56 for constraint_id, evidence in self.evidence.items():
57 if evidence.confidence < threshold:
58 weak.append(constraint_id)
59 return weak