webscout 8.2.8__py3-none-any.whl → 8.2.9__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.
- webscout/AIauto.py +32 -14
- webscout/AIbase.py +96 -37
- webscout/AIutel.py +491 -87
- webscout/Bard.py +441 -323
- webscout/Extra/GitToolkit/__init__.py +10 -10
- webscout/Extra/YTToolkit/ytapi/video.py +232 -232
- webscout/Litlogger/README.md +10 -0
- webscout/Litlogger/__init__.py +7 -59
- webscout/Litlogger/formats.py +4 -0
- webscout/Litlogger/handlers.py +103 -0
- webscout/Litlogger/levels.py +13 -0
- webscout/Litlogger/logger.py +92 -0
- webscout/Provider/AISEARCH/Perplexity.py +332 -358
- webscout/Provider/AISEARCH/felo_search.py +9 -35
- webscout/Provider/AISEARCH/genspark_search.py +30 -56
- webscout/Provider/AISEARCH/hika_search.py +4 -16
- webscout/Provider/AISEARCH/iask_search.py +410 -436
- webscout/Provider/AISEARCH/monica_search.py +4 -30
- webscout/Provider/AISEARCH/scira_search.py +6 -32
- webscout/Provider/AISEARCH/webpilotai_search.py +38 -64
- webscout/Provider/Blackboxai.py +153 -35
- webscout/Provider/Deepinfra.py +339 -339
- webscout/Provider/ExaChat.py +358 -358
- webscout/Provider/Gemini.py +169 -169
- webscout/Provider/GithubChat.py +1 -2
- webscout/Provider/Glider.py +3 -3
- webscout/Provider/HeckAI.py +171 -81
- webscout/Provider/OPENAI/BLACKBOXAI.py +766 -735
- webscout/Provider/OPENAI/Cloudflare.py +7 -7
- webscout/Provider/OPENAI/FreeGemini.py +6 -5
- webscout/Provider/OPENAI/NEMOTRON.py +8 -20
- webscout/Provider/OPENAI/Qwen3.py +283 -0
- webscout/Provider/OPENAI/README.md +952 -1253
- webscout/Provider/OPENAI/TwoAI.py +357 -0
- webscout/Provider/OPENAI/__init__.py +5 -1
- webscout/Provider/OPENAI/ai4chat.py +40 -40
- webscout/Provider/OPENAI/api.py +808 -649
- webscout/Provider/OPENAI/c4ai.py +3 -3
- webscout/Provider/OPENAI/chatgpt.py +555 -555
- webscout/Provider/OPENAI/chatgptclone.py +493 -487
- webscout/Provider/OPENAI/chatsandbox.py +4 -3
- webscout/Provider/OPENAI/copilot.py +242 -0
- webscout/Provider/OPENAI/deepinfra.py +5 -2
- webscout/Provider/OPENAI/e2b.py +63 -5
- webscout/Provider/OPENAI/exaai.py +416 -410
- webscout/Provider/OPENAI/exachat.py +444 -443
- webscout/Provider/OPENAI/freeaichat.py +2 -2
- webscout/Provider/OPENAI/glider.py +5 -2
- webscout/Provider/OPENAI/groq.py +5 -2
- webscout/Provider/OPENAI/heckai.py +308 -307
- webscout/Provider/OPENAI/mcpcore.py +8 -2
- webscout/Provider/OPENAI/multichat.py +4 -4
- webscout/Provider/OPENAI/netwrck.py +6 -5
- webscout/Provider/OPENAI/oivscode.py +287 -0
- webscout/Provider/OPENAI/opkfc.py +496 -496
- webscout/Provider/OPENAI/pydantic_imports.py +172 -0
- webscout/Provider/OPENAI/scirachat.py +15 -9
- webscout/Provider/OPENAI/sonus.py +304 -303
- webscout/Provider/OPENAI/standardinput.py +433 -433
- webscout/Provider/OPENAI/textpollinations.py +4 -4
- webscout/Provider/OPENAI/toolbaz.py +413 -413
- webscout/Provider/OPENAI/typefully.py +3 -3
- webscout/Provider/OPENAI/typegpt.py +11 -5
- webscout/Provider/OPENAI/uncovrAI.py +463 -462
- webscout/Provider/OPENAI/utils.py +90 -79
- webscout/Provider/OPENAI/venice.py +431 -425
- webscout/Provider/OPENAI/wisecat.py +387 -381
- webscout/Provider/OPENAI/writecream.py +3 -3
- webscout/Provider/OPENAI/x0gpt.py +365 -378
- webscout/Provider/OPENAI/yep.py +39 -13
- webscout/Provider/TTI/README.md +55 -101
- webscout/Provider/TTI/__init__.py +4 -9
- webscout/Provider/TTI/aiarta.py +365 -0
- webscout/Provider/TTI/artbit.py +0 -0
- webscout/Provider/TTI/base.py +64 -0
- webscout/Provider/TTI/fastflux.py +200 -0
- webscout/Provider/TTI/magicstudio.py +201 -0
- webscout/Provider/TTI/piclumen.py +203 -0
- webscout/Provider/TTI/pixelmuse.py +225 -0
- webscout/Provider/TTI/pollinations.py +221 -0
- webscout/Provider/TTI/utils.py +11 -0
- webscout/Provider/TTS/__init__.py +2 -1
- webscout/Provider/TTS/base.py +159 -159
- webscout/Provider/TTS/openai_fm.py +129 -0
- webscout/Provider/TextPollinationsAI.py +308 -308
- webscout/Provider/TwoAI.py +239 -44
- webscout/Provider/UNFINISHED/Youchat.py +330 -330
- webscout/Provider/UNFINISHED/puterjs.py +635 -0
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
- webscout/Provider/Writecream.py +246 -246
- webscout/Provider/__init__.py +2 -0
- webscout/Provider/ai4chat.py +33 -8
- webscout/Provider/koala.py +169 -169
- webscout/Provider/oivscode.py +309 -0
- webscout/Provider/samurai.py +3 -2
- webscout/Provider/typegpt.py +3 -3
- webscout/Provider/uncovr.py +368 -368
- webscout/client.py +70 -0
- webscout/litprinter/__init__.py +58 -58
- webscout/optimizers.py +419 -419
- webscout/scout/README.md +3 -1
- webscout/scout/core/crawler.py +134 -64
- webscout/scout/core/scout.py +148 -109
- webscout/scout/element.py +106 -88
- webscout/swiftcli/Readme.md +323 -323
- webscout/swiftcli/plugins/manager.py +9 -2
- webscout/version.py +1 -1
- webscout/zeroart/__init__.py +134 -134
- webscout/zeroart/effects.py +100 -100
- webscout/zeroart/fonts.py +1238 -1238
- {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/METADATA +159 -35
- {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/RECORD +116 -161
- {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/WHEEL +1 -1
- {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/entry_points.txt +1 -0
- webscout/Litlogger/Readme.md +0 -175
- webscout/Litlogger/core/__init__.py +0 -6
- webscout/Litlogger/core/level.py +0 -23
- webscout/Litlogger/core/logger.py +0 -165
- webscout/Litlogger/handlers/__init__.py +0 -12
- webscout/Litlogger/handlers/console.py +0 -33
- webscout/Litlogger/handlers/file.py +0 -143
- webscout/Litlogger/handlers/network.py +0 -173
- webscout/Litlogger/styles/__init__.py +0 -7
- webscout/Litlogger/styles/colors.py +0 -249
- webscout/Litlogger/styles/formats.py +0 -458
- webscout/Litlogger/styles/text.py +0 -87
- webscout/Litlogger/utils/__init__.py +0 -6
- webscout/Litlogger/utils/detectors.py +0 -153
- webscout/Litlogger/utils/formatters.py +0 -200
- webscout/Provider/TTI/AiForce/README.md +0 -159
- webscout/Provider/TTI/AiForce/__init__.py +0 -22
- webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
- webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
- webscout/Provider/TTI/FreeAIPlayground/README.md +0 -99
- webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
- webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
- webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
- webscout/Provider/TTI/ImgSys/README.md +0 -174
- webscout/Provider/TTI/ImgSys/__init__.py +0 -23
- webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
- webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
- webscout/Provider/TTI/MagicStudio/README.md +0 -101
- webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
- webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
- webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
- webscout/Provider/TTI/Nexra/README.md +0 -155
- webscout/Provider/TTI/Nexra/__init__.py +0 -22
- webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
- webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
- webscout/Provider/TTI/PollinationsAI/README.md +0 -146
- webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
- webscout/Provider/TTI/aiarta/README.md +0 -134
- webscout/Provider/TTI/aiarta/__init__.py +0 -2
- webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
- webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
- webscout/Provider/TTI/artbit/README.md +0 -100
- webscout/Provider/TTI/artbit/__init__.py +0 -22
- webscout/Provider/TTI/artbit/async_artbit.py +0 -155
- webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
- webscout/Provider/TTI/fastflux/README.md +0 -129
- webscout/Provider/TTI/fastflux/__init__.py +0 -22
- webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
- webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
- webscout/Provider/TTI/huggingface/README.md +0 -114
- webscout/Provider/TTI/huggingface/__init__.py +0 -22
- webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
- webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
- webscout/Provider/TTI/piclumen/README.md +0 -161
- webscout/Provider/TTI/piclumen/__init__.py +0 -23
- webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
- webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
- webscout/Provider/TTI/pixelmuse/README.md +0 -79
- webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
- webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
- webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
- webscout/Provider/TTI/talkai/README.md +0 -139
- webscout/Provider/TTI/talkai/__init__.py +0 -4
- webscout/Provider/TTI/talkai/async_talkai.py +0 -229
- webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
- webscout/Provider/UNFINISHED/oivscode.py +0 -351
- {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/top_level.txt +0 -0
|
@@ -4,37 +4,11 @@ import re
|
|
|
4
4
|
import uuid
|
|
5
5
|
from typing import Dict, Optional, Generator, Union, Any
|
|
6
6
|
|
|
7
|
-
from webscout.AIbase import AISearch
|
|
7
|
+
from webscout.AIbase import AISearch, SearchResponse
|
|
8
8
|
from webscout import exceptions
|
|
9
9
|
from webscout.litagent import LitAgent
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class Response:
|
|
13
|
-
"""A wrapper class for Monica API responses.
|
|
14
|
-
|
|
15
|
-
This class automatically converts response objects to their text representation
|
|
16
|
-
when printed or converted to string.
|
|
17
|
-
|
|
18
|
-
Attributes:
|
|
19
|
-
text (str): The text content of the response
|
|
20
|
-
|
|
21
|
-
Example:
|
|
22
|
-
>>> response = Response("Hello, world!")
|
|
23
|
-
>>> print(response)
|
|
24
|
-
Hello, world!
|
|
25
|
-
>>> str(response)
|
|
26
|
-
'Hello, world!'
|
|
27
|
-
"""
|
|
28
|
-
def __init__(self, text: str):
|
|
29
|
-
self.text = text
|
|
30
|
-
|
|
31
|
-
def __str__(self):
|
|
32
|
-
return self.text
|
|
33
|
-
|
|
34
|
-
def __repr__(self):
|
|
35
|
-
return self.text
|
|
36
|
-
|
|
37
|
-
|
|
38
12
|
class Monica(AISearch):
|
|
39
13
|
"""A class to interact with the Monica AI search API.
|
|
40
14
|
|
|
@@ -121,7 +95,7 @@ class Monica(AISearch):
|
|
|
121
95
|
prompt: str,
|
|
122
96
|
stream: bool = False,
|
|
123
97
|
raw: bool = False,
|
|
124
|
-
) -> Union[
|
|
98
|
+
) -> Union[SearchResponse, Generator[Union[Dict[str, str], SearchResponse], None, None]]:
|
|
125
99
|
"""Search using the Monica API and get AI-generated responses.
|
|
126
100
|
|
|
127
101
|
This method sends a search query to Monica and returns the AI-generated response.
|
|
@@ -185,7 +159,7 @@ class Monica(AISearch):
|
|
|
185
159
|
if raw:
|
|
186
160
|
yield {"text": text_chunk}
|
|
187
161
|
else:
|
|
188
|
-
yield
|
|
162
|
+
yield SearchResponse(text_chunk)
|
|
189
163
|
|
|
190
164
|
# Check if stream is finished
|
|
191
165
|
if "finished" in data and data["finished"]:
|
|
@@ -210,7 +184,7 @@ class Monica(AISearch):
|
|
|
210
184
|
if not raw:
|
|
211
185
|
# Process the full response to clean up formatting
|
|
212
186
|
formatted_response = self.format_response(full_response)
|
|
213
|
-
self.last_response =
|
|
187
|
+
self.last_response = SearchResponse(formatted_response)
|
|
214
188
|
return self.last_response
|
|
215
189
|
|
|
216
190
|
return for_stream() if stream else for_non_stream()
|
|
@@ -5,37 +5,11 @@ import uuid
|
|
|
5
5
|
import time
|
|
6
6
|
from typing import Dict, Optional, Generator, Union, Any
|
|
7
7
|
|
|
8
|
-
from webscout.AIbase import AISearch
|
|
8
|
+
from webscout.AIbase import AISearch, SearchResponse
|
|
9
9
|
from webscout import exceptions
|
|
10
10
|
from webscout.litagent import LitAgent
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class Response:
|
|
14
|
-
"""A wrapper class for SCIRA API responses.
|
|
15
|
-
|
|
16
|
-
This class automatically converts response objects to their text representation
|
|
17
|
-
when printed or converted to string.
|
|
18
|
-
|
|
19
|
-
Attributes:
|
|
20
|
-
text (str): The text content of the response
|
|
21
|
-
|
|
22
|
-
Example:
|
|
23
|
-
>>> response = Response("Hello, world!")
|
|
24
|
-
>>> print(response)
|
|
25
|
-
Hello, world!
|
|
26
|
-
>>> str(response)
|
|
27
|
-
'Hello, world!'
|
|
28
|
-
"""
|
|
29
|
-
def __init__(self, text: str):
|
|
30
|
-
self.text = text
|
|
31
|
-
|
|
32
|
-
def __str__(self):
|
|
33
|
-
return self.text
|
|
34
|
-
|
|
35
|
-
def __repr__(self):
|
|
36
|
-
return self.text
|
|
37
|
-
|
|
38
|
-
|
|
39
13
|
class Scira(AISearch):
|
|
40
14
|
"""A class to interact with the SCIRA AI search API.
|
|
41
15
|
|
|
@@ -131,7 +105,7 @@ class Scira(AISearch):
|
|
|
131
105
|
prompt: str,
|
|
132
106
|
stream: bool = False,
|
|
133
107
|
raw: bool = False,
|
|
134
|
-
) -> Union[
|
|
108
|
+
) -> Union[SearchResponse, Generator[Union[Dict[str, str], SearchResponse], None, None]]:
|
|
135
109
|
"""Search using the SCIRA API and get AI-generated responses.
|
|
136
110
|
|
|
137
111
|
This method sends a search query to SCIRA and returns the AI-generated response.
|
|
@@ -224,7 +198,7 @@ class Scira(AISearch):
|
|
|
224
198
|
self,
|
|
225
199
|
response: requests.Response,
|
|
226
200
|
raw: bool
|
|
227
|
-
) -> Generator[Union[Dict[str, str],
|
|
201
|
+
) -> Generator[Union[Dict[str, str], SearchResponse], None, None]:
|
|
228
202
|
"""Handle streaming response from the API.
|
|
229
203
|
|
|
230
204
|
Args:
|
|
@@ -252,7 +226,7 @@ class Scira(AISearch):
|
|
|
252
226
|
if raw:
|
|
253
227
|
yield {"text": content}
|
|
254
228
|
else:
|
|
255
|
-
yield
|
|
229
|
+
yield SearchResponse(content)
|
|
256
230
|
except Exception:
|
|
257
231
|
# Skip lines that can't be processed
|
|
258
232
|
pass
|
|
@@ -261,7 +235,7 @@ class Scira(AISearch):
|
|
|
261
235
|
self,
|
|
262
236
|
response: requests.Response,
|
|
263
237
|
raw: bool
|
|
264
|
-
) -> Union[Dict[str, str],
|
|
238
|
+
) -> Union[Dict[str, str], SearchResponse]:
|
|
265
239
|
"""Handle non-streaming response from the API.
|
|
266
240
|
|
|
267
241
|
Args:
|
|
@@ -295,7 +269,7 @@ class Scira(AISearch):
|
|
|
295
269
|
if raw:
|
|
296
270
|
return {"text": full_text}
|
|
297
271
|
else:
|
|
298
|
-
return
|
|
272
|
+
return SearchResponse(full_text)
|
|
299
273
|
|
|
300
274
|
@staticmethod
|
|
301
275
|
def clean_content(text: str) -> str:
|
|
@@ -3,43 +3,17 @@ import json
|
|
|
3
3
|
import re
|
|
4
4
|
from typing import Dict, Optional, Generator, Union, Any
|
|
5
5
|
|
|
6
|
-
from webscout.AIbase import AISearch
|
|
6
|
+
from webscout.AIbase import AISearch, SearchResponse
|
|
7
7
|
from webscout import exceptions
|
|
8
8
|
from webscout.litagent import LitAgent
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class Response:
|
|
12
|
-
"""A wrapper class for webpilotai API responses.
|
|
13
|
-
|
|
14
|
-
This class automatically converts response objects to their text representation
|
|
15
|
-
when printed or converted to string.
|
|
16
|
-
|
|
17
|
-
Attributes:
|
|
18
|
-
text (str): The text content of the response
|
|
19
|
-
|
|
20
|
-
Example:
|
|
21
|
-
>>> response = Response("Hello, world!")
|
|
22
|
-
>>> print(response)
|
|
23
|
-
Hello, world!
|
|
24
|
-
>>> str(response)
|
|
25
|
-
'Hello, world!'
|
|
26
|
-
"""
|
|
27
|
-
def __init__(self, text: str):
|
|
28
|
-
self.text = text
|
|
29
|
-
|
|
30
|
-
def __str__(self):
|
|
31
|
-
return self.text
|
|
32
|
-
|
|
33
|
-
def __repr__(self):
|
|
34
|
-
return self.text
|
|
35
|
-
|
|
36
|
-
|
|
37
11
|
class webpilotai(AISearch):
|
|
38
12
|
"""A class to interact with the webpilotai (WebPilot) AI search API.
|
|
39
13
|
|
|
40
|
-
webpilotai provides a web-based comprehensive search
|
|
41
|
-
|
|
42
|
-
non-streaming
|
|
14
|
+
webpilotai provides a web-based comprehensive search SearchResponse interface that returns AI-generated
|
|
15
|
+
SearchResponses with source references and related questions. It supports both streaming and
|
|
16
|
+
non-streaming SearchResponses.
|
|
43
17
|
|
|
44
18
|
Basic Usage:
|
|
45
19
|
>>> from webscout import webpilotai
|
|
@@ -54,7 +28,7 @@ class webpilotai(AISearch):
|
|
|
54
28
|
... print(chunk, end="", flush=True)
|
|
55
29
|
Artificial Intelligence is...
|
|
56
30
|
|
|
57
|
-
>>> # Raw
|
|
31
|
+
>>> # Raw SearchResponse format
|
|
58
32
|
>>> for chunk in ai.search("Hello", stream=True, raw=True):
|
|
59
33
|
... print(chunk)
|
|
60
34
|
{'text': 'Hello'}
|
|
@@ -83,7 +57,7 @@ class webpilotai(AISearch):
|
|
|
83
57
|
self.session = requests.Session()
|
|
84
58
|
self.api_endpoint = "https://api.webpilotai.com/rupee/v1/search"
|
|
85
59
|
self.timeout = timeout
|
|
86
|
-
self.
|
|
60
|
+
self.last_SearchResponse = {}
|
|
87
61
|
|
|
88
62
|
# The 'Bearer null' is part of the API's expected headers
|
|
89
63
|
self.headers = {
|
|
@@ -103,24 +77,24 @@ class webpilotai(AISearch):
|
|
|
103
77
|
prompt: str,
|
|
104
78
|
stream: bool = False,
|
|
105
79
|
raw: bool = False,
|
|
106
|
-
) -> Union[
|
|
107
|
-
"""Search using the webpilotai API and get AI-generated
|
|
80
|
+
) -> Union[SearchResponse, Generator[Union[Dict[str, str], SearchResponse], None, None]]:
|
|
81
|
+
"""Search using the webpilotai API and get AI-generated SearchResponses.
|
|
108
82
|
|
|
109
|
-
This method sends a search query to webpilotai and returns the AI-generated
|
|
110
|
-
It supports both streaming and non-streaming modes, as well as raw
|
|
83
|
+
This method sends a search query to webpilotai and returns the AI-generated SearchResponse.
|
|
84
|
+
It supports both streaming and non-streaming modes, as well as raw SearchResponse format.
|
|
111
85
|
|
|
112
86
|
Args:
|
|
113
87
|
prompt (str): The search query or prompt to send to the API.
|
|
114
|
-
stream (bool, optional): If True, yields
|
|
115
|
-
If False, returns complete
|
|
116
|
-
raw (bool, optional): If True, returns raw
|
|
117
|
-
If False, returns
|
|
88
|
+
stream (bool, optional): If True, yields SearchResponse chunks as they arrive.
|
|
89
|
+
If False, returns complete SearchResponse. Defaults to False.
|
|
90
|
+
raw (bool, optional): If True, returns raw SearchResponse dictionaries with 'text' key.
|
|
91
|
+
If False, returns SearchResponse objects that convert to text automatically.
|
|
118
92
|
Defaults to False.
|
|
119
93
|
|
|
120
94
|
Returns:
|
|
121
|
-
Union[
|
|
122
|
-
- If stream=False: Returns complete
|
|
123
|
-
- If stream=True: Yields
|
|
95
|
+
Union[SearchResponse, Generator[Union[Dict[str, str], SearchResponse], None, None]]:
|
|
96
|
+
- If stream=False: Returns complete SearchResponse as SearchResponse object
|
|
97
|
+
- If stream=True: Yields SearchResponse chunks as either Dict or SearchResponse objects
|
|
124
98
|
|
|
125
99
|
Raises:
|
|
126
100
|
APIConnectionError: If the API request fails
|
|
@@ -132,12 +106,12 @@ class webpilotai(AISearch):
|
|
|
132
106
|
>>> print(response)
|
|
133
107
|
Python is a programming language...
|
|
134
108
|
|
|
135
|
-
Streaming
|
|
109
|
+
Streaming SearchResponse:
|
|
136
110
|
>>> for chunk in ai.search("Tell me about AI", stream=True):
|
|
137
111
|
... print(chunk, end="")
|
|
138
112
|
Artificial Intelligence...
|
|
139
113
|
|
|
140
|
-
Raw
|
|
114
|
+
Raw SearchResponse format:
|
|
141
115
|
>>> for chunk in ai.search("Hello", stream=True, raw=True):
|
|
142
116
|
... print(chunk)
|
|
143
117
|
{'text': 'Hello'}
|
|
@@ -149,7 +123,7 @@ class webpilotai(AISearch):
|
|
|
149
123
|
}
|
|
150
124
|
|
|
151
125
|
def for_stream():
|
|
152
|
-
|
|
126
|
+
full_SearchResponse_content = ""
|
|
153
127
|
current_event_name = None
|
|
154
128
|
current_data_buffer = []
|
|
155
129
|
|
|
@@ -175,17 +149,17 @@ class webpilotai(AISearch):
|
|
|
175
149
|
if current_event_name == "message":
|
|
176
150
|
try:
|
|
177
151
|
data_payload = json.loads(full_data)
|
|
178
|
-
# Check structure based on the API
|
|
152
|
+
# Check structure based on the API SearchResponse
|
|
179
153
|
if data_payload.get('type') == 'data':
|
|
180
154
|
content_chunk = data_payload.get('data', {}).get('content', "")
|
|
181
155
|
if content_chunk:
|
|
182
|
-
|
|
156
|
+
full_SearchResponse_content += content_chunk
|
|
183
157
|
|
|
184
158
|
# Yield the new content chunk
|
|
185
159
|
if raw:
|
|
186
160
|
yield {"text": content_chunk}
|
|
187
161
|
else:
|
|
188
|
-
yield
|
|
162
|
+
yield SearchResponse(content_chunk)
|
|
189
163
|
except json.JSONDecodeError:
|
|
190
164
|
pass
|
|
191
165
|
except Exception as e:
|
|
@@ -214,14 +188,14 @@ class webpilotai(AISearch):
|
|
|
214
188
|
data_payload = json.loads(full_data)
|
|
215
189
|
if data_payload.get('type') == 'data':
|
|
216
190
|
content_chunk = data_payload.get('data', {}).get('content', "")
|
|
217
|
-
if content_chunk and len(content_chunk) > len(
|
|
218
|
-
delta = content_chunk[len(
|
|
219
|
-
|
|
191
|
+
if content_chunk and len(content_chunk) > len(full_SearchResponse_content):
|
|
192
|
+
delta = content_chunk[len(full_SearchResponse_content):]
|
|
193
|
+
full_SearchResponse_content += delta
|
|
220
194
|
|
|
221
195
|
if raw:
|
|
222
196
|
yield {"text": delta}
|
|
223
197
|
else:
|
|
224
|
-
yield
|
|
198
|
+
yield SearchResponse(delta)
|
|
225
199
|
except (json.JSONDecodeError, Exception):
|
|
226
200
|
pass
|
|
227
201
|
|
|
@@ -231,27 +205,27 @@ class webpilotai(AISearch):
|
|
|
231
205
|
raise exceptions.APIConnectionError(f"Request failed: {e}")
|
|
232
206
|
|
|
233
207
|
def for_non_stream():
|
|
234
|
-
|
|
208
|
+
full_SearchResponse = ""
|
|
235
209
|
for chunk in for_stream():
|
|
236
210
|
if raw:
|
|
237
211
|
yield chunk
|
|
238
212
|
else:
|
|
239
|
-
|
|
213
|
+
full_SearchResponse += str(chunk)
|
|
240
214
|
|
|
241
215
|
if not raw:
|
|
242
|
-
# Format the
|
|
243
|
-
|
|
244
|
-
self.last_response =
|
|
245
|
-
return self.
|
|
216
|
+
# Format the SearchResponse for better readability
|
|
217
|
+
formatted_SearchResponse = self.format_SearchResponse(full_SearchResponse)
|
|
218
|
+
self.last_response = SearchResponse(formatted_SearchResponse)
|
|
219
|
+
return self.last_SearchResponse
|
|
246
220
|
|
|
247
221
|
return for_stream() if stream else for_non_stream()
|
|
248
222
|
|
|
249
223
|
@staticmethod
|
|
250
|
-
def
|
|
251
|
-
"""Format the
|
|
224
|
+
def format_SearchResponse(text: str) -> str:
|
|
225
|
+
"""Format the SearchResponse text for better readability.
|
|
252
226
|
|
|
253
227
|
Args:
|
|
254
|
-
text (str): The raw
|
|
228
|
+
text (str): The raw SearchResponse text
|
|
255
229
|
|
|
256
230
|
Returns:
|
|
257
231
|
str: Formatted text with improved structure
|
|
@@ -276,6 +250,6 @@ if __name__ == "__main__":
|
|
|
276
250
|
from rich import print
|
|
277
251
|
|
|
278
252
|
ai = webpilotai()
|
|
279
|
-
|
|
280
|
-
for chunk in
|
|
253
|
+
r = ai.search(input(">>> "), stream=True, raw=False)
|
|
254
|
+
for chunk in r:
|
|
281
255
|
print(chunk, end="", flush=True)
|
webscout/Provider/Blackboxai.py
CHANGED
|
@@ -94,8 +94,13 @@ class BLACKBOXAI(Provider):
|
|
|
94
94
|
default_model,
|
|
95
95
|
"o3-mini",
|
|
96
96
|
"gpt-4.1-nano",
|
|
97
|
+
"Claude Opus 4", # Added Claude Opus 4
|
|
98
|
+
"Claude Sonnet 4", # Added Claude Sonnet 4
|
|
97
99
|
"Claude-sonnet-3.7",
|
|
98
100
|
"Claude-sonnet-3.5",
|
|
101
|
+
"Grok 3", # Added Grok 3
|
|
102
|
+
"Gemini 2.5 Pro", # Added Gemini 2.5 Pro
|
|
103
|
+
"UI-TARS 72B", # Added UI-TARS 72B
|
|
99
104
|
"DeepSeek-R1",
|
|
100
105
|
"Mistral-Small-24B-Instruct-2501",
|
|
101
106
|
*openrouter_models,
|
|
@@ -109,10 +114,10 @@ class BLACKBOXAI(Provider):
|
|
|
109
114
|
]
|
|
110
115
|
|
|
111
116
|
# Models that support vision capabilities
|
|
112
|
-
vision_models = [default_vision_model, 'o3-mini', "Llama 3.2 11B Vision Instruct"] # Added Llama vision
|
|
117
|
+
vision_models = [default_vision_model, 'o3-mini', "Llama 3.2 11B Vision Instruct", "Gemini 2.5 Pro", "Claude Sonnet 4", "Claude Opus 4", "UI-TARS 72B"] # Added Llama vision, Gemini 2.5 Pro, Claude Sonnet 4, Claude Opus 4, and UI-TARS 72B
|
|
113
118
|
|
|
114
119
|
# Models that can be directly selected by users
|
|
115
|
-
userSelectedModel = ['o3-mini','Claude-sonnet-3.7', 'Claude-sonnet-3.5', 'DeepSeek-R1', 'Mistral-Small-24B-Instruct-2501'] + openrouter_models
|
|
120
|
+
userSelectedModel = ['o3-mini', 'Claude Opus 4', 'Claude Sonnet 4', 'Claude-sonnet-3.7', 'Claude-sonnet-3.5', 'Grok 3', 'Gemini 2.5 Pro', 'UI-TARS 72B', 'DeepSeek-R1', 'Mistral-Small-24B-Instruct-2501'] + openrouter_models
|
|
116
121
|
|
|
117
122
|
# Agent mode configurations
|
|
118
123
|
agentMode = {
|
|
@@ -161,8 +166,13 @@ class BLACKBOXAI(Provider):
|
|
|
161
166
|
'R1 Distill Qwen 14B': {'mode': True, 'id': "deepseek/deepseek-r1-distill-qwen-14b:free", 'name': "R1 Distill Qwen 14B"},
|
|
162
167
|
'R1 Distill Qwen 32B': {'mode': True, 'id': "deepseek/deepseek-r1-distill-qwen-32b:free", 'name': "R1 Distill Qwen 32B"},
|
|
163
168
|
# Default models from the new list
|
|
169
|
+
'Claude Opus 4': {'mode': True, 'id': "anthropic/claude-opus-4", 'name': "Claude Opus 4"},
|
|
170
|
+
'Claude Sonnet 4': {'mode': True, 'id': "anthropic/claude-sonnet-4", 'name': "Claude Sonnet 4"},
|
|
164
171
|
'Claude-sonnet-3.7': {'mode': True, 'id': "Claude-sonnet-3.7", 'name': "Claude-sonnet-3.7"},
|
|
165
172
|
'Claude-sonnet-3.5': {'mode': True, 'id': "Claude-sonnet-3.5", 'name': "Claude-sonnet-3.5"},
|
|
173
|
+
'Grok 3': {'mode': True, 'id': "x-ai/grok-3-beta", 'name': "Grok 3"},
|
|
174
|
+
'Gemini 2.5 Pro': {'mode': True, 'id': "google/gemini-2.5-pro-preview-03-25", 'name': "Gemini 2.5 Pro"},
|
|
175
|
+
'UI-TARS 72B': {'mode': True, 'id': "bytedance-research/ui-tars-72b:free", 'name': "UI-TARS 72B"},
|
|
166
176
|
'DeepSeek-R1': {'mode': True, 'id': "deepseek-reasoner", 'name': "DeepSeek-R1"}, # This is 'R1' in openrouter, but 'DeepSeek-R1' in base models
|
|
167
177
|
'Mistral-Small-24B-Instruct-2501': {'mode': True, 'id': "mistralai/Mistral-Small-24B-Instruct-2501", 'name': "Mistral-Small-24B-Instruct-2501"},
|
|
168
178
|
# Add default_model if it's not covered and has an agent mode
|
|
@@ -224,8 +234,18 @@ class BLACKBOXAI(Provider):
|
|
|
224
234
|
"gpt-4.1": default_model,
|
|
225
235
|
"gpt-4o": default_model, # Defaulting to GPT-4.1 as per previous logic if specific GPT-4o handling isn't defined elsewhere
|
|
226
236
|
"gpt-4o-mini": default_model, # Defaulting
|
|
237
|
+
"claude-opus-4": "Claude Opus 4",
|
|
238
|
+
"claude-4-opus": "Claude Opus 4",
|
|
239
|
+
"claude-sonnet-4": "Claude Sonnet 4",
|
|
240
|
+
"claude-4-sonnet": "Claude Sonnet 4",
|
|
227
241
|
"claude-3.7-sonnet": "Claude-sonnet-3.7",
|
|
228
242
|
"claude-3.5-sonnet": "Claude-sonnet-3.5",
|
|
243
|
+
"grok-3": "Grok 3",
|
|
244
|
+
"grok3": "Grok 3",
|
|
245
|
+
"gemini-2.5-pro": "Gemini 2.5 Pro",
|
|
246
|
+
"gemini-2.5": "Gemini 2.5 Pro",
|
|
247
|
+
"ui-tars-72b": "UI-TARS 72B",
|
|
248
|
+
"ui-tars": "UI-TARS 72B",
|
|
229
249
|
# "deepseek-r1": "DeepSeek-R1", # This is in base models, maps to R1 or DeepSeek R1 Zero in agentMode
|
|
230
250
|
#
|
|
231
251
|
"deepcoder-14b": "Deepcoder 14B Preview",
|
|
@@ -307,10 +327,10 @@ class BLACKBOXAI(Provider):
|
|
|
307
327
|
'__cf_bm': self.generate_id(32),
|
|
308
328
|
}
|
|
309
329
|
|
|
310
|
-
self.__available_optimizers =
|
|
330
|
+
self.__available_optimizers = [
|
|
311
331
|
method for method in dir(Optimizers)
|
|
312
332
|
if callable(getattr(Optimizers, method)) and not method.startswith("__")
|
|
313
|
-
|
|
333
|
+
]
|
|
314
334
|
|
|
315
335
|
Conversation.intro = (
|
|
316
336
|
AwesomePrompts().get_act(
|
|
@@ -347,22 +367,79 @@ class BLACKBOXAI(Provider):
|
|
|
347
367
|
raise ValueError(f"Unknown model: {model}. Available models: {', '.join(cls.AVAILABLE_MODELS)}")
|
|
348
368
|
|
|
349
369
|
@classmethod
|
|
350
|
-
def generate_session(cls, email: str, id_length: int = 21, days_ahead: int = 30) -> dict:
|
|
370
|
+
def generate_session(cls, email: str = None, id_length: int = 21, days_ahead: int = 30) -> dict:
|
|
351
371
|
"""
|
|
352
372
|
Generate a dynamic session with proper ID and expiry format using a specific email.
|
|
373
|
+
Uses a large hardcoded list of names and domains for diversity.
|
|
353
374
|
|
|
354
375
|
Args:
|
|
355
|
-
email: The email to use for this session
|
|
376
|
+
email: The email to use for this session (optional, will be generated if not provided)
|
|
356
377
|
id_length: Length of the numeric ID (default: 21)
|
|
357
378
|
days_ahead: Number of days ahead for expiry (default: 30)
|
|
358
379
|
|
|
359
380
|
Returns:
|
|
360
381
|
dict: A session dictionary with user information and expiry
|
|
361
382
|
"""
|
|
362
|
-
#
|
|
363
|
-
first_names = [
|
|
364
|
-
|
|
383
|
+
# Large list of first and last names
|
|
384
|
+
first_names = [
|
|
385
|
+
"Alex", "Jordan", "Taylor", "Morgan", "Casey", "Riley", "Avery", "Quinn", "Skyler", "Dakota",
|
|
386
|
+
"Jamie", "Cameron", "Drew", "Harper", "Peyton", "Reese", "Rowan", "Sawyer", "Shawn", "Terry",
|
|
387
|
+
"Robin", "Kendall", "Finley", "Blake", "Charlie", "Emerson", "Hayden", "Jesse", "Kai", "Lane",
|
|
388
|
+
"Logan", "Marley", "Micah", "Parker", "Phoenix", "Remy", "Rory", "Sage", "Shiloh", "Spencer",
|
|
389
|
+
"Sydney", "Tatum", "Teagan", "Tristan", "Val", "Winter", "Zion", "Bailey", "Brett", "Case",
|
|
390
|
+
"Corey", "Devon", "Eden", "Ellis", "Frankie", "Gray", "Indigo", "Jaden", "Jules", "Justice",
|
|
391
|
+
"Kieran", "Lake", "Lennon", "Linden", "Luca", "Milan", "Monroe", "Oakley", "Perry", "Quincy",
|
|
392
|
+
"Reagan", "Reed", "Rene", "River", "Robin", "Sasha", "Shane", "Shawn", "Sky", "Sterling",
|
|
393
|
+
"Storm", "Toby", "Vesper", "Wren", "Zane", "Zuri", "Ainsley", "Arden", "Aspen", "Blaine", "Briar",
|
|
394
|
+
"Campbell", "Cleo", "Cruz", "Dallas", "Darby", "Denver", "Echo", "Emery", "Everest", "Hollis",
|
|
395
|
+
"Indy", "Joss", "Karsen", "Kit", "Laken", "Linden", "Lyle", "Marlow", "Merritt", "Nico", "Onyx",
|
|
396
|
+
"Pax", "Peyton", "Quill", "Raleigh", "Reeve", "Ridley", "Rio", "Rylan", "Sailor", "Scout", "Shia",
|
|
397
|
+
"Sonny", "Story", "Tanner", "Tate", "Tegan", "Tiernan", "True", "Vaughn", "Wynn", "Zephyr",
|
|
398
|
+
# Add more names as needed for diversity
|
|
399
|
+
]
|
|
400
|
+
last_names = [
|
|
401
|
+
"Smith", "Johnson", "Williams", "Brown", "Jones", "Miller", "Davis", "Garcia", "Rodriguez", "Wilson",
|
|
402
|
+
"Martinez", "Anderson", "Taylor", "Thomas", "Hernandez", "Moore", "Martin", "Jackson", "Thompson", "White",
|
|
403
|
+
"Lopez", "Lee", "Gonzalez", "Harris", "Clark", "Lewis", "Robinson", "Walker", "Perez", "Hall",
|
|
404
|
+
"Young", "Allen", "Sanchez", "Wright", "King", "Scott", "Green", "Baker", "AdAMS", "Nelson",
|
|
405
|
+
"Carter", "Mitchell", "Perez", "Roberts", "Turner", "Phillips", "Campbell", "Parker", "Evans", "Edwards",
|
|
406
|
+
"Collins", "Stewart", "Sanchez", "Morris", "Rogers", "Reed", "Cook", "Morgan", "Bell", "Murphy",
|
|
407
|
+
"Bailey", "Rivera", "Cooper", "Richardson", "Cox", "Howard", "Ward", "Torres", "Peterson", "Gray",
|
|
408
|
+
"Ramirez", "James", "Watson", "Brooks", "Kelly", "Sanders", "Price", "Bennett", "Wood", "Barnes",
|
|
409
|
+
"Ross", "Henderson", "Coleman", "Jenkins", "Perry", "Powell", "Long", "Patterson", "Hughes", "Flores",
|
|
410
|
+
"Washington", "Butler", "Simmons", "Foster", "Gonzales", "Bryant", "Alexander", "Russell", "Griffin", "Diaz",
|
|
411
|
+
# Add more last names as needed
|
|
412
|
+
]
|
|
413
|
+
# Large list of fake domains
|
|
414
|
+
fake_domains = [
|
|
415
|
+
"example.com", "mailinator.com", "fakemail.com", "tempmail.net", "yopmail.com", "testmail.org", "maildrop.cc",
|
|
416
|
+
"inboxkitten.com", "guerrillamail.com", "sharklasers.com", "mailnesia.com", "dispostable.com", "getnada.com",
|
|
417
|
+
"10minutemail.com", "throwawaymail.com", "mailcatch.com", "spambog.com", "mintemail.com", "mail-temp.com",
|
|
418
|
+
"fakeinbox.com", "mytrashmail.com", "trashmail.com", "mailnull.com", "spamgourmet.com", "mailhazard.com",
|
|
419
|
+
"mailbox52.ga", "mailpoof.com", "mailtothis.com", "nowmymail.com", "mailimate.com", "mailboxy.fun",
|
|
420
|
+
"mailbolt.net", "mailblip.com", "mailbucket.org", "mailchimp.biz", "mailclark.ai", "maildog.info",
|
|
421
|
+
"maildrop.cc", "maildu.de", "maileater.com", "mailexpire.com", "mailforspam.com", "mailfreeonline.com",
|
|
422
|
+
"mailhub24.com", "mailimate.com", "mailin8r.com", "mailinator.net", "mailismagic.com", "mailjunk.cf",
|
|
423
|
+
"mailmate.com", "mailme24.com", "mailmoat.com", "mailnator.com", "mailnesia.com", "mailnull.com",
|
|
424
|
+
"mailpick.biz", "mailrock.biz", "mailsac.com", "mailseal.de", "mailtemp.net", "mailtothis.com",
|
|
425
|
+
"mailtrash.net", "mailtv.net", "mailup.net", "mailwire.net", "mailzilla.com", "meltmail.com",
|
|
426
|
+
"moakt.com", "my10minutemail.com", "mytemp.email", "neomailbox.com", "nospamfor.us", "objectmail.com",
|
|
427
|
+
"oneoffemail.com", "owlpic.com", "pookmail.com", "proxymail.eu", "rcpt.at", "sharklasers.com",
|
|
428
|
+
"smellfear.com", "sogetthis.com", "spam4.me", "spamavert.com", "spambob.com", "spambog.com",
|
|
429
|
+
"spambox.us", "spamcannon.com", "spamday.com", "spamex.com", "spamfree24.com", "spamgourmet.com",
|
|
430
|
+
"spamhole.com", "spaminator.de", "spamkill.info", "spaml.com", "spammotel.com", "spamobox.com",
|
|
431
|
+
"spamspot.com", "superrito.com", "teleworm.us", "temp-mail.org", "temp-mail.ru", "tempail.com",
|
|
432
|
+
"tempe-mail.com", "tempemail.co.za", "tempinbox.com", "tempmail.eu", "tempmail.net", "tempmail.us",
|
|
433
|
+
"tempomail.fr", "temporaryemail.net", "thankyou2010.com", "thisisnotmyrealemail.com", "throwam.com",
|
|
434
|
+
"throwawayemailaddress.com", "trash-mail.com", "trash2009.com", "trashdevil.com", "trashemail.de",
|
|
435
|
+
"trashmail.at", "trashmail.com", "trashmail.me", "trashmail.net", "trashymail.com", "trbvm.com",
|
|
436
|
+
"yepmail.net", "yopmail.com", "zoemail.net"
|
|
437
|
+
# Add more as needed
|
|
438
|
+
]
|
|
365
439
|
name = f"{random.choice(first_names)} {random.choice(last_names)}"
|
|
440
|
+
if not email:
|
|
441
|
+
domain = random.choice(fake_domains)
|
|
442
|
+
email = f"{name.lower().replace(' ','.')}{random.randint(1,9999)}@{domain}"
|
|
366
443
|
|
|
367
444
|
# Generate numeric ID - using Google-like ID format
|
|
368
445
|
numeric_id = ''.join(random.choice('0123456789') for _ in range(id_length))
|
|
@@ -433,7 +510,34 @@ class BLACKBOXAI(Provider):
|
|
|
433
510
|
# Generate a random email for the session
|
|
434
511
|
chars = string.ascii_lowercase + string.digits
|
|
435
512
|
random_team = ''.join(random.choice(chars) for _ in range(8))
|
|
436
|
-
|
|
513
|
+
# Use a random domain from the fake_domains set for the request email
|
|
514
|
+
fake_domains = [
|
|
515
|
+
"example.com", "mailinator.com", "fakemail.com", "tempmail.net", "yopmail.com", "testmail.org", "maildrop.cc",
|
|
516
|
+
"inboxkitten.com", "guerrillamail.com", "sharklasers.com", "mailnesia.com", "dispostable.com", "getnada.com",
|
|
517
|
+
"10minutemail.com", "throwawaymail.com", "mailcatch.com", "spambog.com", "mintemail.com", "mail-temp.com",
|
|
518
|
+
"fakeinbox.com", "mytrashmail.com", "trashmail.com", "mailnull.com", "spamgourmet.com", "mailhazard.com",
|
|
519
|
+
"mailbox52.ga", "mailpoof.com", "mailtothis.com", "nowmymail.com", "mailimate.com", "mailboxy.fun",
|
|
520
|
+
"mailbolt.net", "mailblip.com", "mailbucket.org", "mailchimp.biz", "mailclark.ai", "maildog.info",
|
|
521
|
+
"maildrop.cc", "maildu.de", "maileater.com", "mailexpire.com", "mailforspam.com", "mailfreeonline.com",
|
|
522
|
+
"mailhub24.com", "mailimate.com", "mailin8r.com", "mailinator.net", "mailismagic.com", "mailjunk.cf",
|
|
523
|
+
"mailmate.com", "mailme24.com", "mailmoat.com", "mailnator.com", "mailnesia.com", "mailnull.com",
|
|
524
|
+
"mailpick.biz", "mailrock.biz", "mailsac.com", "mailseal.de", "mailtemp.net", "mailtothis.com",
|
|
525
|
+
"mailtrash.net", "mailtv.net", "mailup.net", "mailwire.net", "mailzilla.com", "meltmail.com",
|
|
526
|
+
"moakt.com", "my10minutemail.com", "mytemp.email", "neomailbox.com", "nospamfor.us", "objectmail.com",
|
|
527
|
+
"oneoffemail.com", "owlpic.com", "pookmail.com", "proxymail.eu", "rcpt.at", "sharklasers.com",
|
|
528
|
+
"smellfear.com", "sogetthis.com", "spam4.me", "spamavert.com", "spambob.com", "spambog.com",
|
|
529
|
+
"spambox.us", "spamcannon.com", "spamday.com", "spamex.com", "spamfree24.com", "spamgourmet.com",
|
|
530
|
+
"spamhole.com", "spaminator.de", "spamkill.info", "spaml.com", "spammotel.com", "spamobox.com",
|
|
531
|
+
"spamspot.com", "superrito.com", "teleworm.us", "temp-mail.org", "temp-mail.ru", "tempail.com",
|
|
532
|
+
"tempe-mail.com", "tempemail.co.za", "tempinbox.com", "tempmail.eu", "tempmail.net", "tempmail.us",
|
|
533
|
+
"tempomail.fr", "temporaryemail.net", "thankyou2010.com", "thisisnotmyrealemail.com", "throwam.com",
|
|
534
|
+
"throwawayemailaddress.com", "trash-mail.com", "trash2009.com", "trashdevil.com", "trashemail.de",
|
|
535
|
+
"trashmail.at", "trashmail.com", "trashmail.me", "trashmail.net", "trashymail.com", "trbvm.com",
|
|
536
|
+
"yepmail.net", "yopmail.com", "zoemail.net"
|
|
537
|
+
# Add more as needed
|
|
538
|
+
]
|
|
539
|
+
domain = random.choice(fake_domains)
|
|
540
|
+
request_email = f"{random_team}@{domain}"
|
|
437
541
|
|
|
438
542
|
# Generate a session with the email
|
|
439
543
|
session_data = self.generate_session(request_email)
|
|
@@ -538,15 +642,24 @@ class BLACKBOXAI(Provider):
|
|
|
538
642
|
raise exceptions.FailedToGenerateResponseError(error_msg)
|
|
539
643
|
|
|
540
644
|
if stream:
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
645
|
+
buffer = ""
|
|
646
|
+
chunk_size = 32
|
|
647
|
+
for chunk in response.iter_content(chunk_size=chunk_size):
|
|
648
|
+
if not chunk:
|
|
649
|
+
continue
|
|
650
|
+
text = chunk.decode(errors="ignore")
|
|
651
|
+
buffer += text
|
|
652
|
+
while len(buffer) >= chunk_size:
|
|
653
|
+
out = buffer[:chunk_size]
|
|
654
|
+
buffer = buffer[chunk_size:]
|
|
655
|
+
if out.strip():
|
|
656
|
+
yield out
|
|
657
|
+
if buffer.strip():
|
|
658
|
+
yield buffer
|
|
546
659
|
else:
|
|
547
660
|
response_text = response.text
|
|
548
661
|
if "You have reached your request limit for the hour" in response_text:
|
|
549
|
-
raise exceptions.
|
|
662
|
+
raise exceptions.RatelimitE("Rate limit exceeded")
|
|
550
663
|
yield response_text
|
|
551
664
|
|
|
552
665
|
except requests.exceptions.RequestException as e:
|
|
@@ -651,23 +764,28 @@ class BLACKBOXAI(Provider):
|
|
|
651
764
|
return response["text"].replace('\\n', '\n').replace('\\n\\n', '\n\n')
|
|
652
765
|
|
|
653
766
|
if __name__ == "__main__":
|
|
654
|
-
print("-" * 80)
|
|
655
|
-
print(f"{'Model':<50} {'Status':<10} {'Response'}")
|
|
656
|
-
print("-" * 80)
|
|
657
|
-
|
|
658
|
-
for model in BLACKBOXAI.AVAILABLE_MODELS:
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
767
|
+
# print("-" * 80)
|
|
768
|
+
# print(f"{'Model':<50} {'Status':<10} {'Response'}")
|
|
769
|
+
# print("-" * 80)
|
|
770
|
+
|
|
771
|
+
# for model in BLACKBOXAI.AVAILABLE_MODELS:
|
|
772
|
+
# try:
|
|
773
|
+
# test_ai = BLACKBOXAI(model=model, timeout=60)
|
|
774
|
+
# response = test_ai.chat("Say 'Hello' in one word")
|
|
775
|
+
# response_text = response
|
|
663
776
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
777
|
+
# if response_text and len(response_text.strip()) > 0:
|
|
778
|
+
# status = "✓"
|
|
779
|
+
# # Truncate response if too long
|
|
780
|
+
# display_text = response_text.strip()[:50] + "..." if len(response_text.strip()) > 50 else response_text.strip()
|
|
781
|
+
# else:
|
|
782
|
+
# status = "✗"
|
|
783
|
+
# display_text = "Empty or invalid response"
|
|
784
|
+
# print(f"{model:<50} {status:<10} {display_text}")
|
|
785
|
+
# except Exception as e:
|
|
786
|
+
# print(f"{model:<50} {'✗':<10} {str(e)}")
|
|
787
|
+
|
|
788
|
+
ai = BLACKBOXAI(model="gpt-4.1", timeout=60)
|
|
789
|
+
response = ai.chat("tell me about humans", stream=True)
|
|
790
|
+
for line in response:
|
|
791
|
+
print(line, end="", flush=True)
|