forked from apurvsinghgautam/robin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
123 lines (105 loc) · 3.27 KB
/
main.py
File metadata and controls
123 lines (105 loc) · 3.27 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
import click
import subprocess
from yaspin import yaspin
from datetime import datetime
from scrape import scrape_multiple
from search import get_search_results
from llm import get_llm, refine_query, filter_results, generate_summary
@click.group()
@click.version_option()
def robin():
"""Robin: AI-Powered Dark Web OSINT Tool."""
pass
@robin.command()
@click.option(
"--model",
"-m",
default="gpt4o",
show_default=True,
type=click.Choice(
["gpt4o", "gpt-4.1", "claude-3-5-sonnet-latest", "llama3.1", "gemini-2.5-flash"]
),
help="Select LLM model to use (e.g., gpt4o, claude sonnet 3.5, ollama models)",
)
@click.option("--query", "-q", required=True, type=str, help="Dark web search query")
@click.option(
"--threads",
"-t",
default=5,
show_default=True,
type=int,
help="Number of threads to use for scraping (Default: 5)",
)
@click.option(
"--output",
"-o",
type=str,
help="Filename to save the final intelligence summary. If not provided, a filename based on the current date and time is used.",
)
def cli(model, query, threads, output):
"""Run Robin in CLI mode.\n
Example commands:\n
- robin -m gpt4o -q "ransomware payments" -t 12\n
- robin --model claude-3-5-sonnet-latest --query "sensitive credentials exposure" --threads 8 --output filename\n
- robin -m llama3.1 -q "zero days"\n
"""
llm = get_llm(model)
# Show spinner while processing the query
with yaspin(text="Processing...", color="cyan") as sp:
refined_query = refine_query(llm, query)
search_results = get_search_results(
refined_query.replace(" ", "+"), max_workers=threads
)
search_filtered = filter_results(llm, refined_query, search_results)
scraped_results = scrape_multiple(search_filtered, max_workers=threads)
sp.ok("✔")
# Generate the intelligence summary.
summary = generate_summary(llm, query, scraped_results)
# Save or print the summary
if not output:
now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
filename = f"summary_{now}.md"
else:
filename = output + ".md"
with open(filename, "w", encoding="utf-8") as f:
f.write(summary)
click.echo(f"\n\n[OUTPUT] Final intelligence summary saved to {filename}")
@robin.command()
@click.option(
"--ui-port",
default=8501,
show_default=True,
type=int,
help="Port for the Streamlit UI",
)
@click.option(
"--ui-host",
default="localhost",
show_default=True,
type=str,
help="Host for the Streamlit UI",
)
def ui(ui_port, ui_host):
"""Run Robin in Web UI mode."""
import sys, os
# Use streamlit's internet CLI entrypoint
from streamlit.web import cli as stcli
# When PyInstaller one-file, data files livei n _MEIPASS
if getattr(sys, "frozen", False):
base = sys._MEIPASS
else:
base = os.path.dirname(__file__)
ui_script = os.path.join(base, "ui.py")
# Build sys.argv
sys.argv = [
"streamlit",
"run",
ui_script,
f"--server.port={ui_port}",
f"--server.address={ui_host}",
"--global.developmentMode=false",
]
# This will never return until streamlit exits
sys.exit(stcli.main())
if __name__ == "__main__":
robin()