22# Licensed under the MIT license.
33
44"""
5- Scenario API response models .
5+ REST envelopes for the scenario endpoints .
66
7- Scenarios are multi-attack security testing campaigns. These models represent
8- the metadata about available scenarios (listing) and scenario execution (runs).
7+ Canonical scenario catalog/run types (``RegisteredScenario``,
8+ ``ScenarioParameterSummary``, ``ScenarioRunSummary``, ``RunScenarioRequest``)
9+ live in ``pyrit.models.catalog.scenario`` and should be imported from there
10+ directly.
911"""
1012
11- from datetime import datetime
12- from enum import Enum
13- from typing import Any
14-
1513from pydantic import BaseModel , Field
1614
1715from pyrit .backend .models .common import PaginationInfo
16+ from pyrit .models .catalog .scenario import RegisteredScenario , ScenarioRunSummary
1817
19-
20- class ScenarioParameterSummary (BaseModel ):
21- """Summary of a scenario-declared parameter."""
22-
23- name : str = Field (..., description = "Parameter name (e.g., 'max_turns')" )
24- description : str = Field (..., description = "Human-readable description of the parameter" )
25- default : str | None = Field (None , description = "Default value as a display string, or None if required" )
26- param_type : str = Field (..., description = "Type of the parameter as a display string (e.g., 'int', 'str')" )
27- choices : list [str ] | None = Field (None , description = "Allowed values as strings, or None if unconstrained" )
28- is_list : bool = Field (False , description = "True when the parameter accepts a list of values (e.g., list[str])" )
29-
30-
31- class RegisteredScenario (BaseModel ):
32- """Summary of a registered scenario."""
33-
34- scenario_name : str = Field (..., description = "Scenario name (e.g., 'foundry.red_team_agent')" )
35- scenario_type : str = Field (..., description = "Scenario type identifier (e.g., 'RedTeamAgentScenario')" )
36- description : str = Field (..., description = "Human-readable description of the scenario" )
37- default_strategy : str = Field (..., description = "Default strategy name used when none specified" )
38- aggregate_strategies : list [str ] = Field (
39- ..., description = "Aggregate strategies that combine multiple attack approaches"
40- )
41- all_strategies : list [str ] = Field (..., description = "All available concrete strategy names" )
42- default_datasets : list [str ] = Field (..., description = "Default dataset names used by the scenario" )
43- max_dataset_size : int | None = Field (None , description = "Maximum items per dataset (None means unlimited)" )
44- supported_parameters : list [ScenarioParameterSummary ] = Field (
45- default_factory = list , description = "Scenario-declared custom parameters"
46- )
18+ __all__ = [
19+ "ListRegisteredScenariosResponse" ,
20+ "ScenarioRunListResponse" ,
21+ ]
4722
4823
4924class ListRegisteredScenariosResponse (BaseModel ):
@@ -53,73 +28,6 @@ class ListRegisteredScenariosResponse(BaseModel):
5328 pagination : PaginationInfo = Field (..., description = "Pagination metadata" )
5429
5530
56- # ============================================================================
57- # Scenario Run Models
58- # ============================================================================
59-
60-
61- class ScenarioRunStatus (str , Enum ):
62- """Status of a scenario run, aligned with core ScenarioRunState."""
63-
64- CREATED = "CREATED"
65- INITIALIZING = "INITIALIZING"
66- IN_PROGRESS = "IN_PROGRESS"
67- COMPLETED = "COMPLETED"
68- FAILED = "FAILED"
69- CANCELLED = "CANCELLED"
70-
71-
72- class RunScenarioRequest (BaseModel ):
73- """Request body for starting a scenario run."""
74-
75- scenario_name : str = Field (..., description = "Scenario name (e.g., 'foundry.red_team_agent')" )
76- target_name : str = Field (..., description = "Name of a registered target from the TargetRegistry" )
77- initializers : list [str ] | None = Field (
78- None , description = "Initializer names to run before scenario (e.g., ['target', 'load_default_datasets'])"
79- )
80- strategies : list [str ] | None = Field (None , description = "Strategy names to use (uses scenario default if omitted)" )
81- dataset_names : list [str ] | None = Field (None , description = "Dataset names to use (uses scenario default if omitted)" )
82- max_dataset_size : int | None = Field (None , ge = 1 , description = "Maximum items per dataset" )
83- max_concurrency : int = Field (10 , ge = 1 , le = 100 , description = "Maximum concurrent operations" )
84- max_retries : int = Field (0 , ge = 0 , le = 20 , description = "Maximum retry attempts on failure" )
85- labels : dict [str , str ] | None = Field (None , description = "Labels to attach to memory entries" )
86- scenario_params : dict [str , Any ] | None = Field (
87- None ,
88- description = "Custom parameters for the scenario (passed to scenario.set_params_from_args). "
89- "Keys are parameter names declared by the scenario's supported_parameters()." ,
90- )
91- initializer_args : dict [str , dict [str , Any ]] | None = Field (
92- None ,
93- description = "Per-initializer arguments keyed by initializer name. "
94- "Each value is a dict of args passed to that initializer's set_params_from_args(). "
95- "Example: {'target': {'endpoint': 'https://...'}}." ,
96- )
97- scenario_result_id : str | None = Field (
98- None ,
99- description = "Optional ID of an existing ScenarioResult to resume. "
100- "If provided, the scenario will resume from prior progress instead of starting fresh." ,
101- )
102-
103-
104- class ScenarioRunSummary (BaseModel ):
105- """Response for a scenario run (status + result details)."""
106-
107- scenario_result_id : str = Field (..., description = "UUID of the ScenarioResult in memory" )
108- scenario_name : str = Field (..., description = "Registry key of the scenario being run" )
109- scenario_version : int = Field (0 , ge = 0 , description = "Version of the scenario" )
110- status : ScenarioRunStatus = Field (..., description = "Current run status" )
111- created_at : datetime = Field (..., description = "When the run was created" )
112- updated_at : datetime = Field (..., description = "When the run status last changed" )
113- error : str | None = Field (None , description = "Error message if status is FAILED" )
114- error_type : str | None = Field (None , description = "Exception class name if status is FAILED" )
115- strategies_used : list [str ] = Field (default_factory = list , description = "Strategy names that were executed" )
116- total_attacks : int = Field (0 , ge = 0 , description = "Total number of attack results persisted for this run" )
117- completed_attacks : int = Field (0 , ge = 0 , description = "Number of attacks that reached a terminal outcome" )
118- objective_achieved_rate : int = Field (0 , ge = 0 , le = 100 , description = "Success rate as percentage (0-100)" )
119- labels : dict [str , str ] = Field (default_factory = dict , description = "Labels attached to this run" )
120- completed_at : datetime | None = Field (None , description = "When the scenario finished" )
121-
122-
12331class ScenarioRunListResponse (BaseModel ):
12432 """Response for listing scenario runs."""
12533
0 commit comments