@@ -30,59 +30,59 @@ class ScenarioConfig(BaseModel):
3030 """Complete scenario configuration parsed from YAML."""
3131 # Target specification
3232 target : str = ""
33-
33+
3434 # Users for authentication
3535 users : List [ScenarioUser ] = Field (default_factory = list )
36-
36+
3737 # Variables for templating
3838 variables : Dict [str , str ] = Field (default_factory = dict )
39-
39+
4040 # Instructions to execute
4141 instructions : List [str ] = Field (default_factory = list )
42-
42+
4343 # Execution settings
4444 mode : str = "agent"
4545 concurrency : int = 5
4646 request_budget : int = 400
47-
47+
4848 # Network settings
4949 proxy : Optional [str ] = None
5050 insecure : bool = False
5151
5252
5353class ScenarioParser :
5454 """Parser for scenario.yaml files."""
55-
55+
5656 @staticmethod
5757 def parse_file (file_path : str ) -> ScenarioConfig :
5858 """Parse a scenario.yaml file.
59-
59+
6060 Args:
6161 file_path: Path to the scenario.yaml file
62-
62+
6363 Returns:
6464 ScenarioConfig object with parsed data
65-
65+
6666 Raises:
6767 FileNotFoundError: If file doesn't exist
6868 ValueError: If file contains invalid YAML
6969 """
7070 path = Path (file_path )
7171 if not path .exists ():
7272 raise FileNotFoundError (f"Scenario file not found: { file_path } " )
73-
73+
7474 with open (path , "r" , encoding = "utf-8" ) as f :
7575 data = yaml .safe_load (f ) or {}
76-
76+
7777 return ScenarioParser .parse_dict (data )
78-
78+
7979 @staticmethod
8080 def parse_dict (data : Dict [str , Any ]) -> ScenarioConfig :
8181 """Parse a dictionary as scenario configuration.
82-
82+
8383 Args:
8484 data: Dictionary containing scenario configuration
85-
85+
8686 Returns:
8787 ScenarioConfig object
8888 """
@@ -92,14 +92,14 @@ def parse_dict(data: Dict[str, Any]) -> ScenarioConfig:
9292 for user_data in data ["users" ]:
9393 if isinstance (user_data , dict ):
9494 users .append (ScenarioUser (** user_data ))
95-
95+
9696 # Process instructions
9797 instructions : List [str ] = []
9898 if "instructions" in data :
9999 instr_list = data ["instructions" ]
100100 if isinstance (instr_list , list ):
101101 instructions = [str (i ) for i in instr_list ]
102-
102+
103103 # Build config
104104 config_data = {
105105 "target" : data .get ("target" , "" ),
@@ -112,28 +112,28 @@ def parse_dict(data: Dict[str, Any]) -> ScenarioConfig:
112112 "proxy" : data .get ("proxy" ),
113113 "insecure" : data .get ("insecure" , False ),
114114 }
115-
115+
116116 return ScenarioConfig (** config_data )
117-
117+
118118 @staticmethod
119119 def validate_file (file_path : str ) -> tuple [bool , Optional [str ]]:
120120 """Validate a scenario.yaml file.
121-
121+
122122 Args:
123123 file_path: Path to the scenario.yaml file
124-
124+
125125 Returns:
126126 Tuple of (is_valid, error_message)
127127 """
128128 try :
129129 config = ScenarioParser .parse_file (file_path )
130-
130+
131131 # Basic validation
132132 if not config .target and not config .users :
133133 return False , "Scenario must have at least a target or users defined"
134-
134+
135135 return True , None
136-
136+
137137 except FileNotFoundError as e :
138138 return False , str (e )
139139 except yaml .YAMLError as e :
@@ -144,10 +144,10 @@ def validate_file(file_path: str) -> tuple[bool, Optional[str]]:
144144
145145def parse_scenario (file_path : str ) -> ScenarioConfig :
146146 """Convenience function to parse a scenario file.
147-
147+
148148 Args:
149149 file_path: Path to scenario.yaml
150-
150+
151151 Returns:
152152 ScenarioConfig object
153153 """
@@ -156,10 +156,10 @@ def parse_scenario(file_path: str) -> ScenarioConfig:
156156
157157def validate_scenario (file_path : str ) -> tuple [bool , Optional [str ]]:
158158 """Convenience function to validate a scenario file.
159-
159+
160160 Args:
161161 file_path: Path to scenario.yaml
162-
162+
163163 Returns:
164164 Tuple of (is_valid, error_message)
165165 """
0 commit comments