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.
Files changed (184) hide show
  1. webscout/AIauto.py +32 -14
  2. webscout/AIbase.py +96 -37
  3. webscout/AIutel.py +491 -87
  4. webscout/Bard.py +441 -323
  5. webscout/Extra/GitToolkit/__init__.py +10 -10
  6. webscout/Extra/YTToolkit/ytapi/video.py +232 -232
  7. webscout/Litlogger/README.md +10 -0
  8. webscout/Litlogger/__init__.py +7 -59
  9. webscout/Litlogger/formats.py +4 -0
  10. webscout/Litlogger/handlers.py +103 -0
  11. webscout/Litlogger/levels.py +13 -0
  12. webscout/Litlogger/logger.py +92 -0
  13. webscout/Provider/AISEARCH/Perplexity.py +332 -358
  14. webscout/Provider/AISEARCH/felo_search.py +9 -35
  15. webscout/Provider/AISEARCH/genspark_search.py +30 -56
  16. webscout/Provider/AISEARCH/hika_search.py +4 -16
  17. webscout/Provider/AISEARCH/iask_search.py +410 -436
  18. webscout/Provider/AISEARCH/monica_search.py +4 -30
  19. webscout/Provider/AISEARCH/scira_search.py +6 -32
  20. webscout/Provider/AISEARCH/webpilotai_search.py +38 -64
  21. webscout/Provider/Blackboxai.py +153 -35
  22. webscout/Provider/Deepinfra.py +339 -339
  23. webscout/Provider/ExaChat.py +358 -358
  24. webscout/Provider/Gemini.py +169 -169
  25. webscout/Provider/GithubChat.py +1 -2
  26. webscout/Provider/Glider.py +3 -3
  27. webscout/Provider/HeckAI.py +171 -81
  28. webscout/Provider/OPENAI/BLACKBOXAI.py +766 -735
  29. webscout/Provider/OPENAI/Cloudflare.py +7 -7
  30. webscout/Provider/OPENAI/FreeGemini.py +6 -5
  31. webscout/Provider/OPENAI/NEMOTRON.py +8 -20
  32. webscout/Provider/OPENAI/Qwen3.py +283 -0
  33. webscout/Provider/OPENAI/README.md +952 -1253
  34. webscout/Provider/OPENAI/TwoAI.py +357 -0
  35. webscout/Provider/OPENAI/__init__.py +5 -1
  36. webscout/Provider/OPENAI/ai4chat.py +40 -40
  37. webscout/Provider/OPENAI/api.py +808 -649
  38. webscout/Provider/OPENAI/c4ai.py +3 -3
  39. webscout/Provider/OPENAI/chatgpt.py +555 -555
  40. webscout/Provider/OPENAI/chatgptclone.py +493 -487
  41. webscout/Provider/OPENAI/chatsandbox.py +4 -3
  42. webscout/Provider/OPENAI/copilot.py +242 -0
  43. webscout/Provider/OPENAI/deepinfra.py +5 -2
  44. webscout/Provider/OPENAI/e2b.py +63 -5
  45. webscout/Provider/OPENAI/exaai.py +416 -410
  46. webscout/Provider/OPENAI/exachat.py +444 -443
  47. webscout/Provider/OPENAI/freeaichat.py +2 -2
  48. webscout/Provider/OPENAI/glider.py +5 -2
  49. webscout/Provider/OPENAI/groq.py +5 -2
  50. webscout/Provider/OPENAI/heckai.py +308 -307
  51. webscout/Provider/OPENAI/mcpcore.py +8 -2
  52. webscout/Provider/OPENAI/multichat.py +4 -4
  53. webscout/Provider/OPENAI/netwrck.py +6 -5
  54. webscout/Provider/OPENAI/oivscode.py +287 -0
  55. webscout/Provider/OPENAI/opkfc.py +496 -496
  56. webscout/Provider/OPENAI/pydantic_imports.py +172 -0
  57. webscout/Provider/OPENAI/scirachat.py +15 -9
  58. webscout/Provider/OPENAI/sonus.py +304 -303
  59. webscout/Provider/OPENAI/standardinput.py +433 -433
  60. webscout/Provider/OPENAI/textpollinations.py +4 -4
  61. webscout/Provider/OPENAI/toolbaz.py +413 -413
  62. webscout/Provider/OPENAI/typefully.py +3 -3
  63. webscout/Provider/OPENAI/typegpt.py +11 -5
  64. webscout/Provider/OPENAI/uncovrAI.py +463 -462
  65. webscout/Provider/OPENAI/utils.py +90 -79
  66. webscout/Provider/OPENAI/venice.py +431 -425
  67. webscout/Provider/OPENAI/wisecat.py +387 -381
  68. webscout/Provider/OPENAI/writecream.py +3 -3
  69. webscout/Provider/OPENAI/x0gpt.py +365 -378
  70. webscout/Provider/OPENAI/yep.py +39 -13
  71. webscout/Provider/TTI/README.md +55 -101
  72. webscout/Provider/TTI/__init__.py +4 -9
  73. webscout/Provider/TTI/aiarta.py +365 -0
  74. webscout/Provider/TTI/artbit.py +0 -0
  75. webscout/Provider/TTI/base.py +64 -0
  76. webscout/Provider/TTI/fastflux.py +200 -0
  77. webscout/Provider/TTI/magicstudio.py +201 -0
  78. webscout/Provider/TTI/piclumen.py +203 -0
  79. webscout/Provider/TTI/pixelmuse.py +225 -0
  80. webscout/Provider/TTI/pollinations.py +221 -0
  81. webscout/Provider/TTI/utils.py +11 -0
  82. webscout/Provider/TTS/__init__.py +2 -1
  83. webscout/Provider/TTS/base.py +159 -159
  84. webscout/Provider/TTS/openai_fm.py +129 -0
  85. webscout/Provider/TextPollinationsAI.py +308 -308
  86. webscout/Provider/TwoAI.py +239 -44
  87. webscout/Provider/UNFINISHED/Youchat.py +330 -330
  88. webscout/Provider/UNFINISHED/puterjs.py +635 -0
  89. webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
  90. webscout/Provider/Writecream.py +246 -246
  91. webscout/Provider/__init__.py +2 -0
  92. webscout/Provider/ai4chat.py +33 -8
  93. webscout/Provider/koala.py +169 -169
  94. webscout/Provider/oivscode.py +309 -0
  95. webscout/Provider/samurai.py +3 -2
  96. webscout/Provider/typegpt.py +3 -3
  97. webscout/Provider/uncovr.py +368 -368
  98. webscout/client.py +70 -0
  99. webscout/litprinter/__init__.py +58 -58
  100. webscout/optimizers.py +419 -419
  101. webscout/scout/README.md +3 -1
  102. webscout/scout/core/crawler.py +134 -64
  103. webscout/scout/core/scout.py +148 -109
  104. webscout/scout/element.py +106 -88
  105. webscout/swiftcli/Readme.md +323 -323
  106. webscout/swiftcli/plugins/manager.py +9 -2
  107. webscout/version.py +1 -1
  108. webscout/zeroart/__init__.py +134 -134
  109. webscout/zeroart/effects.py +100 -100
  110. webscout/zeroart/fonts.py +1238 -1238
  111. {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/METADATA +159 -35
  112. {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/RECORD +116 -161
  113. {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/WHEEL +1 -1
  114. {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/entry_points.txt +1 -0
  115. webscout/Litlogger/Readme.md +0 -175
  116. webscout/Litlogger/core/__init__.py +0 -6
  117. webscout/Litlogger/core/level.py +0 -23
  118. webscout/Litlogger/core/logger.py +0 -165
  119. webscout/Litlogger/handlers/__init__.py +0 -12
  120. webscout/Litlogger/handlers/console.py +0 -33
  121. webscout/Litlogger/handlers/file.py +0 -143
  122. webscout/Litlogger/handlers/network.py +0 -173
  123. webscout/Litlogger/styles/__init__.py +0 -7
  124. webscout/Litlogger/styles/colors.py +0 -249
  125. webscout/Litlogger/styles/formats.py +0 -458
  126. webscout/Litlogger/styles/text.py +0 -87
  127. webscout/Litlogger/utils/__init__.py +0 -6
  128. webscout/Litlogger/utils/detectors.py +0 -153
  129. webscout/Litlogger/utils/formatters.py +0 -200
  130. webscout/Provider/TTI/AiForce/README.md +0 -159
  131. webscout/Provider/TTI/AiForce/__init__.py +0 -22
  132. webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
  133. webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
  134. webscout/Provider/TTI/FreeAIPlayground/README.md +0 -99
  135. webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
  136. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
  137. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
  138. webscout/Provider/TTI/ImgSys/README.md +0 -174
  139. webscout/Provider/TTI/ImgSys/__init__.py +0 -23
  140. webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
  141. webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
  142. webscout/Provider/TTI/MagicStudio/README.md +0 -101
  143. webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
  144. webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
  145. webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
  146. webscout/Provider/TTI/Nexra/README.md +0 -155
  147. webscout/Provider/TTI/Nexra/__init__.py +0 -22
  148. webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
  149. webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
  150. webscout/Provider/TTI/PollinationsAI/README.md +0 -146
  151. webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
  152. webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
  153. webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
  154. webscout/Provider/TTI/aiarta/README.md +0 -134
  155. webscout/Provider/TTI/aiarta/__init__.py +0 -2
  156. webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
  157. webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
  158. webscout/Provider/TTI/artbit/README.md +0 -100
  159. webscout/Provider/TTI/artbit/__init__.py +0 -22
  160. webscout/Provider/TTI/artbit/async_artbit.py +0 -155
  161. webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
  162. webscout/Provider/TTI/fastflux/README.md +0 -129
  163. webscout/Provider/TTI/fastflux/__init__.py +0 -22
  164. webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
  165. webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
  166. webscout/Provider/TTI/huggingface/README.md +0 -114
  167. webscout/Provider/TTI/huggingface/__init__.py +0 -22
  168. webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
  169. webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
  170. webscout/Provider/TTI/piclumen/README.md +0 -161
  171. webscout/Provider/TTI/piclumen/__init__.py +0 -23
  172. webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
  173. webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
  174. webscout/Provider/TTI/pixelmuse/README.md +0 -79
  175. webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
  176. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
  177. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
  178. webscout/Provider/TTI/talkai/README.md +0 -139
  179. webscout/Provider/TTI/talkai/__init__.py +0 -4
  180. webscout/Provider/TTI/talkai/async_talkai.py +0 -229
  181. webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
  182. webscout/Provider/UNFINISHED/oivscode.py +0 -351
  183. {webscout-8.2.8.dist-info → webscout-8.2.9.dist-info}/licenses/LICENSE.md +0 -0
  184. {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[Response, Generator[Union[Dict[str, str], Response], None, None]]:
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 Response(text_chunk)
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 = Response(formatted_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[Response, Generator[Union[Dict[str, str], Response], None, None]]:
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], Response], None, None]:
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 Response(content)
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], Response]:
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 Response(full_text)
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 response interface that returns AI-generated
41
- responses with source references and related questions. It supports both streaming and
42
- non-streaming responses.
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 response format
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.last_response = {}
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[Response, Generator[Union[Dict[str, str], Response], None, None]]:
107
- """Search using the webpilotai API and get AI-generated responses.
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 response.
110
- It supports both streaming and non-streaming modes, as well as raw response format.
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 response chunks as they arrive.
115
- If False, returns complete response. Defaults to False.
116
- raw (bool, optional): If True, returns raw response dictionaries with 'text' key.
117
- If False, returns Response objects that convert to text automatically.
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[Response, Generator[Union[Dict[str, str], Response], None, None]]:
122
- - If stream=False: Returns complete response as Response object
123
- - If stream=True: Yields response chunks as either Dict or Response objects
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 response:
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 response format:
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
- full_response_content = ""
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 response
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
- full_response_content += content_chunk
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 Response(content_chunk)
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(full_response_content):
218
- delta = content_chunk[len(full_response_content):]
219
- full_response_content += delta
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 Response(delta)
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
- full_response = ""
208
+ full_SearchResponse = ""
235
209
  for chunk in for_stream():
236
210
  if raw:
237
211
  yield chunk
238
212
  else:
239
- full_response += str(chunk)
213
+ full_SearchResponse += str(chunk)
240
214
 
241
215
  if not raw:
242
- # Format the response for better readability
243
- formatted_response = self.format_response(full_response)
244
- self.last_response = Response(formatted_response)
245
- return self.last_response
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 format_response(text: str) -> str:
251
- """Format the response text for better readability.
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 response text
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
- response = ai.search(input(">>> "), stream=True, raw=False)
280
- for chunk in response:
253
+ r = ai.search(input(">>> "), stream=True, raw=False)
254
+ for chunk in r:
281
255
  print(chunk, end="", flush=True)
@@ -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
- # Generate a random name
363
- first_names = ["Alex", "Jordan", "Taylor", "Morgan", "Casey", "Riley", "Avery", "Quinn", "Skyler", "Dakota"]
364
- last_names = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Miller", "Davis", "Garcia", "Rodriguez", "Wilson"]
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
- request_email = f"{random_team}@blackbox.ai"
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
- for line in response.iter_lines(decode_unicode=True):
542
- if line:
543
- if "You have reached your request limit for the hour" in line:
544
- raise exceptions.RateLimitError("Rate limit exceeded")
545
- yield line
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.RateLimitError("Rate limit exceeded")
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
- try:
660
- test_ai = BLACKBOXAI(model=model, timeout=60)
661
- response = test_ai.chat("Say 'Hello' in one word")
662
- response_text = response
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
- if response_text and len(response_text.strip()) > 0:
665
- status = "✓"
666
- # Truncate response if too long
667
- display_text = response_text.strip()[:50] + "..." if len(response_text.strip()) > 50 else response_text.strip()
668
- else:
669
- status = "✗"
670
- display_text = "Empty or invalid response"
671
- print(f"{model:<50} {status:<10} {display_text}")
672
- except Exception as e:
673
- print(f"{model:<50} {'✗':<10} {str(e)}")
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)