hackagent 0.11.0__tar.gz → 0.13.0__tar.gz

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