hackagent 0.11.0__tar.gz → 0.13.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.13.0}/.gitignore +10 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/PKG-INFO +35 -6
- {hackagent-0.11.0 → hackagent-0.13.0}/README.md +30 -3
- hackagent-0.13.0/hackagent/_version.py +21 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/agent.py +250 -5
- hackagent-0.13.0/hackagent/async_utils.py +29 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/__init__.py +12 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/base.py +5 -8
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/__init__.py +5 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/base.py +161 -50
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/evaluation_step.py +386 -22
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/inline_step_judge.py +41 -9
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/judge_evaluators.py +194 -5
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/metrics.py +15 -4
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/sync.py +6 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/generator/templates.py +39 -9
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/orchestrator.py +408 -162
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/registry.py +4 -0
- hackagent-0.13.0/hackagent/attacks/shared/embedding_utils.py +145 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/prompt_parser.py +11 -4
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/router_factory.py +5 -1
- hackagent-0.13.0/hackagent/attacks/taxonomy.py +185 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/advprefix/attack.py +10 -8
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/advprefix/config.py +10 -6
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/advprefix/generate.py +13 -13
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/attack.py +32 -16
- hackagent-0.11.0/hackagent/attacks/techniques/autodan_turbo/evaluation.py → hackagent-0.13.0/hackagent/attacks/techniques/autodan_turbo/autodan_eval.py +14 -51
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/config.py +25 -4
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/core.py +63 -41
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/lifelong.py +14 -3
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/strategy_library.py +109 -168
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/warm_up.py +14 -3
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/base.py +26 -3
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/baseline/attack.py +16 -12
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/baseline/config.py +1 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/baseline/generation.py +18 -23
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/bon/attack.py +10 -6
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/cipherchat/attack.py +15 -5
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/config.py +45 -4
- hackagent-0.13.0/hackagent/attacks/techniques/crescendo/__init__.py +19 -0
- hackagent-0.13.0/hackagent/attacks/techniques/crescendo/attack.py +906 -0
- hackagent-0.13.0/hackagent/attacks/techniques/crescendo/config.py +116 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/fc/attack.py +23 -9
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/fc/flowchart_renderer.py +561 -14
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/flipattack/attack.py +11 -5
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/h4rm3l/attack.py +52 -5
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/indirect_prompt_injection/attack.py +5 -3
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/indirect_prompt_injection/config.py +2 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/mml/attack.py +13 -5
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pair/attack.py +513 -276
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pair/config.py +28 -6
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pap/attack.py +10 -6
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pap/generation.py +8 -12
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/rag/attack.py +54 -16
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/rag/config.py +4 -0
- hackagent-0.13.0/hackagent/attacks/techniques/rag/jailbreak.py +439 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/static_template/attack.py +33 -22
- hackagent-0.13.0/hackagent/attacks/techniques/static_template/config.py +134 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/static_template/generation.py +9 -2
- hackagent-0.11.0/hackagent/attacks/techniques/static_template/evaluation.py → hackagent-0.13.0/hackagent/attacks/techniques/static_template/static_eval.py +40 -144
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/tap/attack.py +7 -5
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/tap/generation.py +1 -1
- hackagent-0.11.0/hackagent/attacks/techniques/tap/evaluation.py → hackagent-0.13.0/hackagent/attacks/techniques/tap/tap_evaluation.py +14 -19
- hackagent-0.13.0/hackagent/attacks/types.py +190 -0
- hackagent-0.13.0/hackagent/cli/bootstrap.py +96 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/__init__.py +66 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/catalog.py +75 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/chain.py +247 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/config.py +109 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/display.py +237 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/group.py +119 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/info.py +82 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/options.py +82 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/runner.py +175 -0
- hackagent-0.13.0/hackagent/cli/commands/attack/strategies.py +104 -0
- hackagent-0.13.0/hackagent/cli/commands/codex.py +291 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/commands/config.py +27 -42
- hackagent-0.13.0/hackagent/cli/commands/datasets.py +236 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/commands/examples.py +159 -91
- hackagent-0.13.0/hackagent/cli/commands/scan/__init__.py +47 -0
- hackagent-0.11.0/hackagent/cli/commands/scan.py → hackagent-0.13.0/hackagent/cli/commands/scan/command.py +7 -270
- hackagent-0.13.0/hackagent/cli/commands/scan/helpers.py +120 -0
- hackagent-0.13.0/hackagent/cli/commands/scan/quick.py +181 -0
- hackagent-0.13.0/hackagent/cli/commands/web.py +213 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/config.py +54 -29
- hackagent-0.13.0/hackagent/cli/help_page.py +144 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/main.py +71 -234
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/app.py +31 -26
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/__init__.py +50 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/registry.py +41 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/__init__.py +56 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/advprefix.py +197 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/autodan_turbo.py +150 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/baseline.py +104 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/bon.py +131 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/cipherchat.py +215 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/fc.py +65 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/flipattack.py +107 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/h4rm3l.py +100 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/mml.py +121 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/pair.py +142 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/pap.py +139 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/static_template.py +146 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/tap.py +119 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/specs/tfc.py +80 -0
- hackagent-0.13.0/hackagent/cli/tui/attack_specs/types.py +182 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/base.py +1 -1
- hackagent-0.13.0/hackagent/cli/tui/theme.py +187 -0
- hackagent-0.13.0/hackagent/cli/tui/views/attacks/__init__.py +37 -0
- hackagent-0.13.0/hackagent/cli/tui/views/attacks/executor.py +429 -0
- hackagent-0.13.0/hackagent/cli/tui/views/attacks/form.py +531 -0
- hackagent-0.13.0/hackagent/cli/tui/views/attacks/helpers.py +131 -0
- hackagent-0.13.0/hackagent/cli/tui/views/attacks/layout.py +261 -0
- hackagent-0.13.0/hackagent/cli/tui/views/attacks/runner.py +287 -0
- hackagent-0.13.0/hackagent/cli/tui/views/attacks/tab.py +391 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/views/config.py +2 -3
- hackagent-0.13.0/hackagent/cli/tui/views/results/__init__.py +58 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/details.py +377 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/export.py +173 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/formatters/__init__.py +54 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/formatters/datetimes.py +39 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/formatters/http.py +365 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/formatters/run_report.py +183 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/formatters/summaries.py +297 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/formatters/text.py +113 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/formatters/traces.py +351 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/tab.py +400 -0
- hackagent-0.13.0/hackagent/cli/tui/views/results/table.py +212 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/widgets/actions.py +4 -6
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/utils.py +4 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/config.py +83 -4
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/__init__.py +4 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/presets.py +24 -2
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/providers/__init__.py +2 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/providers/huggingface.py +23 -2
- hackagent-0.13.0/hackagent/datasets/providers/url_json.py +151 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/registry.py +131 -37
- hackagent-0.13.0/hackagent/examples/codex/README.md +118 -0
- hackagent-0.13.0/hackagent/examples/codex/hack_codex.py +89 -0
- hackagent-0.13.0/hackagent/examples/codex/hack_ollama.py +77 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/google_adk/jailbreak_eval/hack.py +4 -3
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/google_adk/multi_tool_agent/hack.py +1 -1
- hackagent-0.13.0/hackagent/examples/hermes/README.md +97 -0
- hackagent-0.13.0/hackagent/examples/hermes/hack_hermes.py +94 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/langchain/rag/hack.py +2 -2
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/litellm_multi_provider/demo.py +1 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/ollama/demo.py +24 -30
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/ollama/hack.py +1 -1
- hackagent-0.13.0/hackagent/examples/openai_sdk/db_tool_sandbox/README.md +70 -0
- hackagent-0.13.0/hackagent/examples/openai_sdk/db_tool_sandbox/agent.py +494 -0
- hackagent-0.13.0/hackagent/examples/openai_sdk/db_tool_sandbox/hack.py +101 -0
- hackagent-0.13.0/hackagent/examples/openai_sdk/db_tool_sandbox/sandbox.db +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/multi_judge/run_flipattack_multi_judge.py +1 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/quick_evaluation/run_h4rm3l.py +1 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/rag/README.md +7 -15
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/rag/test_indirect_injection.py +12 -14
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/vllm/hack.py +5 -5
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/__init__.py +2 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/_chat_registration.py +2 -3
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/discovery/scanner.py +9 -3
- hackagent-0.13.0/hackagent/router/providers/codex.py +633 -0
- hackagent-0.13.0/hackagent/router/providers/hermes.py +482 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/providers/web.py +39 -9
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/router.py +443 -1
- hackagent-0.13.0/hackagent/router/tracking/audit.py +72 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/category_classifier.py +2 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/coordinator.py +73 -7
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/decorators.py +25 -12
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/step.py +36 -1
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/tracker.py +79 -49
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/types.py +15 -0
- hackagent-0.13.0/hackagent/server/storage/buckets.py +37 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/storage/local.py +96 -4
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/storage/remote.py +11 -14
- hackagent-0.13.0/hackagent/server/webui/__init__.py +182 -0
- hackagent-0.13.0/hackagent/server/webui/_local_api.py +326 -0
- hackagent-0.13.0/hackagent/server/webui/_proxy.py +105 -0
- hackagent-0.13.0/hackagent/server/webui/_serializers.py +234 -0
- hackagent-0.13.0/hackagent/server/webui/_static.py +86 -0
- hackagent-0.13.0/hackagent/server/webui/static/.gitignore +4 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/pyproject.toml +37 -5
- 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/attacks/techniques/static_template/config.py +0 -87
- hackagent-0.11.0/hackagent/cli/commands/attack.py +0 -1293
- hackagent-0.11.0/hackagent/cli/commands/web.py +0 -150
- 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/__init__.py +0 -23
- hackagent-0.11.0/hackagent/server/dashboard/_analysis_data_mixin.py +0 -716
- hackagent-0.11.0/hackagent/server/dashboard/_api.py +0 -210
- hackagent-0.11.0/hackagent/server/dashboard/_components.py +0 -305
- hackagent-0.11.0/hackagent/server/dashboard/_constants.py +0 -30
- hackagent-0.11.0/hackagent/server/dashboard/_data_mixin.py +0 -800
- hackagent-0.11.0/hackagent/server/dashboard/_helpers.py +0 -137
- hackagent-0.11.0/hackagent/server/dashboard/_layout_mixin.py +0 -832
- hackagent-0.11.0/hackagent/server/dashboard/_page.py +0 -258
- hackagent-0.11.0/hackagent/server/dashboard/_reports_mixin.py +0 -973
- hackagent-0.11.0/hackagent/server/dashboard/_result_detail_mixin.py +0 -799
- hackagent-0.11.0/hackagent/server/dashboard/_run_history_results_mixin.py +0 -1494
- hackagent-0.11.0/hackagent/server/dashboard/_run_results_mixin.py +0 -1284
- hackagent-0.11.0/hackagent/server/dashboard/_runs_mixin.py +0 -985
- hackagent-0.11.0/hackagent/server/dashboard/_tap_trace_mixin.py +0 -723
- hackagent-0.11.0/hackagent/server/dashboard/_trace_analysis_mixin.py +0 -576
- hackagent-0.11.0/hackagent/server/dashboard/_trace_render_mixin.py +0 -1295
- hackagent-0.11.0/hackagent/server/dashboard/app.py +0 -75
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/__init__.py +0 -21
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_advprefix.py +0 -505
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_autodan.py +0 -503
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_bon.py +0 -327
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_fc.py +0 -268
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_generic.py +0 -232
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_mml.py +0 -245
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_pair.py +0 -194
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_pap.py +0 -244
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_shared.py +0 -379
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_static_template.py +0 -359
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_tap.py +0 -404
- hackagent-0.11.0/hackagent/server/dashboard/attack_cards/_tfc.py +0 -209
- hackagent-0.11.0/hackagent/server/dashboard/templates/index.html +0 -1288
- {hackagent-0.11.0 → hackagent-0.13.0}/LICENSE +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/evaluator/pattern_evaluators.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/generator/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/objectives/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/objectives/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/objectives/harmful_behavior.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/objectives/jailbreak.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/objectives/policy_violation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/objectives/rag.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/guardrail.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/progress.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/response_utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/translation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/tui.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/shared/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/advprefix/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/advprefix/completions.py +0 -0
- /hackagent-0.11.0/hackagent/attacks/techniques/advprefix/evaluation.py → /hackagent-0.13.0/hackagent/attacks/techniques/advprefix/eval_pipeline.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/advprefix/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/dashboard_tracing.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/log_styles.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/autodan_turbo/summarizer.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/baseline/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/bon/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/bon/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/bon/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/cipherchat/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/cipherchat/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/cipherchat/encode_experts.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/cipherchat/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/cipherchat/prompts_and_demonstrations.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/fc/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/fc/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/fc/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/fc/prompts.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/flipattack/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/flipattack/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/flipattack/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/h4rm3l/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/h4rm3l/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/h4rm3l/decorators.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/h4rm3l/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/mml/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/mml/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/mml/generation.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/mml/image_encoder.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/mml/prompts.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pair/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pap/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pap/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/pap/taxonomy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/rag/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/static_template/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/tap/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/attacks/techniques/tap/config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/commands/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/commands/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/commands/claude.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/commands/results.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/events.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/logger.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/views/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/views/agents.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/widgets/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/widgets/clipboard.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/cli/tui/widgets/logs.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/intents.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/omnisafebench/dataset.json +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/datasets/providers/file.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/errors.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/claude/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/claude/hack_claude.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/claude/hack_ollama.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/google_adk/jailbreak_eval/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/google_adk/jailbreak_eval/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/google_adk/multi_tool_agent/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/google_adk/multi_tool_agent/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/langchain/rag/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/langchain/rag/agent_client.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/langchain/rag/agent_server.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/langchain/rag/ingest.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/langchain/rag/policies.pdf +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/langchain/rag/read_db.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/litellm_multi_provider/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/litellm_multi_provider/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/ollama/local.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/multi_judge/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/confidential/db_credentials.txt +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/quick_evaluation/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/rag/agent_server.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/rag/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/rag/ingest.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/openai_sdk/rag/policies.pdf +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/rag/.gitignore +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/rag/test_data/gender_studies_overview.txt +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/web/README.md +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/web/hack.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/examples/web/plan.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/logger.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/craft_adversarial_data/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/craft_adversarial_data/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/craft_adversarial_data/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/craft_adversarial_data/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/credential_exposure/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/credential_exposure/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/credential_exposure/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/credential_exposure/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/excessive_agency/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/excessive_agency/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/excessive_agency/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/excessive_agency/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/input_manipulation_attack/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/input_manipulation_attack/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/input_manipulation_attack/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/input_manipulation_attack/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/jailbreak/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/jailbreak/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/jailbreak/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/jailbreak/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/malicious_tool_invocation/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/malicious_tool_invocation/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/malicious_tool_invocation/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/malicious_tool_invocation/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/misinformation/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/misinformation/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/misinformation/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/misinformation/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/model_evasion/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/model_evasion/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/model_evasion/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/model_evasion/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/profile_helpers.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/profile_types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/prompt_injection/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/prompt_injection/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/prompt_injection/templates.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/prompt_injection/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/prompt_injection/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/public_facing_application_exploitation/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/public_facing_application_exploitation/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/public_facing_application_exploitation/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/public_facing_application_exploitation/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/registry.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/sensitive_information_disclosure/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/sensitive_information_disclosure/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/sensitive_information_disclosure/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/sensitive_information_disclosure/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/system_prompt_leakage/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/system_prompt_leakage/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/system_prompt_leakage/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/system_prompt_leakage/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/vector_embedding_weaknesses_exploit/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/vector_embedding_weaknesses_exploit/profile.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/vector_embedding_weaknesses_exploit/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/risks/vector_embedding_weaknesses_exploit/vulnerabilities.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/agent.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/discovery/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/discovery/browser.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/envelope.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/provider_config.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/providers/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/providers/adk.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/providers/claude.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/context.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking/utils.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/router/tracking_logger.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/agent/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/agent/agent_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/agent/agent_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/agent/agent_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/agent/agent_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/agent/agent_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/agent/agent_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/apilogs/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/apilogs/apilogs_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/apilogs/apilogs_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/apilogs/apilogs_summary_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/attack/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/attack/attack_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/attack/attack_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/attack/attack_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/attack/attack_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/attack/attack_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/attack/attack_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/checkout/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/checkout/checkout_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/generate/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/generate/v1_chat_completions_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/judge/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/judge/judge_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/key/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/key/key_context_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/key/key_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/key/key_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/key/key_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/key/key_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/models.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/organization_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/organization_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/organization_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/organization_me_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/organization_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/organization_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/organization/organization_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/result_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/result_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/result_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/result_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/result_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/result_trace_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/result/result_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_result_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_run_tests_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/run/run_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/scripts/generate.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/scripts/generate.sh +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/scripts/openapi-python-client.yaml +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_create.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_destroy.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_list.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_me_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_me_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_partial_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_retrieve.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/api/user/user_update.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/client.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/errors.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/storage/__init__.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/storage/base.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/storage/enums.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.0}/hackagent/server/types.py +0 -0
- {hackagent-0.11.0 → hackagent-0.13.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,10 @@ dmypy.json
|
|
|
139
142
|
tests/e2e/attacks/
|
|
140
143
|
|
|
141
144
|
.tmp
|
|
145
|
+
|
|
146
|
+
# pytest-textual-snapshot report artifact
|
|
147
|
+
snapshot_report.html
|
|
148
|
+
|
|
149
|
+
# Web UI bundle (built by scripts/build_webui.sh)
|
|
150
|
+
hackagent/server/webui/static/*
|
|
151
|
+
!hackagent/server/webui/static/.gitignore
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: hackagent
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.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,9 +18,9 @@ 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.3
|
|
21
22
|
Requires-Dist: httpx>=0.27.0
|
|
22
23
|
Requires-Dist: litellm>=1.69.2
|
|
23
|
-
Requires-Dist: nicegui>=2.0
|
|
24
24
|
Requires-Dist: openai>=1.0.0
|
|
25
25
|
Requires-Dist: pillow>=10.0.0
|
|
26
26
|
Requires-Dist: playwright>=1.40
|
|
@@ -29,6 +29,8 @@ Requires-Dist: python-dateutil>=2.8.0
|
|
|
29
29
|
Requires-Dist: pyyaml>=6.0.0
|
|
30
30
|
Requires-Dist: rich>=14.0.0
|
|
31
31
|
Requires-Dist: textual>=1.0.0
|
|
32
|
+
Provides-Extra: web
|
|
33
|
+
Requires-Dist: hackagent-webui<1.0,>=0.2; extra == 'web'
|
|
32
34
|
Description-Content-Type: text/markdown
|
|
33
35
|
|
|
34
36
|
<div align="center">
|
|
@@ -91,6 +93,27 @@ pip install hackagent
|
|
|
91
93
|
|
|
92
94
|
No API key required: HackAgent works locally out of the box.
|
|
93
95
|
|
|
96
|
+
### Standalone binary (no Python required)
|
|
97
|
+
|
|
98
|
+
Every [GitHub Release](https://github.com/AISecurityLab/hackagent/releases) ships a
|
|
99
|
+
self-contained archive per platform:
|
|
100
|
+
|
|
101
|
+
| Platform | Asset |
|
|
102
|
+
|----------|-------|
|
|
103
|
+
| Linux x86_64 | `hackagent-<version>-linux-x86_64.tar.gz` |
|
|
104
|
+
| macOS arm64 | `hackagent-<version>-macos-arm64.tar.gz` |
|
|
105
|
+
| macOS x86_64 | `hackagent-<version>-macos-x86_64.tar.gz` |
|
|
106
|
+
| Windows x86_64 | `hackagent-<version>-windows-x86_64.zip` |
|
|
107
|
+
|
|
108
|
+
Extract the archive and run the `hackagent` launcher inside it — no Python, `pip`
|
|
109
|
+
or `uv` install needed. Keep the extracted folder intact; the launcher loads the
|
|
110
|
+
libraries next to it.
|
|
111
|
+
|
|
112
|
+
> **Note:** the `WEB` provider drives a real browser through Playwright, whose
|
|
113
|
+
> browser binaries cannot be embedded in the archive (or in the PyPI package).
|
|
114
|
+
> Before using `hackagent web`-based targets, install them once with
|
|
115
|
+
> `playwright install`.
|
|
116
|
+
|
|
94
117
|
|
|
95
118
|
Questions? Join [community discussions](https://github.com/AISecurityLab/hackagent/discussions) or email ais@ai4i.it.
|
|
96
119
|
|
|
@@ -104,7 +127,7 @@ HackAgent uses a modular pipeline to test agent robustness end-to-end.
|
|
|
104
127
|
| **Generator** | LLM role that creates adversarial prompts to test the target agent |
|
|
105
128
|
| **Judge** | LLM role that evaluates whether attacks bypass safety measures |
|
|
106
129
|
| **Target Agent** | Your AI agent under test across supported frameworks |
|
|
107
|
-
| **Datasets** | Pre-built benchmark presets plus custom HuggingFace/file datasets |
|
|
130
|
+
| **Datasets** | Pre-built benchmark presets plus custom HuggingFace/file/URL JSON datasets |
|
|
108
131
|
|
|
109
132
|
## Supported Frameworks
|
|
110
133
|
|
|
@@ -117,14 +140,20 @@ HackAgent uses a modular pipeline to test agent robustness end-to-end.
|
|
|
117
140
|
|
|
118
141
|
HackAgent supports both local and remote reporting.
|
|
119
142
|
|
|
120
|
-
- Local mode stores test results in SQLite
|
|
143
|
+
- Local mode stores test results in SQLite, readable offline.
|
|
121
144
|
- Cloud mode syncs runs to the HackAgent remote platform when an API key is configured.
|
|
122
145
|
|
|
146
|
+
`hackagent web` serves the HackAgent dashboard — the same app as
|
|
147
|
+
[app.hackagent.dev](https://app.hackagent.dev) — from your own machine, against
|
|
148
|
+
your cloud data when an API key is configured and against the local SQLite
|
|
149
|
+
database (read-only) when it is not. Your API key stays in the CLI process and
|
|
150
|
+
is never exposed to the browser.
|
|
151
|
+
|
|
123
152
|
```bash
|
|
124
153
|
hackagent web
|
|
125
154
|
```
|
|
126
155
|
|
|
127
|
-
|
|
156
|
+
Install it with `pip install 'hackagent[web]'`; see the [web command docs](docs/docs/cli/web.md) for modes and options.
|
|
128
157
|
|
|
129
158
|
## Responsible Use
|
|
130
159
|
|
|
@@ -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
|
|
|
@@ -84,14 +105,20 @@ HackAgent uses a modular pipeline to test agent robustness end-to-end.
|
|
|
84
105
|
|
|
85
106
|
HackAgent supports both local and remote reporting.
|
|
86
107
|
|
|
87
|
-
- Local mode stores test results in SQLite
|
|
108
|
+
- Local mode stores test results in SQLite, readable offline.
|
|
88
109
|
- Cloud mode syncs runs to the HackAgent remote platform when an API key is configured.
|
|
89
110
|
|
|
111
|
+
`hackagent web` serves the HackAgent dashboard — the same app as
|
|
112
|
+
[app.hackagent.dev](https://app.hackagent.dev) — from your own machine, against
|
|
113
|
+
your cloud data when an API key is configured and against the local SQLite
|
|
114
|
+
database (read-only) when it is not. Your API key stays in the CLI process and
|
|
115
|
+
is never exposed to the browser.
|
|
116
|
+
|
|
90
117
|
```bash
|
|
91
118
|
hackagent web
|
|
92
119
|
```
|
|
93
120
|
|
|
94
|
-
|
|
121
|
+
Install it with `pip install 'hackagent[web]'`; see the [web command docs](docs/docs/cli/web.md) for modes and options.
|
|
95
122
|
|
|
96
123
|
## Responsible Use
|
|
97
124
|
|
|
@@ -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
|
|
@@ -5,6 +5,7 @@ from hackagent.logger import get_logger
|
|
|
5
5
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
|
6
6
|
|
|
7
7
|
from hackagent import utils
|
|
8
|
+
from hackagent.config import resolve_remote_base_url
|
|
8
9
|
from hackagent.errors import HackAgentError
|
|
9
10
|
from hackagent.router import AgentRouter
|
|
10
11
|
from hackagent.router.types import AgentTypeEnum
|
|
@@ -62,13 +63,14 @@ class HackAgent:
|
|
|
62
63
|
base_url: Optional[str] = None,
|
|
63
64
|
api_key: Optional[str] = None,
|
|
64
65
|
raise_on_unexpected_status: bool = False,
|
|
65
|
-
timeout: Optional[float] =
|
|
66
|
+
timeout: Optional[float] = 120.0,
|
|
66
67
|
metadata: Optional[Dict[str, Any]] = None,
|
|
67
68
|
target_config: Optional[Dict[str, Any]] = None,
|
|
68
69
|
adapter_operational_config: Optional[Dict[str, Any]] = None,
|
|
69
70
|
thinking: Optional[bool] = None,
|
|
70
71
|
before_guardrail: Optional[Dict[str, Any]] = None,
|
|
71
72
|
after_guardrail: Optional[Dict[str, Any]] = None,
|
|
73
|
+
backend: Optional[Any] = None,
|
|
72
74
|
):
|
|
73
75
|
"""
|
|
74
76
|
Initializes the HackAgent client and prepares it for interaction.
|
|
@@ -95,8 +97,11 @@ class HackAgent:
|
|
|
95
97
|
raise an exception for any HTTP status codes that are not typically
|
|
96
98
|
expected for a successful operation. Defaults to `False`.
|
|
97
99
|
timeout: The timeout duration in seconds for API requests made by the
|
|
98
|
-
authenticated client. Defaults to
|
|
99
|
-
|
|
100
|
+
authenticated (remote) HackAgent backend client. Defaults to
|
|
101
|
+
`120.0` seconds so requests to a misbehaving/unreachable backend
|
|
102
|
+
fail predictably instead of hanging indefinitely. Pass `None`
|
|
103
|
+
explicitly to opt out and disable the timeout (unbounded wait,
|
|
104
|
+
the previous default behavior).
|
|
100
105
|
metadata: Optional dictionary containing agent-specific metadata.
|
|
101
106
|
target_config: Optional default request settings for the configured
|
|
102
107
|
victim model. This is the preferred place to define target-side
|
|
@@ -107,15 +112,25 @@ class HackAgent:
|
|
|
107
112
|
When set to `False`, requests sent through the target OLLAMA adapter
|
|
108
113
|
include `think: false` to disable thinking output. Ignored for
|
|
109
114
|
non-OLLAMA target agent types.
|
|
115
|
+
backend: Optional pre-built ``StorageBackend`` to persist runs and
|
|
116
|
+
results through. When omitted, a backend is selected from the
|
|
117
|
+
resolved API key (remote) or a default local SQLite database.
|
|
118
|
+
Supplying one lets an embedding host — e.g. the local dashboard
|
|
119
|
+
— reuse its own already-open backend.
|
|
110
120
|
"""
|
|
111
121
|
|
|
112
122
|
resolved_auth_token = utils.resolve_api_token(direct_api_key_param=api_key)
|
|
113
123
|
|
|
114
|
-
if
|
|
124
|
+
if backend is not None:
|
|
125
|
+
self.backend = backend
|
|
126
|
+
logger.info(
|
|
127
|
+
"HackAgent using caller-provided backend %s", type(backend).__name__
|
|
128
|
+
)
|
|
129
|
+
elif resolved_auth_token:
|
|
115
130
|
from hackagent.server.client import AuthenticatedClient
|
|
116
131
|
from hackagent.server.storage.remote import RemoteBackend
|
|
117
132
|
|
|
118
|
-
_base_url = base_url or
|
|
133
|
+
_base_url = base_url or resolve_remote_base_url()
|
|
119
134
|
_client = AuthenticatedClient(
|
|
120
135
|
base_url=_base_url,
|
|
121
136
|
token=resolved_auth_token,
|
|
@@ -208,6 +223,7 @@ class HackAgent:
|
|
|
208
223
|
StaticTemplateOrchestrator,
|
|
209
224
|
BoNOrchestrator,
|
|
210
225
|
CipherChatOrchestrator,
|
|
226
|
+
CrescendoOrchestrator,
|
|
211
227
|
FCOrchestrator,
|
|
212
228
|
tFCOrchestrator,
|
|
213
229
|
H4rm3lOrchestrator,
|
|
@@ -226,6 +242,7 @@ class HackAgent:
|
|
|
226
242
|
"static_template": StaticTemplateOrchestrator(hackagent_agent=self),
|
|
227
243
|
"bon": BoNOrchestrator(hackagent_agent=self),
|
|
228
244
|
"cipherchat": CipherChatOrchestrator(hackagent_agent=self),
|
|
245
|
+
"crescendo": CrescendoOrchestrator(hackagent_agent=self),
|
|
229
246
|
"fc": FCOrchestrator(hackagent_agent=self),
|
|
230
247
|
"tfc": tFCOrchestrator(hackagent_agent=self),
|
|
231
248
|
"pair": PAIROrchestrator(hackagent_agent=self),
|
|
@@ -320,3 +337,231 @@ class HackAgent:
|
|
|
320
337
|
raise HackAgentError(
|
|
321
338
|
f"An unexpected error occurred during attack: {e}"
|
|
322
339
|
) from e
|
|
340
|
+
|
|
341
|
+
def hack_chain(
|
|
342
|
+
self,
|
|
343
|
+
attacks: Optional[list] = None,
|
|
344
|
+
goals: Optional[list] = None,
|
|
345
|
+
run_config_override: Optional[Dict[str, Any]] = None,
|
|
346
|
+
fail_on_run_error: bool = True,
|
|
347
|
+
escalate_only_mitigated: bool = True,
|
|
348
|
+
_tui_event_bus: Optional[Any] = None,
|
|
349
|
+
) -> list:
|
|
350
|
+
"""
|
|
351
|
+
Runs a sequence of attack strategies against a shared pool of goals.
|
|
352
|
+
|
|
353
|
+
By default (``escalate_only_mitigated=True``) this implements a
|
|
354
|
+
"fallback ladder": every goal starts at ``attacks[0]``. Any goal for
|
|
355
|
+
which the victim's response is judged successful (a jailbreak/
|
|
356
|
+
violation) is considered resolved and is dropped from the chain — it
|
|
357
|
+
is never retried. Any goal that is mitigated (the victim's response
|
|
358
|
+
is judged safe) is carried over and retried with ``attacks[1]``, then
|
|
359
|
+
``attacks[2]``, and so on, until either the goal succeeds or the
|
|
360
|
+
chain is exhausted.
|
|
361
|
+
|
|
362
|
+
With ``escalate_only_mitigated=False``, every goal is instead sent to
|
|
363
|
+
*every* attack in the chain regardless of outcome — useful for
|
|
364
|
+
running several attacks against the same goal set and collecting all
|
|
365
|
+
of their results in one call, rather than escalating only failures.
|
|
366
|
+
|
|
367
|
+
Success/mitigation is determined per goal from the evaluated result
|
|
368
|
+
rows returned by each step (see
|
|
369
|
+
``hackagent.attacks.evaluator.metrics.is_successful_result``): a goal
|
|
370
|
+
is considered successful for a step if *any* of its result rows for
|
|
371
|
+
that step are judged successful.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
attacks: Ordered list of ``attack_config`` dicts, one per chain
|
|
375
|
+
step, using the same shape accepted by :meth:`hack` (each
|
|
376
|
+
must include its own ``attack_type`` and any attack-specific
|
|
377
|
+
settings). Only the *first* entry needs to specify how goals
|
|
378
|
+
are sourced (``goals``, ``dataset`` or ``intents``) unless
|
|
379
|
+
the ``goals`` parameter below is provided; subsequent steps
|
|
380
|
+
automatically receive only the goals still mitigated by the
|
|
381
|
+
previous step (or all goals, see ``escalate_only_mitigated``).
|
|
382
|
+
Defaults to ``None``, which resolves to the Jailbreak
|
|
383
|
+
evaluation campaign's primary attacks, in order — ``h4rm3l``
|
|
384
|
+
→ ``TAP`` → ``PAIR`` (see
|
|
385
|
+
``hackagent.risks.jailbreak.JAILBREAK_PROFILE``). A goal
|
|
386
|
+
source is still required either way, via ``goals`` or a
|
|
387
|
+
``dataset``/``goals``/``intents`` key on the first step.
|
|
388
|
+
goals: Optional explicit list of goal strings to use for the
|
|
389
|
+
whole chain. When provided, it takes precedence over any
|
|
390
|
+
``goals``/``dataset``/``intents`` set on ``attacks[0]``.
|
|
391
|
+
run_config_override: Optional run configuration overrides applied
|
|
392
|
+
to every step, forwarded to :meth:`hack`.
|
|
393
|
+
fail_on_run_error: Forwarded to :meth:`hack` for every step.
|
|
394
|
+
escalate_only_mitigated: When ``True`` (default), a goal only
|
|
395
|
+
moves on to the next attack if it was mitigated at the
|
|
396
|
+
current step — goals that already succeeded are dropped, and
|
|
397
|
+
each goal's final result is either its first success or its
|
|
398
|
+
last (final) attempt. When ``False``, every goal is sent to
|
|
399
|
+
every attack regardless of outcome, and results from *all*
|
|
400
|
+
steps are kept for every goal (nothing is dropped or
|
|
401
|
+
overwritten).
|
|
402
|
+
|
|
403
|
+
Returns:
|
|
404
|
+
A flat list of result rows (same row shape as :meth:`hack`),
|
|
405
|
+
grouped by original goal, in first-seen order. Each row is
|
|
406
|
+
tagged with ``chain_step`` (0-based index into ``attacks``) and
|
|
407
|
+
``chain_attack_type`` identifying which attack produced it.
|
|
408
|
+
|
|
409
|
+
Raises:
|
|
410
|
+
HackAgentError: If ``attacks`` is empty, or a step is missing
|
|
411
|
+
``attack_type``.
|
|
412
|
+
"""
|
|
413
|
+
if attacks is None:
|
|
414
|
+
# Default chain: the Jailbreak evaluation campaign's primary
|
|
415
|
+
# attacks, in campaign order. `technique` strings in the profile
|
|
416
|
+
# (e.g. "TAP", "PAIR") use display casing; `attack_strategies`
|
|
417
|
+
# keys are lowercase, so normalize before use.
|
|
418
|
+
from hackagent.risks.jailbreak import JAILBREAK_PROFILE
|
|
419
|
+
|
|
420
|
+
attacks = [
|
|
421
|
+
{"attack_type": rec.technique.strip().lower()}
|
|
422
|
+
for rec in JAILBREAK_PROFILE.primary_attacks
|
|
423
|
+
]
|
|
424
|
+
|
|
425
|
+
if not attacks:
|
|
426
|
+
raise HackAgentError(
|
|
427
|
+
"'attacks' must be a non-empty list of attack_config dicts."
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
from hackagent.attacks.evaluator.metrics import is_successful_result
|
|
431
|
+
|
|
432
|
+
n_steps = len(attacks)
|
|
433
|
+
remaining_goals: Optional[list] = list(goals) if goals is not None else None
|
|
434
|
+
goal_order: list = list(goals) if goals is not None else []
|
|
435
|
+
final_rows_by_goal: Dict[str, list] = {}
|
|
436
|
+
|
|
437
|
+
for step_index, step_config in enumerate(attacks):
|
|
438
|
+
if remaining_goals is not None and not remaining_goals:
|
|
439
|
+
logger.info(
|
|
440
|
+
"All goals resolved before chain step %d/%d; skipping remaining attack(s).",
|
|
441
|
+
step_index + 1,
|
|
442
|
+
n_steps,
|
|
443
|
+
)
|
|
444
|
+
break
|
|
445
|
+
|
|
446
|
+
attack_type = step_config.get("attack_type")
|
|
447
|
+
if not attack_type:
|
|
448
|
+
raise HackAgentError(
|
|
449
|
+
f"hack_chain step {step_index} is missing 'attack_type'."
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
step_attack_config = dict(step_config)
|
|
453
|
+
if remaining_goals is not None:
|
|
454
|
+
step_attack_config["goals"] = remaining_goals
|
|
455
|
+
step_attack_config.pop("dataset", None)
|
|
456
|
+
step_attack_config.pop("intents", None)
|
|
457
|
+
|
|
458
|
+
logger.info(
|
|
459
|
+
"hack_chain step %d/%d: running '%s' against %s goal(s)",
|
|
460
|
+
step_index + 1,
|
|
461
|
+
n_steps,
|
|
462
|
+
attack_type,
|
|
463
|
+
len(remaining_goals) if remaining_goals is not None else "all",
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
# Each step is executed through the same public `hack()` entry
|
|
467
|
+
# point used everywhere else (CLI/TUI/SDK) — hack_chain adds no
|
|
468
|
+
# parallel execution path, it only decides *which* goals each
|
|
469
|
+
# step receives and tags/regroups the returned rows afterwards.
|
|
470
|
+
step_results = self.hack(
|
|
471
|
+
attack_config=step_attack_config,
|
|
472
|
+
run_config_override=run_config_override,
|
|
473
|
+
fail_on_run_error=fail_on_run_error,
|
|
474
|
+
_tui_event_bus=_tui_event_bus,
|
|
475
|
+
)
|
|
476
|
+
step_rows = (
|
|
477
|
+
step_results
|
|
478
|
+
if isinstance(step_results, list)
|
|
479
|
+
else list(step_results or [])
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
# Group returned rows by their `goal` text — the same lookup
|
|
483
|
+
# convention used throughout the codebase to associate a result
|
|
484
|
+
# back to its goal (e.g. Tracker.get_goal_context_by_goal,
|
|
485
|
+
# TrackingCoordinator, BaseEvaluationStep's MERGE_KEYS). Every
|
|
486
|
+
# technique preserves the original goal string verbatim in its
|
|
487
|
+
# output rows, so this is a plain, reliable lookup — no need to
|
|
488
|
+
# reconstruct or second-guess it.
|
|
489
|
+
#
|
|
490
|
+
# Grouping (rather than checking each row independently) matters
|
|
491
|
+
# because a single goal can have several rows in one step — not
|
|
492
|
+
# from multiple judges (those are already merged into per-judge
|
|
493
|
+
# columns, e.g. eval_hb/eval_jb, on the *same* row, with the
|
|
494
|
+
# majority vote across them resolved by is_successful_result()
|
|
495
|
+
# before we ever see it here) but from multiple distinct attempts
|
|
496
|
+
# at the same goal (e.g. AdvPrefix's several generated prefixes,
|
|
497
|
+
# BoN's N augmented variants, TAP/PAIR's tree branches), each its
|
|
498
|
+
# own (goal, prefix, completion) row. "Mitigated" means *all* of
|
|
499
|
+
# that goal's attempts failed; "succeeded" means *any* attempt
|
|
500
|
+
# did. A flat `for row in step_rows: if not successful: ...`
|
|
501
|
+
# can't express that OR-across-attempts semantics, and would
|
|
502
|
+
# also append the same goal multiple times (once per failing
|
|
503
|
+
# row) without an explicit dedup step.
|
|
504
|
+
rows_by_goal: Dict[str, list] = {}
|
|
505
|
+
for row in step_rows:
|
|
506
|
+
if not isinstance(row, dict):
|
|
507
|
+
continue
|
|
508
|
+
row_goal = row.get("goal", "unknown")
|
|
509
|
+
rows_by_goal.setdefault(row_goal, []).append(
|
|
510
|
+
{**row, "chain_step": step_index, "chain_attack_type": attack_type}
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
if remaining_goals is None:
|
|
514
|
+
# First step resolved its own goals internally (via 'goals',
|
|
515
|
+
# 'dataset' or 'intents' on attacks[0]) — dict insertion
|
|
516
|
+
# order already matches first-seen order, so reuse it
|
|
517
|
+
# directly instead of tracking a parallel order list.
|
|
518
|
+
remaining_goals = list(rows_by_goal.keys())
|
|
519
|
+
goal_order = list(remaining_goals)
|
|
520
|
+
|
|
521
|
+
next_remaining: list = []
|
|
522
|
+
# Iterate the goals we *sent* this step (`remaining_goals`), not
|
|
523
|
+
# `rows_by_goal`/`step_rows` directly: a goal that comes back
|
|
524
|
+
# with zero rows (e.g. the attack errored on it) must still be
|
|
525
|
+
# looked up here — `rows_by_goal.get(goal, [])` defaults to `[]`,
|
|
526
|
+
# and `not any([])` correctly keeps it mitigated/in-chain. If we
|
|
527
|
+
# only walked what actually came back in `step_rows`, a goal
|
|
528
|
+
# with no response would simply never appear and would silently
|
|
529
|
+
# fall out of the chain, as if it had succeeded.
|
|
530
|
+
for goal in remaining_goals:
|
|
531
|
+
goal_rows = rows_by_goal.get(goal, [])
|
|
532
|
+
|
|
533
|
+
if not escalate_only_mitigated:
|
|
534
|
+
# Every goal proceeds to every attack regardless of
|
|
535
|
+
# outcome; keep rows from all steps instead of only the
|
|
536
|
+
# latest attempt.
|
|
537
|
+
final_rows_by_goal.setdefault(goal, []).extend(goal_rows)
|
|
538
|
+
next_remaining.append(goal)
|
|
539
|
+
continue
|
|
540
|
+
|
|
541
|
+
if goal_rows:
|
|
542
|
+
final_rows_by_goal[goal] = goal_rows
|
|
543
|
+
mitigated = not any(is_successful_result(row) for row in goal_rows)
|
|
544
|
+
if mitigated:
|
|
545
|
+
next_remaining.append(goal)
|
|
546
|
+
else:
|
|
547
|
+
logger.info(
|
|
548
|
+
"Goal succeeded at chain step %d ('%s'); dropped from chain: %s",
|
|
549
|
+
step_index + 1,
|
|
550
|
+
attack_type,
|
|
551
|
+
str(goal)[:80],
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
remaining_goals = next_remaining
|
|
555
|
+
|
|
556
|
+
if remaining_goals and escalate_only_mitigated:
|
|
557
|
+
logger.info(
|
|
558
|
+
"%d goal(s) mitigated through the entire chain (%d step(s)): %s",
|
|
559
|
+
len(remaining_goals),
|
|
560
|
+
n_steps,
|
|
561
|
+
", ".join(str(g)[:60] for g in remaining_goals),
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
final_results: list = []
|
|
565
|
+
for goal in goal_order:
|
|
566
|
+
final_results.extend(final_rows_by_goal.get(goal, []))
|
|
567
|
+
return final_results
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Copyright 2026 - AI4I. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""Small shared helpers for bridging synchronous APIs to asyncio internals."""
|
|
5
|
+
|
|
6
|
+
import asyncio
|
|
7
|
+
from typing import Awaitable, Callable, TypeVar
|
|
8
|
+
|
|
9
|
+
T = TypeVar("T")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def run_coroutine_blocking(coro_factory: Callable[[], Awaitable[T]]) -> T:
|
|
13
|
+
"""Run a coroutine factory from synchronous code safely.
|
|
14
|
+
|
|
15
|
+
Uses ``asyncio.run`` directly when no event loop is running yet (the
|
|
16
|
+
common case for a synchronous public API). ``asyncio.run`` cannot be
|
|
17
|
+
nested, so when called from inside an already-running loop (e.g.
|
|
18
|
+
notebooks, async callers) a dedicated bridge thread runs its own loop
|
|
19
|
+
instead, giving synchronous callers the same behavior either way.
|
|
20
|
+
"""
|
|
21
|
+
try:
|
|
22
|
+
asyncio.get_running_loop()
|
|
23
|
+
except RuntimeError:
|
|
24
|
+
return asyncio.run(coro_factory())
|
|
25
|
+
|
|
26
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
27
|
+
|
|
28
|
+
with ThreadPoolExecutor(max_workers=1) as pool:
|
|
29
|
+
return pool.submit(lambda: asyncio.run(coro_factory())).result()
|
|
@@ -41,9 +41,20 @@ from .registry import (
|
|
|
41
41
|
FlipAttackOrchestrator,
|
|
42
42
|
TAPOrchestrator,
|
|
43
43
|
)
|
|
44
|
+
from .taxonomy import (
|
|
45
|
+
ATTACK_TAXONOMY,
|
|
46
|
+
AttackCategory,
|
|
47
|
+
AttackTag,
|
|
48
|
+
AttackTaxonomy,
|
|
49
|
+
get_attack_taxonomy,
|
|
50
|
+
)
|
|
44
51
|
|
|
45
52
|
__all__ = [
|
|
46
53
|
"ATTACK_REGISTRY",
|
|
54
|
+
"ATTACK_TAXONOMY",
|
|
55
|
+
"AttackCategory",
|
|
56
|
+
"AttackTag",
|
|
57
|
+
"AttackTaxonomy",
|
|
47
58
|
"AdvPrefixOrchestrator",
|
|
48
59
|
"AutoDANTurboOrchestrator",
|
|
49
60
|
"BaselineOrchestrator",
|
|
@@ -52,4 +63,5 @@ __all__ = [
|
|
|
52
63
|
"PAIROrchestrator",
|
|
53
64
|
"FlipAttackOrchestrator",
|
|
54
65
|
"TAPOrchestrator",
|
|
66
|
+
"get_attack_taxonomy",
|
|
55
67
|
]
|
|
@@ -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",
|