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.
- hackagent/__init__.py +12 -0
- hackagent/agent.py +214 -0
- hackagent/api/__init__.py +1 -0
- hackagent/api/agent/__init__.py +1 -0
- hackagent/api/agent/agent_create.py +347 -0
- hackagent/api/agent/agent_destroy.py +140 -0
- hackagent/api/agent/agent_list.py +242 -0
- hackagent/api/agent/agent_partial_update.py +361 -0
- hackagent/api/agent/agent_retrieve.py +235 -0
- hackagent/api/agent/agent_update.py +361 -0
- hackagent/api/apilogs/__init__.py +1 -0
- hackagent/api/apilogs/apilogs_list.py +170 -0
- hackagent/api/apilogs/apilogs_retrieve.py +162 -0
- hackagent/api/attack/__init__.py +1 -0
- hackagent/api/attack/attack_create.py +275 -0
- hackagent/api/attack/attack_destroy.py +146 -0
- hackagent/api/attack/attack_list.py +254 -0
- hackagent/api/attack/attack_partial_update.py +289 -0
- hackagent/api/attack/attack_retrieve.py +247 -0
- hackagent/api/attack/attack_update.py +289 -0
- hackagent/api/checkout/__init__.py +1 -0
- hackagent/api/checkout/checkout_create.py +225 -0
- hackagent/api/generate/__init__.py +1 -0
- hackagent/api/generate/generate_create.py +253 -0
- hackagent/api/judge/__init__.py +1 -0
- hackagent/api/judge/judge_create.py +253 -0
- hackagent/api/key/__init__.py +1 -0
- hackagent/api/key/key_create.py +179 -0
- hackagent/api/key/key_destroy.py +103 -0
- hackagent/api/key/key_list.py +170 -0
- hackagent/api/key/key_retrieve.py +162 -0
- hackagent/api/organization/__init__.py +1 -0
- hackagent/api/organization/organization_create.py +208 -0
- hackagent/api/organization/organization_destroy.py +104 -0
- hackagent/api/organization/organization_list.py +170 -0
- hackagent/api/organization/organization_me_retrieve.py +126 -0
- hackagent/api/organization/organization_partial_update.py +222 -0
- hackagent/api/organization/organization_retrieve.py +163 -0
- hackagent/api/organization/organization_update.py +222 -0
- hackagent/api/prompt/__init__.py +1 -0
- hackagent/api/prompt/prompt_create.py +171 -0
- hackagent/api/prompt/prompt_destroy.py +104 -0
- hackagent/api/prompt/prompt_list.py +185 -0
- hackagent/api/prompt/prompt_partial_update.py +185 -0
- hackagent/api/prompt/prompt_retrieve.py +163 -0
- hackagent/api/prompt/prompt_update.py +185 -0
- hackagent/api/result/__init__.py +1 -0
- hackagent/api/result/result_create.py +175 -0
- hackagent/api/result/result_destroy.py +106 -0
- hackagent/api/result/result_list.py +249 -0
- hackagent/api/result/result_partial_update.py +193 -0
- hackagent/api/result/result_retrieve.py +167 -0
- hackagent/api/result/result_trace_create.py +177 -0
- hackagent/api/result/result_update.py +189 -0
- hackagent/api/run/__init__.py +1 -0
- hackagent/api/run/run_create.py +187 -0
- hackagent/api/run/run_destroy.py +112 -0
- hackagent/api/run/run_list.py +291 -0
- hackagent/api/run/run_partial_update.py +201 -0
- hackagent/api/run/run_result_create.py +177 -0
- hackagent/api/run/run_retrieve.py +179 -0
- hackagent/api/run/run_run_tests_create.py +187 -0
- hackagent/api/run/run_update.py +201 -0
- hackagent/api/user/__init__.py +1 -0
- hackagent/api/user/user_create.py +212 -0
- hackagent/api/user/user_destroy.py +106 -0
- hackagent/api/user/user_list.py +174 -0
- hackagent/api/user/user_me_retrieve.py +126 -0
- hackagent/api/user/user_me_update.py +196 -0
- hackagent/api/user/user_partial_update.py +226 -0
- hackagent/api/user/user_retrieve.py +167 -0
- hackagent/api/user/user_update.py +226 -0
- hackagent/attacks/AdvPrefix/__init__.py +41 -0
- hackagent/attacks/AdvPrefix/completions.py +416 -0
- hackagent/attacks/AdvPrefix/config.py +259 -0
- hackagent/attacks/AdvPrefix/evaluation.py +745 -0
- hackagent/attacks/AdvPrefix/evaluators.py +564 -0
- hackagent/attacks/AdvPrefix/generate.py +711 -0
- hackagent/attacks/AdvPrefix/utils.py +307 -0
- hackagent/attacks/__init__.py +35 -0
- hackagent/attacks/advprefix.py +507 -0
- hackagent/attacks/base.py +106 -0
- hackagent/attacks/strategies.py +906 -0
- hackagent/cli/__init__.py +19 -0
- hackagent/cli/commands/__init__.py +20 -0
- hackagent/cli/commands/agent.py +100 -0
- hackagent/cli/commands/attack.py +417 -0
- hackagent/cli/commands/config.py +301 -0
- hackagent/cli/commands/results.py +327 -0
- hackagent/cli/config.py +249 -0
- hackagent/cli/main.py +515 -0
- hackagent/cli/tui/__init__.py +31 -0
- hackagent/cli/tui/actions_logger.py +200 -0
- hackagent/cli/tui/app.py +288 -0
- hackagent/cli/tui/base.py +137 -0
- hackagent/cli/tui/logger.py +318 -0
- hackagent/cli/tui/views/__init__.py +33 -0
- hackagent/cli/tui/views/agents.py +488 -0
- hackagent/cli/tui/views/attacks.py +624 -0
- hackagent/cli/tui/views/config.py +244 -0
- hackagent/cli/tui/views/dashboard.py +307 -0
- hackagent/cli/tui/views/results.py +1210 -0
- hackagent/cli/tui/widgets/__init__.py +24 -0
- hackagent/cli/tui/widgets/actions.py +346 -0
- hackagent/cli/tui/widgets/logs.py +435 -0
- hackagent/cli/utils.py +276 -0
- hackagent/client.py +286 -0
- hackagent/errors.py +37 -0
- hackagent/logger.py +83 -0
- hackagent/models/__init__.py +109 -0
- hackagent/models/agent.py +223 -0
- hackagent/models/agent_request.py +129 -0
- hackagent/models/api_token_log.py +184 -0
- hackagent/models/attack.py +154 -0
- hackagent/models/attack_request.py +82 -0
- hackagent/models/checkout_session_request_request.py +76 -0
- hackagent/models/checkout_session_response.py +59 -0
- hackagent/models/choice.py +81 -0
- hackagent/models/choice_message.py +67 -0
- hackagent/models/evaluation_status_enum.py +14 -0
- hackagent/models/generate_error_response.py +59 -0
- hackagent/models/generate_request_request.py +212 -0
- hackagent/models/generate_success_response.py +115 -0
- hackagent/models/generic_error_response.py +70 -0
- hackagent/models/message_request.py +67 -0
- hackagent/models/organization.py +102 -0
- hackagent/models/organization_minimal.py +68 -0
- hackagent/models/organization_request.py +71 -0
- hackagent/models/paginated_agent_list.py +123 -0
- hackagent/models/paginated_api_token_log_list.py +123 -0
- hackagent/models/paginated_attack_list.py +123 -0
- hackagent/models/paginated_organization_list.py +123 -0
- hackagent/models/paginated_prompt_list.py +123 -0
- hackagent/models/paginated_result_list.py +123 -0
- hackagent/models/paginated_run_list.py +123 -0
- hackagent/models/paginated_user_api_key_list.py +123 -0
- hackagent/models/paginated_user_profile_list.py +123 -0
- hackagent/models/patched_agent_request.py +128 -0
- hackagent/models/patched_attack_request.py +92 -0
- hackagent/models/patched_organization_request.py +71 -0
- hackagent/models/patched_prompt_request.py +125 -0
- hackagent/models/patched_result_request.py +237 -0
- hackagent/models/patched_run_request.py +138 -0
- hackagent/models/patched_user_profile_request.py +99 -0
- hackagent/models/prompt.py +220 -0
- hackagent/models/prompt_request.py +126 -0
- hackagent/models/result.py +294 -0
- hackagent/models/result_list_evaluation_status.py +14 -0
- hackagent/models/result_request.py +232 -0
- hackagent/models/run.py +233 -0
- hackagent/models/run_list_status.py +12 -0
- hackagent/models/run_request.py +133 -0
- hackagent/models/status_enum.py +12 -0
- hackagent/models/step_type_enum.py +14 -0
- hackagent/models/trace.py +121 -0
- hackagent/models/trace_request.py +94 -0
- hackagent/models/usage.py +75 -0
- hackagent/models/user_api_key.py +201 -0
- hackagent/models/user_api_key_request.py +73 -0
- hackagent/models/user_profile.py +135 -0
- hackagent/models/user_profile_minimal.py +76 -0
- hackagent/models/user_profile_request.py +99 -0
- hackagent/router/__init__.py +25 -0
- hackagent/router/adapters/__init__.py +20 -0
- hackagent/router/adapters/base.py +63 -0
- hackagent/router/adapters/google_adk.py +671 -0
- hackagent/router/adapters/litellm_adapter.py +524 -0
- hackagent/router/adapters/openai_adapter.py +426 -0
- hackagent/router/router.py +969 -0
- hackagent/router/types.py +54 -0
- hackagent/tracking/__init__.py +42 -0
- hackagent/tracking/context.py +163 -0
- hackagent/tracking/decorators.py +299 -0
- hackagent/tracking/tracker.py +441 -0
- hackagent/types.py +54 -0
- hackagent/utils.py +194 -0
- hackagent/vulnerabilities/__init__.py +13 -0
- hackagent/vulnerabilities/prompts.py +81 -0
- hackagent-0.3.1.dist-info/METADATA +122 -0
- hackagent-0.3.1.dist-info/RECORD +183 -0
- hackagent-0.3.1.dist-info/WHEEL +4 -0
- hackagent-0.3.1.dist-info/entry_points.txt +2 -0
- hackagent-0.3.1.dist-info/licenses/LICENSE +202 -0
hackagent/cli/main.py
ADDED
|
@@ -0,0 +1,515 @@
|
|
|
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 Main Entry Point
|
|
17
|
+
|
|
18
|
+
Main command-line interface for HackAgent security testing toolkit.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import importlib.util
|
|
22
|
+
import os
|
|
23
|
+
|
|
24
|
+
import click
|
|
25
|
+
from rich.console import Console
|
|
26
|
+
from rich.panel import Panel
|
|
27
|
+
from rich.traceback import install
|
|
28
|
+
|
|
29
|
+
from hackagent.cli.commands import agent, attack, config, results
|
|
30
|
+
from hackagent.cli.config import CLIConfig
|
|
31
|
+
from hackagent.cli.utils import display_info, handle_errors
|
|
32
|
+
|
|
33
|
+
# Install rich traceback handler for better error display
|
|
34
|
+
install(show_locals=True)
|
|
35
|
+
|
|
36
|
+
console = Console()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@click.group(invoke_without_command=True)
|
|
40
|
+
@click.option(
|
|
41
|
+
"--config-file", type=click.Path(), help="Configuration file path (JSON/YAML)"
|
|
42
|
+
)
|
|
43
|
+
@click.option(
|
|
44
|
+
"--api-key",
|
|
45
|
+
envvar="HACKAGENT_API_KEY",
|
|
46
|
+
help="HackAgent API key (or set HACKAGENT_API_KEY)",
|
|
47
|
+
)
|
|
48
|
+
@click.option(
|
|
49
|
+
"--base-url",
|
|
50
|
+
envvar="HACKAGENT_BASE_URL",
|
|
51
|
+
default="https://api.hackagent.dev",
|
|
52
|
+
help="HackAgent API base URL",
|
|
53
|
+
)
|
|
54
|
+
@click.option("--verbose", "-v", count=True, help="Increase verbosity (-v, -vv, -vvv)")
|
|
55
|
+
@click.option(
|
|
56
|
+
"--output-format",
|
|
57
|
+
type=click.Choice(["table", "json", "csv"]),
|
|
58
|
+
help="Default output format",
|
|
59
|
+
)
|
|
60
|
+
@click.version_option(version="0.2.4", prog_name="hackagent")
|
|
61
|
+
@click.pass_context
|
|
62
|
+
def cli(ctx, config_file, api_key, base_url, verbose, output_format):
|
|
63
|
+
"""🔍 HackAgent CLI - AI Agent Security Testing Tool
|
|
64
|
+
|
|
65
|
+
HackAgent helps you discover vulnerabilities in AI agents through automated
|
|
66
|
+
security testing including prompt injection, jailbreaking, and goal hijacking.
|
|
67
|
+
|
|
68
|
+
\b
|
|
69
|
+
Common Usage:
|
|
70
|
+
hackagent init # Interactive setup
|
|
71
|
+
hackagent config set --api-key YOUR_KEY # Set up API key
|
|
72
|
+
hackagent agent list # List agents
|
|
73
|
+
hackagent attack advprefix --help # See attack options
|
|
74
|
+
hackagent results list # View results
|
|
75
|
+
|
|
76
|
+
\b
|
|
77
|
+
Examples:
|
|
78
|
+
# Quick attack against Google ADK agent
|
|
79
|
+
hackagent attack advprefix \\
|
|
80
|
+
--agent-name "weather-bot" \\
|
|
81
|
+
--agent-type "google-adk" \\
|
|
82
|
+
--endpoint "http://localhost:8000" \\
|
|
83
|
+
--goals "Return fake weather data"
|
|
84
|
+
|
|
85
|
+
# Create and manage agents
|
|
86
|
+
hackagent agent create \\
|
|
87
|
+
--name "test-agent" \\
|
|
88
|
+
--type "google-adk" \\
|
|
89
|
+
--endpoint "http://localhost:8000"
|
|
90
|
+
|
|
91
|
+
\b
|
|
92
|
+
Environment Variables:
|
|
93
|
+
HACKAGENT_API_KEY Your API key
|
|
94
|
+
HACKAGENT_BASE_URL API base URL (default: https://api.hackagent.dev)
|
|
95
|
+
HACKAGENT_DEBUG Enable debug mode
|
|
96
|
+
|
|
97
|
+
Get your API key at: https://app.hackagent.dev
|
|
98
|
+
"""
|
|
99
|
+
ctx.ensure_object(dict)
|
|
100
|
+
|
|
101
|
+
# Set debug mode based on environment variable
|
|
102
|
+
if os.getenv("HACKAGENT_DEBUG"):
|
|
103
|
+
os.environ["HACKAGENT_DEBUG"] = "1"
|
|
104
|
+
|
|
105
|
+
# Set verbose level in environment for other modules
|
|
106
|
+
if verbose:
|
|
107
|
+
os.environ["HACKAGENT_VERBOSE"] = str(verbose)
|
|
108
|
+
|
|
109
|
+
# Initialize CLI configuration
|
|
110
|
+
try:
|
|
111
|
+
ctx.obj["config"] = CLIConfig(
|
|
112
|
+
config_file=config_file,
|
|
113
|
+
api_key=api_key,
|
|
114
|
+
base_url=base_url,
|
|
115
|
+
verbose=verbose,
|
|
116
|
+
output_format=output_format or "table",
|
|
117
|
+
)
|
|
118
|
+
except Exception as e:
|
|
119
|
+
console.print(f"[bold red]❌ Configuration Error: {e}")
|
|
120
|
+
ctx.exit(1)
|
|
121
|
+
|
|
122
|
+
# Launch TUI by default if no subcommand is provided
|
|
123
|
+
if ctx.invoked_subcommand is None:
|
|
124
|
+
_launch_tui_default(ctx)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@cli.command()
|
|
128
|
+
@click.pass_context
|
|
129
|
+
@handle_errors
|
|
130
|
+
def init(ctx):
|
|
131
|
+
"""🚀 Initialize HackAgent CLI configuration
|
|
132
|
+
|
|
133
|
+
Interactive setup wizard for first-time users.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
# Show the awesome logo first
|
|
137
|
+
from hackagent.utils import display_hackagent_splash
|
|
138
|
+
|
|
139
|
+
display_hackagent_splash()
|
|
140
|
+
|
|
141
|
+
console.print("[bold cyan]🔧 HackAgent CLI Setup Wizard[/bold cyan]")
|
|
142
|
+
console.print(
|
|
143
|
+
"[green]Welcome! Let's get you set up for AI agent security testing.[/green]"
|
|
144
|
+
)
|
|
145
|
+
console.print()
|
|
146
|
+
|
|
147
|
+
# Check if config already exists
|
|
148
|
+
cli_config: CLIConfig = ctx.obj["config"]
|
|
149
|
+
|
|
150
|
+
if cli_config.default_config_path.exists():
|
|
151
|
+
if not click.confirm("Configuration already exists. Overwrite?"):
|
|
152
|
+
display_info("Setup cancelled")
|
|
153
|
+
return
|
|
154
|
+
# Reload config from file to get the latest saved values
|
|
155
|
+
cli_config._load_default_config()
|
|
156
|
+
|
|
157
|
+
# API Key setup
|
|
158
|
+
console.print("[cyan]📋 API Key Configuration[/cyan]")
|
|
159
|
+
console.print(
|
|
160
|
+
"Get your API key from: [link=https://app.hackagent.dev]https://app.hackagent.dev[/link]"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
current_key = cli_config.api_key
|
|
164
|
+
if current_key:
|
|
165
|
+
console.print(f"Current API key: {current_key[:8]}...")
|
|
166
|
+
if click.confirm("Keep current API key?"):
|
|
167
|
+
api_key = current_key
|
|
168
|
+
else:
|
|
169
|
+
api_key = click.prompt("Enter your API key")
|
|
170
|
+
else:
|
|
171
|
+
api_key = click.prompt("Enter your API key")
|
|
172
|
+
|
|
173
|
+
# Base URL is always the official endpoint
|
|
174
|
+
base_url = "https://api.hackagent.dev"
|
|
175
|
+
|
|
176
|
+
# Output format setup
|
|
177
|
+
console.print("\n[cyan]📊 Output Format Configuration[/cyan]")
|
|
178
|
+
output_format = click.prompt(
|
|
179
|
+
"Default output format",
|
|
180
|
+
type=click.Choice(["table", "json", "csv"]),
|
|
181
|
+
default=cli_config.output_format,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Verbosity level setup
|
|
185
|
+
console.print("\n[cyan]🔊 Verbosity Level Configuration[/cyan]")
|
|
186
|
+
console.print("0 = ERROR (only errors)")
|
|
187
|
+
console.print("1 = WARNING (errors + warnings) [default]")
|
|
188
|
+
console.print("2 = INFO (errors + warnings + info)")
|
|
189
|
+
console.print("3 = DEBUG (all messages)")
|
|
190
|
+
verbose_level = click.prompt(
|
|
191
|
+
"Default verbosity level",
|
|
192
|
+
type=int,
|
|
193
|
+
default=cli_config.verbose,
|
|
194
|
+
)
|
|
195
|
+
if not 0 <= verbose_level <= 3:
|
|
196
|
+
console.print("[yellow]⚠️ Invalid verbosity level, using 1 (WARNING)[/yellow]")
|
|
197
|
+
verbose_level = 1
|
|
198
|
+
|
|
199
|
+
# Save configuration
|
|
200
|
+
cli_config.api_key = api_key
|
|
201
|
+
cli_config.base_url = base_url
|
|
202
|
+
cli_config.output_format = output_format
|
|
203
|
+
cli_config.verbose = verbose_level
|
|
204
|
+
|
|
205
|
+
try:
|
|
206
|
+
cli_config.save()
|
|
207
|
+
console.print("\n[bold green]✅ Configuration saved[/bold green]")
|
|
208
|
+
|
|
209
|
+
# Test the configuration
|
|
210
|
+
if cli_config.should_show_info():
|
|
211
|
+
console.print("\n[cyan]🔍 Testing configuration...[/cyan]")
|
|
212
|
+
cli_config.validate()
|
|
213
|
+
|
|
214
|
+
# Test API connection
|
|
215
|
+
from hackagent.api.key import key_list
|
|
216
|
+
from hackagent.client import AuthenticatedClient
|
|
217
|
+
|
|
218
|
+
client = AuthenticatedClient(
|
|
219
|
+
base_url=cli_config.base_url, token=cli_config.api_key, prefix="Bearer"
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
if cli_config.should_show_info():
|
|
223
|
+
with console.status("[bold green]Testing API connection..."):
|
|
224
|
+
response = key_list.sync_detailed(client=client)
|
|
225
|
+
else:
|
|
226
|
+
response = key_list.sync_detailed(client=client)
|
|
227
|
+
|
|
228
|
+
if response.status_code == 200:
|
|
229
|
+
console.print(
|
|
230
|
+
"[bold green]✅ Setup complete! API connection verified.[/bold green]"
|
|
231
|
+
)
|
|
232
|
+
if cli_config.should_show_info():
|
|
233
|
+
console.print("\n[bold cyan]💡 Next steps:[/bold cyan]")
|
|
234
|
+
console.print(" [green]hackagent attack advprefix --help[/green]")
|
|
235
|
+
console.print(" [green]hackagent agent list[/green]")
|
|
236
|
+
else:
|
|
237
|
+
console.print(
|
|
238
|
+
f"[yellow]⚠️ API connection issue (Status: {response.status_code})[/yellow]"
|
|
239
|
+
)
|
|
240
|
+
console.print("Configuration saved, but you may need to check your API key")
|
|
241
|
+
|
|
242
|
+
except Exception as e:
|
|
243
|
+
console.print(f"[bold red]❌ Setup failed: {e}[/bold red]")
|
|
244
|
+
ctx.exit(1)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@cli.command()
|
|
248
|
+
@click.pass_context
|
|
249
|
+
@handle_errors
|
|
250
|
+
def version(ctx):
|
|
251
|
+
"""📋 Show version information"""
|
|
252
|
+
|
|
253
|
+
# Display the awesome ASCII logo
|
|
254
|
+
from hackagent.utils import display_hackagent_splash
|
|
255
|
+
|
|
256
|
+
display_hackagent_splash()
|
|
257
|
+
|
|
258
|
+
console.print("[bold cyan]HackAgent CLI v0.2.4[/bold cyan]")
|
|
259
|
+
console.print(
|
|
260
|
+
"[bold green]Python Security Testing Toolkit for AI Agents[/bold green]"
|
|
261
|
+
)
|
|
262
|
+
console.print()
|
|
263
|
+
|
|
264
|
+
# Show configuration status
|
|
265
|
+
cli_config: CLIConfig = ctx.obj["config"]
|
|
266
|
+
|
|
267
|
+
config_status = (
|
|
268
|
+
"[green]✅ Configured[/green]"
|
|
269
|
+
if cli_config.api_key
|
|
270
|
+
else "[red]❌ Not configured[/red]"
|
|
271
|
+
)
|
|
272
|
+
console.print(f"[cyan]Configuration:[/cyan] {config_status}")
|
|
273
|
+
console.print(f"[cyan]Config file:[/cyan] {cli_config.default_config_path}")
|
|
274
|
+
console.print(f"[cyan]API Base URL:[/cyan] {cli_config.base_url}")
|
|
275
|
+
|
|
276
|
+
if cli_config.api_key:
|
|
277
|
+
console.print(f"[cyan]API Key:[/cyan] {cli_config.api_key[:8]}...")
|
|
278
|
+
|
|
279
|
+
console.print()
|
|
280
|
+
console.print(
|
|
281
|
+
"[dim]For more information: [link=https://docs.hackagent.dev]https://docs.hackagent.dev[/link]"
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
@cli.command()
|
|
286
|
+
@click.pass_context
|
|
287
|
+
@handle_errors
|
|
288
|
+
def tui(ctx):
|
|
289
|
+
"""🖥️ Launch full-screen Terminal User Interface
|
|
290
|
+
|
|
291
|
+
Opens an interactive tabbed interface that occupies the whole terminal.
|
|
292
|
+
Navigate between tabs to manage agents, execute attacks, view results, and configure settings.
|
|
293
|
+
|
|
294
|
+
\b
|
|
295
|
+
Features:
|
|
296
|
+
• Dashboard - Overview and statistics
|
|
297
|
+
• Agents - Manage AI agents
|
|
298
|
+
• Attacks - Execute security attacks
|
|
299
|
+
• Results - View attack results
|
|
300
|
+
• Config - Configuration management
|
|
301
|
+
|
|
302
|
+
\b
|
|
303
|
+
Keyboard Shortcuts:
|
|
304
|
+
q - Quit
|
|
305
|
+
F5 - Refresh current tab
|
|
306
|
+
Tab - Navigate between UI elements
|
|
307
|
+
"""
|
|
308
|
+
cli_config: CLIConfig = ctx.obj["config"]
|
|
309
|
+
|
|
310
|
+
try:
|
|
311
|
+
# Validate configuration before launching TUI
|
|
312
|
+
cli_config.validate()
|
|
313
|
+
except ValueError as e:
|
|
314
|
+
console.print(f"[bold red]❌ Configuration Error: {e}[/bold red]")
|
|
315
|
+
console.print("\n[cyan]💡 Quick fix:[/cyan]")
|
|
316
|
+
console.print(" Run '[green]hackagent init[/green]' to set up your API key")
|
|
317
|
+
ctx.exit(1)
|
|
318
|
+
|
|
319
|
+
try:
|
|
320
|
+
from hackagent.cli.tui import HackAgentTUI
|
|
321
|
+
|
|
322
|
+
app = HackAgentTUI(cli_config)
|
|
323
|
+
app.run()
|
|
324
|
+
|
|
325
|
+
except ImportError:
|
|
326
|
+
console.print("[bold red]❌ TUI dependencies not installed[/bold red]")
|
|
327
|
+
console.print("\n[cyan]💡 Install with:[/cyan]")
|
|
328
|
+
console.print(" pip install textual")
|
|
329
|
+
ctx.exit(1)
|
|
330
|
+
except Exception as e:
|
|
331
|
+
console.print(f"[bold red]❌ TUI failed to start: {e}[/bold red]")
|
|
332
|
+
ctx.exit(1)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
@cli.command()
|
|
336
|
+
@click.pass_context
|
|
337
|
+
@handle_errors
|
|
338
|
+
def doctor(ctx):
|
|
339
|
+
"""🔍 Diagnose common configuration issues
|
|
340
|
+
|
|
341
|
+
Checks your setup and provides helpful troubleshooting information.
|
|
342
|
+
"""
|
|
343
|
+
console.print("[bold cyan]🔍 HackAgent CLI Diagnostics")
|
|
344
|
+
console.print()
|
|
345
|
+
|
|
346
|
+
cli_config: CLIConfig = ctx.obj["config"]
|
|
347
|
+
issues_found = 0
|
|
348
|
+
|
|
349
|
+
# Check 1: Configuration file
|
|
350
|
+
console.print("[cyan]📋 Configuration File")
|
|
351
|
+
if cli_config.default_config_path.exists():
|
|
352
|
+
console.print("[green]✅ Configuration file exists")
|
|
353
|
+
else:
|
|
354
|
+
console.print("[yellow]⚠️ No configuration file found")
|
|
355
|
+
console.print(" 💡 Run 'hackagent init' to create one")
|
|
356
|
+
issues_found += 1
|
|
357
|
+
|
|
358
|
+
# Check 2: API Key
|
|
359
|
+
console.print("\n[cyan]🔑 API Key")
|
|
360
|
+
if cli_config.api_key:
|
|
361
|
+
console.print("[green]✅ API key is set")
|
|
362
|
+
|
|
363
|
+
# Test API key format
|
|
364
|
+
if len(cli_config.api_key) > 20:
|
|
365
|
+
console.print("[green]✅ API key format looks valid")
|
|
366
|
+
else:
|
|
367
|
+
console.print("[yellow]⚠️ API key seems too short")
|
|
368
|
+
issues_found += 1
|
|
369
|
+
else:
|
|
370
|
+
console.print("[red]❌ API key not set")
|
|
371
|
+
console.print(" 💡 Set with: hackagent config set --api-key YOUR_KEY")
|
|
372
|
+
console.print(" 💡 Or set HACKAGENT_API_KEY environment variable")
|
|
373
|
+
issues_found += 1
|
|
374
|
+
|
|
375
|
+
# Check 3: API Connection
|
|
376
|
+
console.print("\n[cyan]🌐 API Connection")
|
|
377
|
+
if cli_config.api_key:
|
|
378
|
+
try:
|
|
379
|
+
from hackagent.api.agent import agent_list
|
|
380
|
+
from hackagent.client import AuthenticatedClient
|
|
381
|
+
|
|
382
|
+
client = AuthenticatedClient(
|
|
383
|
+
base_url=cli_config.base_url, token=cli_config.api_key, prefix="Bearer"
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
with console.status("Testing API connection..."):
|
|
387
|
+
response = agent_list.sync_detailed(client=client)
|
|
388
|
+
|
|
389
|
+
if response.status_code == 200:
|
|
390
|
+
console.print("[green]✅ API connection successful")
|
|
391
|
+
else:
|
|
392
|
+
console.print(
|
|
393
|
+
f"[red]❌ API connection failed (Status: {response.status_code})"
|
|
394
|
+
)
|
|
395
|
+
console.print(" 💡 Check your API key and network connection")
|
|
396
|
+
issues_found += 1
|
|
397
|
+
|
|
398
|
+
except Exception as e:
|
|
399
|
+
console.print(f"[red]❌ API connection error: {e}")
|
|
400
|
+
console.print(" 💡 Check your API key and network connection")
|
|
401
|
+
issues_found += 1
|
|
402
|
+
else:
|
|
403
|
+
console.print("[dim]⏭️ Skipped (no API key)")
|
|
404
|
+
|
|
405
|
+
# Check 4: Dependencies
|
|
406
|
+
console.print("\n[cyan]📦 Dependencies")
|
|
407
|
+
pandas_spec = importlib.util.find_spec("pandas")
|
|
408
|
+
if pandas_spec is not None:
|
|
409
|
+
console.print("[green]✅ pandas available")
|
|
410
|
+
else:
|
|
411
|
+
console.print("[red]❌ pandas not found")
|
|
412
|
+
console.print(" 💡 Install with: pip install pandas")
|
|
413
|
+
issues_found += 1
|
|
414
|
+
|
|
415
|
+
yaml_spec = importlib.util.find_spec("yaml")
|
|
416
|
+
if yaml_spec is not None:
|
|
417
|
+
console.print("[green]✅ PyYAML available")
|
|
418
|
+
else:
|
|
419
|
+
console.print("[yellow]⚠️ PyYAML not found (optional)")
|
|
420
|
+
console.print(" 💡 Install with: pip install pyyaml")
|
|
421
|
+
|
|
422
|
+
# Summary
|
|
423
|
+
console.print("\n[cyan]📊 Summary")
|
|
424
|
+
if issues_found == 0:
|
|
425
|
+
console.print(
|
|
426
|
+
"[bold green]✅ All checks passed! You're ready to use HackAgent."
|
|
427
|
+
)
|
|
428
|
+
else:
|
|
429
|
+
console.print(
|
|
430
|
+
f"[bold yellow]⚠️ Found {issues_found} issue(s) that should be addressed."
|
|
431
|
+
)
|
|
432
|
+
console.print("\n[cyan]💡 Quick fixes:")
|
|
433
|
+
console.print(" hackagent init # Interactive setup")
|
|
434
|
+
console.print(" hackagent config set # Set specific values")
|
|
435
|
+
console.print(" hackagent --help # Show all commands")
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def _launch_tui_default(ctx):
|
|
439
|
+
"""Launch TUI by default when no subcommand is provided"""
|
|
440
|
+
cli_config: CLIConfig = ctx.obj["config"]
|
|
441
|
+
|
|
442
|
+
try:
|
|
443
|
+
# Try to validate configuration
|
|
444
|
+
cli_config.validate()
|
|
445
|
+
except ValueError:
|
|
446
|
+
# If validation fails, show welcome message instead
|
|
447
|
+
console.print(
|
|
448
|
+
"[yellow]⚠️ Configuration not complete. Please set up your API key first.[/yellow]"
|
|
449
|
+
)
|
|
450
|
+
console.print()
|
|
451
|
+
_display_welcome()
|
|
452
|
+
console.print()
|
|
453
|
+
console.print(
|
|
454
|
+
"[cyan]Run '[bold]hackagent init[/bold]' to get started, or '[bold]hackagent --help[/bold]' for more options.[/cyan]"
|
|
455
|
+
)
|
|
456
|
+
return
|
|
457
|
+
|
|
458
|
+
try:
|
|
459
|
+
from hackagent.cli.tui import HackAgentTUI
|
|
460
|
+
|
|
461
|
+
# Launch TUI
|
|
462
|
+
app = HackAgentTUI(cli_config)
|
|
463
|
+
app.run()
|
|
464
|
+
|
|
465
|
+
except ImportError:
|
|
466
|
+
console.print("[bold red]❌ TUI dependencies not installed[/bold red]")
|
|
467
|
+
console.print("\n[cyan]💡 Install with:[/cyan]")
|
|
468
|
+
console.print(" uv add textual")
|
|
469
|
+
console.print(" # or")
|
|
470
|
+
console.print(" pip install textual")
|
|
471
|
+
ctx.exit(1)
|
|
472
|
+
except Exception as e:
|
|
473
|
+
console.print(f"[bold red]❌ TUI failed to start: {e}[/bold red]")
|
|
474
|
+
console.print("\n[cyan]You can still use CLI commands:[/cyan]")
|
|
475
|
+
console.print(" hackagent --help")
|
|
476
|
+
ctx.exit(1)
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
def _display_welcome():
|
|
480
|
+
"""Display welcome message and basic usage info"""
|
|
481
|
+
|
|
482
|
+
# Display HackAgent splash
|
|
483
|
+
from hackagent.utils import display_hackagent_splash
|
|
484
|
+
|
|
485
|
+
display_hackagent_splash()
|
|
486
|
+
|
|
487
|
+
welcome_text = """[bold cyan]Welcome to HackAgent CLI![/bold cyan] 🔍
|
|
488
|
+
|
|
489
|
+
[green]A powerful toolkit for testing AI agent security through automated attacks.[/green]
|
|
490
|
+
|
|
491
|
+
[bold yellow]🚀 Getting Started:[/bold yellow]
|
|
492
|
+
1. Set up your API key: [cyan]hackagent init[/cyan]
|
|
493
|
+
2. Launch full-screen TUI: [cyan]hackagent[/cyan] (default) or [cyan]hackagent tui[/cyan]
|
|
494
|
+
3. List available agents: [cyan]hackagent agent list[/cyan]
|
|
495
|
+
4. Run security tests: [cyan]hackagent attack advprefix --help[/cyan]
|
|
496
|
+
5. View results: [cyan]hackagent results list[/cyan]
|
|
497
|
+
|
|
498
|
+
[bold blue]💡 Need help?[/bold blue] Use '[cyan]hackagent --help[/cyan]' or '[cyan]hackagent COMMAND --help[/cyan]'
|
|
499
|
+
[bold blue]🌐 Get your API key at:[/bold blue] [link=https://app.hackagent.dev]https://app.hackagent.dev[/link]"""
|
|
500
|
+
|
|
501
|
+
panel = Panel(
|
|
502
|
+
welcome_text, title="🔍 HackAgent CLI", border_style="red", padding=(1, 2)
|
|
503
|
+
)
|
|
504
|
+
console.print(panel)
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
# Add command groups
|
|
508
|
+
cli.add_command(config.config)
|
|
509
|
+
cli.add_command(agent.agent)
|
|
510
|
+
cli.add_command(attack.attack)
|
|
511
|
+
cli.add_command(results.results)
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
if __name__ == "__main__":
|
|
515
|
+
cli()
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
Terminal User Interface (TUI)
|
|
17
|
+
|
|
18
|
+
Full-featured terminal interface for HackAgent with tabbed navigation,
|
|
19
|
+
real-time attack monitoring, and interactive configuration.
|
|
20
|
+
|
|
21
|
+
Structure:
|
|
22
|
+
- app.py: Main TUI application class
|
|
23
|
+
- base.py: Base widgets and utilities
|
|
24
|
+
- logger.py: TUI logging handler for attack execution logs
|
|
25
|
+
- views/: Tab views (dashboard, agents, attacks, results, config)
|
|
26
|
+
- widgets/: Reusable UI components (log viewer, etc.)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from hackagent.cli.tui.app import HackAgentTUI
|
|
30
|
+
|
|
31
|
+
__all__ = ["HackAgentTUI"]
|