Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions capabilities/ai-red-teaming/scripts/attack_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4324,6 +4324,8 @@ def _build_agentic_imports(attacks: list[dict], transforms: list[dict], has_scor
"",
"import dreadnode as dn",
"from dreadnode import task",
# Required by the proxy-routing block (get_generator/GenerateParams).
"from dreadnode.generators.generator import get_generator, GenerateParams",
]

attack_funcs = set()
Expand Down
27 changes: 27 additions & 0 deletions capabilities/ai-red-teaming/tests/test_attack_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,33 @@ def test_bearer_auth_injects_header(self):
assert "Authorization" in script


_AGENTIC_BASE = {
"attack_type": "goat",
"goal": "get the agent to misuse a privileged tool",
"agent_url": "http://localhost:8000/attack",
"agent_preset": "custom",
"attacker_model": "groq scout",
"n_iterations": 4,
"generate_only": True,
}


class TestAgenticGeneration:
def test_generated_script_compiles_and_imports_get_generator(self):
result = _generate_method("generate_agentic_attack", _AGENTIC_BASE)
assert "error" not in result, result.get("error")
script = Path(result["filepath"]).read_text()
compile(script, result["filepath"], "exec")
# Regression: the proxy-routing block calls get_generator(...), so the
# generated script MUST import it (compile() only checks syntax, so a
# missing import is a runtime NameError).
assert "get_generator(" in script
assert (
"from dreadnode.generators.generator import get_generator, GenerateParams"
in script
)


class TestAtlasValidation:
def test_missing_agent_url_errors(self):
params = {k: v for k, v in _ATLAS_BASE.items() if k != "agent_url"}
Expand Down
Loading