-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.py
More file actions
179 lines (146 loc) · 6.43 KB
/
setup.py
File metadata and controls
179 lines (146 loc) · 6.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env python3
"""
Nmappy Setup - Configure LLM Provider
by Faizan | github.com/IncredibleHacker/nmappy
"""
import os
import json
import sys
from rich.console import Console
from rich.prompt import Prompt, Confirm
from rich.panel import Panel
from rich.table import Table
console = Console()
CONFIG_FILE = "config.json"
SUPPORTED_PROVIDERS = {
"1": {"name": "Qwen (Alibaba)", "model": "qwen-max", "url": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"},
"2": {"name": "Qwen via OpenRouter", "model": "qwen/qwen-max", "url": "https://openrouter.ai/api/v1"},
"3": {"name": "Anthropic Claude", "model": "claude-sonnet-4-20250514", "url": "https://api.anthropic.com"},
"4": {"name": "Offline Mode (No LLM)", "model": None, "url": None},
}
def load_config():
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, "r") as f:
return json.load(f)
return {
"llm": {"provider": "", "api_key": "", "model": "", "base_url": ""},
"app": {"enable_offline_mode": True, "default_target": "", "log_scans": True}
}
def save_config(config):
with open(CONFIG_FILE, "w") as f:
json.dump(config, f, indent=2)
console.print("[bold green]✓[/bold green] Configuration saved to [cyan]config.json[/cyan]\n")
def print_banner():
console.print("""
[bold cyan]╔════════════════════════════════════════════╗[/bold cyan]
[bold cyan]║[/bold cyan] [bold white]NmapWhisperer Setup - LLM Config[/bold white] [bold cyan]║[/bold cyan]
[bold cyan]╚════════════════════════════════════════════╝[/bold cyan]
""")
def select_provider():
table = Table(title="Select LLM Provider", show_header=True, header_style="bold cyan")
table.add_column("#", style="dim", width=4)
table.add_column("Provider", style="bold white")
table.add_column("Default Model", style="green")
for num, info in SUPPORTED_PROVIDERS.items():
table.add_row(num, info["name"], info["model"] or "N/A")
console.print(table)
while True:
choice = Prompt.ask("[bold yellow]Enter choice[/bold yellow]", choices=["1", "2", "3", "4"], default="1")
return SUPPORTED_PROVIDERS[choice]
def get_api_key(provider_name):
if provider_name == "Offline Mode (No LLM)":
return ""
console.print(f"\n[bold cyan]→[/bold cyan] Get your API key for [bold]{provider_name}[/bold]")
if "Qwen" in provider_name:
console.print(" [dim]• Qwen (Alibaba): https://dashscope.console.aliyun.com/apiKey[/dim]")
console.print(" [dim]• OpenRouter: https://openrouter.ai/keys[/dim]")
elif "Anthropic" in provider_name:
console.print(" [dim]• https://console.anthropic.com/settings/keys[/dim]")
console.print()
api_key = Prompt.ask("[bold yellow]API Key[/bold yellow]", password=True)
if not api_key or api_key.strip() == "":
if Confirm.ask("[yellow]Skip API key? (Offline mode will be used)[/yellow]", default=True):
return ""
return api_key.strip()
def test_connection(config):
if not config["llm"]["api_key"]:
console.print("[dim]→ Skipping connection test (no API key)[/dim]\n")
return True
console.print("[bold cyan]→[/bold cyan] Testing connection...")
try:
if "openrouter" in config["llm"]["base_url"].lower():
import requests
headers = {
"Authorization": f"Bearer {config['llm']['api_key']}",
"Content-Type": "application/json"
}
response = requests.get(
"https://openrouter.ai/api/v1/models",
headers=headers,
timeout=10
)
if response.status_code == 200:
console.print("[bold green]✓[/bold green] Connection successful!\n")
return True
else:
console.print(f"[yellow]⚠ API returned status {response.status_code}[/yellow]\n")
return False
else:
console.print("[dim]→ Manual test required for this provider[/dim]\n")
return True
except Exception as e:
console.print(f"[yellow]⚠ Connection test failed: {e}[/yellow]\n")
return Confirm.ask("Continue anyway?", default=True)
def main():
print_banner()
config = load_config()
console.print(Panel(
"[dim]This setup wizard will configure your LLM provider.\n"
"You can always re-run setup or edit [cyan]config.json[/cyan] manually.[/dim]",
border_style="cyan",
padding=(1, 2)
))
console.print()
# Select provider
provider = select_provider()
config["llm"]["provider"] = provider["name"]
config["llm"]["model"] = provider["model"] or ""
config["llm"]["base_url"] = provider["url"] or ""
# Get API key
api_key = get_api_key(provider["name"])
config["llm"]["api_key"] = api_key
# Offline mode
if not api_key:
config["app"]["enable_offline_mode"] = True
console.print("\n[bold green]✓[/bold green] Offline mode enabled (no LLM)\n")
else:
# Test connection
test_connection(config)
# App settings
console.print("\n[bold cyan]→[/bold cyan] App Settings")
default_target = Prompt.ask(
"[dim]Default scan target (leave empty for none)[/dim]",
default=config["app"].get("default_target", "")
)
config["app"]["default_target"] = default_target
log_scans = Confirm.ask(
"[dim]Log scan history to ~/.nmap-whisperer/history.log?[/dim]",
default=config["app"].get("log_scans", True)
)
config["app"]["log_scans"] = log_scans
# Save
save_config(config)
# Summary
console.print(Panel(
f"[bold]Configuration Summary[/bold]\n\n"
f"Provider: [cyan]{config['llm']['provider']}[/cyan]\n"
f"Model: [green]{config['llm']['model'] or 'N/A'}[/green]\n"
f"Offline Mode: [yellow]{'Enabled' if not config['llm']['api_key'] else 'Disabled'}[/yellow]\n"
f"Log Scans: [green]{'Yes' if log_scans else 'No'}[/green]",
border_style="green",
padding=(1, 2)
))
console.print("\n[bold green]✓ Setup complete![/bold green]")
console.print("[dim]Run: python nmap_whisperer.py[/dim]\n")
if __name__ == "__main__":
main()