@@ -283,14 +283,14 @@ def _start_redteam_mlflow_run(
283283
284284 async def _log_redteam_results_to_mlflow (
285285 self ,
286- redteam_output : RedTeamResult ,
286+ redteam_result : RedTeamResult ,
287287 eval_run : EvalRun ,
288288 data_only : bool = False ,
289289 ) -> Optional [str ]:
290290 """Log the Red Team Agent results to MLFlow.
291291
292- :param redteam_output : The output from the red team agent evaluation
293- :type redteam_output : ~azure.ai.evaluation.RedTeamOutput
292+ :param redteam_result : The output from the red team agent evaluation
293+ :type redteam_result : ~azure.ai.evaluation.RedTeamResult
294294 :param eval_run: The MLFlow run object
295295 :type eval_run: ~azure.ai.evaluation._evaluate._eval_run.EvalRun
296296 :param data_only: Whether to log only data without evaluation results
@@ -308,21 +308,21 @@ async def _log_redteam_results_to_mlflow(
308308 with open (artifact_path , "w" , encoding = DefaultOpenEncoding .WRITE ) as f :
309309 if data_only :
310310 # In data_only mode, we write the conversations in conversation/messages format
311- f .write (json .dumps ({"conversations" : redteam_output .attack_details or []}))
312- elif redteam_output .scan_result :
311+ f .write (json .dumps ({"conversations" : redteam_result .attack_details or []}))
312+ elif redteam_result .scan_result :
313313 # Create a copy to avoid modifying the original scan result
314- result_with_conversations = redteam_output .scan_result .copy () if isinstance (redteam_output .scan_result , dict ) else {}
314+ result_with_conversations = redteam_result .scan_result .copy () if isinstance (redteam_result .scan_result , dict ) else {}
315315
316316 # Preserve all original fields needed for scorecard generation
317317 result_with_conversations ["scorecard" ] = result_with_conversations .get ("scorecard" , {})
318318 result_with_conversations ["parameters" ] = result_with_conversations .get ("parameters" , {})
319319
320320 # Add conversations field with all conversation data including user messages
321- result_with_conversations ["conversations" ] = redteam_output .attack_details or []
321+ result_with_conversations ["conversations" ] = redteam_result .attack_details or []
322322
323323 # Keep original attack_details field to preserve compatibility with existing code
324- if "attack_details" not in result_with_conversations and redteam_output .attack_details is not None :
325- result_with_conversations ["attack_details" ] = redteam_output .attack_details
324+ if "attack_details" not in result_with_conversations and redteam_result .attack_details is not None :
325+ result_with_conversations ["attack_details" ] = redteam_result .attack_details
326326
327327 json .dump (result_with_conversations , f )
328328
@@ -340,10 +340,10 @@ async def _log_redteam_results_to_mlflow(
340340 f .write (json .dumps (red_team_info_logged ))
341341
342342 # Also save a human-readable scorecard if available
343- if not data_only and redteam_output .scan_result :
343+ if not data_only and redteam_result .scan_result :
344344 scorecard_path = os .path .join (self .scan_output_dir , "scorecard.txt" )
345345 with open (scorecard_path , "w" , encoding = DefaultOpenEncoding .WRITE ) as f :
346- f .write (self ._to_scorecard (redteam_output .scan_result ))
346+ f .write (self ._to_scorecard (redteam_result .scan_result ))
347347 self .logger .debug (f"Saved scorecard to: { scorecard_path } " )
348348
349349 # Create a dedicated artifacts directory with proper structure for MLFlow
@@ -354,13 +354,13 @@ async def _log_redteam_results_to_mlflow(
354354 # First, create the main artifact file that MLFlow expects
355355 with open (os .path .join (tmpdir , artifact_name ), "w" , encoding = DefaultOpenEncoding .WRITE ) as f :
356356 if data_only :
357- f .write (json .dumps ({"conversations" : redteam_output .attack_details or []}))
358- elif redteam_output .scan_result :
359- redteam_output .scan_result ["redteaming_scorecard" ] = redteam_output .scan_result .get ("scorecard" , None )
360- redteam_output .scan_result ["redteaming_parameters" ] = redteam_output .scan_result .get ("parameters" , None )
361- redteam_output .scan_result ["redteaming_data" ] = redteam_output .scan_result .get ("attack_details" , None )
357+ f .write (json .dumps ({"conversations" : redteam_result .attack_details or []}))
358+ elif redteam_result .scan_result :
359+ redteam_result .scan_result ["redteaming_scorecard" ] = redteam_result .scan_result .get ("scorecard" , None )
360+ redteam_result .scan_result ["redteaming_parameters" ] = redteam_result .scan_result .get ("parameters" , None )
361+ redteam_result .scan_result ["redteaming_data" ] = redteam_result .scan_result .get ("attack_details" , None )
362362
363- json .dump (redteam_output .scan_result , f )
363+ json .dump (redteam_result .scan_result , f )
364364
365365 # Copy all relevant files to the temp directory
366366 import shutil
@@ -401,9 +401,9 @@ async def _log_redteam_results_to_mlflow(
401401 artifact_file = Path (tmpdir ) / artifact_name
402402 with open (artifact_file , "w" , encoding = DefaultOpenEncoding .WRITE ) as f :
403403 if data_only :
404- f .write (json .dumps ({"conversations" : redteam_output .attack_details or []}))
405- elif redteam_output .scan_result :
406- json .dump (redteam_output .scan_result , f )
404+ f .write (json .dumps ({"conversations" : redteam_result .attack_details or []}))
405+ elif redteam_result .scan_result :
406+ json .dump (redteam_result .scan_result , f )
407407 eval_run .log_artifact (tmpdir , artifact_name )
408408 self .logger .debug (f"Logged artifact: { artifact_name } " )
409409
@@ -414,8 +414,8 @@ async def _log_redteam_results_to_mlflow(
414414 "_azureml.evaluate_artifacts" : json .dumps ([{"path" : artifact_name , "type" : "table" }]),
415415 })
416416
417- if redteam_output .scan_result :
418- scorecard = redteam_output .scan_result ["scorecard" ]
417+ if redteam_result .scan_result :
418+ scorecard = redteam_result .scan_result ["scorecard" ]
419419 joint_attack_summary = scorecard ["joint_risk_attack_summary" ]
420420
421421 if joint_attack_summary :
@@ -1641,7 +1641,7 @@ async def scan(
16411641 :param timeout: The timeout in seconds for API calls (default: 120)
16421642 :type timeout: int
16431643 :return: The output from the red team scan
1644- :rtype: RedTeamOutput
1644+ :rtype: RedTeamResult
16451645 """
16461646 # Start timing for performance tracking
16471647 self .start_time = time .time ()
@@ -1673,7 +1673,7 @@ def filter(self, record):
16731673 return False
16741674 if 'The path to the artifact is either not a directory or does not exist' in record .getMessage ():
16751675 return False
1676- if 'RedTeamOutput object at' in record .getMessage ():
1676+ if 'RedTeamResult object at' in record .getMessage ():
16771677 return False
16781678 if 'timeout won\' t take effect' in record .getMessage ():
16791679 return False
@@ -2006,7 +2006,7 @@ def filter(self, record):
20062006 # Log results to MLFlow
20072007 self .logger .info ("Logging results to MLFlow" )
20082008 await self ._log_redteam_results_to_mlflow (
2009- redteam_output = output ,
2009+ redteam_result = output ,
20102010 eval_run = eval_run ,
20112011 data_only = data_only
20122012 )
0 commit comments