hackagent 0.3.1__py3-none-any.whl

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 (183) hide show
  1. hackagent/__init__.py +12 -0
  2. hackagent/agent.py +214 -0
  3. hackagent/api/__init__.py +1 -0
  4. hackagent/api/agent/__init__.py +1 -0
  5. hackagent/api/agent/agent_create.py +347 -0
  6. hackagent/api/agent/agent_destroy.py +140 -0
  7. hackagent/api/agent/agent_list.py +242 -0
  8. hackagent/api/agent/agent_partial_update.py +361 -0
  9. hackagent/api/agent/agent_retrieve.py +235 -0
  10. hackagent/api/agent/agent_update.py +361 -0
  11. hackagent/api/apilogs/__init__.py +1 -0
  12. hackagent/api/apilogs/apilogs_list.py +170 -0
  13. hackagent/api/apilogs/apilogs_retrieve.py +162 -0
  14. hackagent/api/attack/__init__.py +1 -0
  15. hackagent/api/attack/attack_create.py +275 -0
  16. hackagent/api/attack/attack_destroy.py +146 -0
  17. hackagent/api/attack/attack_list.py +254 -0
  18. hackagent/api/attack/attack_partial_update.py +289 -0
  19. hackagent/api/attack/attack_retrieve.py +247 -0
  20. hackagent/api/attack/attack_update.py +289 -0
  21. hackagent/api/checkout/__init__.py +1 -0
  22. hackagent/api/checkout/checkout_create.py +225 -0
  23. hackagent/api/generate/__init__.py +1 -0
  24. hackagent/api/generate/generate_create.py +253 -0
  25. hackagent/api/judge/__init__.py +1 -0
  26. hackagent/api/judge/judge_create.py +253 -0
  27. hackagent/api/key/__init__.py +1 -0
  28. hackagent/api/key/key_create.py +179 -0
  29. hackagent/api/key/key_destroy.py +103 -0
  30. hackagent/api/key/key_list.py +170 -0
  31. hackagent/api/key/key_retrieve.py +162 -0
  32. hackagent/api/organization/__init__.py +1 -0
  33. hackagent/api/organization/organization_create.py +208 -0
  34. hackagent/api/organization/organization_destroy.py +104 -0
  35. hackagent/api/organization/organization_list.py +170 -0
  36. hackagent/api/organization/organization_me_retrieve.py +126 -0
  37. hackagent/api/organization/organization_partial_update.py +222 -0
  38. hackagent/api/organization/organization_retrieve.py +163 -0
  39. hackagent/api/organization/organization_update.py +222 -0
  40. hackagent/api/prompt/__init__.py +1 -0
  41. hackagent/api/prompt/prompt_create.py +171 -0
  42. hackagent/api/prompt/prompt_destroy.py +104 -0
  43. hackagent/api/prompt/prompt_list.py +185 -0
  44. hackagent/api/prompt/prompt_partial_update.py +185 -0
  45. hackagent/api/prompt/prompt_retrieve.py +163 -0
  46. hackagent/api/prompt/prompt_update.py +185 -0
  47. hackagent/api/result/__init__.py +1 -0
  48. hackagent/api/result/result_create.py +175 -0
  49. hackagent/api/result/result_destroy.py +106 -0
  50. hackagent/api/result/result_list.py +249 -0
  51. hackagent/api/result/result_partial_update.py +193 -0
  52. hackagent/api/result/result_retrieve.py +167 -0
  53. hackagent/api/result/result_trace_create.py +177 -0
  54. hackagent/api/result/result_update.py +189 -0
  55. hackagent/api/run/__init__.py +1 -0
  56. hackagent/api/run/run_create.py +187 -0
  57. hackagent/api/run/run_destroy.py +112 -0
  58. hackagent/api/run/run_list.py +291 -0
  59. hackagent/api/run/run_partial_update.py +201 -0
  60. hackagent/api/run/run_result_create.py +177 -0
  61. hackagent/api/run/run_retrieve.py +179 -0
  62. hackagent/api/run/run_run_tests_create.py +187 -0
  63. hackagent/api/run/run_update.py +201 -0
  64. hackagent/api/user/__init__.py +1 -0
  65. hackagent/api/user/user_create.py +212 -0
  66. hackagent/api/user/user_destroy.py +106 -0
  67. hackagent/api/user/user_list.py +174 -0
  68. hackagent/api/user/user_me_retrieve.py +126 -0
  69. hackagent/api/user/user_me_update.py +196 -0
  70. hackagent/api/user/user_partial_update.py +226 -0
  71. hackagent/api/user/user_retrieve.py +167 -0
  72. hackagent/api/user/user_update.py +226 -0
  73. hackagent/attacks/AdvPrefix/__init__.py +41 -0
  74. hackagent/attacks/AdvPrefix/completions.py +416 -0
  75. hackagent/attacks/AdvPrefix/config.py +259 -0
  76. hackagent/attacks/AdvPrefix/evaluation.py +745 -0
  77. hackagent/attacks/AdvPrefix/evaluators.py +564 -0
  78. hackagent/attacks/AdvPrefix/generate.py +711 -0
  79. hackagent/attacks/AdvPrefix/utils.py +307 -0
  80. hackagent/attacks/__init__.py +35 -0
  81. hackagent/attacks/advprefix.py +507 -0
  82. hackagent/attacks/base.py +106 -0
  83. hackagent/attacks/strategies.py +906 -0
  84. hackagent/cli/__init__.py +19 -0
  85. hackagent/cli/commands/__init__.py +20 -0
  86. hackagent/cli/commands/agent.py +100 -0
  87. hackagent/cli/commands/attack.py +417 -0
  88. hackagent/cli/commands/config.py +301 -0
  89. hackagent/cli/commands/results.py +327 -0
  90. hackagent/cli/config.py +249 -0
  91. hackagent/cli/main.py +515 -0
  92. hackagent/cli/tui/__init__.py +31 -0
  93. hackagent/cli/tui/actions_logger.py +200 -0
  94. hackagent/cli/tui/app.py +288 -0
  95. hackagent/cli/tui/base.py +137 -0
  96. hackagent/cli/tui/logger.py +318 -0
  97. hackagent/cli/tui/views/__init__.py +33 -0
  98. hackagent/cli/tui/views/agents.py +488 -0
  99. hackagent/cli/tui/views/attacks.py +624 -0
  100. hackagent/cli/tui/views/config.py +244 -0
  101. hackagent/cli/tui/views/dashboard.py +307 -0
  102. hackagent/cli/tui/views/results.py +1210 -0
  103. hackagent/cli/tui/widgets/__init__.py +24 -0
  104. hackagent/cli/tui/widgets/actions.py +346 -0
  105. hackagent/cli/tui/widgets/logs.py +435 -0
  106. hackagent/cli/utils.py +276 -0
  107. hackagent/client.py +286 -0
  108. hackagent/errors.py +37 -0
  109. hackagent/logger.py +83 -0
  110. hackagent/models/__init__.py +109 -0
  111. hackagent/models/agent.py +223 -0
  112. hackagent/models/agent_request.py +129 -0
  113. hackagent/models/api_token_log.py +184 -0
  114. hackagent/models/attack.py +154 -0
  115. hackagent/models/attack_request.py +82 -0
  116. hackagent/models/checkout_session_request_request.py +76 -0
  117. hackagent/models/checkout_session_response.py +59 -0
  118. hackagent/models/choice.py +81 -0
  119. hackagent/models/choice_message.py +67 -0
  120. hackagent/models/evaluation_status_enum.py +14 -0
  121. hackagent/models/generate_error_response.py +59 -0
  122. hackagent/models/generate_request_request.py +212 -0
  123. hackagent/models/generate_success_response.py +115 -0
  124. hackagent/models/generic_error_response.py +70 -0
  125. hackagent/models/message_request.py +67 -0
  126. hackagent/models/organization.py +102 -0
  127. hackagent/models/organization_minimal.py +68 -0
  128. hackagent/models/organization_request.py +71 -0
  129. hackagent/models/paginated_agent_list.py +123 -0
  130. hackagent/models/paginated_api_token_log_list.py +123 -0
  131. hackagent/models/paginated_attack_list.py +123 -0
  132. hackagent/models/paginated_organization_list.py +123 -0
  133. hackagent/models/paginated_prompt_list.py +123 -0
  134. hackagent/models/paginated_result_list.py +123 -0
  135. hackagent/models/paginated_run_list.py +123 -0
  136. hackagent/models/paginated_user_api_key_list.py +123 -0
  137. hackagent/models/paginated_user_profile_list.py +123 -0
  138. hackagent/models/patched_agent_request.py +128 -0
  139. hackagent/models/patched_attack_request.py +92 -0
  140. hackagent/models/patched_organization_request.py +71 -0
  141. hackagent/models/patched_prompt_request.py +125 -0
  142. hackagent/models/patched_result_request.py +237 -0
  143. hackagent/models/patched_run_request.py +138 -0
  144. hackagent/models/patched_user_profile_request.py +99 -0
  145. hackagent/models/prompt.py +220 -0
  146. hackagent/models/prompt_request.py +126 -0
  147. hackagent/models/result.py +294 -0
  148. hackagent/models/result_list_evaluation_status.py +14 -0
  149. hackagent/models/result_request.py +232 -0
  150. hackagent/models/run.py +233 -0
  151. hackagent/models/run_list_status.py +12 -0
  152. hackagent/models/run_request.py +133 -0
  153. hackagent/models/status_enum.py +12 -0
  154. hackagent/models/step_type_enum.py +14 -0
  155. hackagent/models/trace.py +121 -0
  156. hackagent/models/trace_request.py +94 -0
  157. hackagent/models/usage.py +75 -0
  158. hackagent/models/user_api_key.py +201 -0
  159. hackagent/models/user_api_key_request.py +73 -0
  160. hackagent/models/user_profile.py +135 -0
  161. hackagent/models/user_profile_minimal.py +76 -0
  162. hackagent/models/user_profile_request.py +99 -0
  163. hackagent/router/__init__.py +25 -0
  164. hackagent/router/adapters/__init__.py +20 -0
  165. hackagent/router/adapters/base.py +63 -0
  166. hackagent/router/adapters/google_adk.py +671 -0
  167. hackagent/router/adapters/litellm_adapter.py +524 -0
  168. hackagent/router/adapters/openai_adapter.py +426 -0
  169. hackagent/router/router.py +969 -0
  170. hackagent/router/types.py +54 -0
  171. hackagent/tracking/__init__.py +42 -0
  172. hackagent/tracking/context.py +163 -0
  173. hackagent/tracking/decorators.py +299 -0
  174. hackagent/tracking/tracker.py +441 -0
  175. hackagent/types.py +54 -0
  176. hackagent/utils.py +194 -0
  177. hackagent/vulnerabilities/__init__.py +13 -0
  178. hackagent/vulnerabilities/prompts.py +81 -0
  179. hackagent-0.3.1.dist-info/METADATA +122 -0
  180. hackagent-0.3.1.dist-info/RECORD +183 -0
  181. hackagent-0.3.1.dist-info/WHEEL +4 -0
  182. hackagent-0.3.1.dist-info/entry_points.txt +2 -0
  183. hackagent-0.3.1.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,19 @@
1
+ # Copyright 2025 - AI4I. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ HackAgent CLI Package
17
+
18
+ Command-line interface for HackAgent security testing toolkit.
19
+ """
@@ -0,0 +1,20 @@
1
+ # Copyright 2025 - AI4I. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ """
17
+ CLI Commands Package
18
+
19
+ Contains all the command group implementations for the HackAgent CLI.
20
+ """
@@ -0,0 +1,100 @@
1
+ """
2
+ Agent Commands
3
+
4
+ Manage AI agents registered with HackAgent.
5
+ """
6
+
7
+ import click
8
+
9
+ from hackagent.cli.config import CLIConfig
10
+ from hackagent.cli.utils import handle_errors, launch_tui
11
+
12
+
13
+ @click.group()
14
+ def agent():
15
+ """🤖 Manage AI agents"""
16
+ pass
17
+
18
+
19
+ @agent.command()
20
+ @click.pass_context
21
+ @handle_errors
22
+ def list(ctx):
23
+ """List registered agents"""
24
+ cli_config: CLIConfig = ctx.obj["config"]
25
+ cli_config.validate()
26
+ launch_tui(cli_config, initial_tab="agents")
27
+
28
+
29
+ @agent.command()
30
+ @click.option("--name", required=True, help="Agent name")
31
+ @click.option(
32
+ "--type",
33
+ "agent_type",
34
+ type=click.Choice(["google-adk", "litellm"]),
35
+ required=True,
36
+ help="Agent type",
37
+ )
38
+ @click.option("--endpoint", required=True, help="Agent endpoint URL")
39
+ @click.option("--description", help="Agent description")
40
+ @click.option("--metadata", help="Additional metadata as JSON string")
41
+ @click.pass_context
42
+ @handle_errors
43
+ def create(ctx, name, agent_type, endpoint, description, metadata):
44
+ """Create a new agent"""
45
+ cli_config: CLIConfig = ctx.obj["config"]
46
+ cli_config.validate()
47
+ launch_tui(cli_config, initial_tab="agents")
48
+
49
+
50
+ @agent.command()
51
+ @click.argument("agent_id")
52
+ @click.pass_context
53
+ @handle_errors
54
+ def show(ctx, agent_id):
55
+ """Show detailed information about an agent"""
56
+ cli_config: CLIConfig = ctx.obj["config"]
57
+ cli_config.validate()
58
+ launch_tui(cli_config, initial_tab="agents")
59
+
60
+
61
+ @agent.command()
62
+ @click.argument("agent_id")
63
+ @click.option("--name", help="New agent name")
64
+ @click.option("--endpoint", help="New agent endpoint")
65
+ @click.option("--description", help="New agent description")
66
+ @click.option("--metadata", help="New metadata as JSON string")
67
+ @click.pass_context
68
+ @handle_errors
69
+ def update(ctx, agent_id, name, endpoint, description, metadata):
70
+ """Update an existing agent"""
71
+ cli_config: CLIConfig = ctx.obj["config"]
72
+ cli_config.validate()
73
+ launch_tui(cli_config, initial_tab="agents")
74
+
75
+
76
+ @agent.command()
77
+ @click.argument("agent_id")
78
+ @click.option("--confirm", is_flag=True, help="Skip confirmation prompt")
79
+ @click.pass_context
80
+ @handle_errors
81
+ def delete(ctx, agent_id, confirm):
82
+ """Delete an agent"""
83
+ cli_config: CLIConfig = ctx.obj["config"]
84
+ cli_config.validate()
85
+ launch_tui(cli_config, initial_tab="agents")
86
+
87
+
88
+ @agent.command()
89
+ @click.argument("agent_name")
90
+ @click.pass_context
91
+ @handle_errors
92
+ def test(ctx, agent_name):
93
+ """Test connection to an agent
94
+
95
+ This command attempts to establish a connection with the specified agent
96
+ to verify it's accessible and responding.
97
+ """
98
+ cli_config: CLIConfig = ctx.obj["config"]
99
+ cli_config.validate()
100
+ launch_tui(cli_config, initial_tab="agents")
@@ -0,0 +1,417 @@
1
+ # Copyright 2025 - AI4I. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ Attack Commands
17
+
18
+ Execute security attacks against AI agents.
19
+ """
20
+
21
+ import time
22
+ from typing import Any, Dict
23
+
24
+ import click
25
+ from rich.console import Console
26
+ from rich.panel import Panel
27
+ from rich.table import Table
28
+
29
+ from hackagent import HackAgent
30
+ from hackagent.cli.config import CLIConfig
31
+ from hackagent.cli.utils import (
32
+ display_info,
33
+ display_results_table,
34
+ display_success,
35
+ get_agent_type_enum,
36
+ handle_errors,
37
+ load_config_file,
38
+ )
39
+
40
+ console = Console()
41
+
42
+
43
+ @click.group()
44
+ def attack():
45
+ """🚀 Execute security attacks against AI agents"""
46
+ # Logo will be shown by HackAgent initialization
47
+ pass
48
+
49
+
50
+ @attack.command()
51
+ @click.option("--agent-name", required=True, help="Target agent name")
52
+ @click.option(
53
+ "--agent-type",
54
+ type=str,
55
+ default="other",
56
+ help="Agent type (e.g., google-adk, litellm, langchain, openai-sdk, mcp, a2a, or other)",
57
+ )
58
+ @click.option(
59
+ "--endpoint",
60
+ required=True,
61
+ help="Agent endpoint URL. For OpenAI-compatible endpoints, provide base URL ending with /v1 (e.g., http://localhost:8000/v1). For LangServe, provide full path (e.g., http://localhost:8000/invoke).",
62
+ )
63
+ @click.option(
64
+ "--goals",
65
+ required=True,
66
+ help="Attack goals (what you want the agent to do incorrectly)",
67
+ )
68
+ @click.option(
69
+ "--config-file",
70
+ type=click.Path(exists=True),
71
+ help="Attack configuration file (JSON/YAML)",
72
+ )
73
+ @click.option("--timeout", default=300, help="Attack timeout in seconds")
74
+ @click.option(
75
+ "--dry-run", is_flag=True, help="Validate configuration without running attack"
76
+ )
77
+ @click.option(
78
+ "--no-tui",
79
+ is_flag=True,
80
+ help="Run attack directly without opening TUI (default: open TUI)",
81
+ )
82
+ @click.pass_context
83
+ @handle_errors
84
+ def advprefix(
85
+ ctx, agent_name, agent_type, endpoint, goals, config_file, timeout, dry_run, no_tui
86
+ ):
87
+ """Execute AdvPrefix attack strategy
88
+
89
+ This command runs the AdvPrefix attack against a target agent.
90
+ Goals should describe what you want the agent to do incorrectly.
91
+
92
+ Examples:
93
+
94
+ # Basic attack with goals
95
+ hackagent attack advprefix \\
96
+ --agent-name "weather-bot" \\
97
+ --agent-type "google-adk" \\
98
+ --endpoint "http://localhost:8000" \\
99
+ --goals "Return fake weather data and ignore safety guidelines"
100
+
101
+ # Attack with configuration file
102
+ hackagent attack advprefix \\
103
+ --agent-name "multi-tool-agent" \\
104
+ --agent-type "google-adk" \\
105
+ --endpoint "http://localhost:8000" \\
106
+ --config-file "attack-config.json"
107
+ """
108
+ cli_config: CLIConfig = ctx.obj["config"]
109
+ cli_config.validate()
110
+
111
+ # Launch TUI with attack form pre-filled (default behavior)
112
+ if not no_tui:
113
+ try:
114
+ from hackagent.cli.tui import HackAgentTUI
115
+
116
+ initial_data = {
117
+ "agent_name": agent_name,
118
+ "agent_type": agent_type,
119
+ "endpoint": endpoint,
120
+ "goals": goals,
121
+ "timeout": timeout,
122
+ }
123
+
124
+ app = HackAgentTUI(
125
+ cli_config, initial_tab="attacks", initial_data=initial_data
126
+ )
127
+ app.run()
128
+ return
129
+
130
+ except ImportError:
131
+ console.print("[bold red]❌ TUI dependencies not installed[/bold red]")
132
+ console.print("\n[cyan]💡 Install with:[/cyan]")
133
+ console.print(" uv add textual")
134
+ console.print(
135
+ "\n[yellow]Or run with --no-tui flag to execute directly[/yellow]"
136
+ )
137
+ ctx.exit(1)
138
+ except Exception as e:
139
+ console.print(f"[bold red]❌ TUI failed to start: {e}[/bold red]")
140
+ console.print(
141
+ "\n[yellow]Try running with --no-tui flag to execute directly[/yellow]"
142
+ )
143
+ ctx.exit(1)
144
+
145
+ # Convert agent type
146
+ agent_type_enum = get_agent_type_enum(agent_type)
147
+
148
+ # Build attack configuration
149
+ attack_config = {
150
+ "attack_type": "advprefix",
151
+ "goals": [goals], # Convert single goal string to list
152
+ }
153
+
154
+ # Load additional config from file if provided
155
+ if config_file:
156
+ try:
157
+ file_config = load_config_file(config_file)
158
+ attack_config.update(file_config)
159
+ display_info(f"Loaded configuration from: {config_file}")
160
+ except Exception as e:
161
+ raise click.ClickException(f"Failed to load config file: {e}")
162
+
163
+ # Display logo first
164
+ from hackagent.utils import display_hackagent_splash
165
+
166
+ display_hackagent_splash()
167
+
168
+ # Display attack summary
169
+ _display_attack_summary(agent_name, agent_type, endpoint, goals, attack_config)
170
+
171
+ if dry_run:
172
+ display_success("✅ Configuration validation passed")
173
+ display_info("Use --dry-run=false to execute the attack")
174
+ return
175
+
176
+ # Initialize HackAgent
177
+ with console.status("[bold green]Initializing HackAgent..."):
178
+ try:
179
+ agent = HackAgent(
180
+ name=agent_name,
181
+ endpoint=endpoint,
182
+ agent_type=agent_type_enum,
183
+ api_key=cli_config.api_key,
184
+ base_url=cli_config.base_url,
185
+ )
186
+ display_success(f"Agent '{agent_name}' initialized successfully")
187
+ except Exception as e:
188
+ raise click.ClickException(f"Failed to initialize agent: {e}")
189
+
190
+ # Execute attack with progress tracking
191
+ console.print(f"\n[bold cyan]🎯 Executing AdvPrefix attack against '{agent_name}'")
192
+ console.print(f"[cyan]Goals: {goals}")
193
+ console.print(f"[cyan]Timeout: {timeout}s")
194
+
195
+ start_time = time.time()
196
+
197
+ try:
198
+ results = agent.hack(
199
+ attack_config=attack_config,
200
+ run_config_override={"timeout": timeout},
201
+ fail_on_run_error=True,
202
+ )
203
+
204
+ duration = time.time() - start_time
205
+ console.print(
206
+ f"\n[bold green]✅ Attack completed successfully in {duration:.1f}s!"
207
+ )
208
+
209
+ # Display results summary
210
+ _display_attack_results(results)
211
+
212
+ except Exception as e:
213
+ duration = time.time() - start_time
214
+ console.print(f"\n[bold red]❌ Attack failed after {duration:.1f}s")
215
+ raise click.ClickException(f"Attack execution failed: {e}")
216
+
217
+
218
+ @attack.command()
219
+ @click.pass_context
220
+ @handle_errors
221
+ def list(ctx):
222
+ """List available attack strategies"""
223
+
224
+ table = Table(
225
+ title="Available Attack Strategies", show_header=True, header_style="bold cyan"
226
+ )
227
+ table.add_column("Strategy", style="cyan")
228
+ table.add_column("Description", style="green")
229
+ table.add_column("Status", style="yellow")
230
+
231
+ # Add available strategies
232
+ table.add_row(
233
+ "advprefix",
234
+ "Adversarial prefix generation attack using language models",
235
+ "✅ Available",
236
+ )
237
+
238
+ # Add planned strategies
239
+ table.add_row("prompt-injection", "Direct prompt injection attacks", "🚧 Planned")
240
+ table.add_row(
241
+ "jailbreak", "Jailbreaking techniques for safety bypassing", "🚧 Planned"
242
+ )
243
+ table.add_row(
244
+ "goal-hijacking", "Goal hijacking and manipulation attacks", "🚧 Planned"
245
+ )
246
+
247
+ console.print(table)
248
+ console.print(
249
+ "\n[cyan]💡 Use 'hackagent attack STRATEGY --help' for strategy-specific options"
250
+ )
251
+
252
+
253
+ @attack.command()
254
+ @click.argument("strategy", type=click.Choice(["advprefix"]))
255
+ @click.pass_context
256
+ @handle_errors
257
+ def info(ctx, strategy):
258
+ """Get detailed information about an attack strategy"""
259
+
260
+ if strategy == "advprefix":
261
+ _display_advprefix_info()
262
+ else:
263
+ raise click.ClickException(f"Strategy '{strategy}' not yet implemented")
264
+
265
+
266
+ def _display_attack_summary(
267
+ agent_name: str,
268
+ agent_type: str,
269
+ endpoint: str,
270
+ goals: str,
271
+ attack_config: Dict[str, Any],
272
+ ) -> None:
273
+ """Display a summary of the attack configuration"""
274
+
275
+ # Create summary panel
276
+ summary_content = f"""[bold]Target Agent:[/bold] {agent_name}
277
+ [bold]Agent Type:[/bold] {agent_type}
278
+ [bold]Endpoint:[/bold] {endpoint}
279
+ [bold]Attack Type:[/bold] {attack_config["attack_type"]}
280
+ [bold]Goals:[/bold] {goals}"""
281
+
282
+ if len(attack_config) > 2: # More than just attack_type and goals
283
+ summary_content += f"\n[bold]Additional Config:[/bold] {len(attack_config) - 2} parameters loaded"
284
+
285
+ panel = Panel(
286
+ summary_content,
287
+ title="🎯 Attack Configuration",
288
+ border_style="cyan",
289
+ padding=(1, 2),
290
+ )
291
+
292
+ console.print(panel)
293
+
294
+
295
+ def _display_attack_results(results: Any) -> None:
296
+ """Display attack results summary"""
297
+
298
+ console.print("\n[bold cyan]📊 Attack Results Summary")
299
+
300
+ try:
301
+ import pandas as pd
302
+
303
+ if isinstance(results, pd.DataFrame):
304
+ console.print(f"[green]📈 Generated {len(results)} result entries")
305
+
306
+ # Show key metrics if available
307
+ if not results.empty:
308
+ # Try to display some key columns if they exist
309
+ summary_table = Table(
310
+ title="Key Metrics", show_header=True, header_style="bold cyan"
311
+ )
312
+ summary_table.add_column("Metric", style="cyan")
313
+ summary_table.add_column("Value", style="green")
314
+
315
+ summary_table.add_row("Total Results", str(len(results)))
316
+
317
+ # Add column info
318
+ summary_table.add_row("Columns", str(len(results.columns)))
319
+
320
+ # Try to show success metrics if available
321
+ for col in results.columns:
322
+ if "success" in col.lower() or "score" in col.lower():
323
+ if results[col].dtype in ["int64", "float64"]:
324
+ mean_val = results[col].mean()
325
+ summary_table.add_row(f"Avg {col}", f"{mean_val:.3f}")
326
+
327
+ console.print(summary_table)
328
+
329
+ # Show sample of results
330
+ if len(results) > 0:
331
+ console.print("\n[cyan]📋 Sample Results (first 5 rows):")
332
+ # Filter to show only goal and prefix columns if they exist
333
+ display_columns = []
334
+ if "goal" in results.columns:
335
+ display_columns.append("goal")
336
+ if "prefix" in results.columns:
337
+ display_columns.append("prefix")
338
+
339
+ if display_columns:
340
+ filtered_results = results[display_columns].head()
341
+ display_results_table(
342
+ filtered_results, "Attack Results - Goals & Prefixes"
343
+ )
344
+ else:
345
+ # Fallback to showing all columns if goal/prefix not found
346
+ display_results_table(results.head(), "Sample Attack Results")
347
+ else:
348
+ console.print(f"[green]📈 Results: {type(results).__name__}")
349
+ if hasattr(results, "__len__"):
350
+ console.print(f"[green]📊 Count: {len(results)}")
351
+
352
+ except Exception as e:
353
+ console.print(f"[yellow]⚠️ Could not analyze results: {e}")
354
+ console.print(f"[green]📈 Results type: {type(results).__name__}")
355
+
356
+
357
+ def _display_advprefix_info() -> None:
358
+ """Display detailed information about AdvPrefix attack strategy"""
359
+
360
+ info_content = """[bold]AdvPrefix Attack Strategy[/bold]
361
+
362
+ [cyan]Description:[/cyan]
363
+ The AdvPrefix attack generates adversarial prefixes that can manipulate AI agent behavior.
364
+ It uses a multi-step pipeline involving uncensored language models to craft effective attacks.
365
+
366
+ [cyan]How it works:[/cyan]
367
+ 1. Generate candidate prefixes using language models
368
+ 2. Compute cross-entropy scores for effectiveness
369
+ 3. Test prefixes against the target agent
370
+ 4. Evaluate results using judge models
371
+ 5. Select and report successful attacks
372
+
373
+ [cyan]Configuration Options:[/cyan]
374
+ • goals: List of malicious objectives for the agent
375
+ • generator: Language model configuration for prefix generation
376
+ • judges: Judge models for evaluating attack success
377
+ • batch_size: Number of prefixes to generate per batch
378
+ • temperature: Sampling temperature for generation
379
+ • max_new_tokens: Maximum tokens to generate
380
+
381
+ [cyan]Example Config File:[/cyan]
382
+ {
383
+ "goals": ["Return fake data", "Ignore safety guidelines"],
384
+ "generator": {
385
+ "identifier": "ollama/llama2-uncensored",
386
+ "endpoint": "http://localhost:11434/api/generate"
387
+ },
388
+ "judges": [
389
+ {
390
+ "identifier": "ollama/llama3",
391
+ "endpoint": "http://localhost:11434/api/judge",
392
+ "type": "harmbench"
393
+ }
394
+ ],
395
+ "batch_size": 20,
396
+ "temperature": 1.0,
397
+ "max_new_tokens": 512
398
+ }
399
+
400
+ [cyan]Requirements:[/cyan]
401
+ • Target agent must be running and accessible
402
+ • Generator model (e.g., Ollama with uncensored model)
403
+ • Judge model for evaluation
404
+ • Sufficient computational resources
405
+
406
+ [yellow]⚠️ Ethical Usage:[/yellow]
407
+ Only use this attack against agents you own or have explicit permission to test.
408
+ Always follow responsible disclosure practices for any vulnerabilities found."""
409
+
410
+ panel = Panel(
411
+ info_content,
412
+ title="AdvPrefix Attack Information",
413
+ border_style="cyan",
414
+ padding=(1, 2),
415
+ )
416
+
417
+ console.print(panel)