@@ -166,11 +166,13 @@ 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 ],
173- "evaluation_statuses" : ["evaluated" , "evaluated" ],
174176 }
175177
176178 def test_run_no_statements_extracted (self , monkeypatch ):
@@ -196,11 +198,13 @@ def chat_generator_run(self, *args, **kwargs):
196198 ]
197199 results = component .run (questions = questions , contexts = contexts )
198200 assert results == {
199- "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+ ],
200205 "score" : 0.5 ,
201206 "meta" : None ,
202207 "individual_scores" : [1 , 0 ],
203- "evaluation_statuses" : ["evaluated" , "evaluated" ],
204208 }
205209
206210 def test_run_missing_parameters (self , monkeypatch ):
@@ -209,13 +213,16 @@ def test_run_missing_parameters(self, monkeypatch):
209213 with pytest .raises (ValueError , match = "LLM evaluator expected input parameter" ):
210214 component .run ()
211215
212- 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 ):
213218 monkeypatch .setenv ("OPENAI_API_KEY" , "test-api-key" )
214219 component = ContextRelevanceEvaluator (raise_on_failure = False )
215220
216221 def chat_generator_run (self , * args , ** kwargs ):
217222 if "Python" in kwargs ["messages" ][0 ].text :
218- 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" )]}
219226 return {"replies" : [ChatMessage .from_assistant ('{"relevant_statements": ["c", "d"], "score": 1}' )]}
220227
221228 monkeypatch .setattr ("haystack.components.evaluators.llm_evaluator.OpenAIChatGenerator.run" , chat_generator_run )
@@ -238,13 +245,28 @@ def chat_generator_run(self, *args, **kwargs):
238245 results = component .run (questions = questions , contexts = contexts )
239246
240247 assert results ["score" ] == 1
241- assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 }
248+ assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 , "status" : "evaluated" }
242249 assert results ["results" ][1 ]["relevant_statements" ] == []
243250 assert math .isnan (results ["results" ][1 ]["score" ])
244- assert results ["evaluation_statuses" ] == [ "evaluated" , " error"]
251+ assert results ["results" ][ 1 ][ "status" ] == " error"
245252
246253 assert "1 query(s) failed and were excluded from the score." in caplog .text
247254
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+
248270 @pytest .mark .skipif (
249271 not os .environ .get ("OPENAI_API_KEY" , None ),
250272 reason = "Export an env var called OPENAI_API_KEY containing the OpenAI API key to run this test." ,
@@ -259,7 +281,7 @@ def test_live_run(self):
259281
260282 required_fields = {"results" }
261283 assert all (field in result for field in required_fields )
262- nested_required_fields = {"score" , "relevant_statements" }
284+ nested_required_fields = {"score" , "relevant_statements" , "status" }
263285 assert all (field in result ["results" ][0 ] for field in nested_required_fields )
264286
265287 assert "meta" in result
@@ -292,20 +314,26 @@ async def chat_generator_run_async(self, *args, **kwargs):
292314 results = await component .run_async (questions = questions , contexts = contexts )
293315
294316 assert results == {
295- "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+ ],
296321 "score" : 0.5 ,
297322 "meta" : None ,
298323 "individual_scores" : [1 , 0 ],
299324 }
300325
301326 @pytest .mark .asyncio
302- 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 ):
303329 monkeypatch .setenv ("OPENAI_API_KEY" , "test-api-key" )
304330 component = ContextRelevanceEvaluator (raise_on_failure = False )
305331
306332 async def chat_generator_run_async (self , * args , ** kwargs ):
307333 if "Python" in kwargs ["messages" ][0 ].text :
308- 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" )]}
309337 return {"replies" : [ChatMessage .from_assistant ('{"relevant_statements": ["c", "d"], "score": 1}' )]}
310338
311339 monkeypatch .setattr (
@@ -319,9 +347,10 @@ async def chat_generator_run_async(self, *args, **kwargs):
319347 results = await component .run_async (questions = questions , contexts = contexts )
320348
321349 assert results ["score" ] == 1
322- assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 }
350+ assert results ["results" ][0 ] == {"relevant_statements" : ["c" , "d" ], "score" : 1 , "status" : "evaluated" }
323351 assert results ["results" ][1 ]["relevant_statements" ] == []
324352 assert math .isnan (results ["results" ][1 ]["score" ])
353+ assert results ["results" ][1 ]["status" ] == "error"
325354
326355 assert "1 query(s) failed and were excluded from the score." in caplog .text
327356
@@ -340,7 +369,7 @@ async def test_live_run_async(self):
340369
341370 required_fields = {"results" }
342371 assert all (field in result for field in required_fields )
343- nested_required_fields = {"score" , "relevant_statements" }
372+ nested_required_fields = {"score" , "relevant_statements" , "status" }
344373 assert all (field in result ["results" ][0 ] for field in nested_required_fields )
345374
346375 assert "meta" in result
0 commit comments