@@ -166,7 +166,10 @@ def chat_generator_run(self, *args, **kwargs):
166166 results = component .run (questions = questions , contexts = contexts )
167167
168168 assert results == {
169- "results" : [{"score" : 1 , "relevant_statements" : ["a" , "b" ]}, {"score" : 0 , "relevant_statements" : []}],
169+ "results" : [
170+ {"score" : 1 , "relevant_statements" : ["a" , "b" ], "status" : "evaluated" },
171+ {"score" : 0 , "relevant_statements" : [], "status" : "evaluated" },
172+ ],
170173 "score" : 0.5 ,
171174 "meta" : None ,
172175 "individual_scores" : [1 , 0 ],
@@ -195,7 +198,10 @@ def chat_generator_run(self, *args, **kwargs):
195198 ]
196199 results = component .run (questions = questions , contexts = contexts )
197200 assert results == {
198- "results" : [{"score" : 1 , "relevant_statements" : ["a" , "b" ]}, {"score" : 0 , "relevant_statements" : []}],
201+ "results" : [
202+ {"score" : 1 , "relevant_statements" : ["a" , "b" ], "status" : "evaluated" },
203+ {"score" : 0 , "relevant_statements" : [], "status" : "evaluated" },
204+ ],
199205 "score" : 0.5 ,
200206 "meta" : None ,
201207 "individual_scores" : [1 , 0 ],
@@ -207,13 +213,16 @@ def test_run_missing_parameters(self, monkeypatch):
207213 with pytest .raises (ValueError , match = "LLM evaluator expected input parameter" ):
208214 component .run ()
209215
210- def test_run_returns_nan_raise_on_failure_false (self , monkeypatch , caplog ):
216+ @pytest .mark .parametrize ("failure_mode" , ["generation" , "parsing" ])
217+ def test_run_returns_nan_raise_on_failure_false (self , monkeypatch , caplog , failure_mode ):
211218 monkeypatch .setenv ("OPENAI_API_KEY" , "test-api-key" )
212219 component = ContextRelevanceEvaluator (raise_on_failure = False )
213220
214221 def chat_generator_run (self , * args , ** kwargs ):
215222 if "Python" in kwargs ["messages" ][0 ].text :
216- raise Exception ("OpenAI API request failed." )
223+ if failure_mode == "generation" :
224+ raise Exception ("OpenAI API request failed." )
225+ return {"replies" : [ChatMessage .from_assistant ("not valid JSON" )]}
217226 return {"replies" : [ChatMessage .from_assistant ('{"relevant_statements": ["c", "d"], "score": 1}' )]}
218227
219228 monkeypatch .setattr ("haystack.components.evaluators.llm_evaluator.OpenAIChatGenerator.run" , chat_generator_run )
@@ -236,12 +245,28 @@ def chat_generator_run(self, *args, **kwargs):
236245 results = component .run (questions = questions , contexts = contexts )
237246
238247 assert results ["score" ] == 1
239- assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 }
248+ assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 , "status" : "evaluated" }
240249 assert results ["results" ][1 ]["relevant_statements" ] == []
241250 assert math .isnan (results ["results" ][1 ]["score" ])
251+ assert results ["results" ][1 ]["status" ] == "error"
242252
243253 assert "1 query(s) failed and were excluded from the score." in caplog .text
244254
255+ def test_run_all_failures_returns_nan_and_error_statuses (self , monkeypatch ):
256+ monkeypatch .setenv ("OPENAI_API_KEY" , "test-api-key" )
257+ component = ContextRelevanceEvaluator (raise_on_failure = False )
258+
259+ def chat_generator_run (self , * args , ** kwargs ):
260+ raise Exception ("OpenAI API request failed." )
261+
262+ monkeypatch .setattr ("haystack.components.evaluators.llm_evaluator.OpenAIChatGenerator.run" , chat_generator_run )
263+
264+ results = component .run (questions = ["q1" , "q2" ], contexts = [["c1" ], ["c2" ]])
265+
266+ assert math .isnan (results ["score" ])
267+ assert all (math .isnan (score ) for score in results ["individual_scores" ])
268+ assert [result ["status" ] for result in results ["results" ]] == ["error" , "error" ]
269+
245270 @pytest .mark .skipif (
246271 not os .environ .get ("OPENAI_API_KEY" , None ),
247272 reason = "Export an env var called OPENAI_API_KEY containing the OpenAI API key to run this test." ,
@@ -256,7 +281,7 @@ def test_live_run(self):
256281
257282 required_fields = {"results" }
258283 assert all (field in result for field in required_fields )
259- nested_required_fields = {"score" , "relevant_statements" }
284+ nested_required_fields = {"score" , "relevant_statements" , "status" }
260285 assert all (field in result ["results" ][0 ] for field in nested_required_fields )
261286
262287 assert "meta" in result
@@ -289,20 +314,26 @@ async def chat_generator_run_async(self, *args, **kwargs):
289314 results = await component .run_async (questions = questions , contexts = contexts )
290315
291316 assert results == {
292- "results" : [{"score" : 1 , "relevant_statements" : ["a" , "b" ]}, {"score" : 0 , "relevant_statements" : []}],
317+ "results" : [
318+ {"score" : 1 , "relevant_statements" : ["a" , "b" ], "status" : "evaluated" },
319+ {"score" : 0 , "relevant_statements" : [], "status" : "evaluated" },
320+ ],
293321 "score" : 0.5 ,
294322 "meta" : None ,
295323 "individual_scores" : [1 , 0 ],
296324 }
297325
298326 @pytest .mark .asyncio
299- async def test_run_async_returns_nan_raise_on_failure_false (self , monkeypatch , caplog ):
327+ @pytest .mark .parametrize ("failure_mode" , ["generation" , "parsing" ])
328+ async def test_run_async_returns_nan_raise_on_failure_false (self , monkeypatch , caplog , failure_mode ):
300329 monkeypatch .setenv ("OPENAI_API_KEY" , "test-api-key" )
301330 component = ContextRelevanceEvaluator (raise_on_failure = False )
302331
303332 async def chat_generator_run_async (self , * args , ** kwargs ):
304333 if "Python" in kwargs ["messages" ][0 ].text :
305- raise Exception ("OpenAI API request failed." )
334+ if failure_mode == "generation" :
335+ raise Exception ("OpenAI API request failed." )
336+ return {"replies" : [ChatMessage .from_assistant ("not valid JSON" )]}
306337 return {"replies" : [ChatMessage .from_assistant ('{"relevant_statements": ["c", "d"], "score": 1}' )]}
307338
308339 monkeypatch .setattr (
@@ -316,9 +347,10 @@ async def chat_generator_run_async(self, *args, **kwargs):
316347 results = await component .run_async (questions = questions , contexts = contexts )
317348
318349 assert results ["score" ] == 1
319- assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 }
350+ assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 , "status" : "evaluated" }
320351 assert results ["results" ][1 ]["relevant_statements" ] == []
321352 assert math .isnan (results ["results" ][1 ]["score" ])
353+ assert results ["results" ][1 ]["status" ] == "error"
322354
323355 assert "1 query(s) failed and were excluded from the score." in caplog .text
324356
@@ -337,7 +369,7 @@ async def test_live_run_async(self):
337369
338370 required_fields = {"results" }
339371 assert all (field in result for field in required_fields )
340- nested_required_fields = {"score" , "relevant_statements" }
372+ nested_required_fields = {"score" , "relevant_statements" , "status" }
341373 assert all (field in result ["results" ][0 ] for field in nested_required_fields )
342374
343375 assert "meta" in result
0 commit comments