eva-exploit 2.5__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.
utils/system.py ADDED
@@ -0,0 +1,264 @@
1
+ import json
2
+ import os
3
+ import socket
4
+ import signal
5
+ import subprocess
6
+ import sys
7
+ import time
8
+ from importlib import metadata
9
+ from pathlib import Path
10
+ from urllib import error, request
11
+ import tomllib
12
+
13
+ from colorama import Fore
14
+
15
+ from config import API_ENDPOINT, APP_NAME, APP_VERSION, ENV_PATH, OLLAMA_MODEL, PYPI_PACKAGE
16
+ from utils.ui import clear, cyber
17
+
18
+
19
+ # ═══════════════════════════════════════════════════════════════
20
+ # :: Utilities
21
+ # Utility functions such as ApiKEY verifier and signal handler
22
+ # ═══════════════════════════════════════════════════════════════
23
+ def checkAPI():
24
+ if API_ENDPOINT == "NOT_SET":
25
+ print(Fore.RED + "\nNo custom API set. Please configure in source code at API_ENPOINT")
26
+ sys.exit(0)
27
+
28
+
29
+ def checkOpenAIKey():
30
+ key = os.getenv("OPENAI_API_KEY")
31
+ if key and key.strip():
32
+ return key.strip()
33
+ if ENV_PATH.exists():
34
+ for line in ENV_PATH.read_text().splitlines():
35
+ if line.startswith("OPENAI_API_KEY="):
36
+ key = line.split("=", 1)[1].strip()
37
+ if key:
38
+ os.environ["OPENAI_API_KEY"] = key
39
+ return key
40
+ os.system("clear")
41
+ cyber("OpenAI key not found! :: Please insert it below", color=Fore.RED)
42
+ print("\nYour OpenAI API key will be stored locally in .env\n")
43
+ key = input("#key > ").strip()
44
+ if not key:
45
+ print(Fore.RED + "\nNo key provided. Aborting.")
46
+ sys.exit(1)
47
+ with open(ENV_PATH, "a") as f:
48
+ f.write(f"\nOPENAI_API_KEY={key}\n")
49
+ os.environ["OPENAI_API_KEY"] = key
50
+ print(Fore.GREEN + "\n✔ OpenAI API key saved successfully.")
51
+ time.sleep(1)
52
+ return key
53
+
54
+
55
+ def checkAnthropicKey():
56
+ key = os.getenv("ANTHROPIC_API_KEY")
57
+ if key and key.strip():
58
+ return key.strip()
59
+ if ENV_PATH.exists():
60
+ for line in ENV_PATH.read_text().splitlines():
61
+ if line.startswith("ANTHROPIC_API_KEY="):
62
+ key = line.split("=", 1)[1].strip()
63
+ if key:
64
+ os.environ["ANTHROPIC_API_KEY"] = key
65
+ return key
66
+ os.system("clear")
67
+ cyber("Anthropic key not found! :: Please insert it below", color=Fore.RED)
68
+ print("\nYour Anthropic API key will be stored locally in .env\n")
69
+ key = input("#key > ").strip()
70
+ if not key:
71
+ print(Fore.RED + "\nNo key provided. Aborting.")
72
+ sys.exit(1)
73
+ with open(ENV_PATH, "a") as f:
74
+ f.write(f"\nANTHROPIC_API_KEY={key}\n")
75
+ os.environ["ANTHROPIC_API_KEY"] = key
76
+ print(Fore.GREEN + "\n✔ Anthropic API key saved successfully.")
77
+ time.sleep(1)
78
+ return key
79
+
80
+
81
+ def checkGeminiKey():
82
+ key = os.getenv("GEMINI_API_KEY")
83
+ if key and key.strip():
84
+ return key.strip()
85
+ if ENV_PATH.exists():
86
+ for line in ENV_PATH.read_text().splitlines():
87
+ if line.startswith("GEMINI_API_KEY="):
88
+ key = line.split("=", 1)[1].strip()
89
+ if key:
90
+ os.environ["GEMINI_API_KEY"] = key
91
+ return key
92
+ os.system("clear")
93
+ cyber("Gemini key not found! :: Please insert it below", color=Fore.RED)
94
+ print("\nYour Gemini API key will be stored locally in .env\n")
95
+ key = input("#key > ").strip()
96
+ if not key:
97
+ print(Fore.RED + "\nNo key provided. Aborting.")
98
+ sys.exit(1)
99
+ with open(ENV_PATH, "a") as f:
100
+ f.write(f"\nGEMINI_API_KEY={key}\n")
101
+ os.environ["GEMINI_API_KEY"] = key
102
+ print(Fore.GREEN + "\n✔ Gemini API key saved successfully.")
103
+ time.sleep(1)
104
+ return key
105
+
106
+
107
+ def ctrl_c_handler(signum, frame):
108
+ raise KeyboardInterrupt
109
+
110
+
111
+ def register_signal_handler():
112
+ signal.signal(signal.SIGINT, ctrl_c_handler)
113
+
114
+
115
+ def graceful_exit():
116
+ cyber("EVA OFFLINE :: SESSION IS SAVED", color=Fore.RED)
117
+ print(Fore.YELLOW + "🜂 E x i t i n g E V A ...")
118
+ time.sleep(2.5)
119
+ clear()
120
+ sys.exit(0)
121
+
122
+
123
+ def _split_version(value):
124
+ clean = str(value).strip().lower().lstrip("v")
125
+ parts = []
126
+ for part in clean.split("."):
127
+ digits = ""
128
+ for char in part:
129
+ if char.isdigit():
130
+ digits += char
131
+ else:
132
+ break
133
+ parts.append(int(digits or 0))
134
+ while len(parts) < 3:
135
+ parts.append(0)
136
+ return tuple(parts[:3])
137
+
138
+
139
+ def _is_newer(latest, current):
140
+ return _split_version(latest) > _split_version(current)
141
+
142
+
143
+ def get_current_version():
144
+ try:
145
+ return metadata.version(PYPI_PACKAGE)
146
+ except metadata.PackageNotFoundError:
147
+ pyproject = Path("pyproject.toml")
148
+ if pyproject.exists():
149
+ try:
150
+ data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
151
+ version = data.get("project", {}).get("version")
152
+ if version:
153
+ return version
154
+ except (tomllib.TOMLDecodeError, OSError):
155
+ pass
156
+ return APP_VERSION
157
+
158
+
159
+ def fetch_latest_pypi_version():
160
+ url = f"https://pypi.org/pypi/{PYPI_PACKAGE}/json"
161
+ req = request.Request(url, headers={"Accept": "application/json", "User-Agent": "eva-update-check"})
162
+ try:
163
+ with request.urlopen(req, timeout=5) as response:
164
+ data = json.loads(response.read().decode("utf-8"))
165
+ return data.get("info", {}).get("version")
166
+ except (error.URLError, TimeoutError, json.JSONDecodeError):
167
+ return None
168
+
169
+
170
+ def checkupdts():
171
+ try:
172
+ socket.create_connection(("pypi.org", 443), timeout=2)
173
+ except OSError:
174
+ return
175
+
176
+ current = get_current_version()
177
+ latest = fetch_latest_pypi_version()
178
+ if not latest:
179
+ return
180
+ if _is_newer(latest, current):
181
+ print("\n" + Fore.CYAN + "=" * 40)
182
+ print(Fore.CYAN + f"🐱 Update available: {current} → {latest}")
183
+ print(Fore.GREEN + "Run: eva -u to update to the latest version")
184
+ print("=" * 40 + Fore.CYAN + "\n")
185
+
186
+
187
+ def run_self_update():
188
+ print(Fore.CYAN + f"\nChecking updates for {APP_NAME}...\n")
189
+ updated = False
190
+
191
+ pip_result = subprocess.run(
192
+ [sys.executable, "-m", "pip", "install", "--upgrade", PYPI_PACKAGE],
193
+ text=True
194
+ )
195
+ if pip_result.returncode == 0:
196
+ updated = True
197
+
198
+ if Path(".git").exists() and command_exists("git"):
199
+ branch = "main"
200
+ branch_detect = subprocess.run(
201
+ ["git", "rev-parse", "--abbrev-ref", "HEAD"],
202
+ capture_output=True,
203
+ text=True
204
+ )
205
+ if branch_detect.returncode == 0 and branch_detect.stdout.strip():
206
+ branch = branch_detect.stdout.strip()
207
+
208
+ pull_result = subprocess.run(["git", "pull", "--tags", "origin", branch], text=True)
209
+ if pull_result.returncode == 0:
210
+ updated = True
211
+
212
+ if updated:
213
+ print(Fore.GREEN + "\n✔ Update process finished. Restart EVA to use the latest version.")
214
+ return 0
215
+
216
+ print(Fore.RED + "\n[!] Could not auto-update EVA in this environment.")
217
+ print(Fore.YELLOW + f"Try manually: {sys.executable} -m pip install --upgrade {PYPI_PACKAGE}")
218
+ return 1
219
+
220
+
221
+ # ================= STARTUP OF EVA here =================
222
+ def command_exists(cmd):
223
+ return subprocess.call(
224
+ ["which", cmd],
225
+ stdout=subprocess.DEVNULL,
226
+ stderr=subprocess.DEVNULL
227
+ ) == 0
228
+
229
+
230
+ def ollama_running():
231
+ try:
232
+ subprocess.check_output(['ollama', 'list'], stderr=subprocess.STDOUT, text=True)
233
+ return True
234
+ except subprocess.CalledProcessError as e:
235
+ if "server not responding" in e.output.lower():
236
+ return False
237
+ return False
238
+
239
+
240
+ def start_ollama():
241
+ clear()
242
+ print("\n\n\n")
243
+ print(Fore.YELLOW + "🜂 OLLAMA NOT RUNNING :: Starting for you...\n\n")
244
+
245
+ with open(os.devnull, 'w') as DEVNULL:
246
+ subprocess.Popen(
247
+ ['ollama', 'serve'],
248
+ stdout=DEVNULL,
249
+ stderr=DEVNULL,
250
+ stdin=DEVNULL,
251
+ close_fds=True,
252
+ start_new_session=True
253
+ )
254
+
255
+ time.sleep(3)
256
+
257
+
258
+ def model_exists():
259
+ r = subprocess.run(
260
+ ["ollama", "list"],
261
+ capture_output=True,
262
+ text=True
263
+ )
264
+ return OLLAMA_MODEL in r.stdout
utils/ui.py ADDED
@@ -0,0 +1,191 @@
1
+ import os
2
+ import re
3
+ import sys
4
+ import termios
5
+ import tty
6
+ import itertools
7
+ import threading
8
+ import time
9
+ from colorama import Fore, Style, init
10
+
11
+ init(autoreset=True)
12
+
13
+
14
+ def clear():
15
+ os.system("clear")
16
+
17
+
18
+ # ════════════════════
19
+ # :: UI FUNCTIONS
20
+ # ════════════════════
21
+
22
+ _spinner_frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
23
+ _spinner_text = " L o a d i n g "
24
+ _spinner_delay = 0.10
25
+ _spinner_running = False
26
+ _spinner_thread = None
27
+
28
+
29
+ def _spinner_animate():
30
+ for i, frame in enumerate(itertools.cycle(_spinner_frames)):
31
+ if not _spinner_running:
32
+ break
33
+ dot_count = (i // 3) % 4 + 1
34
+ dots = "." * dot_count
35
+ spaces = " " * (4 - dot_count)
36
+ sys.stdout.write(f"\r {frame} {_spinner_text}{dots}{spaces}")
37
+ sys.stdout.flush()
38
+ time.sleep(_spinner_delay)
39
+
40
+
41
+ def spinner_start():
42
+ global _spinner_running, _spinner_thread
43
+ if _spinner_running:
44
+ return
45
+ _spinner_running = True
46
+ sys.stdout.write(f"\n\n")
47
+ _spinner_thread = threading.Thread(target=_spinner_animate)
48
+ _spinner_thread.daemon = True
49
+ _spinner_thread.start()
50
+
51
+
52
+ def spinner_stop():
53
+ global _spinner_running
54
+ _spinner_running = False
55
+ if _spinner_thread:
56
+ _spinner_thread.join()
57
+ sys.stdout.write("\r" + " " * (len(_spinner_text) + 4) + "\r")
58
+ sys.stdout.flush()
59
+
60
+
61
+ def cyber(msg="", width=50, color=Fore.GREEN):
62
+ """
63
+ Stylized output in a centered scifi box.
64
+ :param msg: message
65
+ :param width: width
66
+ :param color: Ccolor
67
+ """
68
+ width = int(width)
69
+ ansi_re = re.compile(r"\x1b\[[0-9;]*m")
70
+
71
+ def visible_len(text):
72
+ return len(ansi_re.sub("", text))
73
+
74
+ lines = str(msg).splitlines() if msg else []
75
+ longest = max((visible_len(line) for line in lines), default=0)
76
+ width = max(width, longest + 4)
77
+
78
+ print(color + "╔" + "═" * width + "╗")
79
+ if lines:
80
+ for line in lines:
81
+ line_len = visible_len(line)
82
+ content_len = line_len + 2
83
+ padding = max(0, width - content_len)
84
+ left_pad = padding // 2
85
+ right_pad = padding - left_pad
86
+ print(color + "║" + " " * left_pad + " " + line + " " + " " * right_pad + "║")
87
+ print(color + "╚" + "═" * width + "╝")
88
+ print(Style.RESET_ALL)
89
+
90
+
91
+
92
+ def banner(version=None):
93
+ clear()
94
+ print(Style.BRIGHT + Fore.CYAN + rf"""
95
+ ╔═════════════════════════════════════════════╗
96
+ ║ ║
97
+ ║ ░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓██████▓▒░ ║
98
+ ║ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ║
99
+ ║ ░▒▓█▓▒░ ░▒▓█▓▒▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ║
100
+ ║ ░▒▓██████▓▒░ ░▒▓█▓▒▒▓█▓▒░░▒▓████████▓▒░ ║
101
+ ║ ░▒▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ║
102
+ ║ ░▒▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ║
103
+ ║ ░▒▓████████▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ║
104
+ ║ Exploit Vector Agent ║
105
+ ║ ║
106
+ ║ ᴍᴀᴅᴇ ʙʏ: 𝝺𝗿𝗰𝗮𝗻𝗴𝗲𝗹𝗼 ║
107
+ ╚═════════════════════════════════════════════╝
108
+ {Style.BRIGHT} {Fore.MAGENTA} version: {version} {Style.RESET_ALL} """)
109
+
110
+
111
+ # ╔═════════░░░═════════╗
112
+ # ░░░ Query input ░░░
113
+ # ╚═════════░░░═════════╝
114
+ def raw_input(prompt=""):
115
+ fd = sys.stdin.fileno()
116
+ old = termios.tcgetattr(fd)
117
+ buf = ""
118
+ try:
119
+ tty.setcbreak(fd)
120
+ print(prompt, end="", flush=True)
121
+ while True:
122
+ ch = sys.stdin.read(1)
123
+ if ch in ("\n", "\r"):
124
+ print()
125
+ return buf
126
+ elif ch in ("\x7f", "\x08"):
127
+ if buf:
128
+ buf = buf[:-1]
129
+ print("\b \b", end="", flush=True)
130
+ elif ch == "\x03":
131
+ raise KeyboardInterrupt
132
+ else:
133
+ buf += ch
134
+ print(ch, end="", flush=True)
135
+ finally:
136
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)
137
+
138
+
139
+ # ╔═════════░░░═════════╗
140
+ # ░░░ Control utilies ░░░
141
+ # ╚═════════░░░═════════╝
142
+
143
+ def menu(title, options):
144
+ idx = 0
145
+ fd = sys.stdin.fileno()
146
+ old = termios.tcgetattr(fd)
147
+ try:
148
+ tty.setcbreak(fd)
149
+ while True:
150
+ os.system("clear")
151
+ cyber(title)
152
+ for i, opt in enumerate(options):
153
+ prefix = "→ " if i == idx else " "
154
+ print(prefix + opt)
155
+ ch = sys.stdin.read(1)
156
+ if ch == "\x1b":
157
+ sys.stdin.read(1)
158
+ arrow = sys.stdin.read(1)
159
+ if arrow == "A":
160
+ idx = (idx - 1) % len(options)
161
+ elif arrow == "B":
162
+ idx = (idx + 1) % len(options)
163
+ elif ch in ("\n", "\r"):
164
+ return idx
165
+ finally:
166
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)
167
+ def get_sessions(title, options, version=None):
168
+ idx = 0
169
+ fd = sys.stdin.fileno()
170
+ old = termios.tcgetattr(fd)
171
+ try:
172
+ tty.setcbreak(fd)
173
+ while True:
174
+ banner(version)
175
+ print("\n")
176
+ cyber(title)
177
+ for i, opt in enumerate(options):
178
+ prefix = "→ " if i == idx else " "
179
+ print(prefix + opt)
180
+ ch = sys.stdin.read(1)
181
+ if ch == "\x1b":
182
+ sys.stdin.read(1)
183
+ arrow = sys.stdin.read(1)
184
+ if arrow == "A":
185
+ idx = (idx - 1) % len(options)
186
+ elif arrow == "B":
187
+ idx = (idx + 1) % len(options)
188
+ elif ch in ("\n", "\r"):
189
+ return idx
190
+ finally:
191
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)