fix(ranking): add explicit NaN check in normalize_weights

Add math.isnan() check before math.isfinite() to properly catch
NaN values in weight totals. Prevents division by NaN which could
produce unexpected results in RRF fusion calculations.

Solution-ID: SOL-20251228113631
Issue-ID: ISS-1766921318981-0
Task-ID: T1
This commit is contained in:
catlog22
2025-12-28 20:55:03 +08:00
parent d3e7ecca21
commit 598eed92cb

View File

@@ -22,12 +22,23 @@ class QueryIntent(str, Enum):
MIXED = "mixed"
def normalize_weights(weights: Dict[str, float]) -> Dict[str, float]:
def normalize_weights(weights: Dict[str, float | None]) -> Dict[str, float | None]:
"""Normalize weights to sum to 1.0 (best-effort)."""
total = sum(float(v) for v in weights.values() if v is not None)
if not math.isfinite(total) or total <= 0:
return {k: float(v) for k, v in weights.items()}
return {k: float(v) / total for k, v in weights.items()}
# NaN total: do not attempt to normalize (division would propagate NaNs).
if math.isnan(total):
return dict(weights)
# Infinite total: do not attempt to normalize (division yields 0 or NaN).
if not math.isfinite(total):
return dict(weights)
# Zero/negative total: do not attempt to normalize (invalid denominator).
if total <= 0:
return dict(weights)
return {k: (float(v) / total if v is not None else None) for k, v in weights.items()}
def detect_query_intent(query: str) -> QueryIntent: