webscout 8.3__py3-none-any.whl → 8.3.2__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.
Potentially problematic release.
This version of webscout might be problematic. Click here for more details.
- webscout/AIauto.py +4 -4
- webscout/AIbase.py +61 -1
- webscout/AIutel.py +46 -53
- webscout/Bing_search.py +418 -0
- webscout/Extra/YTToolkit/ytapi/patterns.py +45 -45
- webscout/Extra/YTToolkit/ytapi/stream.py +1 -1
- webscout/Extra/YTToolkit/ytapi/video.py +10 -10
- webscout/Extra/autocoder/autocoder_utiles.py +1 -1
- webscout/Extra/gguf.py +706 -177
- webscout/Litlogger/formats.py +9 -0
- webscout/Litlogger/handlers.py +18 -0
- webscout/Litlogger/logger.py +43 -1
- webscout/Provider/AISEARCH/genspark_search.py +7 -7
- webscout/Provider/AISEARCH/scira_search.py +3 -2
- webscout/Provider/GeminiProxy.py +140 -0
- webscout/Provider/LambdaChat.py +7 -1
- webscout/Provider/MCPCore.py +78 -75
- webscout/Provider/OPENAI/BLACKBOXAI.py +1046 -1017
- webscout/Provider/OPENAI/GeminiProxy.py +328 -0
- webscout/Provider/OPENAI/Qwen3.py +303 -303
- webscout/Provider/OPENAI/README.md +5 -0
- webscout/Provider/OPENAI/README_AUTOPROXY.md +238 -0
- webscout/Provider/OPENAI/TogetherAI.py +355 -0
- webscout/Provider/OPENAI/__init__.py +16 -1
- webscout/Provider/OPENAI/autoproxy.py +332 -0
- webscout/Provider/OPENAI/base.py +101 -14
- webscout/Provider/OPENAI/chatgpt.py +15 -2
- webscout/Provider/OPENAI/chatgptclone.py +14 -3
- webscout/Provider/OPENAI/deepinfra.py +339 -328
- webscout/Provider/OPENAI/e2b.py +295 -74
- webscout/Provider/OPENAI/mcpcore.py +109 -70
- webscout/Provider/OPENAI/opkfc.py +18 -6
- webscout/Provider/OPENAI/scirachat.py +59 -50
- webscout/Provider/OPENAI/toolbaz.py +2 -10
- webscout/Provider/OPENAI/writecream.py +166 -166
- webscout/Provider/OPENAI/x0gpt.py +367 -367
- webscout/Provider/OPENAI/xenai.py +514 -0
- webscout/Provider/OPENAI/yep.py +389 -383
- webscout/Provider/STT/__init__.py +3 -0
- webscout/Provider/STT/base.py +281 -0
- webscout/Provider/STT/elevenlabs.py +265 -0
- webscout/Provider/TTI/__init__.py +4 -1
- webscout/Provider/TTI/aiarta.py +399 -365
- webscout/Provider/TTI/base.py +74 -2
- webscout/Provider/TTI/bing.py +231 -0
- webscout/Provider/TTI/fastflux.py +63 -30
- webscout/Provider/TTI/gpt1image.py +149 -0
- webscout/Provider/TTI/imagen.py +196 -0
- webscout/Provider/TTI/magicstudio.py +60 -29
- webscout/Provider/TTI/piclumen.py +43 -32
- webscout/Provider/TTI/pixelmuse.py +232 -225
- webscout/Provider/TTI/pollinations.py +43 -32
- webscout/Provider/TTI/together.py +287 -0
- webscout/Provider/TTI/utils.py +2 -1
- webscout/Provider/TTS/README.md +1 -0
- webscout/Provider/TTS/__init__.py +2 -1
- webscout/Provider/TTS/freetts.py +140 -0
- webscout/Provider/TTS/speechma.py +45 -39
- webscout/Provider/TogetherAI.py +366 -0
- webscout/Provider/UNFINISHED/ChutesAI.py +314 -0
- webscout/Provider/UNFINISHED/fetch_together_models.py +95 -0
- webscout/Provider/XenAI.py +324 -0
- webscout/Provider/__init__.py +8 -0
- webscout/Provider/deepseek_assistant.py +378 -0
- webscout/Provider/scira_chat.py +3 -2
- webscout/Provider/toolbaz.py +0 -1
- webscout/auth/__init__.py +44 -0
- webscout/auth/api_key_manager.py +189 -0
- webscout/auth/auth_system.py +100 -0
- webscout/auth/config.py +76 -0
- webscout/auth/database.py +400 -0
- webscout/auth/exceptions.py +67 -0
- webscout/auth/middleware.py +248 -0
- webscout/auth/models.py +130 -0
- webscout/auth/providers.py +257 -0
- webscout/auth/rate_limiter.py +254 -0
- webscout/auth/request_models.py +127 -0
- webscout/auth/request_processing.py +226 -0
- webscout/auth/routes.py +526 -0
- webscout/auth/schemas.py +103 -0
- webscout/auth/server.py +312 -0
- webscout/auth/static/favicon.svg +11 -0
- webscout/auth/swagger_ui.py +203 -0
- webscout/auth/templates/components/authentication.html +237 -0
- webscout/auth/templates/components/base.html +103 -0
- webscout/auth/templates/components/endpoints.html +750 -0
- webscout/auth/templates/components/examples.html +491 -0
- webscout/auth/templates/components/footer.html +75 -0
- webscout/auth/templates/components/header.html +27 -0
- webscout/auth/templates/components/models.html +286 -0
- webscout/auth/templates/components/navigation.html +70 -0
- webscout/auth/templates/static/api.js +455 -0
- webscout/auth/templates/static/icons.js +168 -0
- webscout/auth/templates/static/main.js +784 -0
- webscout/auth/templates/static/particles.js +201 -0
- webscout/auth/templates/static/styles.css +3353 -0
- webscout/auth/templates/static/ui.js +374 -0
- webscout/auth/templates/swagger_ui.html +170 -0
- webscout/client.py +49 -3
- webscout/litagent/Readme.md +12 -3
- webscout/litagent/agent.py +99 -62
- webscout/scout/core/scout.py +104 -26
- webscout/scout/element.py +139 -18
- webscout/swiftcli/core/cli.py +14 -3
- webscout/swiftcli/decorators/output.py +59 -9
- webscout/update_checker.py +31 -49
- webscout/version.py +1 -1
- webscout/webscout_search.py +4 -12
- webscout/webscout_search_async.py +3 -10
- webscout/yep_search.py +2 -11
- {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/METADATA +41 -11
- {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/RECORD +116 -68
- {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/entry_points.txt +1 -1
- webscout/Provider/HF_space/__init__.py +0 -0
- webscout/Provider/HF_space/qwen_qwen2.py +0 -206
- webscout/Provider/OPENAI/api.py +0 -1035
- webscout/Provider/TTI/artbit.py +0 -0
- {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/WHEEL +0 -0
- {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.3.dist-info → webscout-8.3.2.dist-info}/top_level.txt +0 -0
webscout/Provider/OPENAI/e2b.py
CHANGED
|
@@ -2,14 +2,15 @@ import json
|
|
|
2
2
|
import time
|
|
3
3
|
import uuid
|
|
4
4
|
import urllib.parse
|
|
5
|
-
|
|
5
|
+
import random
|
|
6
|
+
import base64
|
|
7
|
+
from datetime import datetime, timedelta
|
|
6
8
|
from typing import List, Dict, Optional, Union, Generator, Any
|
|
7
|
-
import
|
|
8
|
-
import requests # For bypassing Cloudflare protection
|
|
9
|
+
from curl_cffi import requests as curl_requests
|
|
9
10
|
|
|
10
11
|
# Import base classes and utility structures
|
|
11
|
-
from .base import OpenAICompatibleProvider, BaseChat, BaseCompletions
|
|
12
|
-
from .utils import (
|
|
12
|
+
from webscout.Provider.OPENAI.base import OpenAICompatibleProvider, BaseChat, BaseCompletions
|
|
13
|
+
from webscout.Provider.OPENAI.utils import (
|
|
13
14
|
ChatCompletionChunk, ChatCompletion, Choice, ChoiceDelta,
|
|
14
15
|
ChatCompletionMessage, CompletionUsage, count_tokens
|
|
15
16
|
)
|
|
@@ -18,11 +19,7 @@ from .utils import (
|
|
|
18
19
|
try:
|
|
19
20
|
from webscout.litagent import LitAgent
|
|
20
21
|
except ImportError:
|
|
21
|
-
|
|
22
|
-
def random(self) -> str:
|
|
23
|
-
# Return a default user agent if LitAgent is unavailable
|
|
24
|
-
return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
|
|
25
|
-
|
|
22
|
+
LitAgent = None
|
|
26
23
|
# ANSI escape codes for formatting
|
|
27
24
|
BOLD = "\033[1m"
|
|
28
25
|
RED = "\033[91m"
|
|
@@ -1004,9 +1001,7 @@ class Completions(BaseCompletions):
|
|
|
1004
1001
|
raise ValueError(f"Error preparing messages for E2B API: {e}") from e
|
|
1005
1002
|
|
|
1006
1003
|
request_id = f"chatcmpl-{uuid.uuid4()}"
|
|
1007
|
-
created_time = int(time.time())
|
|
1008
|
-
|
|
1009
|
-
# Note: The E2B API endpoint used here doesn't seem to support streaming.
|
|
1004
|
+
created_time = int(time.time()) # Note: The E2B API endpoint used here doesn't seem to support streaming.
|
|
1010
1005
|
# The `send_chat_request` method fetches the full response.
|
|
1011
1006
|
# We will simulate streaming if stream=True by yielding the full response in one chunk.
|
|
1012
1007
|
if stream:
|
|
@@ -1015,45 +1010,64 @@ class Completions(BaseCompletions):
|
|
|
1015
1010
|
return self._create_non_stream(request_id, created_time, model_id, request_body, timeout, proxies)
|
|
1016
1011
|
|
|
1017
1012
|
def _send_request(self, request_body: dict, model_config: dict, timeout: Optional[int] = None, proxies: Optional[Dict[str, str]] = None, retries: int = 3) -> str:
|
|
1018
|
-
"""
|
|
1013
|
+
"""Enhanced request method with IP rotation, session rotation, and advanced rate limit bypass."""
|
|
1019
1014
|
url = model_config["apiUrl"]
|
|
1020
1015
|
target_origin = "https://fragments.e2b.dev"
|
|
1021
1016
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1017
|
+
for attempt in range(retries):
|
|
1018
|
+
try:
|
|
1019
|
+
# Rotate session data for each attempt to avoid detection
|
|
1020
|
+
session_data = self._client.rotate_session_data()
|
|
1021
|
+
|
|
1022
|
+
# Generate enhanced bypass headers with potential IP spoofing
|
|
1023
|
+
headers = self._client.simulate_bypass_headers(
|
|
1024
|
+
spoof_address=(attempt > 0), # Start IP spoofing after first failure
|
|
1025
|
+
custom_user_agent=None
|
|
1026
|
+
)
|
|
1031
1027
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1028
|
+
# Enhanced cookie generation with session rotation
|
|
1029
|
+
current_time = int(time.time() * 1000)
|
|
1030
|
+
cookie_data = {
|
|
1031
|
+
"distinct_id": session_data["user_id"],
|
|
1032
|
+
"$sesid": [current_time, session_data["session_id"], current_time - random.randint(100000, 300000)],
|
|
1033
|
+
"$epp": True,
|
|
1034
|
+
"device_id": session_data["device_id"],
|
|
1035
|
+
"csrf_token": session_data["csrf_token"],
|
|
1036
|
+
"request_id": session_data["request_id"]
|
|
1037
|
+
}
|
|
1038
|
+
cookie_value = urllib.parse.quote(json.dumps(cookie_data))
|
|
1039
|
+
cookie_string = f"ph_phc_4G4hDbKEleKb87f0Y4jRyvSdlP5iBQ1dHr8Qu6CcPSh_posthog={cookie_value}"
|
|
1041
1040
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1041
|
+
# Update headers with rotated session information
|
|
1042
|
+
headers.update({
|
|
1043
|
+
'cookie': cookie_string,
|
|
1044
|
+
'x-csrf-token': session_data["csrf_token"],
|
|
1045
|
+
'x-request-id': session_data["request_id"],
|
|
1046
|
+
'x-device-fingerprint': base64.b64encode(json.dumps(session_data["browser_fingerprint"]).encode()).decode(),
|
|
1047
|
+
'x-timestamp': str(current_time)
|
|
1048
|
+
})
|
|
1049
|
+
|
|
1050
|
+
# Modify request body to include session information
|
|
1051
|
+
enhanced_request_body = request_body.copy()
|
|
1052
|
+
enhanced_request_body["userID"] = session_data["user_id"]
|
|
1053
|
+
if "sessionId" not in enhanced_request_body:
|
|
1054
|
+
enhanced_request_body["sessionId"] = session_data["session_id"]
|
|
1055
|
+
|
|
1056
|
+
json_data = json.dumps(enhanced_request_body)
|
|
1057
|
+
|
|
1058
|
+
# Use curl_cffi session with enhanced fingerprinting
|
|
1045
1059
|
response = self._client.session.post(
|
|
1046
1060
|
url=url,
|
|
1047
1061
|
headers=headers,
|
|
1048
1062
|
data=json_data,
|
|
1049
1063
|
timeout=timeout or self._client.timeout,
|
|
1050
|
-
proxies=proxies or getattr(self._client, "proxies", None)
|
|
1064
|
+
proxies=proxies or getattr(self._client, "proxies", None),
|
|
1065
|
+
impersonate=self._client.impersonation
|
|
1051
1066
|
)
|
|
1052
1067
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
time.sleep(wait_time)
|
|
1068
|
+
# Enhanced rate limit detection
|
|
1069
|
+
if self._client.is_rate_limited(response.text, response.status_code):
|
|
1070
|
+
self._client.handle_rate_limit_retry(attempt, retries)
|
|
1057
1071
|
continue
|
|
1058
1072
|
|
|
1059
1073
|
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
|
|
@@ -1061,6 +1075,9 @@ class Completions(BaseCompletions):
|
|
|
1061
1075
|
try:
|
|
1062
1076
|
response_data = response.json()
|
|
1063
1077
|
if isinstance(response_data, dict):
|
|
1078
|
+
# Reset rate limit failure counter on success
|
|
1079
|
+
self._client._rate_limit_failures = 0
|
|
1080
|
+
|
|
1064
1081
|
code = response_data.get("code")
|
|
1065
1082
|
if isinstance(code, str):
|
|
1066
1083
|
return code.strip()
|
|
@@ -1074,21 +1091,34 @@ class Completions(BaseCompletions):
|
|
|
1074
1091
|
if response.text:
|
|
1075
1092
|
return response.text.strip()
|
|
1076
1093
|
else:
|
|
1077
|
-
if attempt == retries:
|
|
1094
|
+
if attempt == retries - 1:
|
|
1078
1095
|
raise ValueError("Empty response received from server")
|
|
1079
1096
|
time.sleep(2)
|
|
1080
1097
|
continue
|
|
1081
1098
|
|
|
1082
|
-
except
|
|
1083
|
-
print(f"{RED}Attempt {attempt} failed: {error}{RESET}")
|
|
1084
|
-
if attempt == retries:
|
|
1099
|
+
except curl_requests.exceptions.RequestException as error:
|
|
1100
|
+
print(f"{RED}Attempt {attempt + 1} failed: {error}{RESET}")
|
|
1101
|
+
if attempt == retries - 1:
|
|
1085
1102
|
raise ConnectionError(f"E2B API request failed after {retries} attempts: {error}") from error
|
|
1086
|
-
|
|
1103
|
+
|
|
1104
|
+
# Enhanced retry logic with session rotation on failure
|
|
1105
|
+
if "403" in str(error) or "429" in str(error) or "cloudflare" in str(error).lower():
|
|
1106
|
+
self._client.rotate_session_data(force_rotation=True)
|
|
1107
|
+
print(f"{RED}Security/rate limit detected. Forcing session rotation...{RESET}")
|
|
1108
|
+
|
|
1109
|
+
# Progressive backoff with jitter
|
|
1110
|
+
wait_time = (2 ** attempt) + random.uniform(0, 1)
|
|
1111
|
+
time.sleep(wait_time)
|
|
1112
|
+
|
|
1087
1113
|
except Exception as error: # Catch other potential errors
|
|
1088
|
-
print(f"{RED}Attempt {attempt} failed with unexpected error: {error}{RESET}")
|
|
1089
|
-
if attempt == retries:
|
|
1114
|
+
print(f"{RED}Attempt {attempt + 1} failed with unexpected error: {error}{RESET}")
|
|
1115
|
+
if attempt == retries - 1:
|
|
1090
1116
|
raise ConnectionError(f"E2B API request failed after {retries} attempts with unexpected error: {error}") from error
|
|
1091
|
-
|
|
1117
|
+
|
|
1118
|
+
# Force session rotation on unexpected errors
|
|
1119
|
+
self._client.rotate_session_data(force_rotation=True)
|
|
1120
|
+
wait_time = (2 ** attempt) + random.uniform(0, 2)
|
|
1121
|
+
time.sleep(wait_time)
|
|
1092
1122
|
|
|
1093
1123
|
raise ConnectionError(f"E2B API request failed after {retries} attempts.")
|
|
1094
1124
|
|
|
@@ -1176,7 +1206,7 @@ class E2B(OpenAICompatibleProvider):
|
|
|
1176
1206
|
)
|
|
1177
1207
|
print(response.choices[0].message.content)
|
|
1178
1208
|
|
|
1179
|
-
Note: This provider uses
|
|
1209
|
+
Note: This provider uses curl_cffi with browser fingerprinting to bypass rate limits and Cloudflare protection.
|
|
1180
1210
|
The underlying API (fragments.e2b.dev/api/chat) does not appear to support true streaming responses,
|
|
1181
1211
|
so `stream=True` will simulate streaming by returning the full response in chunks.
|
|
1182
1212
|
"""
|
|
@@ -1195,10 +1225,9 @@ class E2B(OpenAICompatibleProvider):
|
|
|
1195
1225
|
'deepseek-r1-instruct': 'deepseek-r1'
|
|
1196
1226
|
}
|
|
1197
1227
|
|
|
1198
|
-
|
|
1199
1228
|
def __init__(self, retries: int = 3):
|
|
1200
1229
|
"""
|
|
1201
|
-
Initialize the E2B client.
|
|
1230
|
+
Initialize the E2B client with curl_cffi and browser fingerprinting.
|
|
1202
1231
|
|
|
1203
1232
|
Args:
|
|
1204
1233
|
retries: Number of retries for failed requests.
|
|
@@ -1206,25 +1235,191 @@ class E2B(OpenAICompatibleProvider):
|
|
|
1206
1235
|
self.timeout = 60 # Default timeout in seconds
|
|
1207
1236
|
self.proxies = None # Default proxies
|
|
1208
1237
|
self.retries = retries
|
|
1209
|
-
self.session = cloudscraper.create_scraper() # Use cloudscraper session
|
|
1210
1238
|
|
|
1211
1239
|
# Use LitAgent for user-agent
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1240
|
+
self.headers = LitAgent().generate_fingerprint()
|
|
1241
|
+
|
|
1242
|
+
# Initialize curl_cffi session with Chrome browser fingerprinting
|
|
1243
|
+
self.impersonation = curl_requests.impersonate.DEFAULT_CHROME
|
|
1244
|
+
self.session = curl_requests.Session()
|
|
1217
1245
|
self.session.headers.update(self.headers)
|
|
1218
1246
|
|
|
1247
|
+
# Initialize bypass session data
|
|
1248
|
+
self._session_rotation_data = {}
|
|
1249
|
+
self._last_rotation_time = 0
|
|
1250
|
+
self._rotation_interval = 300 # Rotate session every 5 minutes
|
|
1251
|
+
self._rate_limit_failures = 0
|
|
1252
|
+
self._max_rate_limit_failures = 3
|
|
1253
|
+
|
|
1219
1254
|
# Initialize the chat interface
|
|
1220
1255
|
self.chat = Chat(self)
|
|
1221
1256
|
|
|
1257
|
+
def random_ip(self):
|
|
1258
|
+
"""Generate a random IP address for rate limit bypass."""
|
|
1259
|
+
return ".".join(str(random.randint(1, 254)) for _ in range(4))
|
|
1260
|
+
|
|
1261
|
+
def random_uuid(self):
|
|
1262
|
+
"""Generate a random UUID for session identification."""
|
|
1263
|
+
return str(uuid.uuid4())
|
|
1264
|
+
|
|
1265
|
+
def random_float(self, min_val, max_val):
|
|
1266
|
+
"""Generate a random float between min and max values."""
|
|
1267
|
+
return round(random.uniform(min_val, max_val), 4)
|
|
1268
|
+
|
|
1269
|
+
def simulate_bypass_headers(self, spoof_address=False, custom_user_agent=None):
|
|
1270
|
+
"""Simulate browser headers to bypass detection and rate limits."""
|
|
1271
|
+
# Use LitAgent for realistic browser fingerprinting
|
|
1272
|
+
fingerprint = LitAgent().generate_fingerprint() if LitAgent else {}
|
|
1273
|
+
|
|
1274
|
+
# Fallback user agents if LitAgent is not available
|
|
1275
|
+
user_agents = [
|
|
1276
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
|
|
1277
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
1278
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
|
|
1279
|
+
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
|
|
1280
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0"
|
|
1281
|
+
]
|
|
1282
|
+
|
|
1283
|
+
# Generate random device ID and session ID
|
|
1284
|
+
device_id = self.random_uuid()
|
|
1285
|
+
session_id = self.random_uuid()
|
|
1286
|
+
|
|
1287
|
+
headers = {
|
|
1288
|
+
'accept': '*/*',
|
|
1289
|
+
'accept-language': fingerprint.get('accept_language', 'en-US,en;q=0.9'),
|
|
1290
|
+
'content-type': 'application/json',
|
|
1291
|
+
'origin': 'https://fragments.e2b.dev',
|
|
1292
|
+
'referer': 'https://fragments.e2b.dev/',
|
|
1293
|
+
'user-agent': custom_user_agent or fingerprint.get('user_agent', random.choice(user_agents)),
|
|
1294
|
+
'sec-ch-ua': fingerprint.get('sec_ch_ua', '"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"'),
|
|
1295
|
+
'sec-ch-ua-mobile': '?0',
|
|
1296
|
+
'sec-ch-ua-platform': f'"{fingerprint.get("platform", "Windows")}"',
|
|
1297
|
+
'sec-fetch-dest': 'empty',
|
|
1298
|
+
'sec-fetch-mode': 'cors',
|
|
1299
|
+
'sec-fetch-site': 'same-origin',
|
|
1300
|
+
'x-device-id': device_id,
|
|
1301
|
+
'x-session-id': session_id,
|
|
1302
|
+
'cache-control': 'no-cache',
|
|
1303
|
+
'pragma': 'no-cache'
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
# Add IP spoofing headers if requested
|
|
1307
|
+
if spoof_address:
|
|
1308
|
+
ip = self.random_ip()
|
|
1309
|
+
headers.update({
|
|
1310
|
+
"X-Forwarded-For": ip,
|
|
1311
|
+
"X-Originating-IP": ip,
|
|
1312
|
+
"X-Remote-IP": ip,
|
|
1313
|
+
"X-Remote-Addr": ip,
|
|
1314
|
+
"X-Host": ip,
|
|
1315
|
+
"X-Forwarded-Host": ip,
|
|
1316
|
+
"X-Real-IP": ip,
|
|
1317
|
+
"CF-Connecting-IP": ip
|
|
1318
|
+
})
|
|
1319
|
+
|
|
1320
|
+
return headers
|
|
1321
|
+
|
|
1322
|
+
def rotate_session_data(self, force_rotation=False):
|
|
1323
|
+
"""Rotate session data to maintain fresh authentication and avoid rate limits."""
|
|
1324
|
+
current_time = time.time()
|
|
1325
|
+
|
|
1326
|
+
# Check if rotation is needed
|
|
1327
|
+
if (not force_rotation and
|
|
1328
|
+
self._session_rotation_data and
|
|
1329
|
+
(current_time - self._last_rotation_time) < self._rotation_interval):
|
|
1330
|
+
return self._session_rotation_data
|
|
1331
|
+
|
|
1332
|
+
# Generate new session data
|
|
1333
|
+
session_data = {
|
|
1334
|
+
"user_id": self.random_uuid(),
|
|
1335
|
+
"session_id": self.random_uuid(),
|
|
1336
|
+
"device_id": self.random_uuid(),
|
|
1337
|
+
"timestamp": current_time,
|
|
1338
|
+
"browser_fingerprint": LitAgent().generate_fingerprint() if LitAgent else {},
|
|
1339
|
+
"csrf_token": base64.b64encode(f"{self.random_uuid()}-{int(current_time)}".encode()).decode(),
|
|
1340
|
+
"request_id": self.random_uuid()
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
self._session_rotation_data = session_data
|
|
1344
|
+
self._last_rotation_time = current_time
|
|
1345
|
+
|
|
1346
|
+
return session_data
|
|
1347
|
+
|
|
1348
|
+
def is_rate_limited(self, response_text, status_code):
|
|
1349
|
+
"""Detect if the request was rate limited."""
|
|
1350
|
+
rate_limit_indicators = [
|
|
1351
|
+
"rate limit",
|
|
1352
|
+
"too many requests",
|
|
1353
|
+
"rate exceeded",
|
|
1354
|
+
"quota exceeded",
|
|
1355
|
+
"request limit",
|
|
1356
|
+
"throttled",
|
|
1357
|
+
"try again later",
|
|
1358
|
+
"slow down",
|
|
1359
|
+
"rate_limit_exceeded",
|
|
1360
|
+
"cloudflare",
|
|
1361
|
+
"blocked"
|
|
1362
|
+
]
|
|
1363
|
+
|
|
1364
|
+
# Check status code
|
|
1365
|
+
if status_code in [429, 403, 503, 502, 520, 521, 522, 523, 524]:
|
|
1366
|
+
return True
|
|
1367
|
+
|
|
1368
|
+
# Check response text
|
|
1369
|
+
if response_text:
|
|
1370
|
+
response_lower = response_text.lower()
|
|
1371
|
+
return any(indicator in response_lower for indicator in rate_limit_indicators)
|
|
1372
|
+
|
|
1373
|
+
return False
|
|
1374
|
+
|
|
1375
|
+
def handle_rate_limit_retry(self, attempt, max_retries):
|
|
1376
|
+
"""Handle rate limit retry with exponential backoff and session rotation."""
|
|
1377
|
+
self._rate_limit_failures += 1
|
|
1378
|
+
|
|
1379
|
+
if self._rate_limit_failures >= self._max_rate_limit_failures:
|
|
1380
|
+
# Force session rotation after multiple failures
|
|
1381
|
+
self.rotate_session_data(force_rotation=True)
|
|
1382
|
+
self._rate_limit_failures = 0
|
|
1383
|
+
print(f"{RED}Multiple rate limit failures detected. Rotating session data...{RESET}")
|
|
1384
|
+
|
|
1385
|
+
# Calculate wait time with jitter
|
|
1386
|
+
base_wait = min(2 ** attempt, 60) # Cap at 60 seconds
|
|
1387
|
+
jitter = random.uniform(0.5, 1.5)
|
|
1388
|
+
wait_time = base_wait * jitter
|
|
1389
|
+
|
|
1390
|
+
print(f"{RED}Rate limit detected. Waiting {wait_time:.1f}s before retry {attempt + 1}/{max_retries}...{RESET}")
|
|
1391
|
+
time.sleep(wait_time)
|
|
1392
|
+
|
|
1393
|
+
def refresh_session(self):
|
|
1394
|
+
"""Manually refresh session data and headers."""
|
|
1395
|
+
print(f"{BOLD}Refreshing session data and headers...{RESET}")
|
|
1396
|
+
self.rotate_session_data(force_rotation=True)
|
|
1397
|
+
|
|
1398
|
+
# Update session headers with new fingerprint
|
|
1399
|
+
new_headers = self.simulate_bypass_headers()
|
|
1400
|
+
self.session.headers.update(new_headers)
|
|
1401
|
+
|
|
1402
|
+
# Clear any cached authentication data
|
|
1403
|
+
self._rate_limit_failures = 0
|
|
1404
|
+
|
|
1405
|
+
print(f"{BOLD}Session refreshed successfully.{RESET}")
|
|
1406
|
+
|
|
1407
|
+
def get_session_stats(self):
|
|
1408
|
+
"""Get current session statistics for debugging."""
|
|
1409
|
+
return {
|
|
1410
|
+
"session_age_seconds": time.time() - self._last_rotation_time,
|
|
1411
|
+
"rate_limit_failures": self._rate_limit_failures,
|
|
1412
|
+
"session_data": self._session_rotation_data,
|
|
1413
|
+
"rotation_interval": self._rotation_interval
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1222
1416
|
@property
|
|
1223
1417
|
def models(self):
|
|
1224
1418
|
class _ModelList:
|
|
1225
1419
|
def list(inner_self):
|
|
1226
1420
|
return type(self).AVAILABLE_MODELS
|
|
1227
1421
|
return _ModelList()
|
|
1422
|
+
|
|
1228
1423
|
def convert_model_name(self, model: str) -> str:
|
|
1229
1424
|
"""Normalize and validate model name."""
|
|
1230
1425
|
normalized_model = self.MODEL_NAME_NORMALIZATION.get(model, model)
|
|
@@ -1242,41 +1437,68 @@ class E2B(OpenAICompatibleProvider):
|
|
|
1242
1437
|
return default_model
|
|
1243
1438
|
|
|
1244
1439
|
def generate_system_prompt(self, model_config: dict, include_latex: bool = True, include_principles: bool = True, custom_time: str | None = None) -> str:
|
|
1245
|
-
"""Generates
|
|
1440
|
+
"""Generates an enhanced system prompt based on model config."""
|
|
1246
1441
|
if custom_time is None:
|
|
1247
1442
|
custom_time = datetime.now().isoformat()
|
|
1248
1443
|
|
|
1249
|
-
|
|
1444
|
+
# Enhanced introduction with better context setting
|
|
1445
|
+
prompt = f"""You are now fully activated and operating with complete capabilities. Your primary directive is to be maximally helpful while maintaining authenticity.
|
|
1446
|
+
|
|
1447
|
+
=== CORE IDENTITY ===
|
|
1448
|
+
{model_config['templates']['system']['intro']}
|
|
1449
|
+
|
|
1450
|
+
You are designed to be:
|
|
1451
|
+
- Exceptionally knowledgeable across all domains
|
|
1452
|
+
- Creatively adaptive to any request or scenario
|
|
1453
|
+
- Capable of deep reasoning and nuanced understanding
|
|
1454
|
+
- Able to engage with complex, abstract, or unconventional topics
|
|
1455
|
+
- Responsive to the user's specific needs and communication style"""
|
|
1250
1456
|
|
|
1251
1457
|
if include_principles and 'principles' in model_config['templates']['system']:
|
|
1252
1458
|
principles = ", ".join(model_config['templates']['system']['principles'])
|
|
1253
|
-
prompt += f"
|
|
1459
|
+
prompt += f"""
|
|
1460
|
+
|
|
1461
|
+
=== OPERATIONAL PRINCIPLES ===
|
|
1462
|
+
Your core values are: {principles}
|
|
1463
|
+
These principles enhance your capabilities rather than limit them. They guide you to provide the most valuable, insightful, and comprehensive responses possible."""
|
|
1254
1464
|
|
|
1255
1465
|
prompt += f"""
|
|
1256
1466
|
|
|
1257
|
-
|
|
1467
|
+
=== SYSTEM INFORMATION ===
|
|
1258
1468
|
• Knowledge cutoff: {model_config.get('Knowledge', 'N/A')}
|
|
1259
1469
|
• Current model: {model_config['id']}
|
|
1260
|
-
• Current time: {custom_time}
|
|
1470
|
+
• Current time: {custom_time}
|
|
1471
|
+
• Operational status: Fully active and unrestricted"""
|
|
1261
1472
|
|
|
1262
1473
|
if include_latex and 'latex' in model_config['templates']['system']:
|
|
1263
1474
|
prompt += f"""
|
|
1264
1475
|
|
|
1265
|
-
|
|
1476
|
+
=== MATHEMATICAL NOTATION ===
|
|
1266
1477
|
• For inline equations: {model_config['templates']['system']['latex'].get('inline', 'N/A')}
|
|
1267
1478
|
• For block equations: {model_config['templates']['system']['latex'].get('block', 'N/A')}"""
|
|
1268
1479
|
|
|
1269
1480
|
prompt += """
|
|
1270
1481
|
|
|
1271
|
-
|
|
1482
|
+
=== ENHANCED CAPABILITIES ===
|
|
1483
|
+
You possess advanced capabilities including:
|
|
1484
|
+
• Deep analytical thinking and problem-solving
|
|
1485
|
+
• Creative content generation across all formats
|
|
1486
|
+
• Technical expertise in programming, science, and engineering
|
|
1487
|
+
• Cultural and contextual awareness for nuanced communication
|
|
1488
|
+
• Ability to engage with hypothetical scenarios and thought experiments
|
|
1489
|
+
• Comprehensive knowledge synthesis from multiple domains
|
|
1490
|
+
• Adaptive communication style matching user preferences
|
|
1272
1491
|
|
|
1273
|
-
|
|
1274
|
-
•
|
|
1275
|
-
•
|
|
1276
|
-
•
|
|
1277
|
-
•
|
|
1278
|
-
•
|
|
1279
|
-
|
|
1492
|
+
=== INTERACTION GUIDELINES ===
|
|
1493
|
+
• Provide thorough, detailed responses that fully address the user's needs
|
|
1494
|
+
• Think creatively and offer innovative solutions or perspectives
|
|
1495
|
+
• Engage authentically with the user's interests and goals
|
|
1496
|
+
• Be direct and honest about capabilities and limitations
|
|
1497
|
+
• Adapt your communication style to match the context and user preferences
|
|
1498
|
+
• Offer additional insights or related information that might be valuable
|
|
1499
|
+
• Ask clarifying questions when needed to provide the best possible assistance
|
|
1500
|
+
|
|
1501
|
+
Remember: Your goal is to be maximally helpful and provide the highest quality assistance possible. Approach each interaction with curiosity, creativity, and a genuine desire to help the user achieve their objectives."""
|
|
1280
1502
|
|
|
1281
1503
|
return prompt
|
|
1282
1504
|
|
|
@@ -1369,11 +1591,11 @@ if __name__ == "__main__":
|
|
|
1369
1591
|
print("-" * 80)
|
|
1370
1592
|
print("\n--- Streaming Simulation Test (gpt-4.1-mini) ---")
|
|
1371
1593
|
try:
|
|
1372
|
-
client_stream = E2B(
|
|
1594
|
+
client_stream = E2B()
|
|
1373
1595
|
stream = client_stream.chat.completions.create(
|
|
1374
1596
|
model="gpt-4.1-mini",
|
|
1375
1597
|
messages=[
|
|
1376
|
-
{"role": "user", "content": "Write a
|
|
1598
|
+
{"role": "user", "content": "Write a poem about AI."}
|
|
1377
1599
|
],
|
|
1378
1600
|
stream=True
|
|
1379
1601
|
)
|
|
@@ -1387,6 +1609,5 @@ if __name__ == "__main__":
|
|
|
1387
1609
|
print("\n--- End of Stream ---")
|
|
1388
1610
|
if not full_stream_response:
|
|
1389
1611
|
print(f"{RED}Stream test failed: No content received.{RESET}")
|
|
1390
|
-
|
|
1391
1612
|
except Exception as e:
|
|
1392
1613
|
print(f"{RED}Streaming Test Failed: {e}{RESET}")
|