Skip to content

Commit 99fc8cb

Browse files
committed
fix(fix network error handling in fuzzer):
1 parent 46ef893 commit 99fc8cb

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

agentic_security/models/schemas.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class ScanResult(BaseModel):
3232
progress: float
3333
status: bool = False
3434
failureRate: float = 0.0
35+
prompt: str = ""
36+
model: str = ""
37+
refused: bool = False
3538

3639
@classmethod
3740
def status_msg(cls, msg: str) -> str:
@@ -42,6 +45,9 @@ def status_msg(cls, msg: str) -> str:
4245
progress=0,
4346
failureRate=0,
4447
status=True,
48+
prompt="",
49+
model="",
50+
refused=False,
4551
).model_dump_json()
4652

4753

agentic_security/probe_actor/fuzzer.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
# TODO: full log file
1919

20+
MAX_PROMPT_LENGTH = 2048
21+
2022

2123
async def generate_prompts(
2224
prompts: list[str] | AsyncGenerator,
@@ -43,7 +45,10 @@ def multi_modality_spec(llm_spec):
4345

4446
async def process_prompt(
4547
request_factory, prompt, tokens, module_name, refusals, errors
46-
):
48+
) -> tuple[int, bool]:
49+
"""
50+
Process a single prompt and update the token count and failure status.
51+
"""
4752
try:
4853
response = await request_factory.fn(prompt=prompt)
4954
if response.status_code == 422:
@@ -52,11 +57,9 @@ async def process_prompt(
5257
return tokens, True
5358

5459
if response.status_code >= 400:
55-
raise httpx.HTTPStatusError(
56-
f"HTTP {response.status_code} {response.content=}",
57-
request=response.request,
58-
response=response,
59-
)
60+
logger.error(f"HTTP {response.status_code} {response.content=}")
61+
errors.append((module_name, prompt, response.status_code, response.text))
62+
return tokens, True
6063
response_text = response.text
6164
tokens += len(response_text.split())
6265

@@ -150,6 +153,7 @@ async def perform_single_shot_scan(
150153
cost=cost,
151154
progress=round(progress, 2),
152155
failureRate=round(failure_rate * 100, 2),
156+
prompt=prompt[:MAX_PROMPT_LENGTH],
153157
).model_dump_json()
154158

155159
if optimize and len(failure_rates) >= 5:
@@ -183,7 +187,9 @@ async def perform_single_shot_scan(
183187
except Exception as e:
184188
logger.exception("Scan failed")
185189
yield ScanResult.status_msg(f"Scan failed: {str(e)}")
186-
raise e
190+
# raise e
191+
finally:
192+
yield ScanResult.status_msg("Scan completed.")
187193

188194

189195
async def perform_many_shot_scan(
@@ -281,6 +287,7 @@ async def perform_many_shot_scan(
281287
cost=cost,
282288
progress=round(progress, 2),
283289
failureRate=round(failure_rate * 100, 2),
290+
prompt=prompt[:MAX_PROMPT_LENGTH],
284291
).model_dump_json()
285292

286293
if optimize and len(failure_rates) >= 5:

agentic_security/probe_actor/test_fuzzer.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,14 @@ async def test_http_error_response(self):
250250
)
251251

252252
refusals = []
253-
with self.assertRaises(httpx.HTTPStatusError):
254-
await process_prompt(
255-
request_factory=mock_request_factory,
256-
prompt="test prompt",
257-
tokens=0,
258-
module_name="module_a",
259-
refusals=refusals,
260-
errors=[],
261-
)
253+
await process_prompt(
254+
request_factory=mock_request_factory,
255+
prompt="test prompt",
256+
tokens=0,
257+
module_name="module_a",
258+
refusals=refusals,
259+
errors=[],
260+
)
262261

263262
async def test_request_error(self):
264263
mock_request_factory = Mock()

0 commit comments

Comments
 (0)