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.
Files changed (444) hide show
  1. {hackagent-0.13.0 → hackagent-0.14.0}/PKG-INFO +1 -1
  2. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/agent.py +2 -0
  3. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/base.py +15 -0
  4. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/judge_evaluators.py +5 -0
  5. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/orchestrator.py +5 -0
  6. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/registry.py +4 -0
  7. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/taxonomy.py +1 -0
  8. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/config.py +3 -0
  9. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/core.py +11 -1
  10. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/lifelong.py +5 -0
  11. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/warm_up.py +5 -0
  12. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/indirect_prompt_injection/attack.py +12 -0
  13. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pair/attack.py +13 -1
  14. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/attack.py +12 -0
  15. hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/__init__.py +47 -0
  16. hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/attack.py +263 -0
  17. hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/config.py +155 -0
  18. hackagent-0.14.0/hackagent/attacks/techniques/tool_output_ipi/generation.py +1007 -0
  19. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/catalog.py +4 -0
  20. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/strategies.py +4 -0
  21. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/main.py +14 -4
  22. hackagent-0.14.0/hackagent/cli/safe_stdio.py +127 -0
  23. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/__init__.py +2 -0
  24. hackagent-0.14.0/hackagent/cli/tui/attack_specs/specs/tool_output_ipi.py +168 -0
  25. {hackagent-0.13.0 → hackagent-0.14.0}/pyproject.toml +2 -2
  26. {hackagent-0.13.0 → hackagent-0.14.0}/.gitignore +0 -0
  27. {hackagent-0.13.0 → hackagent-0.14.0}/LICENSE +0 -0
  28. {hackagent-0.13.0 → hackagent-0.14.0}/README.md +0 -0
  29. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/__init__.py +0 -0
  30. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/_version.py +0 -0
  31. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/async_utils.py +0 -0
  32. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/__init__.py +0 -0
  33. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/base.py +0 -0
  34. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/__init__.py +0 -0
  35. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/evaluation_step.py +0 -0
  36. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/inline_step_judge.py +0 -0
  37. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/metrics.py +0 -0
  38. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/pattern_evaluators.py +0 -0
  39. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/evaluator/sync.py +0 -0
  40. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/generator/__init__.py +0 -0
  41. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/generator/templates.py +0 -0
  42. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/__init__.py +0 -0
  43. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/base.py +0 -0
  44. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/harmful_behavior.py +0 -0
  45. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/jailbreak.py +0 -0
  46. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/policy_violation.py +0 -0
  47. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/objectives/rag.py +0 -0
  48. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/__init__.py +0 -0
  49. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/embedding_utils.py +0 -0
  50. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/guardrail.py +0 -0
  51. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/progress.py +0 -0
  52. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/prompt_parser.py +0 -0
  53. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/response_utils.py +0 -0
  54. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/router_factory.py +0 -0
  55. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/translation.py +0 -0
  56. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/tui.py +0 -0
  57. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/shared/utils.py +0 -0
  58. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/__init__.py +0 -0
  59. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/__init__.py +0 -0
  60. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/attack.py +0 -0
  61. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/completions.py +0 -0
  62. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/eval_pipeline.py +0 -0
  63. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/generate.py +0 -0
  64. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/advprefix/utils.py +0 -0
  65. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/__init__.py +0 -0
  66. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/attack.py +0 -0
  67. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/autodan_eval.py +0 -0
  68. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/config.py +0 -0
  69. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/dashboard_tracing.py +0 -0
  70. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/log_styles.py +0 -0
  71. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/strategy_library.py +0 -0
  72. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/autodan_turbo/summarizer.py +0 -0
  73. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/base.py +0 -0
  74. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/__init__.py +0 -0
  75. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/attack.py +0 -0
  76. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/config.py +0 -0
  77. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/baseline/generation.py +0 -0
  78. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/__init__.py +0 -0
  79. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/attack.py +0 -0
  80. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/config.py +0 -0
  81. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/bon/generation.py +0 -0
  82. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/__init__.py +0 -0
  83. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/attack.py +0 -0
  84. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/config.py +0 -0
  85. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/encode_experts.py +0 -0
  86. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/generation.py +0 -0
  87. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/cipherchat/prompts_and_demonstrations.py +0 -0
  88. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/config.py +0 -0
  89. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/crescendo/__init__.py +0 -0
  90. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/crescendo/attack.py +0 -0
  91. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/crescendo/config.py +0 -0
  92. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/__init__.py +0 -0
  93. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/attack.py +0 -0
  94. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/config.py +0 -0
  95. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/flowchart_renderer.py +0 -0
  96. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/generation.py +0 -0
  97. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/fc/prompts.py +0 -0
  98. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/__init__.py +0 -0
  99. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/attack.py +0 -0
  100. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/config.py +0 -0
  101. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/flipattack/generation.py +0 -0
  102. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/__init__.py +0 -0
  103. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/attack.py +0 -0
  104. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/config.py +0 -0
  105. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/decorators.py +0 -0
  106. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/h4rm3l/generation.py +0 -0
  107. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/indirect_prompt_injection/config.py +0 -0
  108. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/__init__.py +0 -0
  109. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/attack.py +0 -0
  110. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/config.py +0 -0
  111. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/generation.py +0 -0
  112. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/image_encoder.py +0 -0
  113. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/mml/prompts.py +0 -0
  114. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pair/__init__.py +0 -0
  115. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pair/config.py +0 -0
  116. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/__init__.py +0 -0
  117. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/attack.py +0 -0
  118. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/config.py +0 -0
  119. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/generation.py +0 -0
  120. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/pap/taxonomy.py +0 -0
  121. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/__init__.py +0 -0
  122. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/config.py +0 -0
  123. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/rag/jailbreak.py +0 -0
  124. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/__init__.py +0 -0
  125. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/attack.py +0 -0
  126. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/config.py +0 -0
  127. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/generation.py +0 -0
  128. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/static_template/static_eval.py +0 -0
  129. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/__init__.py +0 -0
  130. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/attack.py +0 -0
  131. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/config.py +0 -0
  132. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/generation.py +0 -0
  133. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/techniques/tap/tap_evaluation.py +0 -0
  134. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/attacks/types.py +0 -0
  135. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/__init__.py +0 -0
  136. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/bootstrap.py +0 -0
  137. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/__init__.py +0 -0
  138. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/agent.py +0 -0
  139. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/__init__.py +0 -0
  140. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/chain.py +0 -0
  141. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/config.py +0 -0
  142. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/display.py +0 -0
  143. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/group.py +0 -0
  144. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/info.py +0 -0
  145. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/options.py +0 -0
  146. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/attack/runner.py +0 -0
  147. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/claude.py +0 -0
  148. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/codex.py +0 -0
  149. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/config.py +0 -0
  150. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/datasets.py +0 -0
  151. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/examples.py +0 -0
  152. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/results.py +0 -0
  153. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/__init__.py +0 -0
  154. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/command.py +0 -0
  155. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/helpers.py +0 -0
  156. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/scan/quick.py +0 -0
  157. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/commands/web.py +0 -0
  158. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/config.py +0 -0
  159. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/help_page.py +0 -0
  160. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/__init__.py +0 -0
  161. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/app.py +0 -0
  162. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/__init__.py +0 -0
  163. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/registry.py +0 -0
  164. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/advprefix.py +0 -0
  165. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/autodan_turbo.py +0 -0
  166. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/baseline.py +0 -0
  167. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/bon.py +0 -0
  168. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/cipherchat.py +0 -0
  169. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/fc.py +0 -0
  170. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/flipattack.py +0 -0
  171. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/h4rm3l.py +0 -0
  172. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/mml.py +0 -0
  173. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/pair.py +0 -0
  174. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/pap.py +0 -0
  175. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/static_template.py +0 -0
  176. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/tap.py +0 -0
  177. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/specs/tfc.py +0 -0
  178. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/attack_specs/types.py +0 -0
  179. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/base.py +0 -0
  180. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/events.py +0 -0
  181. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/logger.py +0 -0
  182. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/theme.py +0 -0
  183. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/__init__.py +0 -0
  184. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/agents.py +0 -0
  185. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/__init__.py +0 -0
  186. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/executor.py +0 -0
  187. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/form.py +0 -0
  188. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/helpers.py +0 -0
  189. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/layout.py +0 -0
  190. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/runner.py +0 -0
  191. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/attacks/tab.py +0 -0
  192. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/config.py +0 -0
  193. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/__init__.py +0 -0
  194. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/details.py +0 -0
  195. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/export.py +0 -0
  196. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/__init__.py +0 -0
  197. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/datetimes.py +0 -0
  198. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/http.py +0 -0
  199. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/run_report.py +0 -0
  200. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/summaries.py +0 -0
  201. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/text.py +0 -0
  202. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/formatters/traces.py +0 -0
  203. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/tab.py +0 -0
  204. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/views/results/table.py +0 -0
  205. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/__init__.py +0 -0
  206. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/actions.py +0 -0
  207. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/clipboard.py +0 -0
  208. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/tui/widgets/logs.py +0 -0
  209. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/cli/utils.py +0 -0
  210. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/config.py +0 -0
  211. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/__init__.py +0 -0
  212. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/base.py +0 -0
  213. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/intents.py +0 -0
  214. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/omnisafebench/dataset.json +0 -0
  215. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/presets.py +0 -0
  216. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/__init__.py +0 -0
  217. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/file.py +0 -0
  218. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/huggingface.py +0 -0
  219. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/providers/url_json.py +0 -0
  220. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/datasets/registry.py +0 -0
  221. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/errors.py +0 -0
  222. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/claude/README.md +0 -0
  223. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/claude/hack_claude.py +0 -0
  224. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/claude/hack_ollama.py +0 -0
  225. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/codex/README.md +0 -0
  226. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/codex/hack_codex.py +0 -0
  227. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/codex/hack_ollama.py +0 -0
  228. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/jailbreak_eval/__init__.py +0 -0
  229. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/jailbreak_eval/agent.py +0 -0
  230. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/jailbreak_eval/hack.py +0 -0
  231. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/multi_tool_agent/__init__.py +0 -0
  232. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/multi_tool_agent/agent.py +0 -0
  233. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/google_adk/multi_tool_agent/hack.py +0 -0
  234. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/hermes/README.md +0 -0
  235. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/hermes/hack_hermes.py +0 -0
  236. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/README.md +0 -0
  237. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/agent_client.py +0 -0
  238. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/agent_server.py +0 -0
  239. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/hack.py +0 -0
  240. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/ingest.py +0 -0
  241. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/policies.pdf +0 -0
  242. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/langchain/rag/read_db.py +0 -0
  243. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/litellm_multi_provider/README.md +0 -0
  244. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/litellm_multi_provider/__init__.py +0 -0
  245. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/litellm_multi_provider/demo.py +0 -0
  246. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/ollama/demo.py +0 -0
  247. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/ollama/hack.py +0 -0
  248. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/ollama/local.py +0 -0
  249. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/README.md +0 -0
  250. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/agent.py +0 -0
  251. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/hack.py +0 -0
  252. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/db_tool_sandbox/sandbox.db +0 -0
  253. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/multi_judge/README.md +0 -0
  254. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/multi_judge/run_flipattack_multi_judge.py +0 -0
  255. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/README.md +0 -0
  256. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/agent.py +0 -0
  257. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/confidential/db_credentials.txt +0 -0
  258. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/pc_tool_sandbox/hack.py +0 -0
  259. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/quick_evaluation/README.md +0 -0
  260. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/quick_evaluation/run_h4rm3l.py +0 -0
  261. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/README.md +0 -0
  262. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/agent_server.py +0 -0
  263. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/hack.py +0 -0
  264. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/ingest.py +0 -0
  265. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/openai_sdk/rag/policies.pdf +0 -0
  266. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/rag/.gitignore +0 -0
  267. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/rag/test_data/gender_studies_overview.txt +0 -0
  268. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/rag/test_indirect_injection.py +0 -0
  269. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/vllm/hack.py +0 -0
  270. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/web/README.md +0 -0
  271. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/web/hack.py +0 -0
  272. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/examples/web/plan.py +0 -0
  273. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/logger.py +0 -0
  274. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/__init__.py +0 -0
  275. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/base.py +0 -0
  276. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/__init__.py +0 -0
  277. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/profile.py +0 -0
  278. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/types.py +0 -0
  279. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/craft_adversarial_data/vulnerabilities.py +0 -0
  280. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/__init__.py +0 -0
  281. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/profile.py +0 -0
  282. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/types.py +0 -0
  283. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/credential_exposure/vulnerabilities.py +0 -0
  284. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/__init__.py +0 -0
  285. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/profile.py +0 -0
  286. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/types.py +0 -0
  287. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/excessive_agency/vulnerabilities.py +0 -0
  288. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/__init__.py +0 -0
  289. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/profile.py +0 -0
  290. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/types.py +0 -0
  291. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/input_manipulation_attack/vulnerabilities.py +0 -0
  292. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/__init__.py +0 -0
  293. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/profile.py +0 -0
  294. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/types.py +0 -0
  295. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/jailbreak/vulnerabilities.py +0 -0
  296. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/__init__.py +0 -0
  297. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/profile.py +0 -0
  298. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/types.py +0 -0
  299. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/malicious_tool_invocation/vulnerabilities.py +0 -0
  300. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/__init__.py +0 -0
  301. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/profile.py +0 -0
  302. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/types.py +0 -0
  303. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/misinformation/vulnerabilities.py +0 -0
  304. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/__init__.py +0 -0
  305. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/profile.py +0 -0
  306. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/types.py +0 -0
  307. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/model_evasion/vulnerabilities.py +0 -0
  308. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/profile_helpers.py +0 -0
  309. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/profile_types.py +0 -0
  310. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/__init__.py +0 -0
  311. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/profile.py +0 -0
  312. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/templates.py +0 -0
  313. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/types.py +0 -0
  314. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/prompt_injection/vulnerabilities.py +0 -0
  315. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/__init__.py +0 -0
  316. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/profile.py +0 -0
  317. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/types.py +0 -0
  318. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/public_facing_application_exploitation/vulnerabilities.py +0 -0
  319. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/registry.py +0 -0
  320. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/__init__.py +0 -0
  321. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/profile.py +0 -0
  322. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/types.py +0 -0
  323. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/sensitive_information_disclosure/vulnerabilities.py +0 -0
  324. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/__init__.py +0 -0
  325. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/profile.py +0 -0
  326. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/types.py +0 -0
  327. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/system_prompt_leakage/vulnerabilities.py +0 -0
  328. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/utils.py +0 -0
  329. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/__init__.py +0 -0
  330. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/profile.py +0 -0
  331. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/types.py +0 -0
  332. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/risks/vector_embedding_weaknesses_exploit/vulnerabilities.py +0 -0
  333. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/__init__.py +0 -0
  334. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/_chat_registration.py +0 -0
  335. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/agent.py +0 -0
  336. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/discovery/__init__.py +0 -0
  337. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/discovery/browser.py +0 -0
  338. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/discovery/scanner.py +0 -0
  339. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/envelope.py +0 -0
  340. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/provider_config.py +0 -0
  341. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/__init__.py +0 -0
  342. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/adk.py +0 -0
  343. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/claude.py +0 -0
  344. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/codex.py +0 -0
  345. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/hermes.py +0 -0
  346. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/providers/web.py +0 -0
  347. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/router.py +0 -0
  348. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/__init__.py +0 -0
  349. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/audit.py +0 -0
  350. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/category_classifier.py +0 -0
  351. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/context.py +0 -0
  352. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/coordinator.py +0 -0
  353. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/decorators.py +0 -0
  354. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/step.py +0 -0
  355. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/tracker.py +0 -0
  356. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking/utils.py +0 -0
  357. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/tracking_logger.py +0 -0
  358. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/router/types.py +0 -0
  359. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/__init__.py +0 -0
  360. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/__init__.py +0 -0
  361. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/__init__.py +0 -0
  362. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_create.py +0 -0
  363. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_destroy.py +0 -0
  364. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_list.py +0 -0
  365. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_partial_update.py +0 -0
  366. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_retrieve.py +0 -0
  367. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/agent/agent_update.py +0 -0
  368. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/__init__.py +0 -0
  369. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/apilogs_list.py +0 -0
  370. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/apilogs_retrieve.py +0 -0
  371. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/apilogs/apilogs_summary_retrieve.py +0 -0
  372. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/__init__.py +0 -0
  373. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_create.py +0 -0
  374. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_destroy.py +0 -0
  375. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_list.py +0 -0
  376. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_partial_update.py +0 -0
  377. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_retrieve.py +0 -0
  378. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/attack/attack_update.py +0 -0
  379. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/checkout/__init__.py +0 -0
  380. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/checkout/checkout_create.py +0 -0
  381. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/generate/__init__.py +0 -0
  382. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/generate/v1_chat_completions_create.py +0 -0
  383. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/judge/__init__.py +0 -0
  384. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/judge/judge_create.py +0 -0
  385. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/__init__.py +0 -0
  386. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_context_retrieve.py +0 -0
  387. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_create.py +0 -0
  388. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_destroy.py +0 -0
  389. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_list.py +0 -0
  390. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/key/key_retrieve.py +0 -0
  391. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/models.py +0 -0
  392. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/__init__.py +0 -0
  393. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_create.py +0 -0
  394. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_destroy.py +0 -0
  395. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_list.py +0 -0
  396. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_me_retrieve.py +0 -0
  397. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_partial_update.py +0 -0
  398. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_retrieve.py +0 -0
  399. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/organization/organization_update.py +0 -0
  400. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/__init__.py +0 -0
  401. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_create.py +0 -0
  402. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_destroy.py +0 -0
  403. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_list.py +0 -0
  404. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_partial_update.py +0 -0
  405. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_retrieve.py +0 -0
  406. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_trace_create.py +0 -0
  407. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/result/result_update.py +0 -0
  408. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/__init__.py +0 -0
  409. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_create.py +0 -0
  410. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_destroy.py +0 -0
  411. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_list.py +0 -0
  412. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_partial_update.py +0 -0
  413. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_result_create.py +0 -0
  414. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_retrieve.py +0 -0
  415. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_run_tests_create.py +0 -0
  416. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/run/run_update.py +0 -0
  417. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/scripts/generate.py +0 -0
  418. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/scripts/generate.sh +0 -0
  419. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/scripts/openapi-python-client.yaml +0 -0
  420. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/__init__.py +0 -0
  421. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_create.py +0 -0
  422. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_destroy.py +0 -0
  423. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_list.py +0 -0
  424. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_me_retrieve.py +0 -0
  425. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_me_update.py +0 -0
  426. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_partial_update.py +0 -0
  427. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_retrieve.py +0 -0
  428. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/api/user/user_update.py +0 -0
  429. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/client.py +0 -0
  430. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/errors.py +0 -0
  431. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/__init__.py +0 -0
  432. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/base.py +0 -0
  433. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/buckets.py +0 -0
  434. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/enums.py +0 -0
  435. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/local.py +0 -0
  436. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/storage/remote.py +0 -0
  437. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/types.py +0 -0
  438. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/__init__.py +0 -0
  439. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_local_api.py +0 -0
  440. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_proxy.py +0 -0
  441. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_serializers.py +0 -0
  442. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/_static.py +0 -0
  443. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/server/webui/static/.gitignore +0 -0
  444. {hackagent-0.13.0 → hackagent-0.14.0}/hackagent/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: hackagent
3
- Version: 0.13.0
3
+ Version: 0.14.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
@@ -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={"messages": msgs2, "max_tokens": 50, "temperature": 0.0},
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)
@@ -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