From c92520f65f70f593c32932116866649fb10e8fac Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Aug 2026 12:53:15 +0000 Subject: [PATCH] fix(metrics): handle None latency_ms in LatencyMetric without crashing kwargs.get("latency_ms", 0.0) only falls back to the default when the key is missing, not when it's explicitly None. The pipeline always passes latency_ms as a kwarg (None when no LLM is configured or generation fails), so `None < 0` crashed on every such evaluation - reproduced in every report checked into reports/*.json. Fixes #285 --- openagent_eval/metrics/performance/latency.py | 9 ++++++++- tests/unit/test_metrics/test_performance_cost.py | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/openagent_eval/metrics/performance/latency.py b/openagent_eval/metrics/performance/latency.py index face4c1..58c7c7f 100644 --- a/openagent_eval/metrics/performance/latency.py +++ b/openagent_eval/metrics/performance/latency.py @@ -40,9 +40,16 @@ def evaluate(self, **kwargs: Any) -> MetricResult: Returns: MetricResult with latency score. """ - latency_ms = kwargs.get("latency_ms", 0.0) + latency_ms = kwargs.get("latency_ms") stage = kwargs.get("stage", "unknown") + if latency_ms is None: + return MetricResult( + score=0.0, + reason="No latency measurement available", + metadata={"stage": stage, "latency_ms": None}, + ) + if latency_ms < 0: return MetricResult( score=0.0, diff --git a/tests/unit/test_metrics/test_performance_cost.py b/tests/unit/test_metrics/test_performance_cost.py index 43181a6..1f9c329 100644 --- a/tests/unit/test_metrics/test_performance_cost.py +++ b/tests/unit/test_metrics/test_performance_cost.py @@ -56,6 +56,17 @@ def test_metadata(self): assert result.metadata["stage"] == "embedding" assert result.metadata["latency_ms"] == 100.0 + def test_none_latency_does_not_raise(self): + """None latency (e.g. no LLM configured, or generation failure) is handled gracefully.""" + result = self.metric.evaluate(latency_ms=None, stage="llm") + assert result.score == 0.0 + assert result.metadata["latency_ms"] is None + + def test_missing_latency_kwarg_does_not_raise(self): + """Omitting latency_ms entirely behaves the same as passing None.""" + result = self.metric.evaluate(stage="llm") + assert result.score == 0.0 + class TestTokenCountMetric: """Tests for TokenCountMetric."""