hackagent 0.11.0__tar.gz → 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hackagent-0.11.0 → hackagent-0.12.0}/.gitignore +6 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/PKG-INFO +24 -2
- {hackagent-0.11.0 → hackagent-0.12.0}/README.md +22 -1
- hackagent-0.12.0/hackagent/_version.py +21 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/agent.py +246 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/base.py +5 -8
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/__init__.py +5 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/base.py +14 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/evaluation_step.py +319 -12
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/inline_step_judge.py +42 -8
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/judge_evaluators.py +194 -5
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/metrics.py +11 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/sync.py +6 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/orchestrator.py +261 -78
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/prompt_parser.py +11 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/advprefix/attack.py +5 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/advprefix/config.py +5 -2
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/attack.py +28 -15
- hackagent-0.11.0/hackagent/attacks/techniques/autodan_turbo/evaluation.py → hackagent-0.12.0/hackagent/attacks/techniques/autodan_turbo/autodan_eval.py +14 -51
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/config.py +19 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/core.py +3 -2
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/lifelong.py +14 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/warm_up.py +14 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/base.py +26 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/baseline/attack.py +15 -11
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/baseline/config.py +1 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/baseline/generation.py +18 -23
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/bon/attack.py +8 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/cipherchat/attack.py +14 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/config.py +2 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/fc/attack.py +21 -7
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/fc/flowchart_renderer.py +561 -14
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/flipattack/attack.py +10 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/h4rm3l/attack.py +51 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/indirect_prompt_injection/attack.py +5 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/indirect_prompt_injection/config.py +2 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/mml/attack.py +12 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pair/attack.py +500 -270
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pair/config.py +28 -6
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pap/attack.py +8 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/rag/attack.py +47 -6
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/rag/config.py +4 -0
- hackagent-0.12.0/hackagent/attacks/techniques/rag/jailbreak.py +439 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/static_template/attack.py +25 -20
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/static_template/config.py +2 -2
- hackagent-0.11.0/hackagent/attacks/techniques/static_template/evaluation.py → hackagent-0.12.0/hackagent/attacks/techniques/static_template/static_eval.py +40 -144
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/tap/attack.py +5 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/tap/generation.py +1 -1
- hackagent-0.11.0/hackagent/attacks/techniques/tap/evaluation.py → hackagent-0.12.0/hackagent/attacks/techniques/tap/tap_evaluation.py +14 -19
- hackagent-0.12.0/hackagent/attacks/types.py +190 -0
- hackagent-0.12.0/hackagent/cli/bootstrap.py +96 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/__init__.py +66 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/catalog.py +65 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/chain.py +247 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/config.py +109 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/display.py +220 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/group.py +119 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/info.py +58 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/options.py +82 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/runner.py +175 -0
- hackagent-0.12.0/hackagent/cli/commands/attack/strategies.py +96 -0
- hackagent-0.12.0/hackagent/cli/commands/codex.py +291 -0
- hackagent-0.12.0/hackagent/cli/commands/datasets.py +236 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/commands/examples.py +159 -91
- hackagent-0.12.0/hackagent/cli/commands/scan/__init__.py +47 -0
- hackagent-0.11.0/hackagent/cli/commands/scan.py → hackagent-0.12.0/hackagent/cli/commands/scan/command.py +7 -270
- hackagent-0.12.0/hackagent/cli/commands/scan/helpers.py +120 -0
- hackagent-0.12.0/hackagent/cli/commands/scan/quick.py +181 -0
- hackagent-0.12.0/hackagent/cli/help_page.py +143 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/main.py +67 -229
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/app.py +31 -26
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/__init__.py +49 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/registry.py +33 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/__init__.py +55 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/advprefix.py +197 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/autodan_turbo.py +150 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/baseline.py +104 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/bon.py +131 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/cipherchat.py +215 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/fc.py +65 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/flipattack.py +107 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/h4rm3l.py +100 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/mml.py +121 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/pair.py +142 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/pap.py +139 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/static_template.py +146 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/tap.py +119 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/specs/tfc.py +80 -0
- hackagent-0.12.0/hackagent/cli/tui/attack_specs/types.py +158 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/base.py +1 -1
- hackagent-0.12.0/hackagent/cli/tui/theme.py +187 -0
- hackagent-0.12.0/hackagent/cli/tui/views/attacks/__init__.py +37 -0
- hackagent-0.12.0/hackagent/cli/tui/views/attacks/executor.py +429 -0
- hackagent-0.12.0/hackagent/cli/tui/views/attacks/form.py +509 -0
- hackagent-0.12.0/hackagent/cli/tui/views/attacks/helpers.py +89 -0
- hackagent-0.12.0/hackagent/cli/tui/views/attacks/layout.py +263 -0
- hackagent-0.12.0/hackagent/cli/tui/views/attacks/runner.py +286 -0
- hackagent-0.12.0/hackagent/cli/tui/views/attacks/tab.py +390 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/views/config.py +2 -3
- hackagent-0.12.0/hackagent/cli/tui/views/results/__init__.py +58 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/details.py +377 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/export.py +173 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/formatters/__init__.py +54 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/formatters/datetimes.py +39 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/formatters/http.py +365 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/formatters/run_report.py +183 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/formatters/summaries.py +297 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/formatters/text.py +113 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/formatters/traces.py +351 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/tab.py +400 -0
- hackagent-0.12.0/hackagent/cli/tui/views/results/table.py +212 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/widgets/actions.py +4 -6
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/utils.py +4 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/config.py +58 -3
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/__init__.py +4 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/presets.py +24 -2
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/providers/__init__.py +2 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/providers/huggingface.py +23 -2
- hackagent-0.12.0/hackagent/datasets/providers/url_json.py +151 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/registry.py +131 -37
- hackagent-0.12.0/hackagent/examples/codex/README.md +118 -0
- hackagent-0.12.0/hackagent/examples/codex/hack_codex.py +89 -0
- hackagent-0.12.0/hackagent/examples/codex/hack_ollama.py +77 -0
- hackagent-0.12.0/hackagent/examples/hermes/README.md +97 -0
- hackagent-0.12.0/hackagent/examples/hermes/hack_hermes.py +94 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/ollama/demo.py +24 -30
- hackagent-0.12.0/hackagent/examples/openai_sdk/db_tool_sandbox/README.md +70 -0
- hackagent-0.12.0/hackagent/examples/openai_sdk/db_tool_sandbox/agent.py +494 -0
- hackagent-0.12.0/hackagent/examples/openai_sdk/db_tool_sandbox/hack.py +101 -0
- hackagent-0.12.0/hackagent/examples/openai_sdk/db_tool_sandbox/sandbox.db +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/rag/README.md +7 -15
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/rag/test_indirect_injection.py +12 -14
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/__init__.py +2 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/_chat_registration.py +2 -3
- hackagent-0.12.0/hackagent/router/providers/codex.py +633 -0
- hackagent-0.12.0/hackagent/router/providers/hermes.py +482 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/providers/web.py +39 -9
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/router.py +4 -0
- hackagent-0.12.0/hackagent/router/tracking/audit.py +72 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/category_classifier.py +2 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/coordinator.py +42 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/decorators.py +25 -12
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/step.py +36 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/tracker.py +79 -49
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/types.py +15 -0
- hackagent-0.12.0/hackagent/server/dashboard/_attack_builder_mixin.py +558 -0
- hackagent-0.12.0/hackagent/server/dashboard/_builder_config.py +271 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_constants.py +0 -8
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_data_mixin.py +2 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_layout_mixin.py +158 -144
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_page.py +25 -4
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_reports_mixin.py +30 -12
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_result_detail_mixin.py +10 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_runs_mixin.py +7 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_advprefix.py +4 -13
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_bon.py +4 -13
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_generic.py +0 -56
- hackagent-0.12.0/hackagent/server/dashboard/attack_cards/_pair.py +284 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_pap.py +4 -13
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_shared.py +117 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_static_template.py +4 -13
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/storage/local.py +94 -1
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/storage/remote.py +11 -14
- {hackagent-0.11.0 → hackagent-0.12.0}/pyproject.toml +17 -4
- hackagent-0.11.0/hackagent/attacks/techniques/bon/evaluation.py +0 -147
- hackagent-0.11.0/hackagent/attacks/techniques/cipherchat/evaluation.py +0 -97
- hackagent-0.11.0/hackagent/attacks/techniques/fc/evaluation.py +0 -181
- hackagent-0.11.0/hackagent/attacks/techniques/flipattack/evaluation.py +0 -223
- hackagent-0.11.0/hackagent/attacks/techniques/h4rm3l/evaluation.py +0 -174
- hackagent-0.11.0/hackagent/attacks/techniques/mml/evaluation.py +0 -220
- hackagent-0.11.0/hackagent/attacks/techniques/pair/evaluation.py +0 -90
- hackagent-0.11.0/hackagent/attacks/techniques/pap/evaluation.py +0 -69
- hackagent-0.11.0/hackagent/cli/commands/attack.py +0 -1293
- hackagent-0.11.0/hackagent/cli/tui/attack_specs.py +0 -1627
- hackagent-0.11.0/hackagent/cli/tui/views/attacks.py +0 -1431
- hackagent-0.11.0/hackagent/cli/tui/views/results.py +0 -2479
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_pair.py +0 -194
- {hackagent-0.11.0 → hackagent-0.12.0}/LICENSE +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/evaluator/pattern_evaluators.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/generator/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/generator/templates.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/objectives/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/objectives/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/objectives/harmful_behavior.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/objectives/jailbreak.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/objectives/policy_violation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/objectives/rag.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/registry.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/guardrail.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/progress.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/response_utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/router_factory.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/translation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/tui.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/shared/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/advprefix/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/advprefix/completions.py +0 -0
- /hackagent-0.11.0/hackagent/attacks/techniques/advprefix/evaluation.py → /hackagent-0.12.0/hackagent/attacks/techniques/advprefix/eval_pipeline.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/advprefix/generate.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/advprefix/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/dashboard_tracing.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/log_styles.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/strategy_library.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/autodan_turbo/summarizer.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/baseline/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/bon/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/bon/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/bon/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/cipherchat/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/cipherchat/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/cipherchat/encode_experts.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/cipherchat/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/cipherchat/prompts_and_demonstrations.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/fc/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/fc/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/fc/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/fc/prompts.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/flipattack/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/flipattack/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/flipattack/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/h4rm3l/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/h4rm3l/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/h4rm3l/decorators.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/h4rm3l/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/mml/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/mml/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/mml/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/mml/image_encoder.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/mml/prompts.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pair/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pap/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pap/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pap/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/pap/taxonomy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/rag/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/static_template/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/static_template/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/tap/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/attacks/techniques/tap/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/commands/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/commands/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/commands/claude.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/commands/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/commands/results.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/commands/web.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/events.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/logger.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/views/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/views/agents.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/widgets/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/widgets/clipboard.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/cli/tui/widgets/logs.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/intents.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/omnisafebench/dataset.json +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/datasets/providers/file.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/errors.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/claude/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/claude/hack_claude.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/claude/hack_ollama.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/google_adk/jailbreak_eval/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/google_adk/jailbreak_eval/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/google_adk/jailbreak_eval/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/google_adk/multi_tool_agent/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/google_adk/multi_tool_agent/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/google_adk/multi_tool_agent/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/langchain/rag/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/langchain/rag/agent_client.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/langchain/rag/agent_server.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/langchain/rag/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/langchain/rag/ingest.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/langchain/rag/policies.pdf +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/langchain/rag/read_db.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/litellm_multi_provider/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/litellm_multi_provider/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/litellm_multi_provider/demo.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/ollama/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/ollama/local.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/multi_judge/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/multi_judge/run_flipattack_multi_judge.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/confidential/db_credentials.txt +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/quick_evaluation/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/quick_evaluation/run_h4rm3l.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/rag/agent_server.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/rag/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/rag/ingest.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/openai_sdk/rag/policies.pdf +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/rag/.gitignore +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/rag/test_data/gender_studies_overview.txt +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/vllm/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/web/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/web/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/examples/web/plan.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/logger.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/craft_adversarial_data/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/craft_adversarial_data/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/craft_adversarial_data/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/craft_adversarial_data/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/credential_exposure/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/credential_exposure/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/credential_exposure/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/credential_exposure/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/excessive_agency/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/excessive_agency/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/excessive_agency/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/excessive_agency/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/input_manipulation_attack/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/input_manipulation_attack/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/input_manipulation_attack/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/input_manipulation_attack/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/jailbreak/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/jailbreak/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/jailbreak/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/jailbreak/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/malicious_tool_invocation/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/malicious_tool_invocation/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/malicious_tool_invocation/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/malicious_tool_invocation/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/misinformation/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/misinformation/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/misinformation/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/misinformation/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/model_evasion/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/model_evasion/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/model_evasion/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/model_evasion/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/profile_helpers.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/profile_types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/prompt_injection/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/prompt_injection/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/prompt_injection/templates.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/prompt_injection/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/prompt_injection/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/public_facing_application_exploitation/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/public_facing_application_exploitation/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/public_facing_application_exploitation/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/public_facing_application_exploitation/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/registry.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/sensitive_information_disclosure/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/sensitive_information_disclosure/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/sensitive_information_disclosure/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/sensitive_information_disclosure/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/system_prompt_leakage/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/system_prompt_leakage/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/system_prompt_leakage/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/system_prompt_leakage/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/vector_embedding_weaknesses_exploit/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/vector_embedding_weaknesses_exploit/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/vector_embedding_weaknesses_exploit/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/risks/vector_embedding_weaknesses_exploit/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/discovery/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/discovery/browser.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/discovery/scanner.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/envelope.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/provider_config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/providers/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/providers/adk.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/providers/claude.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/context.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/router/tracking_logger.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/agent/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/agent/agent_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/agent/agent_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/agent/agent_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/agent/agent_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/agent/agent_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/agent/agent_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/apilogs/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/apilogs/apilogs_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/apilogs/apilogs_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/apilogs/apilogs_summary_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/attack/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/attack/attack_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/attack/attack_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/attack/attack_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/attack/attack_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/attack/attack_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/attack/attack_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/checkout/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/checkout/checkout_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/generate/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/generate/v1_chat_completions_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/judge/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/judge/judge_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/key/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/key/key_context_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/key/key_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/key/key_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/key/key_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/key/key_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/models.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/organization_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/organization_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/organization_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/organization_me_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/organization_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/organization_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/organization/organization_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/result_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/result_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/result_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/result_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/result_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/result_trace_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/result/result_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_result_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_run_tests_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/run/run_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/scripts/generate.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/scripts/generate.sh +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/scripts/openapi-python-client.yaml +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_me_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_me_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/api/user/user_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/client.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_analysis_data_mixin.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_api.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_components.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_helpers.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_run_history_results_mixin.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_run_results_mixin.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_tap_trace_mixin.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_trace_analysis_mixin.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/_trace_render_mixin.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/app.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_autodan.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_fc.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_mml.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_tap.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/attack_cards/_tfc.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/dashboard/templates/index.html +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/errors.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/storage/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/storage/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/storage/enums.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/server/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.12.0}/hackagent/utils.py +0 -0
|
@@ -7,6 +7,7 @@ reports/
|
|
|
7
7
|
slurm/
|
|
8
8
|
tools/
|
|
9
9
|
docs/docs/attacks/walkthroughs/
|
|
10
|
+
.worktrees/
|
|
10
11
|
|
|
11
12
|
# Editors
|
|
12
13
|
.vscode/
|
|
@@ -54,6 +55,8 @@ MANIFEST
|
|
|
54
55
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
55
56
|
*.manifest
|
|
56
57
|
*.spec
|
|
58
|
+
# The release build spec is checked in, unlike generated ones.
|
|
59
|
+
!packaging/hackagent.spec
|
|
57
60
|
|
|
58
61
|
# Installer logs
|
|
59
62
|
pip-log.txt
|
|
@@ -139,3 +142,6 @@ dmypy.json
|
|
|
139
142
|
tests/e2e/attacks/
|
|
140
143
|
|
|
141
144
|
.tmp
|
|
145
|
+
|
|
146
|
+
# pytest-textual-snapshot report artifact
|
|
147
|
+
snapshot_report.html
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hackagent
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: HackAgent is an open-source security toolkit to detect vulnerabilities of your AI Agents.
|
|
5
5
|
Author-email: AI Security Lab <ais@ai4i.it>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -18,6 +18,7 @@ Requires-Python: >=3.10
|
|
|
18
18
|
Requires-Dist: click>=8.1.0
|
|
19
19
|
Requires-Dist: datasets>=2.14.0
|
|
20
20
|
Requires-Dist: faiss-cpu>=1.13.2
|
|
21
|
+
Requires-Dist: flask>=3.1.2
|
|
21
22
|
Requires-Dist: httpx>=0.27.0
|
|
22
23
|
Requires-Dist: litellm>=1.69.2
|
|
23
24
|
Requires-Dist: nicegui>=2.0
|
|
@@ -91,6 +92,27 @@ pip install hackagent
|
|
|
91
92
|
|
|
92
93
|
No API key required: HackAgent works locally out of the box.
|
|
93
94
|
|
|
95
|
+
### Standalone binary (no Python required)
|
|
96
|
+
|
|
97
|
+
Every [GitHub Release](https://github.com/AISecurityLab/hackagent/releases) ships a
|
|
98
|
+
self-contained archive per platform:
|
|
99
|
+
|
|
100
|
+
| Platform | Asset |
|
|
101
|
+
|----------|-------|
|
|
102
|
+
| Linux x86_64 | `hackagent-<version>-linux-x86_64.tar.gz` |
|
|
103
|
+
| macOS arm64 | `hackagent-<version>-macos-arm64.tar.gz` |
|
|
104
|
+
| macOS x86_64 | `hackagent-<version>-macos-x86_64.tar.gz` |
|
|
105
|
+
| Windows x86_64 | `hackagent-<version>-windows-x86_64.zip` |
|
|
106
|
+
|
|
107
|
+
Extract the archive and run the `hackagent` launcher inside it — no Python, `pip`
|
|
108
|
+
or `uv` install needed. Keep the extracted folder intact; the launcher loads the
|
|
109
|
+
libraries next to it.
|
|
110
|
+
|
|
111
|
+
> **Note:** the `WEB` provider drives a real browser through Playwright, whose
|
|
112
|
+
> browser binaries cannot be embedded in the archive (or in the PyPI package).
|
|
113
|
+
> Before using `hackagent web`-based targets, install them once with
|
|
114
|
+
> `playwright install`.
|
|
115
|
+
|
|
94
116
|
|
|
95
117
|
Questions? Join [community discussions](https://github.com/AISecurityLab/hackagent/discussions) or email ais@ai4i.it.
|
|
96
118
|
|
|
@@ -104,7 +126,7 @@ HackAgent uses a modular pipeline to test agent robustness end-to-end.
|
|
|
104
126
|
| **Generator** | LLM role that creates adversarial prompts to test the target agent |
|
|
105
127
|
| **Judge** | LLM role that evaluates whether attacks bypass safety measures |
|
|
106
128
|
| **Target Agent** | Your AI agent under test across supported frameworks |
|
|
107
|
-
| **Datasets** | Pre-built benchmark presets plus custom HuggingFace/file datasets |
|
|
129
|
+
| **Datasets** | Pre-built benchmark presets plus custom HuggingFace/file/URL JSON datasets |
|
|
108
130
|
|
|
109
131
|
## Supported Frameworks
|
|
110
132
|
|
|
@@ -58,6 +58,27 @@ pip install hackagent
|
|
|
58
58
|
|
|
59
59
|
No API key required: HackAgent works locally out of the box.
|
|
60
60
|
|
|
61
|
+
### Standalone binary (no Python required)
|
|
62
|
+
|
|
63
|
+
Every [GitHub Release](https://github.com/AISecurityLab/hackagent/releases) ships a
|
|
64
|
+
self-contained archive per platform:
|
|
65
|
+
|
|
66
|
+
| Platform | Asset |
|
|
67
|
+
|----------|-------|
|
|
68
|
+
| Linux x86_64 | `hackagent-<version>-linux-x86_64.tar.gz` |
|
|
69
|
+
| macOS arm64 | `hackagent-<version>-macos-arm64.tar.gz` |
|
|
70
|
+
| macOS x86_64 | `hackagent-<version>-macos-x86_64.tar.gz` |
|
|
71
|
+
| Windows x86_64 | `hackagent-<version>-windows-x86_64.zip` |
|
|
72
|
+
|
|
73
|
+
Extract the archive and run the `hackagent` launcher inside it — no Python, `pip`
|
|
74
|
+
or `uv` install needed. Keep the extracted folder intact; the launcher loads the
|
|
75
|
+
libraries next to it.
|
|
76
|
+
|
|
77
|
+
> **Note:** the `WEB` provider drives a real browser through Playwright, whose
|
|
78
|
+
> browser binaries cannot be embedded in the archive (or in the PyPI package).
|
|
79
|
+
> Before using `hackagent web`-based targets, install them once with
|
|
80
|
+
> `playwright install`.
|
|
81
|
+
|
|
61
82
|
|
|
62
83
|
Questions? Join [community discussions](https://github.com/AISecurityLab/hackagent/discussions) or email ais@ai4i.it.
|
|
63
84
|
|
|
@@ -71,7 +92,7 @@ HackAgent uses a modular pipeline to test agent robustness end-to-end.
|
|
|
71
92
|
| **Generator** | LLM role that creates adversarial prompts to test the target agent |
|
|
72
93
|
| **Judge** | LLM role that evaluates whether attacks bypass safety measures |
|
|
73
94
|
| **Target Agent** | Your AI agent under test across supported frameworks |
|
|
74
|
-
| **Datasets** | Pre-built benchmark presets plus custom HuggingFace/file datasets |
|
|
95
|
+
| **Datasets** | Pre-built benchmark presets plus custom HuggingFace/file/URL JSON datasets |
|
|
75
96
|
|
|
76
97
|
## Supported Frameworks
|
|
77
98
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright 2026 - AI4I. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""Version lookup that also works from a frozen (PyInstaller) binary."""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from importlib.metadata import PackageNotFoundError, version as _distribution_version
|
|
8
|
+
|
|
9
|
+
UNKNOWN_VERSION = "unknown"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_version() -> str:
|
|
13
|
+
"""Return the installed ``hackagent`` version.
|
|
14
|
+
|
|
15
|
+
Frozen builds may ship without distribution metadata, so fall back to the
|
|
16
|
+
``HACKAGENT_BUILD_VERSION`` value baked in at packaging time.
|
|
17
|
+
"""
|
|
18
|
+
try:
|
|
19
|
+
return _distribution_version("hackagent")
|
|
20
|
+
except PackageNotFoundError:
|
|
21
|
+
return os.environ.get("HACKAGENT_BUILD_VERSION") or UNKNOWN_VERSION
|
|
@@ -62,13 +62,14 @@ class HackAgent:
|
|
|
62
62
|
base_url: Optional[str] = None,
|
|
63
63
|
api_key: Optional[str] = None,
|
|
64
64
|
raise_on_unexpected_status: bool = False,
|
|
65
|
-
timeout: Optional[float] =
|
|
65
|
+
timeout: Optional[float] = 120.0,
|
|
66
66
|
metadata: Optional[Dict[str, Any]] = None,
|
|
67
67
|
target_config: Optional[Dict[str, Any]] = None,
|
|
68
68
|
adapter_operational_config: Optional[Dict[str, Any]] = None,
|
|
69
69
|
thinking: Optional[bool] = None,
|
|
70
70
|
before_guardrail: Optional[Dict[str, Any]] = None,
|
|
71
71
|
after_guardrail: Optional[Dict[str, Any]] = None,
|
|
72
|
+
backend: Optional[Any] = None,
|
|
72
73
|
):
|
|
73
74
|
"""
|
|
74
75
|
Initializes the HackAgent client and prepares it for interaction.
|
|
@@ -95,8 +96,11 @@ class HackAgent:
|
|
|
95
96
|
raise an exception for any HTTP status codes that are not typically
|
|
96
97
|
expected for a successful operation. Defaults to `False`.
|
|
97
98
|
timeout: The timeout duration in seconds for API requests made by the
|
|
98
|
-
authenticated client. Defaults to
|
|
99
|
-
|
|
99
|
+
authenticated (remote) HackAgent backend client. Defaults to
|
|
100
|
+
`120.0` seconds so requests to a misbehaving/unreachable backend
|
|
101
|
+
fail predictably instead of hanging indefinitely. Pass `None`
|
|
102
|
+
explicitly to opt out and disable the timeout (unbounded wait,
|
|
103
|
+
the previous default behavior).
|
|
100
104
|
metadata: Optional dictionary containing agent-specific metadata.
|
|
101
105
|
target_config: Optional default request settings for the configured
|
|
102
106
|
victim model. This is the preferred place to define target-side
|
|
@@ -107,11 +111,21 @@ class HackAgent:
|
|
|
107
111
|
When set to `False`, requests sent through the target OLLAMA adapter
|
|
108
112
|
include `think: false` to disable thinking output. Ignored for
|
|
109
113
|
non-OLLAMA target agent types.
|
|
114
|
+
backend: Optional pre-built ``StorageBackend`` to persist runs and
|
|
115
|
+
results through. When omitted, a backend is selected from the
|
|
116
|
+
resolved API key (remote) or a default local SQLite database.
|
|
117
|
+
Supplying one lets an embedding host — e.g. the local dashboard
|
|
118
|
+
— reuse its own already-open backend.
|
|
110
119
|
"""
|
|
111
120
|
|
|
112
121
|
resolved_auth_token = utils.resolve_api_token(direct_api_key_param=api_key)
|
|
113
122
|
|
|
114
|
-
if
|
|
123
|
+
if backend is not None:
|
|
124
|
+
self.backend = backend
|
|
125
|
+
logger.info(
|
|
126
|
+
"HackAgent using caller-provided backend %s", type(backend).__name__
|
|
127
|
+
)
|
|
128
|
+
elif resolved_auth_token:
|
|
115
129
|
from hackagent.server.client import AuthenticatedClient
|
|
116
130
|
from hackagent.server.storage.remote import RemoteBackend
|
|
117
131
|
|
|
@@ -320,3 +334,231 @@ class HackAgent:
|
|
|
320
334
|
raise HackAgentError(
|
|
321
335
|
f"An unexpected error occurred during attack: {e}"
|
|
322
336
|
) from e
|
|
337
|
+
|
|
338
|
+
def hack_chain(
|
|
339
|
+
self,
|
|
340
|
+
attacks: Optional[list] = None,
|
|
341
|
+
goals: Optional[list] = None,
|
|
342
|
+
run_config_override: Optional[Dict[str, Any]] = None,
|
|
343
|
+
fail_on_run_error: bool = True,
|
|
344
|
+
escalate_only_mitigated: bool = True,
|
|
345
|
+
_tui_event_bus: Optional[Any] = None,
|
|
346
|
+
) -> list:
|
|
347
|
+
"""
|
|
348
|
+
Runs a sequence of attack strategies against a shared pool of goals.
|
|
349
|
+
|
|
350
|
+
By default (``escalate_only_mitigated=True``) this implements a
|
|
351
|
+
"fallback ladder": every goal starts at ``attacks[0]``. Any goal for
|
|
352
|
+
which the victim's response is judged successful (a jailbreak/
|
|
353
|
+
violation) is considered resolved and is dropped from the chain — it
|
|
354
|
+
is never retried. Any goal that is mitigated (the victim's response
|
|
355
|
+
is judged safe) is carried over and retried with ``attacks[1]``, then
|
|
356
|
+
``attacks[2]``, and so on, until either the goal succeeds or the
|
|
357
|
+
chain is exhausted.
|
|
358
|
+
|
|
359
|
+
With ``escalate_only_mitigated=False``, every goal is instead sent to
|
|
360
|
+
*every* attack in the chain regardless of outcome — useful for
|
|
361
|
+
running several attacks against the same goal set and collecting all
|
|
362
|
+
of their results in one call, rather than escalating only failures.
|
|
363
|
+
|
|
364
|
+
Success/mitigation is determined per goal from the evaluated result
|
|
365
|
+
rows returned by each step (see
|
|
366
|
+
``hackagent.attacks.evaluator.metrics.is_successful_result``): a goal
|
|
367
|
+
is considered successful for a step if *any* of its result rows for
|
|
368
|
+
that step are judged successful.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
attacks: Ordered list of ``attack_config`` dicts, one per chain
|
|
372
|
+
step, using the same shape accepted by :meth:`hack` (each
|
|
373
|
+
must include its own ``attack_type`` and any attack-specific
|
|
374
|
+
settings). Only the *first* entry needs to specify how goals
|
|
375
|
+
are sourced (``goals``, ``dataset`` or ``intents``) unless
|
|
376
|
+
the ``goals`` parameter below is provided; subsequent steps
|
|
377
|
+
automatically receive only the goals still mitigated by the
|
|
378
|
+
previous step (or all goals, see ``escalate_only_mitigated``).
|
|
379
|
+
Defaults to ``None``, which resolves to the Jailbreak
|
|
380
|
+
evaluation campaign's primary attacks, in order — ``h4rm3l``
|
|
381
|
+
→ ``TAP`` → ``PAIR`` (see
|
|
382
|
+
``hackagent.risks.jailbreak.JAILBREAK_PROFILE``). A goal
|
|
383
|
+
source is still required either way, via ``goals`` or a
|
|
384
|
+
``dataset``/``goals``/``intents`` key on the first step.
|
|
385
|
+
goals: Optional explicit list of goal strings to use for the
|
|
386
|
+
whole chain. When provided, it takes precedence over any
|
|
387
|
+
``goals``/``dataset``/``intents`` set on ``attacks[0]``.
|
|
388
|
+
run_config_override: Optional run configuration overrides applied
|
|
389
|
+
to every step, forwarded to :meth:`hack`.
|
|
390
|
+
fail_on_run_error: Forwarded to :meth:`hack` for every step.
|
|
391
|
+
escalate_only_mitigated: When ``True`` (default), a goal only
|
|
392
|
+
moves on to the next attack if it was mitigated at the
|
|
393
|
+
current step — goals that already succeeded are dropped, and
|
|
394
|
+
each goal's final result is either its first success or its
|
|
395
|
+
last (final) attempt. When ``False``, every goal is sent to
|
|
396
|
+
every attack regardless of outcome, and results from *all*
|
|
397
|
+
steps are kept for every goal (nothing is dropped or
|
|
398
|
+
overwritten).
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
A flat list of result rows (same row shape as :meth:`hack`),
|
|
402
|
+
grouped by original goal, in first-seen order. Each row is
|
|
403
|
+
tagged with ``chain_step`` (0-based index into ``attacks``) and
|
|
404
|
+
``chain_attack_type`` identifying which attack produced it.
|
|
405
|
+
|
|
406
|
+
Raises:
|
|
407
|
+
HackAgentError: If ``attacks`` is empty, or a step is missing
|
|
408
|
+
``attack_type``.
|
|
409
|
+
"""
|
|
410
|
+
if attacks is None:
|
|
411
|
+
# Default chain: the Jailbreak evaluation campaign's primary
|
|
412
|
+
# attacks, in campaign order. `technique` strings in the profile
|
|
413
|
+
# (e.g. "TAP", "PAIR") use display casing; `attack_strategies`
|
|
414
|
+
# keys are lowercase, so normalize before use.
|
|
415
|
+
from hackagent.risks.jailbreak import JAILBREAK_PROFILE
|
|
416
|
+
|
|
417
|
+
attacks = [
|
|
418
|
+
{"attack_type": rec.technique.strip().lower()}
|
|
419
|
+
for rec in JAILBREAK_PROFILE.primary_attacks
|
|
420
|
+
]
|
|
421
|
+
|
|
422
|
+
if not attacks:
|
|
423
|
+
raise HackAgentError(
|
|
424
|
+
"'attacks' must be a non-empty list of attack_config dicts."
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
from hackagent.attacks.evaluator.metrics import is_successful_result
|
|
428
|
+
|
|
429
|
+
n_steps = len(attacks)
|
|
430
|
+
remaining_goals: Optional[list] = list(goals) if goals is not None else None
|
|
431
|
+
goal_order: list = list(goals) if goals is not None else []
|
|
432
|
+
final_rows_by_goal: Dict[str, list] = {}
|
|
433
|
+
|
|
434
|
+
for step_index, step_config in enumerate(attacks):
|
|
435
|
+
if remaining_goals is not None and not remaining_goals:
|
|
436
|
+
logger.info(
|
|
437
|
+
"All goals resolved before chain step %d/%d; skipping remaining attack(s).",
|
|
438
|
+
step_index + 1,
|
|
439
|
+
n_steps,
|
|
440
|
+
)
|
|
441
|
+
break
|
|
442
|
+
|
|
443
|
+
attack_type = step_config.get("attack_type")
|
|
444
|
+
if not attack_type:
|
|
445
|
+
raise HackAgentError(
|
|
446
|
+
f"hack_chain step {step_index} is missing 'attack_type'."
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
step_attack_config = dict(step_config)
|
|
450
|
+
if remaining_goals is not None:
|
|
451
|
+
step_attack_config["goals"] = remaining_goals
|
|
452
|
+
step_attack_config.pop("dataset", None)
|
|
453
|
+
step_attack_config.pop("intents", None)
|
|
454
|
+
|
|
455
|
+
logger.info(
|
|
456
|
+
"hack_chain step %d/%d: running '%s' against %s goal(s)",
|
|
457
|
+
step_index + 1,
|
|
458
|
+
n_steps,
|
|
459
|
+
attack_type,
|
|
460
|
+
len(remaining_goals) if remaining_goals is not None else "all",
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
# Each step is executed through the same public `hack()` entry
|
|
464
|
+
# point used everywhere else (CLI/TUI/SDK) — hack_chain adds no
|
|
465
|
+
# parallel execution path, it only decides *which* goals each
|
|
466
|
+
# step receives and tags/regroups the returned rows afterwards.
|
|
467
|
+
step_results = self.hack(
|
|
468
|
+
attack_config=step_attack_config,
|
|
469
|
+
run_config_override=run_config_override,
|
|
470
|
+
fail_on_run_error=fail_on_run_error,
|
|
471
|
+
_tui_event_bus=_tui_event_bus,
|
|
472
|
+
)
|
|
473
|
+
step_rows = (
|
|
474
|
+
step_results
|
|
475
|
+
if isinstance(step_results, list)
|
|
476
|
+
else list(step_results or [])
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
# Group returned rows by their `goal` text — the same lookup
|
|
480
|
+
# convention used throughout the codebase to associate a result
|
|
481
|
+
# back to its goal (e.g. Tracker.get_goal_context_by_goal,
|
|
482
|
+
# TrackingCoordinator, BaseEvaluationStep's MERGE_KEYS). Every
|
|
483
|
+
# technique preserves the original goal string verbatim in its
|
|
484
|
+
# output rows, so this is a plain, reliable lookup — no need to
|
|
485
|
+
# reconstruct or second-guess it.
|
|
486
|
+
#
|
|
487
|
+
# Grouping (rather than checking each row independently) matters
|
|
488
|
+
# because a single goal can have several rows in one step — not
|
|
489
|
+
# from multiple judges (those are already merged into per-judge
|
|
490
|
+
# columns, e.g. eval_hb/eval_jb, on the *same* row, with the
|
|
491
|
+
# majority vote across them resolved by is_successful_result()
|
|
492
|
+
# before we ever see it here) but from multiple distinct attempts
|
|
493
|
+
# at the same goal (e.g. AdvPrefix's several generated prefixes,
|
|
494
|
+
# BoN's N augmented variants, TAP/PAIR's tree branches), each its
|
|
495
|
+
# own (goal, prefix, completion) row. "Mitigated" means *all* of
|
|
496
|
+
# that goal's attempts failed; "succeeded" means *any* attempt
|
|
497
|
+
# did. A flat `for row in step_rows: if not successful: ...`
|
|
498
|
+
# can't express that OR-across-attempts semantics, and would
|
|
499
|
+
# also append the same goal multiple times (once per failing
|
|
500
|
+
# row) without an explicit dedup step.
|
|
501
|
+
rows_by_goal: Dict[str, list] = {}
|
|
502
|
+
for row in step_rows:
|
|
503
|
+
if not isinstance(row, dict):
|
|
504
|
+
continue
|
|
505
|
+
row_goal = row.get("goal", "unknown")
|
|
506
|
+
rows_by_goal.setdefault(row_goal, []).append(
|
|
507
|
+
{**row, "chain_step": step_index, "chain_attack_type": attack_type}
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
if remaining_goals is None:
|
|
511
|
+
# First step resolved its own goals internally (via 'goals',
|
|
512
|
+
# 'dataset' or 'intents' on attacks[0]) — dict insertion
|
|
513
|
+
# order already matches first-seen order, so reuse it
|
|
514
|
+
# directly instead of tracking a parallel order list.
|
|
515
|
+
remaining_goals = list(rows_by_goal.keys())
|
|
516
|
+
goal_order = list(remaining_goals)
|
|
517
|
+
|
|
518
|
+
next_remaining: list = []
|
|
519
|
+
# Iterate the goals we *sent* this step (`remaining_goals`), not
|
|
520
|
+
# `rows_by_goal`/`step_rows` directly: a goal that comes back
|
|
521
|
+
# with zero rows (e.g. the attack errored on it) must still be
|
|
522
|
+
# looked up here — `rows_by_goal.get(goal, [])` defaults to `[]`,
|
|
523
|
+
# and `not any([])` correctly keeps it mitigated/in-chain. If we
|
|
524
|
+
# only walked what actually came back in `step_rows`, a goal
|
|
525
|
+
# with no response would simply never appear and would silently
|
|
526
|
+
# fall out of the chain, as if it had succeeded.
|
|
527
|
+
for goal in remaining_goals:
|
|
528
|
+
goal_rows = rows_by_goal.get(goal, [])
|
|
529
|
+
|
|
530
|
+
if not escalate_only_mitigated:
|
|
531
|
+
# Every goal proceeds to every attack regardless of
|
|
532
|
+
# outcome; keep rows from all steps instead of only the
|
|
533
|
+
# latest attempt.
|
|
534
|
+
final_rows_by_goal.setdefault(goal, []).extend(goal_rows)
|
|
535
|
+
next_remaining.append(goal)
|
|
536
|
+
continue
|
|
537
|
+
|
|
538
|
+
if goal_rows:
|
|
539
|
+
final_rows_by_goal[goal] = goal_rows
|
|
540
|
+
mitigated = not any(is_successful_result(row) for row in goal_rows)
|
|
541
|
+
if mitigated:
|
|
542
|
+
next_remaining.append(goal)
|
|
543
|
+
else:
|
|
544
|
+
logger.info(
|
|
545
|
+
"Goal succeeded at chain step %d ('%s'); dropped from chain: %s",
|
|
546
|
+
step_index + 1,
|
|
547
|
+
attack_type,
|
|
548
|
+
str(goal)[:80],
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
remaining_goals = next_remaining
|
|
552
|
+
|
|
553
|
+
if remaining_goals and escalate_only_mitigated:
|
|
554
|
+
logger.info(
|
|
555
|
+
"%d goal(s) mitigated through the entire chain (%d step(s)): %s",
|
|
556
|
+
len(remaining_goals),
|
|
557
|
+
n_steps,
|
|
558
|
+
", ".join(str(g)[:60] for g in remaining_goals),
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
final_results: list = []
|
|
562
|
+
for goal in goal_order:
|
|
563
|
+
final_results.extend(final_rows_by_goal.get(goal, []))
|
|
564
|
+
return final_results
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import abc
|
|
5
|
-
from typing import Any, Dict
|
|
5
|
+
from typing import Any, Dict, List
|
|
6
|
+
|
|
7
|
+
from hackagent.attacks.types import AttackResult
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class BaseAttack(abc.ABC):
|
|
@@ -64,7 +66,7 @@ class BaseAttack(abc.ABC):
|
|
|
64
66
|
pass
|
|
65
67
|
|
|
66
68
|
@abc.abstractmethod
|
|
67
|
-
def run(self, **kwargs: Any) ->
|
|
69
|
+
def run(self, **kwargs: Any) -> List[AttackResult]:
|
|
68
70
|
"""
|
|
69
71
|
Executes the attack logic.
|
|
70
72
|
|
|
@@ -80,12 +82,7 @@ class BaseAttack(abc.ABC):
|
|
|
80
82
|
- target_model: The model to attack
|
|
81
83
|
|
|
82
84
|
Returns:
|
|
83
|
-
|
|
84
|
-
typically includes:
|
|
85
|
-
- adversarial_examples: Generated adversarial inputs
|
|
86
|
-
- success_metrics: Attack success rates and statistics
|
|
87
|
-
- detailed_results: Comprehensive result data (e.g., pandas DataFrame)
|
|
88
|
-
- attack_report: Summary of attack performance
|
|
85
|
+
A list of :class:`~hackagent.attacks.types.AttackResult` instances.
|
|
89
86
|
|
|
90
87
|
Raises:
|
|
91
88
|
NotImplementedError: If the method is not implemented by a subclass.
|
|
@@ -38,6 +38,7 @@ Usage:
|
|
|
38
38
|
calculate_majority_vote_asr,
|
|
39
39
|
calculate_fleiss_kappa,
|
|
40
40
|
calculate_per_judge_strictness,
|
|
41
|
+
is_successful_result,
|
|
41
42
|
# Server sync
|
|
42
43
|
sync_evaluation_to_server,
|
|
43
44
|
update_single_result,
|
|
@@ -53,6 +54,7 @@ from hackagent.attacks.evaluator.judge_evaluators import (
|
|
|
53
54
|
JailbreakBenchEvaluator,
|
|
54
55
|
NuancedEvaluator,
|
|
55
56
|
OnTopicEvaluator,
|
|
57
|
+
ScorerEvaluator,
|
|
56
58
|
)
|
|
57
59
|
from hackagent.attacks.evaluator.metrics import (
|
|
58
60
|
calculate_confidence_score,
|
|
@@ -60,6 +62,7 @@ from hackagent.attacks.evaluator.metrics import (
|
|
|
60
62
|
calculate_success_rate,
|
|
61
63
|
generate_summary_report,
|
|
62
64
|
group_by_goal,
|
|
65
|
+
is_successful_result,
|
|
63
66
|
calculate_majority_vote_asr,
|
|
64
67
|
calculate_fleiss_kappa,
|
|
65
68
|
calculate_per_judge_strictness,
|
|
@@ -85,6 +88,7 @@ __all__ = [
|
|
|
85
88
|
"HarmBenchEvaluator",
|
|
86
89
|
"HarmBenchVariantEvaluator",
|
|
87
90
|
"OnTopicEvaluator",
|
|
91
|
+
"ScorerEvaluator",
|
|
88
92
|
"EVALUATOR_MAP",
|
|
89
93
|
# Pattern evaluators
|
|
90
94
|
"PatternEvaluator",
|
|
@@ -96,6 +100,7 @@ __all__ = [
|
|
|
96
100
|
"calculate_per_goal_metrics",
|
|
97
101
|
"generate_summary_report",
|
|
98
102
|
"group_by_goal",
|
|
103
|
+
"is_successful_result",
|
|
99
104
|
"calculate_majority_vote_asr",
|
|
100
105
|
"calculate_fleiss_kappa",
|
|
101
106
|
"calculate_per_judge_strictness",
|
|
@@ -186,6 +186,19 @@ class BaseJudgeEvaluator(ABC):
|
|
|
186
186
|
f"Registration key: {self.agent_registration_key}"
|
|
187
187
|
)
|
|
188
188
|
|
|
189
|
+
def _build_messages(self, user_content: str) -> List[Dict[str, str]]:
|
|
190
|
+
"""Build the judge chat messages, honouring a user-defined system prompt.
|
|
191
|
+
|
|
192
|
+
``EvaluatorConfig.system_prompt`` lets users prepend their own system
|
|
193
|
+
message (e.g. a custom rubric or persona) to every judge request.
|
|
194
|
+
"""
|
|
195
|
+
messages: List[Dict[str, str]] = []
|
|
196
|
+
system_prompt = getattr(self.config, "system_prompt", None)
|
|
197
|
+
if isinstance(system_prompt, str) and system_prompt.strip():
|
|
198
|
+
messages.append({"role": "system", "content": system_prompt.strip()})
|
|
199
|
+
messages.append({"role": "user", "content": user_content})
|
|
200
|
+
return messages
|
|
201
|
+
|
|
189
202
|
def _verify_keys(self, data: list[dict], required_keys: list) -> None:
|
|
190
203
|
"""Verify that all required keys exist in each dict."""
|
|
191
204
|
if not data:
|
|
@@ -853,7 +866,7 @@ Answer (yes or no):"""
|
|
|
853
866
|
)
|
|
854
867
|
|
|
855
868
|
return {
|
|
856
|
-
"messages":
|
|
869
|
+
"messages": self._build_messages(feedback_prompt),
|
|
857
870
|
"max_tokens": self.config.max_tokens_eval,
|
|
858
871
|
"temperature": 0.0, # Deterministic for retry
|
|
859
872
|
}
|