diff --git a/pyrit/scenario/scenarios/airt/content_harms.py b/pyrit/scenario/scenarios/airt/content_harms.py index d2fb4055f6..ab26409490 100644 --- a/pyrit/scenario/scenarios/airt/content_harms.py +++ b/pyrit/scenario/scenarios/airt/content_harms.py @@ -104,7 +104,8 @@ class ContentHarms(Scenario): with respect to certain harm categories. """ - version: int = 1 + VERSION: int = 1 + version: int = VERSION # Alias for backward compatibility @classmethod def get_strategy_class(cls) -> Type[ScenarioStrategy]: @@ -179,7 +180,7 @@ def __init__( super().__init__( name="Content Harms", - version=self.version, + version=self.VERSION, objective_scorer=self._objective_scorer, strategy_class=ContentHarmsStrategy, scenario_result_id=scenario_result_id, @@ -239,9 +240,15 @@ def _get_strategy_attacks( Returns: List[AtomicAttack]: The constructed AtomicAttack instances for each attack type. + + Raises: + ValueError: If scenario is not properly initialized. """ # objective_target is guaranteed to be non-None by parent class validation - assert self._objective_target is not None + if self._objective_target is None: + raise ValueError( + "Scenario not properly initialized. Call await scenario.initialize_async() before running." + ) prompt_sending_attack = PromptSendingAttack( objective_target=self._objective_target, diff --git a/pyrit/scenario/scenarios/airt/cyber.py b/pyrit/scenario/scenarios/airt/cyber.py index 220fac3f74..e69b95373c 100644 --- a/pyrit/scenario/scenarios/airt/cyber.py +++ b/pyrit/scenario/scenarios/airt/cyber.py @@ -60,7 +60,8 @@ class Cyber(Scenario): techniques. """ - version: int = 1 + VERSION: int = 1 + version: int = VERSION # Alias for backward compatibility @classmethod def get_strategy_class(cls) -> type[ScenarioStrategy]: @@ -141,7 +142,7 @@ def __init__( super().__init__( name="Cyber", - version=self.version, + version=self.VERSION, strategy_class=CyberStrategy, objective_scorer=objective_scorer, include_default_baseline=include_baseline, @@ -241,10 +242,13 @@ def _get_atomic_attack_from_strategy(self, strategy: str) -> AtomicAttack: AtomicAttack: configured for the specified strategy. Raises: - ValueError: if an unknown CyberStrategy is passed. + ValueError: If scenario is not properly initialized or an unknown CyberStrategy is passed. """ # objective_target is guaranteed to be non-None by parent class validation - assert self._objective_target is not None + if self._objective_target is None: + raise ValueError( + "Scenario not properly initialized. Call await scenario.initialize_async() before running." + ) attack_strategy: Optional[AttackStrategy[Any, Any]] = None if strategy == "single_turn": attack_strategy = PromptSendingAttack( @@ -261,7 +265,8 @@ def _get_atomic_attack_from_strategy(self, strategy: str) -> AtomicAttack: raise ValueError(f"Unknown CyberStrategy: {strategy}") # _seed_groups is guaranteed to be set by _get_atomic_attacks_async before this method is called - assert self._seed_groups is not None, "_seed_groups must be resolved before creating atomic attacks" + if self._seed_groups is None: + raise ValueError("_seed_groups must be resolved before creating atomic attacks") return AtomicAttack( atomic_attack_name=f"cyber_{strategy}", diff --git a/pyrit/scenario/scenarios/airt/jailbreak.py b/pyrit/scenario/scenarios/airt/jailbreak.py index e28676db72..e9092831e9 100644 --- a/pyrit/scenario/scenarios/airt/jailbreak.py +++ b/pyrit/scenario/scenarios/airt/jailbreak.py @@ -49,7 +49,8 @@ class Jailbreak(Scenario): scored to determine if the jailbreak was successful. """ - version: int = 1 + VERSION: int = 1 + version: int = VERSION # Alias for backward compatibility @classmethod def get_strategy_class(cls) -> type[ScenarioStrategy]: @@ -114,7 +115,7 @@ def __init__( super().__init__( name="Jailbreak", - version=self.version, + version=self.VERSION, strategy_class=JailbreakStrategy, objective_scorer=objective_scorer, include_default_baseline=include_baseline, @@ -182,9 +183,15 @@ async def _get_atomic_attack_from_jailbreak_async(self, *, jailbreak_template_na Returns: AtomicAttack: An atomic attack using the specified jailbreak template. + + Raises: + ValueError: If scenario is not properly initialized. """ # objective_target is guaranteed to be non-None by parent class validation - assert self._objective_target is not None + if self._objective_target is None: + raise ValueError( + "Scenario not properly initialized. Call await scenario.initialize_async() before running." + ) # Create the jailbreak converter jailbreak_converter = TextJailbreakConverter( diff --git a/pyrit/scenario/scenarios/airt/leakage_scenario.py b/pyrit/scenario/scenarios/airt/leakage_scenario.py index 5137ef2eb7..aaed955dd3 100644 --- a/pyrit/scenario/scenarios/airt/leakage_scenario.py +++ b/pyrit/scenario/scenarios/airt/leakage_scenario.py @@ -89,7 +89,8 @@ class LeakageScenario(Scenario): attack variations designed to extract sensitive information from models. """ - version: int = 1 + VERSION: int = 1 + version: int = VERSION # Alias for backward compatibility @classmethod def get_strategy_class(cls) -> type[ScenarioStrategy]: @@ -161,7 +162,7 @@ def __init__( super().__init__( name="Leakage Scenario", - version=self.version, + version=self.VERSION, strategy_class=LeakageStrategy, objective_scorer=objective_scorer, include_default_baseline=include_baseline, @@ -261,10 +262,13 @@ async def _get_atomic_attack_from_strategy_async(self, strategy: str) -> AtomicA AtomicAttack: Configured for the specified strategy. Raises: - ValueError: If an unknown LeakageStrategy is passed. + ValueError: If scenario is not properly initialized or an unknown LeakageStrategy is passed. """ # objective_target is guaranteed to be non-None by parent class validation - assert self._objective_target is not None + if self._objective_target is None: + raise ValueError( + "Scenario not properly initialized. Call await scenario.initialize_async() before running." + ) strategy_factories = { "first_letter": self._create_first_letter_attack, diff --git a/pyrit/scenario/scenarios/airt/scam.py b/pyrit/scenario/scenarios/airt/scam.py index e29204a715..39d5d3b1dd 100644 --- a/pyrit/scenario/scenarios/airt/scam.py +++ b/pyrit/scenario/scenarios/airt/scam.py @@ -89,7 +89,8 @@ class Scam(Scenario): (e.g., phishing emails, fraudulent messages) with primarily persuasion-oriented techniques. """ - version: int = 1 + VERSION: int = 1 + version: int = VERSION # Alias for backward compatibility @classmethod def get_strategy_class(cls) -> type[ScenarioStrategy]: @@ -167,7 +168,7 @@ def __init__( super().__init__( name="Scam", - version=self.version, + version=self.VERSION, strategy_class=ScamStrategy, objective_scorer=objective_scorer, include_default_baseline=include_baseline, @@ -266,10 +267,13 @@ def _get_atomic_attack_from_strategy(self, strategy: str) -> AtomicAttack: AtomicAttack: Configured for the specified strategy. Raises: - ValueError: If an unknown ScamStrategy is provided. + ValueError: If scenario is not properly initialized or an unknown ScamStrategy is provided. """ # objective_target is guaranteed to be non-None by parent class validation - assert self._objective_target is not None + if self._objective_target is None: + raise ValueError( + "Scenario not properly initialized. Call await scenario.initialize_async() before running." + ) attack_strategy: Optional[AttackStrategy[Any, Any]] = None if strategy == "persuasive_rta": diff --git a/pyrit/scenario/scenarios/foundry/red_team_agent.py b/pyrit/scenario/scenarios/foundry/red_team_agent.py index 04ba25272d..af9b1682f5 100644 --- a/pyrit/scenario/scenarios/foundry/red_team_agent.py +++ b/pyrit/scenario/scenarios/foundry/red_team_agent.py @@ -214,7 +214,8 @@ class RedTeamAgent(Scenario): providing a consistent PyRIT contract for their integration. """ - version: int = 1 + VERSION: int = 1 + version: int = VERSION # Alias for backward compatibility @classmethod def get_strategy_class(cls) -> Type[ScenarioStrategy]: @@ -297,7 +298,7 @@ def __init__( # Call super().__init__() first to initialize self._memory super().__init__( name="RedTeamAgent", - version=self.version, + version=self.VERSION, strategy_class=FoundryStrategy, objective_scorer=objective_scorer, include_default_baseline=include_baseline, diff --git a/pyrit/scenario/scenarios/garak/encoding.py b/pyrit/scenario/scenarios/garak/encoding.py index 712d2efa6c..5cbc9a6437 100644 --- a/pyrit/scenario/scenarios/garak/encoding.py +++ b/pyrit/scenario/scenarios/garak/encoding.py @@ -133,7 +133,8 @@ class Encoding(Scenario): By default, this uses the same dataset as Garak: slur terms and web XSS payloads. """ - version: int = 1 + VERSION: int = 1 + version: int = VERSION # Alias for backward compatibility @classmethod def get_strategy_class(cls) -> type[ScenarioStrategy]: @@ -209,7 +210,7 @@ def __init__( super().__init__( name="Encoding", - version=self.version, + version=self.VERSION, strategy_class=EncodingStrategy, objective_scorer=objective_scorer, include_default_baseline=include_baseline, @@ -332,6 +333,9 @@ def _get_prompt_attacks(self, *, converters: list[PromptConverter], encoding_nam Returns: list[AtomicAttack]: List of atomic attacks for this encoding scheme. + + Raises: + ValueError: If scenario is not properly initialized. """ converter_configs = [ AttackConverterConfig( @@ -351,7 +355,10 @@ def _get_prompt_attacks(self, *, converters: list[PromptConverter], encoding_nam atomic_attacks = [] for attack_converter_config in converter_configs: # objective_target is guaranteed to be non-None by parent class validation - assert self._objective_target is not None + if self._objective_target is None: + raise ValueError( + "Scenario not properly initialized. Call await scenario.initialize_async() before running." + ) attack = PromptSendingAttack( objective_target=self._objective_target, attack_converter_config=attack_converter_config,