webscout 7.0__py3-none-any.whl → 7.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 +191 -191
- webscout/AIbase.py +122 -122
- webscout/AIutel.py +440 -440
- webscout/Bard.py +343 -161
- webscout/DWEBS.py +489 -492
- webscout/Extra/YTToolkit/YTdownloader.py +995 -995
- webscout/Extra/YTToolkit/__init__.py +2 -2
- webscout/Extra/YTToolkit/transcriber.py +476 -479
- webscout/Extra/YTToolkit/ytapi/channel.py +307 -307
- webscout/Extra/YTToolkit/ytapi/playlist.py +58 -58
- webscout/Extra/YTToolkit/ytapi/pool.py +7 -7
- webscout/Extra/YTToolkit/ytapi/utils.py +62 -62
- webscout/Extra/YTToolkit/ytapi/video.py +103 -103
- webscout/Extra/autocoder/__init__.py +9 -9
- webscout/Extra/autocoder/autocoder_utiles.py +199 -199
- webscout/Extra/autocoder/rawdog.py +5 -7
- webscout/Extra/autollama.py +230 -230
- webscout/Extra/gguf.py +3 -3
- webscout/Extra/weather.py +171 -171
- webscout/LLM.py +442 -442
- webscout/Litlogger/__init__.py +67 -681
- webscout/Litlogger/core/__init__.py +6 -0
- webscout/Litlogger/core/level.py +20 -0
- webscout/Litlogger/core/logger.py +123 -0
- webscout/Litlogger/handlers/__init__.py +12 -0
- webscout/Litlogger/handlers/console.py +50 -0
- webscout/Litlogger/handlers/file.py +143 -0
- webscout/Litlogger/handlers/network.py +174 -0
- webscout/Litlogger/styles/__init__.py +7 -0
- webscout/Litlogger/styles/colors.py +231 -0
- webscout/Litlogger/styles/formats.py +377 -0
- webscout/Litlogger/styles/text.py +87 -0
- webscout/Litlogger/utils/__init__.py +6 -0
- webscout/Litlogger/utils/detectors.py +154 -0
- webscout/Litlogger/utils/formatters.py +200 -0
- webscout/Provider/AISEARCH/DeepFind.py +250 -250
- webscout/Provider/Blackboxai.py +136 -137
- webscout/Provider/ChatGPTGratis.py +226 -0
- webscout/Provider/Cloudflare.py +91 -78
- webscout/Provider/DeepSeek.py +218 -0
- webscout/Provider/Deepinfra.py +59 -35
- webscout/Provider/Free2GPT.py +131 -124
- webscout/Provider/Gemini.py +100 -115
- webscout/Provider/Glider.py +74 -59
- webscout/Provider/Groq.py +30 -18
- webscout/Provider/Jadve.py +108 -77
- webscout/Provider/Llama3.py +117 -94
- webscout/Provider/Marcus.py +191 -137
- webscout/Provider/Netwrck.py +62 -50
- webscout/Provider/PI.py +79 -124
- webscout/Provider/PizzaGPT.py +129 -83
- webscout/Provider/QwenLM.py +311 -0
- webscout/Provider/TTI/AiForce/__init__.py +22 -22
- webscout/Provider/TTI/AiForce/async_aiforce.py +257 -257
- webscout/Provider/TTI/AiForce/sync_aiforce.py +242 -242
- webscout/Provider/TTI/Nexra/__init__.py +22 -22
- webscout/Provider/TTI/Nexra/async_nexra.py +286 -286
- webscout/Provider/TTI/Nexra/sync_nexra.py +258 -258
- webscout/Provider/TTI/PollinationsAI/__init__.py +23 -23
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +330 -330
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +285 -285
- webscout/Provider/TTI/artbit/__init__.py +22 -22
- webscout/Provider/TTI/artbit/async_artbit.py +184 -184
- webscout/Provider/TTI/artbit/sync_artbit.py +176 -176
- webscout/Provider/TTI/blackbox/__init__.py +4 -4
- webscout/Provider/TTI/blackbox/async_blackbox.py +212 -212
- webscout/Provider/TTI/blackbox/sync_blackbox.py +199 -199
- webscout/Provider/TTI/deepinfra/__init__.py +4 -4
- webscout/Provider/TTI/deepinfra/async_deepinfra.py +227 -227
- webscout/Provider/TTI/deepinfra/sync_deepinfra.py +199 -199
- webscout/Provider/TTI/huggingface/__init__.py +22 -22
- webscout/Provider/TTI/huggingface/async_huggingface.py +199 -199
- webscout/Provider/TTI/huggingface/sync_huggingface.py +195 -195
- webscout/Provider/TTI/imgninza/__init__.py +4 -4
- webscout/Provider/TTI/imgninza/async_ninza.py +214 -214
- webscout/Provider/TTI/imgninza/sync_ninza.py +209 -209
- webscout/Provider/TTI/talkai/__init__.py +4 -4
- webscout/Provider/TTI/talkai/async_talkai.py +229 -229
- webscout/Provider/TTI/talkai/sync_talkai.py +207 -207
- webscout/Provider/TTS/deepgram.py +182 -182
- webscout/Provider/TTS/elevenlabs.py +136 -136
- webscout/Provider/TTS/gesserit.py +150 -150
- webscout/Provider/TTS/murfai.py +138 -138
- webscout/Provider/TTS/parler.py +133 -134
- webscout/Provider/TTS/streamElements.py +360 -360
- webscout/Provider/TTS/utils.py +280 -280
- webscout/Provider/TTS/voicepod.py +116 -116
- webscout/Provider/TextPollinationsAI.py +74 -47
- webscout/Provider/WiseCat.py +193 -0
- webscout/Provider/__init__.py +144 -136
- webscout/Provider/cerebras.py +242 -227
- webscout/Provider/chatglm.py +204 -204
- webscout/Provider/dgaf.py +67 -39
- webscout/Provider/gaurish.py +105 -66
- webscout/Provider/geminiapi.py +208 -208
- webscout/Provider/granite.py +223 -0
- webscout/Provider/hermes.py +218 -218
- webscout/Provider/llama3mitril.py +179 -179
- webscout/Provider/llamatutor.py +72 -62
- webscout/Provider/llmchat.py +60 -35
- webscout/Provider/meta.py +794 -794
- webscout/Provider/multichat.py +331 -230
- webscout/Provider/typegpt.py +359 -356
- webscout/Provider/yep.py +5 -5
- webscout/__main__.py +5 -5
- webscout/cli.py +319 -319
- webscout/conversation.py +241 -242
- webscout/exceptions.py +328 -328
- webscout/litagent/__init__.py +28 -28
- webscout/litagent/agent.py +2 -3
- webscout/litprinter/__init__.py +0 -58
- webscout/scout/__init__.py +8 -8
- webscout/scout/core.py +884 -884
- webscout/scout/element.py +459 -459
- webscout/scout/parsers/__init__.py +69 -69
- webscout/scout/parsers/html5lib_parser.py +172 -172
- webscout/scout/parsers/html_parser.py +236 -236
- webscout/scout/parsers/lxml_parser.py +178 -178
- webscout/scout/utils.py +38 -38
- webscout/swiftcli/__init__.py +811 -811
- webscout/update_checker.py +2 -12
- webscout/version.py +1 -1
- webscout/webscout_search.py +1142 -1140
- webscout/webscout_search_async.py +635 -635
- webscout/zeroart/__init__.py +54 -54
- webscout/zeroart/base.py +60 -60
- webscout/zeroart/effects.py +99 -99
- webscout/zeroart/fonts.py +816 -816
- {webscout-7.0.dist-info → webscout-7.2.dist-info}/METADATA +21 -28
- webscout-7.2.dist-info/RECORD +217 -0
- webstoken/__init__.py +30 -30
- webstoken/classifier.py +189 -189
- webstoken/keywords.py +216 -216
- webstoken/language.py +128 -128
- webstoken/ner.py +164 -164
- webstoken/normalizer.py +35 -35
- webstoken/processor.py +77 -77
- webstoken/sentiment.py +206 -206
- webstoken/stemmer.py +73 -73
- webstoken/tagger.py +60 -60
- webstoken/tokenizer.py +158 -158
- webscout/Provider/RUBIKSAI.py +0 -272
- webscout-7.0.dist-info/RECORD +0 -199
- {webscout-7.0.dist-info → webscout-7.2.dist-info}/LICENSE.md +0 -0
- {webscout-7.0.dist-info → webscout-7.2.dist-info}/WHEEL +0 -0
- {webscout-7.0.dist-info → webscout-7.2.dist-info}/entry_points.txt +0 -0
- {webscout-7.0.dist-info → webscout-7.2.dist-info}/top_level.txt +0 -0
webscout/AIauto.py
CHANGED
|
@@ -1,191 +1,191 @@
|
|
|
1
|
-
from webscout.AIbase import Provider
|
|
2
|
-
from webscout.g4f import GPT4FREE, TestProviders
|
|
3
|
-
from webscout.exceptions import AllProvidersFailure
|
|
4
|
-
from webscout.Litlogger import Litlogger, LogFormat, ColorScheme
|
|
5
|
-
from typing import Union, Any, Dict, Generator
|
|
6
|
-
import importlib
|
|
7
|
-
import pkgutil
|
|
8
|
-
import random
|
|
9
|
-
import inspect
|
|
10
|
-
|
|
11
|
-
# Initialize LitLogger with cyberpunk theme
|
|
12
|
-
logger = Litlogger(
|
|
13
|
-
name="AIauto",
|
|
14
|
-
format=LogFormat.DETAILED,
|
|
15
|
-
color_scheme=ColorScheme.CYBERPUNK
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
def load_providers():
|
|
19
|
-
provider_map = {}
|
|
20
|
-
api_key_providers = set()
|
|
21
|
-
provider_package = importlib.import_module("webscout.Provider")
|
|
22
|
-
|
|
23
|
-
for _, module_name, _ in pkgutil.iter_modules(provider_package.__path__):
|
|
24
|
-
try:
|
|
25
|
-
module = importlib.import_module(f"webscout.Provider.{module_name}")
|
|
26
|
-
for attr_name in dir(module):
|
|
27
|
-
attr = getattr(module, attr_name)
|
|
28
|
-
if isinstance(attr, type) and issubclass(attr, Provider) and attr != Provider:
|
|
29
|
-
provider_map[attr_name.upper()] = attr
|
|
30
|
-
# Check if the provider needs an API key
|
|
31
|
-
if 'api_key' in inspect.signature(attr.__init__).parameters:
|
|
32
|
-
api_key_providers.add(attr_name.upper())
|
|
33
|
-
logger.debug(f"Provider {attr_name} requires API key")
|
|
34
|
-
logger.success(f"Loaded provider module: {module_name}")
|
|
35
|
-
except Exception as e:
|
|
36
|
-
logger.error(f"Failed to load provider {module_name}: {str(e)}")
|
|
37
|
-
|
|
38
|
-
logger.info(f"Total providers loaded: {len(provider_map)}")
|
|
39
|
-
logger.info(f"API key providers: {len(api_key_providers)}")
|
|
40
|
-
return provider_map, api_key_providers
|
|
41
|
-
|
|
42
|
-
provider_map, api_key_providers = load_providers()
|
|
43
|
-
|
|
44
|
-
class AUTO(Provider):
|
|
45
|
-
def __init__(
|
|
46
|
-
self,
|
|
47
|
-
is_conversation: bool = True,
|
|
48
|
-
max_tokens: int = 600,
|
|
49
|
-
timeout: int = 30,
|
|
50
|
-
intro: str = None,
|
|
51
|
-
filepath: str = None,
|
|
52
|
-
update_file: bool = True,
|
|
53
|
-
proxies: dict = {},
|
|
54
|
-
history_offset: int = 10250,
|
|
55
|
-
act: str = None,
|
|
56
|
-
exclude: list[str] = [],
|
|
57
|
-
):
|
|
58
|
-
self.provider = None
|
|
59
|
-
self.provider_name = None
|
|
60
|
-
self.is_conversation = is_conversation
|
|
61
|
-
self.max_tokens = max_tokens
|
|
62
|
-
self.timeout = timeout
|
|
63
|
-
self.intro = intro
|
|
64
|
-
self.filepath = filepath
|
|
65
|
-
self.update_file = update_file
|
|
66
|
-
self.proxies = proxies
|
|
67
|
-
self.history_offset = history_offset
|
|
68
|
-
self.act = act
|
|
69
|
-
self.exclude = [e.upper() for e in exclude]
|
|
70
|
-
|
|
71
|
-
@property
|
|
72
|
-
def last_response(self) -> dict[str, Any]:
|
|
73
|
-
return self.provider.last_response if self.provider else {}
|
|
74
|
-
|
|
75
|
-
@property
|
|
76
|
-
def conversation(self) -> object:
|
|
77
|
-
return self.provider.conversation if self.provider else None
|
|
78
|
-
|
|
79
|
-
def ask(
|
|
80
|
-
self,
|
|
81
|
-
prompt: str,
|
|
82
|
-
stream: bool = False,
|
|
83
|
-
raw: bool = False,
|
|
84
|
-
optimizer: str = None,
|
|
85
|
-
conversationally: bool = False,
|
|
86
|
-
run_new_test: bool = False,
|
|
87
|
-
) -> Union[Dict, Generator]:
|
|
88
|
-
ask_kwargs = {
|
|
89
|
-
"prompt": prompt,
|
|
90
|
-
"stream": stream,
|
|
91
|
-
"raw": raw,
|
|
92
|
-
"optimizer": optimizer,
|
|
93
|
-
"conversationally": conversationally,
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
# Filter out API key required providers and excluded providers
|
|
97
|
-
available_providers = [
|
|
98
|
-
(name, cls) for name, cls in provider_map.items()
|
|
99
|
-
if name not in api_key_providers and name not in self.exclude
|
|
100
|
-
]
|
|
101
|
-
|
|
102
|
-
# Shuffle the list of available providers
|
|
103
|
-
random.shuffle(available_providers)
|
|
104
|
-
|
|
105
|
-
# Try webscout-based providers
|
|
106
|
-
for provider_name, provider_class in available_providers:
|
|
107
|
-
try:
|
|
108
|
-
self.provider_name = f"webscout-{provider_name}"
|
|
109
|
-
logger.info(f"Trying provider: {self.provider_name}")
|
|
110
|
-
|
|
111
|
-
self.provider = provider_class(
|
|
112
|
-
is_conversation=self.is_conversation,
|
|
113
|
-
max_tokens=self.max_tokens,
|
|
114
|
-
timeout=self.timeout,
|
|
115
|
-
intro=self.intro,
|
|
116
|
-
filepath=self.filepath,
|
|
117
|
-
update_file=self.update_file,
|
|
118
|
-
proxies=self.proxies,
|
|
119
|
-
history_offset=self.history_offset,
|
|
120
|
-
act=self.act,
|
|
121
|
-
)
|
|
122
|
-
response = self.provider.ask(**ask_kwargs)
|
|
123
|
-
logger.success(f"Successfully used provider: {self.provider_name}")
|
|
124
|
-
return response
|
|
125
|
-
except Exception as e:
|
|
126
|
-
logger.warning(f"Provider {self.provider_name} failed: {str(e)}")
|
|
127
|
-
continue
|
|
128
|
-
|
|
129
|
-
# Try GPT4FREE providers
|
|
130
|
-
gpt4free_providers = TestProviders(timeout=self.timeout).get_results(run=run_new_test)
|
|
131
|
-
random.shuffle(gpt4free_providers)
|
|
132
|
-
|
|
133
|
-
for provider_info in gpt4free_providers:
|
|
134
|
-
if provider_info["name"].upper() in self.exclude:
|
|
135
|
-
continue
|
|
136
|
-
try:
|
|
137
|
-
self.provider_name = f"g4f-{provider_info['name']}"
|
|
138
|
-
logger.info(f"Trying provider: {self.provider_name}")
|
|
139
|
-
|
|
140
|
-
self.provider = GPT4FREE(
|
|
141
|
-
provider=provider_info["name"],
|
|
142
|
-
is_conversation=self.is_conversation,
|
|
143
|
-
max_tokens=self.max_tokens,
|
|
144
|
-
intro=self.intro,
|
|
145
|
-
filepath=self.filepath,
|
|
146
|
-
update_file=self.update_file,
|
|
147
|
-
proxies=self.proxies,
|
|
148
|
-
history_offset=self.history_offset,
|
|
149
|
-
act=self.act,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
response = self.provider.ask(**ask_kwargs)
|
|
153
|
-
logger.success(f"Successfully used provider: {self.provider_name}")
|
|
154
|
-
return response
|
|
155
|
-
except Exception as e:
|
|
156
|
-
logger.warning(f"Provider {self.provider_name} failed: {str(e)}")
|
|
157
|
-
continue
|
|
158
|
-
|
|
159
|
-
# If we get here, all providers failed
|
|
160
|
-
logger.error("All providers failed to process the request")
|
|
161
|
-
raise AllProvidersFailure("All providers failed to process the request")
|
|
162
|
-
|
|
163
|
-
def chat(
|
|
164
|
-
self,
|
|
165
|
-
prompt: str,
|
|
166
|
-
stream: bool = False,
|
|
167
|
-
optimizer: str = None,
|
|
168
|
-
conversationally: bool = False,
|
|
169
|
-
run_new_test: bool = False,
|
|
170
|
-
) -> Union[str, Generator[str, None, None]]:
|
|
171
|
-
response = self.ask(
|
|
172
|
-
prompt,
|
|
173
|
-
stream,
|
|
174
|
-
optimizer=optimizer,
|
|
175
|
-
conversationally=conversationally,
|
|
176
|
-
run_new_test=run_new_test,
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
if stream:
|
|
180
|
-
return (self.get_message(chunk) for chunk in response)
|
|
181
|
-
else:
|
|
182
|
-
return self.get_message(response)
|
|
183
|
-
|
|
184
|
-
def get_message(self, response: dict) -> str:
|
|
185
|
-
assert self.provider is not None, "Chat with AI first"
|
|
186
|
-
return self.provider.get_message(response)
|
|
187
|
-
if __name__ == "__main__":
|
|
188
|
-
auto = AUTO()
|
|
189
|
-
|
|
190
|
-
response = auto.chat("Hello, how are you?")
|
|
191
|
-
print(response)
|
|
1
|
+
from webscout.AIbase import Provider
|
|
2
|
+
from webscout.g4f import GPT4FREE, TestProviders
|
|
3
|
+
from webscout.exceptions import AllProvidersFailure
|
|
4
|
+
from webscout.Litlogger import Litlogger, LogFormat, ColorScheme
|
|
5
|
+
from typing import Union, Any, Dict, Generator
|
|
6
|
+
import importlib
|
|
7
|
+
import pkgutil
|
|
8
|
+
import random
|
|
9
|
+
import inspect
|
|
10
|
+
|
|
11
|
+
# Initialize LitLogger with cyberpunk theme
|
|
12
|
+
logger = Litlogger(
|
|
13
|
+
name="AIauto",
|
|
14
|
+
format=LogFormat.DETAILED,
|
|
15
|
+
color_scheme=ColorScheme.CYBERPUNK
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
def load_providers():
|
|
19
|
+
provider_map = {}
|
|
20
|
+
api_key_providers = set()
|
|
21
|
+
provider_package = importlib.import_module("webscout.Provider")
|
|
22
|
+
|
|
23
|
+
for _, module_name, _ in pkgutil.iter_modules(provider_package.__path__):
|
|
24
|
+
try:
|
|
25
|
+
module = importlib.import_module(f"webscout.Provider.{module_name}")
|
|
26
|
+
for attr_name in dir(module):
|
|
27
|
+
attr = getattr(module, attr_name)
|
|
28
|
+
if isinstance(attr, type) and issubclass(attr, Provider) and attr != Provider:
|
|
29
|
+
provider_map[attr_name.upper()] = attr
|
|
30
|
+
# Check if the provider needs an API key
|
|
31
|
+
if 'api_key' in inspect.signature(attr.__init__).parameters:
|
|
32
|
+
api_key_providers.add(attr_name.upper())
|
|
33
|
+
logger.debug(f"Provider {attr_name} requires API key")
|
|
34
|
+
logger.success(f"Loaded provider module: {module_name}")
|
|
35
|
+
except Exception as e:
|
|
36
|
+
logger.error(f"Failed to load provider {module_name}: {str(e)}")
|
|
37
|
+
|
|
38
|
+
logger.info(f"Total providers loaded: {len(provider_map)}")
|
|
39
|
+
logger.info(f"API key providers: {len(api_key_providers)}")
|
|
40
|
+
return provider_map, api_key_providers
|
|
41
|
+
|
|
42
|
+
provider_map, api_key_providers = load_providers()
|
|
43
|
+
|
|
44
|
+
class AUTO(Provider):
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
is_conversation: bool = True,
|
|
48
|
+
max_tokens: int = 600,
|
|
49
|
+
timeout: int = 30,
|
|
50
|
+
intro: str = None,
|
|
51
|
+
filepath: str = None,
|
|
52
|
+
update_file: bool = True,
|
|
53
|
+
proxies: dict = {},
|
|
54
|
+
history_offset: int = 10250,
|
|
55
|
+
act: str = None,
|
|
56
|
+
exclude: list[str] = [],
|
|
57
|
+
):
|
|
58
|
+
self.provider = None
|
|
59
|
+
self.provider_name = None
|
|
60
|
+
self.is_conversation = is_conversation
|
|
61
|
+
self.max_tokens = max_tokens
|
|
62
|
+
self.timeout = timeout
|
|
63
|
+
self.intro = intro
|
|
64
|
+
self.filepath = filepath
|
|
65
|
+
self.update_file = update_file
|
|
66
|
+
self.proxies = proxies
|
|
67
|
+
self.history_offset = history_offset
|
|
68
|
+
self.act = act
|
|
69
|
+
self.exclude = [e.upper() for e in exclude]
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def last_response(self) -> dict[str, Any]:
|
|
73
|
+
return self.provider.last_response if self.provider else {}
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def conversation(self) -> object:
|
|
77
|
+
return self.provider.conversation if self.provider else None
|
|
78
|
+
|
|
79
|
+
def ask(
|
|
80
|
+
self,
|
|
81
|
+
prompt: str,
|
|
82
|
+
stream: bool = False,
|
|
83
|
+
raw: bool = False,
|
|
84
|
+
optimizer: str = None,
|
|
85
|
+
conversationally: bool = False,
|
|
86
|
+
run_new_test: bool = False,
|
|
87
|
+
) -> Union[Dict, Generator]:
|
|
88
|
+
ask_kwargs = {
|
|
89
|
+
"prompt": prompt,
|
|
90
|
+
"stream": stream,
|
|
91
|
+
"raw": raw,
|
|
92
|
+
"optimizer": optimizer,
|
|
93
|
+
"conversationally": conversationally,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Filter out API key required providers and excluded providers
|
|
97
|
+
available_providers = [
|
|
98
|
+
(name, cls) for name, cls in provider_map.items()
|
|
99
|
+
if name not in api_key_providers and name not in self.exclude
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
# Shuffle the list of available providers
|
|
103
|
+
random.shuffle(available_providers)
|
|
104
|
+
|
|
105
|
+
# Try webscout-based providers
|
|
106
|
+
for provider_name, provider_class in available_providers:
|
|
107
|
+
try:
|
|
108
|
+
self.provider_name = f"webscout-{provider_name}"
|
|
109
|
+
logger.info(f"Trying provider: {self.provider_name}")
|
|
110
|
+
|
|
111
|
+
self.provider = provider_class(
|
|
112
|
+
is_conversation=self.is_conversation,
|
|
113
|
+
max_tokens=self.max_tokens,
|
|
114
|
+
timeout=self.timeout,
|
|
115
|
+
intro=self.intro,
|
|
116
|
+
filepath=self.filepath,
|
|
117
|
+
update_file=self.update_file,
|
|
118
|
+
proxies=self.proxies,
|
|
119
|
+
history_offset=self.history_offset,
|
|
120
|
+
act=self.act,
|
|
121
|
+
)
|
|
122
|
+
response = self.provider.ask(**ask_kwargs)
|
|
123
|
+
logger.success(f"Successfully used provider: {self.provider_name}")
|
|
124
|
+
return response
|
|
125
|
+
except Exception as e:
|
|
126
|
+
logger.warning(f"Provider {self.provider_name} failed: {str(e)}")
|
|
127
|
+
continue
|
|
128
|
+
|
|
129
|
+
# Try GPT4FREE providers
|
|
130
|
+
gpt4free_providers = TestProviders(timeout=self.timeout).get_results(run=run_new_test)
|
|
131
|
+
random.shuffle(gpt4free_providers)
|
|
132
|
+
|
|
133
|
+
for provider_info in gpt4free_providers:
|
|
134
|
+
if provider_info["name"].upper() in self.exclude:
|
|
135
|
+
continue
|
|
136
|
+
try:
|
|
137
|
+
self.provider_name = f"g4f-{provider_info['name']}"
|
|
138
|
+
logger.info(f"Trying provider: {self.provider_name}")
|
|
139
|
+
|
|
140
|
+
self.provider = GPT4FREE(
|
|
141
|
+
provider=provider_info["name"],
|
|
142
|
+
is_conversation=self.is_conversation,
|
|
143
|
+
max_tokens=self.max_tokens,
|
|
144
|
+
intro=self.intro,
|
|
145
|
+
filepath=self.filepath,
|
|
146
|
+
update_file=self.update_file,
|
|
147
|
+
proxies=self.proxies,
|
|
148
|
+
history_offset=self.history_offset,
|
|
149
|
+
act=self.act,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
response = self.provider.ask(**ask_kwargs)
|
|
153
|
+
logger.success(f"Successfully used provider: {self.provider_name}")
|
|
154
|
+
return response
|
|
155
|
+
except Exception as e:
|
|
156
|
+
logger.warning(f"Provider {self.provider_name} failed: {str(e)}")
|
|
157
|
+
continue
|
|
158
|
+
|
|
159
|
+
# If we get here, all providers failed
|
|
160
|
+
logger.error("All providers failed to process the request")
|
|
161
|
+
raise AllProvidersFailure("All providers failed to process the request")
|
|
162
|
+
|
|
163
|
+
def chat(
|
|
164
|
+
self,
|
|
165
|
+
prompt: str,
|
|
166
|
+
stream: bool = False,
|
|
167
|
+
optimizer: str = None,
|
|
168
|
+
conversationally: bool = False,
|
|
169
|
+
run_new_test: bool = False,
|
|
170
|
+
) -> Union[str, Generator[str, None, None]]:
|
|
171
|
+
response = self.ask(
|
|
172
|
+
prompt,
|
|
173
|
+
stream,
|
|
174
|
+
optimizer=optimizer,
|
|
175
|
+
conversationally=conversationally,
|
|
176
|
+
run_new_test=run_new_test,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
if stream:
|
|
180
|
+
return (self.get_message(chunk) for chunk in response)
|
|
181
|
+
else:
|
|
182
|
+
return self.get_message(response)
|
|
183
|
+
|
|
184
|
+
def get_message(self, response: dict) -> str:
|
|
185
|
+
assert self.provider is not None, "Chat with AI first"
|
|
186
|
+
return self.provider.get_message(response)
|
|
187
|
+
if __name__ == "__main__":
|
|
188
|
+
auto = AUTO()
|
|
189
|
+
|
|
190
|
+
response = auto.chat("Hello, how are you?")
|
|
191
|
+
print(response)
|
webscout/AIbase.py
CHANGED
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import AsyncGenerator, List, Union, Generator, Optional
|
|
4
|
-
from typing_extensions import TypeAlias
|
|
5
|
-
|
|
6
|
-
# Type aliases for better readability
|
|
7
|
-
Response: TypeAlias = dict[str, Union[str, bool, None]]
|
|
8
|
-
ImageData: TypeAlias = Union[bytes, str, Generator[bytes, None, None]]
|
|
9
|
-
AsyncImageData: TypeAlias = Union[bytes, str, AsyncGenerator[bytes, None]]
|
|
10
|
-
|
|
11
|
-
class AIProviderError(Exception):
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
class Provider(ABC):
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def ask(
|
|
18
|
-
self,
|
|
19
|
-
prompt: str,
|
|
20
|
-
stream: bool = False,
|
|
21
|
-
raw: bool = False,
|
|
22
|
-
optimizer: Optional[str] = None,
|
|
23
|
-
conversationally: bool = False,
|
|
24
|
-
) -> Response:
|
|
25
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
26
|
-
|
|
27
|
-
@abstractmethod
|
|
28
|
-
def chat(
|
|
29
|
-
self,
|
|
30
|
-
prompt: str,
|
|
31
|
-
stream: bool = False,
|
|
32
|
-
optimizer: Optional[str] = None,
|
|
33
|
-
conversationally: bool = False,
|
|
34
|
-
) -> str:
|
|
35
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
36
|
-
|
|
37
|
-
@abstractmethod
|
|
38
|
-
def get_message(self, response: Response) -> str:
|
|
39
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
40
|
-
|
|
41
|
-
class AsyncProvider(ABC):
|
|
42
|
-
|
|
43
|
-
@abstractmethod
|
|
44
|
-
async def ask(
|
|
45
|
-
self,
|
|
46
|
-
prompt: str,
|
|
47
|
-
stream: bool = False,
|
|
48
|
-
raw: bool = False,
|
|
49
|
-
optimizer: Optional[str] = None,
|
|
50
|
-
conversationally: bool = False,
|
|
51
|
-
) -> Response:
|
|
52
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
53
|
-
|
|
54
|
-
@abstractmethod
|
|
55
|
-
async def chat(
|
|
56
|
-
self,
|
|
57
|
-
prompt: str,
|
|
58
|
-
stream: bool = False,
|
|
59
|
-
optimizer: Optional[str] = None,
|
|
60
|
-
conversationally: bool = False,
|
|
61
|
-
) -> str:
|
|
62
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
63
|
-
|
|
64
|
-
@abstractmethod
|
|
65
|
-
async def get_message(self, response: Response) -> str:
|
|
66
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
67
|
-
|
|
68
|
-
class TTSProvider(ABC):
|
|
69
|
-
|
|
70
|
-
@abstractmethod
|
|
71
|
-
def tts(self, text: str) -> ImageData:
|
|
72
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
73
|
-
|
|
74
|
-
class AsyncTTSProvider(ABC):
|
|
75
|
-
|
|
76
|
-
@abstractmethod
|
|
77
|
-
async def tts(self, text: str) -> AsyncImageData:
|
|
78
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
79
|
-
|
|
80
|
-
class ImageProvider(ABC):
|
|
81
|
-
|
|
82
|
-
@abstractmethod
|
|
83
|
-
def generate(self, prompt: str, amount: int = 1) -> List[bytes]:
|
|
84
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
85
|
-
|
|
86
|
-
@abstractmethod
|
|
87
|
-
def save(
|
|
88
|
-
self,
|
|
89
|
-
response: List[bytes],
|
|
90
|
-
name: Optional[str] = None,
|
|
91
|
-
dir: Optional[Union[str, Path]] = None
|
|
92
|
-
) -> List[str]:
|
|
93
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
94
|
-
|
|
95
|
-
class AsyncImageProvider(ABC):
|
|
96
|
-
|
|
97
|
-
@abstractmethod
|
|
98
|
-
async def generate(
|
|
99
|
-
self,
|
|
100
|
-
prompt: str,
|
|
101
|
-
amount: int = 1
|
|
102
|
-
) -> Union[AsyncGenerator[bytes, None], List[bytes]]:
|
|
103
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
104
|
-
|
|
105
|
-
@abstractmethod
|
|
106
|
-
async def save(
|
|
107
|
-
self,
|
|
108
|
-
response: Union[AsyncGenerator[bytes, None], List[bytes]],
|
|
109
|
-
name: Optional[str] = None,
|
|
110
|
-
dir: Optional[Union[str, Path]] = None
|
|
111
|
-
) -> List[str]:
|
|
112
|
-
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
113
|
-
|
|
114
|
-
class AISearch(ABC):
|
|
115
|
-
|
|
116
|
-
@abstractmethod
|
|
117
|
-
def search(
|
|
118
|
-
self,
|
|
119
|
-
prompt: str,
|
|
120
|
-
stream: bool = False,
|
|
121
|
-
raw: bool = False,
|
|
122
|
-
) -> Response:
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import AsyncGenerator, List, Union, Generator, Optional
|
|
4
|
+
from typing_extensions import TypeAlias
|
|
5
|
+
|
|
6
|
+
# Type aliases for better readability
|
|
7
|
+
Response: TypeAlias = dict[str, Union[str, bool, None]]
|
|
8
|
+
ImageData: TypeAlias = Union[bytes, str, Generator[bytes, None, None]]
|
|
9
|
+
AsyncImageData: TypeAlias = Union[bytes, str, AsyncGenerator[bytes, None]]
|
|
10
|
+
|
|
11
|
+
class AIProviderError(Exception):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
class Provider(ABC):
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def ask(
|
|
18
|
+
self,
|
|
19
|
+
prompt: str,
|
|
20
|
+
stream: bool = False,
|
|
21
|
+
raw: bool = False,
|
|
22
|
+
optimizer: Optional[str] = None,
|
|
23
|
+
conversationally: bool = False,
|
|
24
|
+
) -> Response:
|
|
25
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
26
|
+
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def chat(
|
|
29
|
+
self,
|
|
30
|
+
prompt: str,
|
|
31
|
+
stream: bool = False,
|
|
32
|
+
optimizer: Optional[str] = None,
|
|
33
|
+
conversationally: bool = False,
|
|
34
|
+
) -> str:
|
|
35
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
def get_message(self, response: Response) -> str:
|
|
39
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
40
|
+
|
|
41
|
+
class AsyncProvider(ABC):
|
|
42
|
+
|
|
43
|
+
@abstractmethod
|
|
44
|
+
async def ask(
|
|
45
|
+
self,
|
|
46
|
+
prompt: str,
|
|
47
|
+
stream: bool = False,
|
|
48
|
+
raw: bool = False,
|
|
49
|
+
optimizer: Optional[str] = None,
|
|
50
|
+
conversationally: bool = False,
|
|
51
|
+
) -> Response:
|
|
52
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
53
|
+
|
|
54
|
+
@abstractmethod
|
|
55
|
+
async def chat(
|
|
56
|
+
self,
|
|
57
|
+
prompt: str,
|
|
58
|
+
stream: bool = False,
|
|
59
|
+
optimizer: Optional[str] = None,
|
|
60
|
+
conversationally: bool = False,
|
|
61
|
+
) -> str:
|
|
62
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
async def get_message(self, response: Response) -> str:
|
|
66
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
67
|
+
|
|
68
|
+
class TTSProvider(ABC):
|
|
69
|
+
|
|
70
|
+
@abstractmethod
|
|
71
|
+
def tts(self, text: str) -> ImageData:
|
|
72
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
73
|
+
|
|
74
|
+
class AsyncTTSProvider(ABC):
|
|
75
|
+
|
|
76
|
+
@abstractmethod
|
|
77
|
+
async def tts(self, text: str) -> AsyncImageData:
|
|
78
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
79
|
+
|
|
80
|
+
class ImageProvider(ABC):
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def generate(self, prompt: str, amount: int = 1) -> List[bytes]:
|
|
84
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
85
|
+
|
|
86
|
+
@abstractmethod
|
|
87
|
+
def save(
|
|
88
|
+
self,
|
|
89
|
+
response: List[bytes],
|
|
90
|
+
name: Optional[str] = None,
|
|
91
|
+
dir: Optional[Union[str, Path]] = None
|
|
92
|
+
) -> List[str]:
|
|
93
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
94
|
+
|
|
95
|
+
class AsyncImageProvider(ABC):
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
async def generate(
|
|
99
|
+
self,
|
|
100
|
+
prompt: str,
|
|
101
|
+
amount: int = 1
|
|
102
|
+
) -> Union[AsyncGenerator[bytes, None], List[bytes]]:
|
|
103
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
104
|
+
|
|
105
|
+
@abstractmethod
|
|
106
|
+
async def save(
|
|
107
|
+
self,
|
|
108
|
+
response: Union[AsyncGenerator[bytes, None], List[bytes]],
|
|
109
|
+
name: Optional[str] = None,
|
|
110
|
+
dir: Optional[Union[str, Path]] = None
|
|
111
|
+
) -> List[str]:
|
|
112
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
113
|
+
|
|
114
|
+
class AISearch(ABC):
|
|
115
|
+
|
|
116
|
+
@abstractmethod
|
|
117
|
+
def search(
|
|
118
|
+
self,
|
|
119
|
+
prompt: str,
|
|
120
|
+
stream: bool = False,
|
|
121
|
+
raw: bool = False,
|
|
122
|
+
) -> Response:
|
|
123
123
|
raise NotImplementedError("Method needs to be implemented in subclass")
|