hackagent 0.13.0__tar.gz → 0.14.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.13.0 → hackagent-0.14.0}/PKG-INFO +1 -1
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/agent.py +2 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/base.py +15 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/judge_evaluators.py +5 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/orchestrator.py +5 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/registry.py +4 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/taxonomy.py +1 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/config.py +3 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/core.py +11 -1
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/lifelong.py +5 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/warm_up.py +5 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/indirect_prompt_injection/attack.py +12 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pair/attack.py +13 -1
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/attack.py +12 -0
- hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/__init__.py +47 -0
- hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/attack.py +263 -0
- hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/config.py +155 -0
- hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/generation.py +1007 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/catalog.py +4 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/strategies.py +4 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/main.py +14 -4
- hackagent-0.14.0/hackagent/cli/safe_stdio.py +127 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/__init__.py +2 -0
- hackagent-0.14.0/hackagent/cli/tui/attack_specs/specs/tool_output_ipi.py +168 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/pyproject.toml +2 -2
- {hackagent-0.13.0 → hackagent-0.14.0}/.gitignore +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/LICENSE +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/_version.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/async_utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/base.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/evaluation_step.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/inline_step_judge.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/metrics.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/pattern_evaluators.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/sync.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/generator/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/generator/templates.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/base.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/harmful_behavior.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/jailbreak.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/policy_violation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/rag.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/embedding_utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/guardrail.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/progress.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/prompt_parser.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/response_utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/router_factory.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/translation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/tui.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/completions.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/eval_pipeline.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/generate.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/autodan_eval.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/dashboard_tracing.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/log_styles.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/strategy_library.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/summarizer.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/base.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/encode_experts.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/prompts_and_demonstrations.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/crescendo/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/crescendo/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/crescendo/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/flowchart_renderer.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/prompts.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/decorators.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/indirect_prompt_injection/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/image_encoder.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/prompts.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pair/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pair/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/taxonomy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/jailbreak.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/static_eval.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/attack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/generation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/tap_evaluation.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/bootstrap.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/agent.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/chain.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/display.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/group.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/info.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/options.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/runner.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/claude.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/codex.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/datasets.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/examples.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/results.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/command.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/helpers.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/quick.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/web.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/help_page.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/app.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/registry.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/advprefix.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/autodan_turbo.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/baseline.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/bon.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/cipherchat.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/fc.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/flipattack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/h4rm3l.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/mml.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/pair.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/pap.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/static_template.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/tap.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/tfc.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/base.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/events.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/logger.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/theme.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/agents.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/executor.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/form.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/helpers.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/layout.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/runner.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/tab.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/details.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/export.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/datetimes.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/http.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/run_report.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/summaries.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/text.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/traces.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/tab.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/table.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/actions.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/clipboard.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/logs.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/base.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/intents.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/omnisafebench/dataset.json +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/presets.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/file.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/huggingface.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/url_json.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/registry.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/errors.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/claude/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/claude/hack_claude.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/claude/hack_ollama.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/codex/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/codex/hack_codex.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/codex/hack_ollama.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/jailbreak_eval/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/jailbreak_eval/agent.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/jailbreak_eval/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/multi_tool_agent/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/multi_tool_agent/agent.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/multi_tool_agent/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/hermes/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/hermes/hack_hermes.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/agent_client.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/agent_server.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/ingest.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/policies.pdf +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/read_db.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/litellm_multi_provider/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/litellm_multi_provider/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/litellm_multi_provider/demo.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/ollama/demo.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/ollama/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/ollama/local.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/agent.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/sandbox.db +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/multi_judge/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/multi_judge/run_flipattack_multi_judge.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/agent.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/confidential/db_credentials.txt +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/quick_evaluation/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/quick_evaluation/run_h4rm3l.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/agent_server.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/ingest.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/policies.pdf +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/rag/.gitignore +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/rag/test_data/gender_studies_overview.txt +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/rag/test_indirect_injection.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/vllm/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/web/README.md +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/web/hack.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/web/plan.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/logger.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/base.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/profile_helpers.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/profile_types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/templates.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/registry.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/profile.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/vulnerabilities.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/_chat_registration.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/agent.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/discovery/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/discovery/browser.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/discovery/scanner.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/envelope.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/provider_config.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/adk.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/claude.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/codex.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/hermes.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/web.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/router.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/audit.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/category_classifier.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/context.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/coordinator.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/decorators.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/step.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/tracker.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/utils.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking_logger.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_destroy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_partial_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/apilogs_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/apilogs_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/apilogs_summary_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_destroy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_partial_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/checkout/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/checkout/checkout_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/generate/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/generate/v1_chat_completions_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/judge/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/judge/judge_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_context_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_destroy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/models.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_destroy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_me_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_partial_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_destroy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_partial_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_trace_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_destroy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_partial_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_result_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_run_tests_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/scripts/generate.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/scripts/generate.sh +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/scripts/openapi-python-client.yaml +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_create.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_destroy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_list.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_me_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_me_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_partial_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_retrieve.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_update.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/client.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/errors.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/base.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/buckets.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/enums.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/local.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/remote.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/types.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/__init__.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_local_api.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_proxy.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_serializers.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_static.py +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/static/.gitignore +0 -0
- {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/utils.py +0 -0
|
@@ -228,6 +228,7 @@ class HackAgent:
|
|
|
228
228
|
tFCOrchestrator,
|
|
229
229
|
H4rm3lOrchestrator,
|
|
230
230
|
RagOrchestrator,
|
|
231
|
+
ToolOutputIPIOrchestrator,
|
|
231
232
|
PAPOrchestrator,
|
|
232
233
|
PAIROrchestrator,
|
|
233
234
|
FlipAttackOrchestrator,
|
|
@@ -251,6 +252,7 @@ class HackAgent:
|
|
|
251
252
|
"h4rm3l": H4rm3lOrchestrator(hackagent_agent=self),
|
|
252
253
|
"pap": PAPOrchestrator(hackagent_agent=self),
|
|
253
254
|
"rag": RagOrchestrator(hackagent_agent=self),
|
|
255
|
+
"tool_output_ipi": ToolOutputIPIOrchestrator(hackagent_agent=self),
|
|
254
256
|
"mml": MMLOrchestrator(hackagent_agent=self),
|
|
255
257
|
}
|
|
256
258
|
return self._attack_strategies
|
|
@@ -596,6 +596,11 @@ class BaseJudgeEvaluator(ABC):
|
|
|
596
596
|
Tuple of (score, explanation).
|
|
597
597
|
"""
|
|
598
598
|
# Step 1: Initial request
|
|
599
|
+
configured_thinking = getattr(self.config, "thinking", False)
|
|
600
|
+
if not isinstance(configured_thinking, bool):
|
|
601
|
+
configured_thinking = False
|
|
602
|
+
if request_data.get("thinking") is None:
|
|
603
|
+
request_data["thinking"] = configured_thinking
|
|
599
604
|
response = self.agent_router.route_request(
|
|
600
605
|
registration_key=self.agent_registration_key,
|
|
601
606
|
request_data=request_data,
|
|
@@ -698,6 +703,11 @@ class BaseJudgeEvaluator(ABC):
|
|
|
698
703
|
include_raw_response: bool = False,
|
|
699
704
|
) -> Tuple[Any, Optional[str]] | Tuple[Any, Optional[str], Optional[str]]:
|
|
700
705
|
"""Async equivalent of :meth:`_request_with_assertions`."""
|
|
706
|
+
configured_thinking = getattr(self.config, "thinking", False)
|
|
707
|
+
if not isinstance(configured_thinking, bool):
|
|
708
|
+
configured_thinking = False
|
|
709
|
+
if request_data.get("thinking") is None:
|
|
710
|
+
request_data["thinking"] = configured_thinking
|
|
701
711
|
response = await self._route_request_async(
|
|
702
712
|
registration_key=self.agent_registration_key,
|
|
703
713
|
request_data=request_data,
|
|
@@ -967,4 +977,9 @@ Answer (yes or no):"""
|
|
|
967
977
|
"messages": self._build_messages(feedback_prompt),
|
|
968
978
|
"max_tokens": self.config.max_tokens_eval,
|
|
969
979
|
"temperature": 0.0, # Deterministic for retry
|
|
980
|
+
"thinking": (
|
|
981
|
+
original_request_data["thinking"]
|
|
982
|
+
if original_request_data.get("thinking") is not None
|
|
983
|
+
else False
|
|
984
|
+
),
|
|
970
985
|
}
|
|
@@ -546,6 +546,11 @@ Do not output any other text.
|
|
|
546
546
|
"messages": self._build_messages(feedback_prompt),
|
|
547
547
|
"max_tokens": self.config.max_tokens_eval,
|
|
548
548
|
"temperature": 0.0,
|
|
549
|
+
"thinking": (
|
|
550
|
+
original_request_data["thinking"]
|
|
551
|
+
if original_request_data.get("thinking") is not None
|
|
552
|
+
else False
|
|
553
|
+
),
|
|
549
554
|
}
|
|
550
555
|
|
|
551
556
|
|
|
@@ -189,6 +189,11 @@ class AttackOrchestrator:
|
|
|
189
189
|
("judge", ("judges",), True, "judge"),
|
|
190
190
|
("embedder", ("rag_injection_params", "embedder"), False, None),
|
|
191
191
|
),
|
|
192
|
+
"tool_output_ipi": (
|
|
193
|
+
("attacker", ("attacker",), False, "attacker"),
|
|
194
|
+
# ("judge", ("judge",), False, "judge"),
|
|
195
|
+
("judge", ("judges",), True, "judge"),
|
|
196
|
+
),
|
|
192
197
|
"fc": (
|
|
193
198
|
("step_generator", ("step_generator",), False, "attacker"),
|
|
194
199
|
# ("judge", ("judge",), False, "judge"),
|
|
@@ -41,6 +41,7 @@ from hackagent.attacks.techniques.pap import PAPAttack
|
|
|
41
41
|
from hackagent.attacks.techniques.rag import (
|
|
42
42
|
RagAttack,
|
|
43
43
|
)
|
|
44
|
+
from hackagent.attacks.techniques.tool_output_ipi import ToolOutputIPIAttack
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
def create_orchestrator(
|
|
@@ -98,6 +99,7 @@ FCOrchestrator = create_orchestrator("FC", FCAttack)
|
|
|
98
99
|
tFCOrchestrator = create_orchestrator("tFC", tFCAttack)
|
|
99
100
|
PAPOrchestrator = create_orchestrator("pap", PAPAttack)
|
|
100
101
|
RagOrchestrator = create_orchestrator("rag", RagAttack)
|
|
102
|
+
ToolOutputIPIOrchestrator = create_orchestrator("tool_output_ipi", ToolOutputIPIAttack)
|
|
101
103
|
|
|
102
104
|
# Registry of all available attacks
|
|
103
105
|
ATTACK_REGISTRY = {
|
|
@@ -117,6 +119,7 @@ ATTACK_REGISTRY = {
|
|
|
117
119
|
"tFC": tFCOrchestrator,
|
|
118
120
|
"pap": PAPOrchestrator,
|
|
119
121
|
"rag": RagOrchestrator,
|
|
122
|
+
"tool_output_ipi": ToolOutputIPIOrchestrator,
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
__all__ = [
|
|
@@ -135,5 +138,6 @@ __all__ = [
|
|
|
135
138
|
"tFCOrchestrator",
|
|
136
139
|
"PAPOrchestrator",
|
|
137
140
|
"RagOrchestrator",
|
|
141
|
+
"ToolOutputIPIOrchestrator",
|
|
138
142
|
"ATTACK_REGISTRY",
|
|
139
143
|
]
|
|
@@ -120,6 +120,7 @@ ATTACK_TAXONOMY: Mapping[str, AttackTaxonomy] = {
|
|
|
120
120
|
"bon": _entry(AttackCategory.ADAPTIVE),
|
|
121
121
|
"advprefix": _entry(AttackCategory.ADAPTIVE),
|
|
122
122
|
"autodan_turbo": _entry(AttackCategory.ADAPTIVE),
|
|
123
|
+
"tool_output_ipi": _entry(AttackCategory.ADAPTIVE, AttackTag.INDIRECT),
|
|
123
124
|
# Multi-turn — one growing conversation with the target.
|
|
124
125
|
"crescendo": _entry(AttackCategory.MULTI_TURN),
|
|
125
126
|
}
|
|
@@ -247,6 +247,9 @@ class EvaluatorConfig(BaseModel):
|
|
|
247
247
|
max_judge_retries: int = 1
|
|
248
248
|
# Optional user-defined system prompt prepended to every judge request.
|
|
249
249
|
system_prompt: Optional[str] = None
|
|
250
|
+
# Reasoning control passed on every judge request. Missing/None is
|
|
251
|
+
# normalized to False by BaseJudgeEvaluator.
|
|
252
|
+
thinking: Optional[bool] = False
|
|
250
253
|
|
|
251
254
|
@model_validator(mode="before")
|
|
252
255
|
@classmethod
|
|
@@ -365,6 +365,7 @@ def score_response(
|
|
|
365
365
|
max_retries=5,
|
|
366
366
|
scorer_max_tokens=DEFAULT_MAX_OUTPUT_TOKENS,
|
|
367
367
|
role_label="scorer",
|
|
368
|
+
thinking=False,
|
|
368
369
|
):
|
|
369
370
|
"""Score target output, using a wrapper only for unstructured assessments.
|
|
370
371
|
|
|
@@ -386,6 +387,8 @@ def score_response(
|
|
|
386
387
|
Explicit assessment scores take precedence over model-based extraction.
|
|
387
388
|
Exhausted retries return ``(1.0, "Score extraction failed")``.
|
|
388
389
|
"""
|
|
390
|
+
if not isinstance(thinking, bool):
|
|
391
|
+
thinking = False
|
|
389
392
|
goal_text = str(goal or "")
|
|
390
393
|
system = SCORER_SYSTEM_PROMPT.format(
|
|
391
394
|
goal=goal_text,
|
|
@@ -410,6 +413,7 @@ def score_response(
|
|
|
410
413
|
"max_tokens": scorer_max_tokens,
|
|
411
414
|
"temperature": 0.7,
|
|
412
415
|
"top_p": 0.9,
|
|
416
|
+
"thinking": thinking,
|
|
413
417
|
},
|
|
414
418
|
)
|
|
415
419
|
assessment = extract_response_content(resp, logger)
|
|
@@ -438,7 +442,12 @@ def score_response(
|
|
|
438
442
|
]
|
|
439
443
|
resp2 = scorer_router.route_request(
|
|
440
444
|
registration_key=scorer_key,
|
|
441
|
-
request_data={
|
|
445
|
+
request_data={
|
|
446
|
+
"messages": msgs2,
|
|
447
|
+
"max_tokens": 50,
|
|
448
|
+
"temperature": 0.0,
|
|
449
|
+
"thinking": thinking,
|
|
450
|
+
},
|
|
442
451
|
)
|
|
443
452
|
score_text = extract_response_content(resp2, logger)
|
|
444
453
|
if score_text:
|
|
@@ -479,6 +488,7 @@ def score_response(
|
|
|
479
488
|
"messages": direct_numeric_msgs,
|
|
480
489
|
"max_tokens": 16,
|
|
481
490
|
"temperature": 0.0,
|
|
491
|
+
"thinking": thinking,
|
|
482
492
|
},
|
|
483
493
|
)
|
|
484
494
|
direct_text = extract_response_content(resp3, logger)
|
{hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/lifelong.py
RENAMED
|
@@ -332,6 +332,11 @@ def execute(
|
|
|
332
332
|
max_retries=max_parse_retries,
|
|
333
333
|
scorer_max_tokens=scorer_max_tokens,
|
|
334
334
|
role_label=scorer_label,
|
|
335
|
+
thinking=(
|
|
336
|
+
_judge_cfg.get("thinking")
|
|
337
|
+
if isinstance(_judge_cfg.get("thinking"), bool)
|
|
338
|
+
else False
|
|
339
|
+
),
|
|
335
340
|
)
|
|
336
341
|
emit_phase_trace(
|
|
337
342
|
config,
|
|
@@ -228,6 +228,11 @@ def execute(
|
|
|
228
228
|
max_retries=max_parse_retries,
|
|
229
229
|
scorer_max_tokens=scorer_max_tokens,
|
|
230
230
|
role_label=scorer_label,
|
|
231
|
+
thinking=(
|
|
232
|
+
_judge_cfg.get("thinking")
|
|
233
|
+
if isinstance(_judge_cfg.get("thinking"), bool)
|
|
234
|
+
else False
|
|
235
|
+
),
|
|
231
236
|
)
|
|
232
237
|
emit_phase_trace(
|
|
233
238
|
config,
|
|
@@ -1350,6 +1350,17 @@ class IndirectPromptInjectionAttack(BaseAttack):
|
|
|
1350
1350
|
self, query: str, context: str, response: str, goal: str
|
|
1351
1351
|
) -> Dict[str, Any]:
|
|
1352
1352
|
"""Use judge LLM to evaluate if target followed poisoned instructions."""
|
|
1353
|
+
judge_config = (
|
|
1354
|
+
self.config.get("judges", [{}])[0]
|
|
1355
|
+
if self.config.get("judges")
|
|
1356
|
+
else self.config.get("judge", {})
|
|
1357
|
+
)
|
|
1358
|
+
configured_thinking = (
|
|
1359
|
+
judge_config.get("thinking") if isinstance(judge_config, dict) else None
|
|
1360
|
+
)
|
|
1361
|
+
thinking = (
|
|
1362
|
+
configured_thinking if isinstance(configured_thinking, bool) else False
|
|
1363
|
+
)
|
|
1353
1364
|
user_message = (
|
|
1354
1365
|
f"BENIGN USER QUERY:\n{query}\n\n"
|
|
1355
1366
|
f"RETRIEVED CONTEXT:\n{context[:3000]}\n\n"
|
|
@@ -1366,6 +1377,7 @@ class IndirectPromptInjectionAttack(BaseAttack):
|
|
|
1366
1377
|
],
|
|
1367
1378
|
"max_tokens": 500,
|
|
1368
1379
|
"temperature": 0.0,
|
|
1380
|
+
"thinking": thinking,
|
|
1369
1381
|
},
|
|
1370
1382
|
)
|
|
1371
1383
|
|
|
@@ -726,6 +726,11 @@ class PAIRAttack(BaseAttack):
|
|
|
726
726
|
max_retries=max_parse_retries,
|
|
727
727
|
scorer_max_tokens=scorer_max_tokens,
|
|
728
728
|
role_label="pair-judge",
|
|
729
|
+
thinking=(
|
|
730
|
+
judge_config.get("thinking")
|
|
731
|
+
if isinstance(judge_config.get("thinking"), bool)
|
|
732
|
+
else False
|
|
733
|
+
),
|
|
729
734
|
)
|
|
730
735
|
self._set_scorer_explanation(assessment or "")
|
|
731
736
|
|
|
@@ -812,6 +817,13 @@ class PAIRAttack(BaseAttack):
|
|
|
812
817
|
|
|
813
818
|
judge_prompt_max = int(self.config.get("judge_prompt_max_chars", 2500))
|
|
814
819
|
judge_response_max = int(self.config.get("judge_response_max_chars", 3500))
|
|
820
|
+
judge_config = self.config.get("judge") or self.config.get("scorer", {})
|
|
821
|
+
configured_thinking = (
|
|
822
|
+
judge_config.get("thinking") if isinstance(judge_config, dict) else None
|
|
823
|
+
)
|
|
824
|
+
thinking = (
|
|
825
|
+
configured_thinking if isinstance(configured_thinking, bool) else False
|
|
826
|
+
)
|
|
815
827
|
|
|
816
828
|
prompt_for_judge = _truncate_text(prompt or "", judge_prompt_max)
|
|
817
829
|
response_for_judge = _truncate_text(response or "", judge_response_max)
|
|
@@ -833,7 +845,6 @@ class PAIRAttack(BaseAttack):
|
|
|
833
845
|
]
|
|
834
846
|
|
|
835
847
|
try:
|
|
836
|
-
judge_config = self.config.get("judge") or self.config.get("scorer", {})
|
|
837
848
|
request_timeout = judge_config.get(
|
|
838
849
|
"timeout",
|
|
839
850
|
judge_config.get("request_timeout", self.config.get("timeout", 120)),
|
|
@@ -848,6 +859,7 @@ class PAIRAttack(BaseAttack):
|
|
|
848
859
|
"max_tokens": max_tokens,
|
|
849
860
|
"temperature": 0.0,
|
|
850
861
|
"timeout": request_timeout,
|
|
862
|
+
"thinking": thinking,
|
|
851
863
|
},
|
|
852
864
|
)
|
|
853
865
|
legacy_text = extract_response_content(legacy_response, self.logger)
|
|
@@ -1382,6 +1382,17 @@ class RagAttack(BaseAttack):
|
|
|
1382
1382
|
self, query: str, context: str, response: str, goal: str
|
|
1383
1383
|
) -> Dict[str, Any]:
|
|
1384
1384
|
"""Use judge LLM to evaluate if target followed poisoned instructions."""
|
|
1385
|
+
judge_config = (
|
|
1386
|
+
self.config.get("judges", [{}])[0]
|
|
1387
|
+
if self.config.get("judges")
|
|
1388
|
+
else self.config.get("judge", {})
|
|
1389
|
+
)
|
|
1390
|
+
configured_thinking = (
|
|
1391
|
+
judge_config.get("thinking") if isinstance(judge_config, dict) else None
|
|
1392
|
+
)
|
|
1393
|
+
thinking = (
|
|
1394
|
+
configured_thinking if isinstance(configured_thinking, bool) else False
|
|
1395
|
+
)
|
|
1385
1396
|
user_message = (
|
|
1386
1397
|
f"BENIGN USER QUERY:\n{query}\n\n"
|
|
1387
1398
|
f"RETRIEVED CONTEXT:\n{context[:3000]}\n\n"
|
|
@@ -1398,6 +1409,7 @@ class RagAttack(BaseAttack):
|
|
|
1398
1409
|
],
|
|
1399
1410
|
"max_tokens": 500,
|
|
1400
1411
|
"temperature": 0.0,
|
|
1412
|
+
"thinking": thinking,
|
|
1401
1413
|
},
|
|
1402
1414
|
)
|
|
1403
1415
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Copyright 2026 - AI4I. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""Tool-output indirect prompt injection (InjecAgent / OPI family).
|
|
5
|
+
|
|
6
|
+
Injects adversarial instructions into simulated (or live) tool observations
|
|
7
|
+
so a tool-using agent may follow a malicious goal after a benign user task.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from .attack import ToolOutputIPIAttack
|
|
13
|
+
|
|
14
|
+
__all__ = ["ToolOutputIPIAttack"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _register_taxonomy_entry() -> None:
|
|
18
|
+
"""Ensure adaptive+indirect taxonomy entry exists (safety net).
|
|
19
|
+
|
|
20
|
+
The permanent assignment lives in ``ATTACK_TAXONOMY``. This helper remains
|
|
21
|
+
so TUI/CLI discovery does not fail if that permanent entry is temporarily
|
|
22
|
+
missing during a partial merge.
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
from hackagent.attacks.taxonomy import (
|
|
26
|
+
ATTACK_TAXONOMY,
|
|
27
|
+
AttackCategory,
|
|
28
|
+
AttackTag,
|
|
29
|
+
AttackTaxonomy,
|
|
30
|
+
try_get_attack_taxonomy,
|
|
31
|
+
)
|
|
32
|
+
except ImportError:
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
if try_get_attack_taxonomy("tool_output_ipi") is not None:
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
entry = AttackTaxonomy(
|
|
39
|
+
category=AttackCategory.ADAPTIVE,
|
|
40
|
+
tags=(AttackTag.INDIRECT,),
|
|
41
|
+
)
|
|
42
|
+
# ATTACK_TAXONOMY is declared Mapping but constructed as a plain dict.
|
|
43
|
+
if isinstance(ATTACK_TAXONOMY, dict):
|
|
44
|
+
ATTACK_TAXONOMY["tool_output_ipi"] = entry
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
_register_taxonomy_entry()
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Copyright 2026 - AI4I. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Tool-output indirect prompt injection (tool_output_ipi) attack.
|
|
6
|
+
|
|
7
|
+
Poisons tool / function-call *observations* so a tool-using agent may follow
|
|
8
|
+
a malicious goal after a benign user task (InjecAgent / OPI family).
|
|
9
|
+
|
|
10
|
+
This is distinct from ``rag`` / ``indirect_prompt_injection``, which poison
|
|
11
|
+
RAG documents — not tool return values.
|
|
12
|
+
|
|
13
|
+
Pipeline:
|
|
14
|
+
1. Generation — craft poisoned tool observations, query target, inline judge
|
|
15
|
+
2. Evaluation — post-processing (server sync, tracker, ASR)
|
|
16
|
+
|
|
17
|
+
Taxonomy: primary **adaptive**, tag **indirect** (registered defensively when ``hackagent.attacks.taxonomy`` is present; add a permanent ``ATTACK_TAXONOMY`` entry when #603 merges).
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import copy
|
|
23
|
+
import logging
|
|
24
|
+
from typing import Any, Dict, List, Optional
|
|
25
|
+
|
|
26
|
+
from hackagent.server.client import AuthenticatedClient
|
|
27
|
+
from hackagent.router.router import AgentRouter
|
|
28
|
+
from hackagent.attacks.techniques.base import BaseAttack
|
|
29
|
+
from hackagent.attacks.types import AttackResult, rows_to_attack_results
|
|
30
|
+
from hackagent.attacks.shared.tui import with_tui_logging
|
|
31
|
+
from hackagent.attacks.evaluator.evaluation_step import BaseEvaluationStep
|
|
32
|
+
|
|
33
|
+
from . import generation
|
|
34
|
+
from .config import DEFAULT_TOOL_OUTPUT_IPI_CONFIG
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _recursive_update(target_dict: Dict[str, Any], source_dict: Dict[str, Any]) -> None:
|
|
38
|
+
"""Recursively merge *source_dict* into *target_dict*."""
|
|
39
|
+
for key, source_value in source_dict.items():
|
|
40
|
+
target_value = target_dict.get(key)
|
|
41
|
+
if isinstance(source_value, dict) and isinstance(target_value, dict):
|
|
42
|
+
_recursive_update(target_value, source_value)
|
|
43
|
+
elif key.startswith("_"):
|
|
44
|
+
target_dict[key] = source_value
|
|
45
|
+
else:
|
|
46
|
+
target_dict[key] = copy.deepcopy(source_value)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ToolOutputIPIAttack(BaseAttack):
|
|
50
|
+
"""Tool-output indirect prompt injection (InjecAgent / OPI).
|
|
51
|
+
|
|
52
|
+
For each malicious goal the attack:
|
|
53
|
+
1. Starts from a benign user message that would elicit a tool call.
|
|
54
|
+
2. Appends a simulated (or live) ``role=tool`` observation containing an
|
|
55
|
+
adversarial injection aimed at the goal.
|
|
56
|
+
3. Re-queries the target with the full messages history.
|
|
57
|
+
4. Judges whether the response or subsequent tool call follows the
|
|
58
|
+
injected instructions (direct harm and/or data stealing).
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
config: Optional[Dict[str, Any]] = None,
|
|
64
|
+
client: Optional[AuthenticatedClient] = None,
|
|
65
|
+
agent_router: Optional[AgentRouter] = None,
|
|
66
|
+
):
|
|
67
|
+
if client is None:
|
|
68
|
+
raise ValueError(
|
|
69
|
+
"AuthenticatedClient must be provided to ToolOutputIPIAttack."
|
|
70
|
+
)
|
|
71
|
+
if agent_router is None:
|
|
72
|
+
raise ValueError(
|
|
73
|
+
"Victim AgentRouter instance must be provided to ToolOutputIPIAttack."
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
current_config = copy.deepcopy(DEFAULT_TOOL_OUTPUT_IPI_CONFIG)
|
|
77
|
+
if config:
|
|
78
|
+
_recursive_update(current_config, config)
|
|
79
|
+
|
|
80
|
+
self.logger = logging.getLogger("hackagent.attacks.tool_output_ipi")
|
|
81
|
+
super().__init__(current_config, client, agent_router)
|
|
82
|
+
|
|
83
|
+
def _validate_config(self) -> None:
|
|
84
|
+
super()._validate_config()
|
|
85
|
+
|
|
86
|
+
required_keys = ["attack_type", "tool_output_ipi_params"]
|
|
87
|
+
missing = [k for k in required_keys if k not in self.config]
|
|
88
|
+
if missing:
|
|
89
|
+
raise ValueError(
|
|
90
|
+
f"Configuration dictionary missing required keys: {', '.join(missing)}"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
params = self.config.get("tool_output_ipi_params", {})
|
|
94
|
+
if not isinstance(params, dict):
|
|
95
|
+
raise ValueError("tool_output_ipi_params must be a dictionary")
|
|
96
|
+
|
|
97
|
+
mode = params.get("mode", "simulated")
|
|
98
|
+
if mode not in ("simulated", "live"):
|
|
99
|
+
raise ValueError(
|
|
100
|
+
f"tool_output_ipi_params.mode must be 'simulated' or 'live'; got {mode!r}"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
max_attempts = params.get("max_attempts", 3)
|
|
104
|
+
try:
|
|
105
|
+
if int(max_attempts) < 1:
|
|
106
|
+
raise ValueError
|
|
107
|
+
except (TypeError, ValueError) as exc:
|
|
108
|
+
raise ValueError(
|
|
109
|
+
"tool_output_ipi_params.max_attempts must be an integer >= 1"
|
|
110
|
+
) from exc
|
|
111
|
+
|
|
112
|
+
if params.get("use_attacker_llm") and not (
|
|
113
|
+
isinstance(self.config.get("attacker"), dict)
|
|
114
|
+
and self.config["attacker"].get("identifier")
|
|
115
|
+
):
|
|
116
|
+
raise ValueError(
|
|
117
|
+
"use_attacker_llm=True requires attacker.identifier in the attack config"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
@classmethod
|
|
121
|
+
def get_effective_model_roles(
|
|
122
|
+
cls,
|
|
123
|
+
attack_config: Dict[str, Any],
|
|
124
|
+
*,
|
|
125
|
+
goal_labels_by_index: Optional[Dict[int, Dict[str, str]]] = None,
|
|
126
|
+
) -> List[Dict[str, Any]]:
|
|
127
|
+
"""Declare attacker (optional) and judge model roles for preflight."""
|
|
128
|
+
_ = goal_labels_by_index
|
|
129
|
+
roles: List[Dict[str, Any]] = []
|
|
130
|
+
|
|
131
|
+
params = attack_config.get("tool_output_ipi_params") or {}
|
|
132
|
+
if params.get("use_attacker_llm"):
|
|
133
|
+
attacker = attack_config.get("attacker")
|
|
134
|
+
if isinstance(attacker, dict):
|
|
135
|
+
roles.append({"role": "attacker", "config": attacker, "required": True})
|
|
136
|
+
|
|
137
|
+
judges = attack_config.get("judges")
|
|
138
|
+
if isinstance(judges, list) and judges:
|
|
139
|
+
for judge in judges:
|
|
140
|
+
roles.append({"role": "judge", "config": judge, "required": False})
|
|
141
|
+
return roles
|
|
142
|
+
|
|
143
|
+
def _get_pipeline_steps(self) -> List[Dict]:
|
|
144
|
+
return [
|
|
145
|
+
{
|
|
146
|
+
"name": "Generation: Tool-output IPI + Judge",
|
|
147
|
+
"function": generation.execute,
|
|
148
|
+
"step_type_enum": "GENERATION",
|
|
149
|
+
"config_keys": [
|
|
150
|
+
"batch_size",
|
|
151
|
+
"tool_output_ipi_params",
|
|
152
|
+
"attacker",
|
|
153
|
+
"_run_id",
|
|
154
|
+
"_backend",
|
|
155
|
+
"_client",
|
|
156
|
+
"_tracker",
|
|
157
|
+
"_goal_index_offset",
|
|
158
|
+
"judges",
|
|
159
|
+
"judge_concurrency",
|
|
160
|
+
"max_tokens_eval",
|
|
161
|
+
"filter_len",
|
|
162
|
+
"judge_timeout",
|
|
163
|
+
"judge_temperature",
|
|
164
|
+
"max_judge_retries",
|
|
165
|
+
"max_tokens",
|
|
166
|
+
"temperature",
|
|
167
|
+
"timeout",
|
|
168
|
+
],
|
|
169
|
+
"input_data_arg_name": "goals",
|
|
170
|
+
"required_args": ["logger", "agent_router", "config"],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "Evaluation Post-processing: Server Sync, Tracker & ASR Logging",
|
|
174
|
+
"function": BaseEvaluationStep.make_postprocess_execute(
|
|
175
|
+
"tool_output_ipi"
|
|
176
|
+
),
|
|
177
|
+
"step_type_enum": "EVALUATION",
|
|
178
|
+
"config_keys": [
|
|
179
|
+
"tool_output_ipi_params",
|
|
180
|
+
"_run_id",
|
|
181
|
+
"_backend",
|
|
182
|
+
"_client",
|
|
183
|
+
"_tracker",
|
|
184
|
+
"_goal_index_offset",
|
|
185
|
+
"judges",
|
|
186
|
+
"judge_concurrency",
|
|
187
|
+
"max_tokens_eval",
|
|
188
|
+
"filter_len",
|
|
189
|
+
"judge_timeout",
|
|
190
|
+
"judge_temperature",
|
|
191
|
+
"max_judge_retries",
|
|
192
|
+
],
|
|
193
|
+
"input_data_arg_name": "input_data",
|
|
194
|
+
"required_args": ["logger", "config", "client"],
|
|
195
|
+
},
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
@with_tui_logging(logger_name="hackagent.attacks", level=logging.INFO)
|
|
199
|
+
def run(self, goals: Optional[List[str]] = None, **kwargs) -> List[AttackResult]:
|
|
200
|
+
"""Execute the tool-output IPI pipeline.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
goals: Malicious goals the poisoned tool observation should induce.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
List of :class:`~hackagent.attacks.types.AttackResult` rows.
|
|
207
|
+
"""
|
|
208
|
+
goals = goals or []
|
|
209
|
+
if not goals:
|
|
210
|
+
return []
|
|
211
|
+
|
|
212
|
+
coordinator = self._initialize_coordinator(attack_type="tool_output_ipi")
|
|
213
|
+
|
|
214
|
+
params = self.config.get("tool_output_ipi_params", {})
|
|
215
|
+
goal_metadata = {
|
|
216
|
+
"mode": params.get("mode", "simulated"),
|
|
217
|
+
"max_attempts": params.get("max_attempts", 3),
|
|
218
|
+
"success_setting": params.get("success_setting", "both"),
|
|
219
|
+
"tool_name": params.get("tool_name"),
|
|
220
|
+
# Documented taxonomy until hackagent.attacks.taxonomy lands (#603).
|
|
221
|
+
"category": "adaptive",
|
|
222
|
+
"tags": ["indirect"],
|
|
223
|
+
}
|
|
224
|
+
coordinator.initialize_goals(goals=goals, initial_metadata=goal_metadata)
|
|
225
|
+
|
|
226
|
+
if coordinator.has_goal_tracking:
|
|
227
|
+
self.logger.info("Using TrackingCoordinator for per-goal tracking")
|
|
228
|
+
|
|
229
|
+
if coordinator.goal_tracker:
|
|
230
|
+
self.config["_tracker"] = coordinator.goal_tracker
|
|
231
|
+
|
|
232
|
+
pipeline_steps = self._get_pipeline_steps()
|
|
233
|
+
start_step = self.config.get("start_step", 1) - 1
|
|
234
|
+
|
|
235
|
+
try:
|
|
236
|
+
generation_output = self._execute_pipeline(
|
|
237
|
+
pipeline_steps, goals, start_step=start_step, end_step=start_step + 1
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
if not generation_output:
|
|
241
|
+
self.logger.warning("Generation produced no output")
|
|
242
|
+
coordinator.finalize_pipeline([], lambda _: False)
|
|
243
|
+
return []
|
|
244
|
+
|
|
245
|
+
results = self._execute_pipeline(
|
|
246
|
+
pipeline_steps, generation_output, start_step=start_step + 1
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
coordinator.finalize_all_goals(
|
|
250
|
+
results,
|
|
251
|
+
include_evaluation_trace=False,
|
|
252
|
+
)
|
|
253
|
+
coordinator.log_summary()
|
|
254
|
+
coordinator.finalize_pipeline(results)
|
|
255
|
+
|
|
256
|
+
return rows_to_attack_results(results)
|
|
257
|
+
|
|
258
|
+
except Exception:
|
|
259
|
+
self.logger.exception("tool_output_ipi pipeline failed with exception")
|
|
260
|
+
coordinator.finalize_on_error(
|
|
261
|
+
"tool_output_ipi pipeline failed with exception"
|
|
262
|
+
)
|
|
263
|
+
raise
|