eva-exploit 3.3__tar.gz → 3.3.1__tar.gz
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.
- {eva_exploit-3.3 → eva_exploit-3.3.1}/PKG-INFO +16 -17
- {eva_exploit-3.3 → eva_exploit-3.3.1}/README.md +15 -16
- {eva_exploit-3.3 → eva_exploit-3.3.1}/config.py +3 -2
- {eva_exploit-3.3 → eva_exploit-3.3.1}/eva.py +7 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/eva_exploit.egg-info/PKG-INFO +16 -17
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/llm.py +38 -1
- {eva_exploit-3.3 → eva_exploit-3.3.1}/pyproject.toml +1 -1
- {eva_exploit-3.3 → eva_exploit-3.3.1}/utils/system.py +101 -6
- {eva_exploit-3.3 → eva_exploit-3.3.1}/eva_exploit.egg-info/SOURCES.txt +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/eva_exploit.egg-info/dependency_links.txt +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/eva_exploit.egg-info/entry_points.txt +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/eva_exploit.egg-info/requires.txt +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/eva_exploit.egg-info/top_level.txt +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/__init__.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/attack_map.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/exploit_search.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/prompt_builder.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/reporting.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/tooling.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/vuln_intel.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/modules/workflow.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/sessions/__init__.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/sessions/eva_session.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/setup.cfg +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/utils/__init__.py +0 -0
- {eva_exploit-3.3 → eva_exploit-3.3.1}/utils/ui.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eva-exploit
|
|
3
|
-
Version: 3.3
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: Exploit Vector Agent
|
|
5
5
|
Author: ARCANGEL0
|
|
6
6
|
License: MIT
|
|
@@ -142,20 +142,23 @@ graph TD
|
|
|
142
142
|
|
|
143
143
|
### 🍎 Installation
|
|
144
144
|
|
|
145
|
+
#### Ollama for local endpoint (required for local models and eva exploit database)
|
|
145
146
|
```bash
|
|
146
|
-
# Ollama for local endpoint (required for local models and eva exploit database)
|
|
147
147
|
curl -fsSL https://ollama.ai/install.sh | shr
|
|
148
|
+
```
|
|
148
149
|
|
|
149
|
-
|
|
150
|
+
#### pip installation
|
|
151
|
+
```bash
|
|
150
152
|
pip install eva-exploit
|
|
151
153
|
eva
|
|
154
|
+
```
|
|
152
155
|
|
|
153
|
-
|
|
156
|
+
#### EVA github installation
|
|
157
|
+
```bash
|
|
154
158
|
git clone https://github.com/ARCANGEL0/EVA.git
|
|
155
159
|
cd EVA
|
|
156
160
|
chmod +x eva.py
|
|
157
161
|
./eva.py
|
|
158
|
-
|
|
159
162
|
# Adding it to PATH to be acessible anywhere
|
|
160
163
|
sudo mv eva.py /usr/local/bin/eva
|
|
161
164
|
```
|
|
@@ -186,14 +189,10 @@ eva --config
|
|
|
186
189
|
│ ├── report1.html
|
|
187
190
|
│ ├── report1.pdf
|
|
188
191
|
│ └── ...
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
├── utils/
|
|
194
|
-
├── modules/
|
|
195
|
-
├── eva
|
|
196
|
-
└── config.py # API keys (auto-generated/persisted)
|
|
192
|
+
└── attack_maps/ # Attack vector maps in HTML/JS
|
|
193
|
+
├── attack_surface1.html
|
|
194
|
+
├── attack_surface2.html
|
|
195
|
+
└── ...
|
|
197
196
|
```
|
|
198
197
|
|
|
199
198
|
### ꀬ Where to change EVA options
|
|
@@ -319,11 +318,11 @@ Let me start with basic system reconnaissance to understand the target better...
|
|
|
319
318
|
<summary><h2>Ξ AI Backends</h2></summary>
|
|
320
319
|
|
|
321
320
|
### 🦙 Ollama (Recommended)
|
|
322
|
-
- **Model**: `
|
|
321
|
+
- **Model**: `ALIENTELLIGENCE/whiterabbitv2"` (best one for OffSec)
|
|
323
322
|
- ✅ Complete offline operation
|
|
324
323
|
- ✅ No API costs
|
|
325
324
|
- ✅ Privacy-focused
|
|
326
|
-
- ❌ Higher CPU/GPU usage, recommended for machines above
|
|
325
|
+
- ❌ Higher CPU/GPU usage, recommended for machines above 8GB+ VRAM/RAM
|
|
327
326
|
- ❌ Heavier model, ~9.8gb model
|
|
328
327
|
|
|
329
328
|
### ⬡ OpenAI GPT
|
|
@@ -414,7 +413,7 @@ Any and all consequences are the sole responsibility of the user.
|
|
|
414
413
|
```
|
|
415
414
|
MIT License
|
|
416
415
|
|
|
417
|
-
Copyright (c)
|
|
416
|
+
Copyright (c) 2026 EVA - Exploit Vector Agent
|
|
418
417
|
|
|
419
418
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
420
419
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -450,7 +449,7 @@ SOFTWARE.
|
|
|
450
449
|
<a href='https://ko-fi.com/J3J7WTYV7' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi3.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
|
451
450
|
<br>
|
|
452
451
|
<strong>Hack the world. Byte by Byte.</strong> ⛛ <br>
|
|
453
|
-
𝝺𝗿𝗰𝗮𝗻𝗴𝗲𝗹𝗼 @
|
|
452
|
+
𝝺𝗿𝗰𝗮𝗻𝗴𝗲𝗹𝗼 @ 2026
|
|
454
453
|
|
|
455
454
|
**[[ꋧ]](#-𝝣𝗩𝝠)**
|
|
456
455
|
|
|
@@ -130,20 +130,23 @@ graph TD
|
|
|
130
130
|
|
|
131
131
|
### 🍎 Installation
|
|
132
132
|
|
|
133
|
+
#### Ollama for local endpoint (required for local models and eva exploit database)
|
|
133
134
|
```bash
|
|
134
|
-
# Ollama for local endpoint (required for local models and eva exploit database)
|
|
135
135
|
curl -fsSL https://ollama.ai/install.sh | shr
|
|
136
|
+
```
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
#### pip installation
|
|
139
|
+
```bash
|
|
138
140
|
pip install eva-exploit
|
|
139
141
|
eva
|
|
142
|
+
```
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
#### EVA github installation
|
|
145
|
+
```bash
|
|
142
146
|
git clone https://github.com/ARCANGEL0/EVA.git
|
|
143
147
|
cd EVA
|
|
144
148
|
chmod +x eva.py
|
|
145
149
|
./eva.py
|
|
146
|
-
|
|
147
150
|
# Adding it to PATH to be acessible anywhere
|
|
148
151
|
sudo mv eva.py /usr/local/bin/eva
|
|
149
152
|
```
|
|
@@ -174,14 +177,10 @@ eva --config
|
|
|
174
177
|
│ ├── report1.html
|
|
175
178
|
│ ├── report1.pdf
|
|
176
179
|
│ └── ...
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
├── utils/
|
|
182
|
-
├── modules/
|
|
183
|
-
├── eva
|
|
184
|
-
└── config.py # API keys (auto-generated/persisted)
|
|
180
|
+
└── attack_maps/ # Attack vector maps in HTML/JS
|
|
181
|
+
├── attack_surface1.html
|
|
182
|
+
├── attack_surface2.html
|
|
183
|
+
└── ...
|
|
185
184
|
```
|
|
186
185
|
|
|
187
186
|
### ꀬ Where to change EVA options
|
|
@@ -307,11 +306,11 @@ Let me start with basic system reconnaissance to understand the target better...
|
|
|
307
306
|
<summary><h2>Ξ AI Backends</h2></summary>
|
|
308
307
|
|
|
309
308
|
### 🦙 Ollama (Recommended)
|
|
310
|
-
- **Model**: `
|
|
309
|
+
- **Model**: `ALIENTELLIGENCE/whiterabbitv2"` (best one for OffSec)
|
|
311
310
|
- ✅ Complete offline operation
|
|
312
311
|
- ✅ No API costs
|
|
313
312
|
- ✅ Privacy-focused
|
|
314
|
-
- ❌ Higher CPU/GPU usage, recommended for machines above
|
|
313
|
+
- ❌ Higher CPU/GPU usage, recommended for machines above 8GB+ VRAM/RAM
|
|
315
314
|
- ❌ Heavier model, ~9.8gb model
|
|
316
315
|
|
|
317
316
|
### ⬡ OpenAI GPT
|
|
@@ -402,7 +401,7 @@ Any and all consequences are the sole responsibility of the user.
|
|
|
402
401
|
```
|
|
403
402
|
MIT License
|
|
404
403
|
|
|
405
|
-
Copyright (c)
|
|
404
|
+
Copyright (c) 2026 EVA - Exploit Vector Agent
|
|
406
405
|
|
|
407
406
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
408
407
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -438,7 +437,7 @@ SOFTWARE.
|
|
|
438
437
|
<a href='https://ko-fi.com/J3J7WTYV7' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi3.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
|
439
438
|
<br>
|
|
440
439
|
<strong>Hack the world. Byte by Byte.</strong> ⛛ <br>
|
|
441
|
-
𝝺𝗿𝗰𝗮𝗻𝗴𝗲𝗹𝗼 @
|
|
440
|
+
𝝺𝗿𝗰𝗮𝗻𝗴𝗲𝗹𝗼 @ 2026
|
|
442
441
|
|
|
443
442
|
**[[ꋧ]](#-𝝣𝗩𝝠)**
|
|
444
443
|
|
|
@@ -10,10 +10,11 @@ from pathlib import Path
|
|
|
10
10
|
|
|
11
11
|
# ================= CONFIG =================
|
|
12
12
|
APP_NAME = "EVA"
|
|
13
|
-
APP_VERSION = "3.3"
|
|
13
|
+
APP_VERSION = "3.3.1"
|
|
14
14
|
GITHUB_REPO = "arcangel0/EVA"
|
|
15
15
|
PYPI_PACKAGE = "eva-exploit"
|
|
16
|
-
API_ENDPOINT = "
|
|
16
|
+
API_ENDPOINT = "https://api.arcangelo.net/api"
|
|
17
|
+
CUSTOM_API_HANDLER = "custom.py"
|
|
17
18
|
G4F_MODEL="gpt-oss-120b"
|
|
18
19
|
G4F_URL="https://api.gpt4free.workers.dev/api/novaai/chat/completions"
|
|
19
20
|
OLLAMA_MODEL = "ALIENTELLIGENCE/whiterabbitv2" # recommended ollama model
|
|
@@ -35,6 +35,7 @@ from utils.system import (
|
|
|
35
35
|
checkOpenAIKey,
|
|
36
36
|
checkupdts,
|
|
37
37
|
command_exists,
|
|
38
|
+
configure_custom_api,
|
|
38
39
|
get_current_version,
|
|
39
40
|
model_exists,
|
|
40
41
|
ollama_running,
|
|
@@ -83,6 +84,7 @@ def main():
|
|
|
83
84
|
return
|
|
84
85
|
|
|
85
86
|
if sel == len(sessions) + 2:
|
|
87
|
+
print("\n")
|
|
86
88
|
cyber("[+] Leaving EVA", color=Fore.RED)
|
|
87
89
|
time.sleep(1.2)
|
|
88
90
|
raise SystemExit(0)
|
|
@@ -164,6 +166,8 @@ def cli():
|
|
|
164
166
|
parser.add_argument("-v", "--version", action="store_true", help="Show EVA version")
|
|
165
167
|
parser.add_argument("-d", "--delete", action="store_true", help="Delete stored sessions & files")
|
|
166
168
|
parser.add_argument("-c", "--config", action="store_true", help="Open EVA config.py in your default editor")
|
|
169
|
+
parser.add_argument("--custom-api", action="store_true", help="Open custom API configuration wizard")
|
|
170
|
+
parser.add_argument("-cfg", action="store_true", help="Open custom API configuration wizard")
|
|
167
171
|
parser.add_argument(
|
|
168
172
|
"-s",
|
|
169
173
|
"--search",
|
|
@@ -180,6 +184,9 @@ def cli():
|
|
|
180
184
|
color = Fore.GREEN if ok else Fore.RED
|
|
181
185
|
cyber(msg, color=color)
|
|
182
186
|
raise SystemExit(0 if ok else 1)
|
|
187
|
+
if args.custom_api or args.cfg:
|
|
188
|
+
ok = configure_custom_api(open_handler=True)
|
|
189
|
+
raise SystemExit(0 if ok else 1)
|
|
183
190
|
|
|
184
191
|
if args.search is not None:
|
|
185
192
|
query = " ".join(args.search).strip()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eva-exploit
|
|
3
|
-
Version: 3.3
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: Exploit Vector Agent
|
|
5
5
|
Author: ARCANGEL0
|
|
6
6
|
License: MIT
|
|
@@ -142,20 +142,23 @@ graph TD
|
|
|
142
142
|
|
|
143
143
|
### 🍎 Installation
|
|
144
144
|
|
|
145
|
+
#### Ollama for local endpoint (required for local models and eva exploit database)
|
|
145
146
|
```bash
|
|
146
|
-
# Ollama for local endpoint (required for local models and eva exploit database)
|
|
147
147
|
curl -fsSL https://ollama.ai/install.sh | shr
|
|
148
|
+
```
|
|
148
149
|
|
|
149
|
-
|
|
150
|
+
#### pip installation
|
|
151
|
+
```bash
|
|
150
152
|
pip install eva-exploit
|
|
151
153
|
eva
|
|
154
|
+
```
|
|
152
155
|
|
|
153
|
-
|
|
156
|
+
#### EVA github installation
|
|
157
|
+
```bash
|
|
154
158
|
git clone https://github.com/ARCANGEL0/EVA.git
|
|
155
159
|
cd EVA
|
|
156
160
|
chmod +x eva.py
|
|
157
161
|
./eva.py
|
|
158
|
-
|
|
159
162
|
# Adding it to PATH to be acessible anywhere
|
|
160
163
|
sudo mv eva.py /usr/local/bin/eva
|
|
161
164
|
```
|
|
@@ -186,14 +189,10 @@ eva --config
|
|
|
186
189
|
│ ├── report1.html
|
|
187
190
|
│ ├── report1.pdf
|
|
188
191
|
│ └── ...
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
├── utils/
|
|
194
|
-
├── modules/
|
|
195
|
-
├── eva
|
|
196
|
-
└── config.py # API keys (auto-generated/persisted)
|
|
192
|
+
└── attack_maps/ # Attack vector maps in HTML/JS
|
|
193
|
+
├── attack_surface1.html
|
|
194
|
+
├── attack_surface2.html
|
|
195
|
+
└── ...
|
|
197
196
|
```
|
|
198
197
|
|
|
199
198
|
### ꀬ Where to change EVA options
|
|
@@ -319,11 +318,11 @@ Let me start with basic system reconnaissance to understand the target better...
|
|
|
319
318
|
<summary><h2>Ξ AI Backends</h2></summary>
|
|
320
319
|
|
|
321
320
|
### 🦙 Ollama (Recommended)
|
|
322
|
-
- **Model**: `
|
|
321
|
+
- **Model**: `ALIENTELLIGENCE/whiterabbitv2"` (best one for OffSec)
|
|
323
322
|
- ✅ Complete offline operation
|
|
324
323
|
- ✅ No API costs
|
|
325
324
|
- ✅ Privacy-focused
|
|
326
|
-
- ❌ Higher CPU/GPU usage, recommended for machines above
|
|
325
|
+
- ❌ Higher CPU/GPU usage, recommended for machines above 8GB+ VRAM/RAM
|
|
327
326
|
- ❌ Heavier model, ~9.8gb model
|
|
328
327
|
|
|
329
328
|
### ⬡ OpenAI GPT
|
|
@@ -414,7 +413,7 @@ Any and all consequences are the sole responsibility of the user.
|
|
|
414
413
|
```
|
|
415
414
|
MIT License
|
|
416
415
|
|
|
417
|
-
Copyright (c)
|
|
416
|
+
Copyright (c) 2026 EVA - Exploit Vector Agent
|
|
418
417
|
|
|
419
418
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
420
419
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -450,7 +449,7 @@ SOFTWARE.
|
|
|
450
449
|
<a href='https://ko-fi.com/J3J7WTYV7' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi3.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
|
451
450
|
<br>
|
|
452
451
|
<strong>Hack the world. Byte by Byte.</strong> ⛛ <br>
|
|
453
|
-
𝝺𝗿𝗰𝗮𝗻𝗴𝗲𝗹𝗼 @
|
|
452
|
+
𝝺𝗿𝗰𝗮𝗻𝗴𝗲𝗹𝗼 @ 2026
|
|
454
453
|
|
|
455
454
|
**[[ꋧ]](#-𝝣𝗩𝝠)**
|
|
456
455
|
|
|
@@ -6,19 +6,23 @@
|
|
|
6
6
|
# ---------------------------------------------------------------------
|
|
7
7
|
|
|
8
8
|
import json
|
|
9
|
+
import importlib.util
|
|
9
10
|
import os
|
|
10
11
|
import re
|
|
11
12
|
import subprocess
|
|
12
13
|
import time
|
|
14
|
+
from pathlib import Path
|
|
13
15
|
|
|
14
16
|
import openai
|
|
15
17
|
import requests
|
|
16
18
|
from colorama import Fore, Style
|
|
19
|
+
import config as config_module
|
|
17
20
|
|
|
18
21
|
from config import (
|
|
19
22
|
ANTHROPIC_MODEL,
|
|
20
23
|
ANTHROPIC_API_KEY,
|
|
21
24
|
API_ENDPOINT,
|
|
25
|
+
CUSTOM_API_HANDLER,
|
|
22
26
|
G4F_MODEL,
|
|
23
27
|
G4F_URL,
|
|
24
28
|
GEMINI_API_KEY,
|
|
@@ -477,7 +481,40 @@ def _query_g4f(history):
|
|
|
477
481
|
|
|
478
482
|
|
|
479
483
|
def _query_custom_api(history):
|
|
480
|
-
|
|
484
|
+
endpoint = str(getattr(config_module, "API_ENDPOINT", API_ENDPOINT) or "").strip()
|
|
485
|
+
handler_path = str(getattr(config_module, "CUSTOM_API_HANDLER", CUSTOM_API_HANDLER) or "").strip()
|
|
486
|
+
|
|
487
|
+
if handler_path and handler_path != "NOT_SET":
|
|
488
|
+
try:
|
|
489
|
+
target = Path(handler_path).expanduser()
|
|
490
|
+
if target.exists():
|
|
491
|
+
mod_name = f"eva_custom_api_{abs(hash(str(target.resolve())))}"
|
|
492
|
+
spec = importlib.util.spec_from_file_location(mod_name, str(target))
|
|
493
|
+
if spec and spec.loader:
|
|
494
|
+
module = importlib.util.module_from_spec(spec)
|
|
495
|
+
spec.loader.exec_module(module)
|
|
496
|
+
query_fn = getattr(module, "query_custom_api", None)
|
|
497
|
+
if callable(query_fn):
|
|
498
|
+
try:
|
|
499
|
+
result = query_fn(history=history, endpoint=endpoint)
|
|
500
|
+
except TypeError:
|
|
501
|
+
try:
|
|
502
|
+
result = query_fn(history, endpoint)
|
|
503
|
+
except TypeError:
|
|
504
|
+
result = query_fn(history)
|
|
505
|
+
if isinstance(result, (dict, list)):
|
|
506
|
+
return json.dumps(result)
|
|
507
|
+
if result is None:
|
|
508
|
+
return ""
|
|
509
|
+
return str(result)
|
|
510
|
+
except Exception as e:
|
|
511
|
+
print(Fore.RED + f"⚠️ Error in custom API handler: {e}")
|
|
512
|
+
|
|
513
|
+
if not endpoint or endpoint == "NOT_SET":
|
|
514
|
+
print(Fore.RED + "⚠️ Custom API endpoint is not configured.")
|
|
515
|
+
return ""
|
|
516
|
+
|
|
517
|
+
r = requests.post(endpoint, json={"conversation": history}, timeout=None)
|
|
481
518
|
return r.text
|
|
482
519
|
|
|
483
520
|
|
|
@@ -27,6 +27,8 @@ from config import (
|
|
|
27
27
|
API_ENDPOINT,
|
|
28
28
|
APP_NAME,
|
|
29
29
|
APP_VERSION,
|
|
30
|
+
CONFIG_DIR,
|
|
31
|
+
CUSTOM_API_HANDLER,
|
|
30
32
|
GEMINI_API_KEY,
|
|
31
33
|
OLLAMA_MODEL,
|
|
32
34
|
OPENAI_API_KEY,
|
|
@@ -40,11 +42,104 @@ from utils.ui import clear, cyber
|
|
|
40
42
|
# Utility functions such as ApiKEY verifier and signal handler
|
|
41
43
|
# ═══════════════════════════════════════════════════════════════
|
|
42
44
|
def checkAPI():
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
endpoint = str(getattr(config_module, "API_ENDPOINT", API_ENDPOINT) or "").strip()
|
|
46
|
+
handler = str(getattr(config_module, "CUSTOM_API_HANDLER", CUSTOM_API_HANDLER) or "").strip()
|
|
47
|
+
endpoint_ok = endpoint and endpoint != "NOT_SET"
|
|
48
|
+
handler_ok = handler and handler != "NOT_SET"
|
|
49
|
+
if not endpoint_ok and not handler_ok:
|
|
50
|
+
configure_custom_api(open_handler=True)
|
|
51
|
+
endpoint = str(getattr(config_module, "API_ENDPOINT", API_ENDPOINT) or "").strip()
|
|
52
|
+
handler = str(getattr(config_module, "CUSTOM_API_HANDLER", CUSTOM_API_HANDLER) or "").strip()
|
|
53
|
+
endpoint_ok = endpoint and endpoint != "NOT_SET"
|
|
54
|
+
handler_ok = handler and handler != "NOT_SET"
|
|
55
|
+
if not endpoint_ok and not handler_ok:
|
|
56
|
+
print(Fore.RED + "\nNo custom API set. Configure it with eva --custom-api")
|
|
45
57
|
sys.exit(0)
|
|
46
58
|
|
|
47
59
|
|
|
60
|
+
def _default_custom_api_handler_path():
|
|
61
|
+
return Path(CONFIG_DIR).expanduser().resolve() / "custom_api_handler.py"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _custom_api_template(endpoint):
|
|
65
|
+
target = str(endpoint or "").strip()
|
|
66
|
+
if not target or target == "NOT_SET":
|
|
67
|
+
target = "http://127.0.0.1:8000/gpt4"
|
|
68
|
+
return (
|
|
69
|
+
"#!/usr/bin/env python3\n"
|
|
70
|
+
"import requests\n\n"
|
|
71
|
+
f"API_ENDPOINT = {json.dumps(target)}\n\n"
|
|
72
|
+
"def query_custom_api(history, endpoint=None):\n"
|
|
73
|
+
" target = endpoint or API_ENDPOINT\n"
|
|
74
|
+
" question = \"\"\n"
|
|
75
|
+
" for item in reversed(history):\n"
|
|
76
|
+
" if item.get(\"role\") == \"user\":\n"
|
|
77
|
+
" question = str(item.get(\"content\", \"\"))\n"
|
|
78
|
+
" break\n"
|
|
79
|
+
" payload = {\"prompt\": question, \"session\": \"eva-session\"}\n"
|
|
80
|
+
" r = requests.post(target, json=payload, timeout=None)\n"
|
|
81
|
+
" try:\n"
|
|
82
|
+
" data = r.json()\n"
|
|
83
|
+
" except ValueError:\n"
|
|
84
|
+
" return r.text\n"
|
|
85
|
+
" if isinstance(data, dict):\n"
|
|
86
|
+
" for key in (\"analysis\", \"response\", \"answer\", \"text\", \"content\", \"message\"):\n"
|
|
87
|
+
" value = data.get(key)\n"
|
|
88
|
+
" if isinstance(value, str) and value.strip():\n"
|
|
89
|
+
" return value\n"
|
|
90
|
+
" return str(data)\n"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _ensure_custom_api_handler_file(path, endpoint):
|
|
95
|
+
target = Path(path).expanduser()
|
|
96
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
97
|
+
if not target.exists():
|
|
98
|
+
target.write_text(_custom_api_template(endpoint), encoding="utf-8")
|
|
99
|
+
return target
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def configure_custom_api(open_handler=True):
|
|
103
|
+
endpoint_current = str(getattr(config_module, "API_ENDPOINT", API_ENDPOINT) or "").strip()
|
|
104
|
+
if endpoint_current == "NOT_SET":
|
|
105
|
+
endpoint_current = ""
|
|
106
|
+
handler_current = str(getattr(config_module, "CUSTOM_API_HANDLER", CUSTOM_API_HANDLER) or "").strip()
|
|
107
|
+
if not handler_current or handler_current == "NOT_SET":
|
|
108
|
+
handler_current = str(_default_custom_api_handler_path())
|
|
109
|
+
|
|
110
|
+
clear()
|
|
111
|
+
cyber("CUSTOM API CONFIGURATION", color=Fore.CYAN)
|
|
112
|
+
endpoint_input = input(f"Custom API endpoint [{endpoint_current}] > ").strip()
|
|
113
|
+
endpoint_value = endpoint_input or endpoint_current or "NOT_SET"
|
|
114
|
+
_persist_key_to_config("API_ENDPOINT", endpoint_value)
|
|
115
|
+
setattr(config_module, "API_ENDPOINT", endpoint_value)
|
|
116
|
+
|
|
117
|
+
handler_input = input(f"Custom API handler file [{handler_current}] > ").strip()
|
|
118
|
+
handler_value = handler_input or handler_current
|
|
119
|
+
_persist_key_to_config("CUSTOM_API_HANDLER", handler_value)
|
|
120
|
+
setattr(config_module, "CUSTOM_API_HANDLER", handler_value)
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
handler_path = _ensure_custom_api_handler_file(handler_value, endpoint_value)
|
|
124
|
+
except OSError:
|
|
125
|
+
fallback_handler = Path(config_module.__file__).resolve().parent / "custom_api_handler.py"
|
|
126
|
+
handler_value = str(fallback_handler)
|
|
127
|
+
_persist_key_to_config("CUSTOM_API_HANDLER", handler_value)
|
|
128
|
+
setattr(config_module, "CUSTOM_API_HANDLER", handler_value)
|
|
129
|
+
try:
|
|
130
|
+
handler_path = _ensure_custom_api_handler_file(handler_value, endpoint_value)
|
|
131
|
+
except OSError as exc:
|
|
132
|
+
cyber(f"Could not prepare custom API handler: {exc}", color=Fore.RED)
|
|
133
|
+
return False
|
|
134
|
+
|
|
135
|
+
if open_handler:
|
|
136
|
+
ok, msg = open_in_default_editor(handler_path)
|
|
137
|
+
color = Fore.GREEN if ok else Fore.YELLOW
|
|
138
|
+
cyber(msg, color=color)
|
|
139
|
+
|
|
140
|
+
return True
|
|
141
|
+
|
|
142
|
+
|
|
48
143
|
def _read_key(name, config_value):
|
|
49
144
|
env_key = os.getenv(name, "").strip()
|
|
50
145
|
if env_key:
|
|
@@ -201,7 +296,7 @@ def run_self_update():
|
|
|
201
296
|
updated = False
|
|
202
297
|
|
|
203
298
|
pip_result = subprocess.run(
|
|
204
|
-
[
|
|
299
|
+
[sys.executable, "-m", "pip", "install", "--upgrade", PYPI_PACKAGE,"--break-system-packages"],
|
|
205
300
|
text=True
|
|
206
301
|
)
|
|
207
302
|
if pip_result.returncode == 0:
|
|
@@ -291,11 +386,11 @@ def open_in_default_editor(path):
|
|
|
291
386
|
if sys.stdin.isatty() and sys.stdout.isatty():
|
|
292
387
|
proc = subprocess.run([*editor_args, str(target)])
|
|
293
388
|
if proc.returncode == 0:
|
|
294
|
-
return True, f"
|
|
295
|
-
return False, f"
|
|
389
|
+
return True, f"::EVA Configuration Saved"
|
|
390
|
+
return False, f":: Error [{proc.returncode}]::"
|
|
296
391
|
else:
|
|
297
392
|
subprocess.Popen([*editor_args, str(target)])
|
|
298
|
-
return True, f"Opened
|
|
393
|
+
return True, f"::Opened EVA config files::"
|
|
299
394
|
except OSError:
|
|
300
395
|
pass
|
|
301
396
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|