webscout 6.2b0__py3-none-any.whl → 6.3__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/AIbase.py +309 -239
- webscout/Agents/functioncall.py +248 -198
- webscout/DWEBS.py +322 -178
- webscout/Extra/gguf.py +250 -60
- webscout/Extra/weather.py +172 -67
- webscout/LLM.py +279 -100
- webscout/Local/formats.py +4 -2
- webscout/Provider/Amigo.py +19 -10
- webscout/Provider/Andi.py +0 -33
- webscout/Provider/Blackboxai.py +4 -204
- webscout/Provider/Llama3.py +1 -1
- webscout/Provider/Marcus.py +137 -0
- webscout/Provider/TTI/__init__.py +2 -1
- webscout/Provider/TTI/talkai.py +116 -0
- webscout/Provider/__init__.py +10 -3
- webscout/Provider/askmyai.py +158 -0
- webscout/Provider/cerebras.py +71 -58
- webscout/Provider/geminiapi.py +208 -198
- webscout/Provider/llama3mitril.py +181 -0
- webscout/Provider/llmchat.py +203 -0
- webscout/Provider/talkai.py +196 -0
- webscout/Provider/twitterclone.py +7 -6
- webscout/cli.py +354 -346
- webscout/version.py +1 -1
- webscout-6.3.dist-info/LICENSE.md +211 -0
- {webscout-6.2b0.dist-info → webscout-6.3.dist-info}/METADATA +11 -13
- {webscout-6.2b0.dist-info → webscout-6.3.dist-info}/RECORD +31 -25
- webscout-6.2b0.dist-info/LICENSE.md +0 -50
- /webscout/Provider/TTI/{AIuncensored.py → AIuncensoredimage.py} +0 -0
- {webscout-6.2b0.dist-info → webscout-6.3.dist-info}/WHEEL +0 -0
- {webscout-6.2b0.dist-info → webscout-6.3.dist-info}/entry_points.txt +0 -0
- {webscout-6.2b0.dist-info → webscout-6.3.dist-info}/top_level.txt +0 -0
webscout/AIbase.py
CHANGED
|
@@ -1,240 +1,310 @@
|
|
|
1
|
-
from abc import ABC
|
|
2
|
-
from abc import abstractmethod
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
""
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
Returns:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
"""
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import AsyncGenerator, List, Union, Generator, Optional
|
|
5
|
+
from typing_extensions import TypeAlias
|
|
6
|
+
|
|
7
|
+
# Type aliases for better readability
|
|
8
|
+
Response: TypeAlias = dict[str, Union[str, bool, None]]
|
|
9
|
+
ImageData: TypeAlias = Union[bytes, str, Generator[bytes, None, None]]
|
|
10
|
+
AsyncImageData: TypeAlias = Union[bytes, str, AsyncGenerator[bytes, None]]
|
|
11
|
+
|
|
12
|
+
class AIProviderError(Exception):
|
|
13
|
+
"""Base exception for AI provider errors"""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
class Provider(ABC):
|
|
17
|
+
"""Base class for text-based AI providers.
|
|
18
|
+
|
|
19
|
+
This class defines the interface for synchronous AI text generation providers.
|
|
20
|
+
All text-based AI providers should inherit from this class and implement
|
|
21
|
+
its abstract methods.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def ask(
|
|
26
|
+
self,
|
|
27
|
+
prompt: str,
|
|
28
|
+
stream: bool = False,
|
|
29
|
+
raw: bool = False,
|
|
30
|
+
optimizer: Optional[str] = None,
|
|
31
|
+
conversationally: bool = False,
|
|
32
|
+
) -> Response:
|
|
33
|
+
"""Chat with AI and get detailed response.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
prompt: The input text to send to the AI
|
|
37
|
+
stream: Whether to stream the response. Defaults to False
|
|
38
|
+
raw: Whether to return raw response as received. Defaults to False
|
|
39
|
+
optimizer: Optional prompt optimizer - choices: ['code', 'shell_command']
|
|
40
|
+
conversationally: Whether to maintain conversation context. Defaults to False
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
A dictionary containing response details:
|
|
44
|
+
{
|
|
45
|
+
"completion": str, # The AI's response
|
|
46
|
+
"stop_reason": str|None, # Reason for response termination
|
|
47
|
+
"truncated": bool, # Whether response was truncated
|
|
48
|
+
"stop": str|None, # Stop token if any
|
|
49
|
+
"model": str, # Model used for generation
|
|
50
|
+
"log_id": str, # Unique log identifier
|
|
51
|
+
"exception": str|None # Error message if any
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
AIProviderError: If there's an error communicating with the AI provider
|
|
56
|
+
"""
|
|
57
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
58
|
+
|
|
59
|
+
@abstractmethod
|
|
60
|
+
def chat(
|
|
61
|
+
self,
|
|
62
|
+
prompt: str,
|
|
63
|
+
stream: bool = False,
|
|
64
|
+
optimizer: Optional[str] = None,
|
|
65
|
+
conversationally: bool = False,
|
|
66
|
+
) -> str:
|
|
67
|
+
"""Generate a simple text response from the AI.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
prompt: The input text to send to the AI
|
|
71
|
+
stream: Whether to stream the response. Defaults to False
|
|
72
|
+
optimizer: Optional prompt optimizer - choices: ['code', 'shell_command']
|
|
73
|
+
conversationally: Whether to maintain conversation context. Defaults to False
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
The AI's text response
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
AIProviderError: If there's an error communicating with the AI provider
|
|
80
|
+
"""
|
|
81
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
82
|
+
|
|
83
|
+
@abstractmethod
|
|
84
|
+
def get_message(self, response: Response) -> str:
|
|
85
|
+
"""Extract the message content from a response dictionary.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
response: Response dictionary from ask() method
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
The extracted message text
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
AIProviderError: If message cannot be extracted from response
|
|
95
|
+
"""
|
|
96
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
97
|
+
|
|
98
|
+
class AsyncProvider(ABC):
|
|
99
|
+
"""Asynchronous base class for text-based AI providers"""
|
|
100
|
+
|
|
101
|
+
@abstractmethod
|
|
102
|
+
async def ask(
|
|
103
|
+
self,
|
|
104
|
+
prompt: str,
|
|
105
|
+
stream: bool = False,
|
|
106
|
+
raw: bool = False,
|
|
107
|
+
optimizer: Optional[str] = None,
|
|
108
|
+
conversationally: bool = False,
|
|
109
|
+
) -> Response:
|
|
110
|
+
"""Asynchronously chat with AI and get detailed response.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
prompt: The input text to send to the AI
|
|
114
|
+
stream: Whether to stream the response. Defaults to False
|
|
115
|
+
raw: Whether to return raw response as received. Defaults to False
|
|
116
|
+
optimizer: Optional prompt optimizer - choices: ['code', 'shell_command']
|
|
117
|
+
conversationally: Whether to maintain conversation context. Defaults to False
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
A dictionary containing response details:
|
|
121
|
+
{
|
|
122
|
+
"completion": str, # The AI's response
|
|
123
|
+
"stop_reason": str|None, # Reason for response termination
|
|
124
|
+
"truncated": bool, # Whether response was truncated
|
|
125
|
+
"stop": str|None, # Stop token if any
|
|
126
|
+
"model": str, # Model used for generation
|
|
127
|
+
"log_id": str, # Unique log identifier
|
|
128
|
+
"exception": str|None # Error message if any
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
AIProviderError: If there's an error communicating with the AI provider
|
|
133
|
+
"""
|
|
134
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
135
|
+
|
|
136
|
+
@abstractmethod
|
|
137
|
+
async def chat(
|
|
138
|
+
self,
|
|
139
|
+
prompt: str,
|
|
140
|
+
stream: bool = False,
|
|
141
|
+
optimizer: Optional[str] = None,
|
|
142
|
+
conversationally: bool = False,
|
|
143
|
+
) -> str:
|
|
144
|
+
"""Asynchronously generate a simple text response from the AI.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
prompt: The input text to send to the AI
|
|
148
|
+
stream: Whether to stream the response. Defaults to False
|
|
149
|
+
optimizer: Optional prompt optimizer - choices: ['code', 'shell_command']
|
|
150
|
+
conversationally: Whether to maintain conversation context. Defaults to False
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
The AI's text response
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
AIProviderError: If there's an error communicating with the AI provider
|
|
157
|
+
"""
|
|
158
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
159
|
+
|
|
160
|
+
@abstractmethod
|
|
161
|
+
async def get_message(self, response: Response) -> str:
|
|
162
|
+
"""Asynchronously extract the message content from a response dictionary.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
response: Response dictionary from ask() method
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
The extracted message text
|
|
169
|
+
|
|
170
|
+
Raises:
|
|
171
|
+
AIProviderError: If message cannot be extracted from response
|
|
172
|
+
"""
|
|
173
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
174
|
+
|
|
175
|
+
class TTSProvider(ABC):
|
|
176
|
+
"""Base class for text-to-speech providers.
|
|
177
|
+
|
|
178
|
+
This class defines the interface for synchronous text-to-speech providers.
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
@abstractmethod
|
|
182
|
+
def tts(self, text: str) -> ImageData:
|
|
183
|
+
"""Convert text to speech.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
text: The text to convert to speech
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
One of:
|
|
190
|
+
- Raw audio bytes
|
|
191
|
+
- Path to saved audio file
|
|
192
|
+
- Generator yielding audio chunks
|
|
193
|
+
|
|
194
|
+
Raises:
|
|
195
|
+
AIProviderError: If text-to-speech conversion fails
|
|
196
|
+
"""
|
|
197
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
198
|
+
|
|
199
|
+
class AsyncTTSProvider(ABC):
|
|
200
|
+
"""Base class for asynchronous text-to-speech providers."""
|
|
201
|
+
|
|
202
|
+
@abstractmethod
|
|
203
|
+
async def tts(self, text: str) -> AsyncImageData:
|
|
204
|
+
"""Asynchronously convert text to speech.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
text: The text to convert to speech
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
One of:
|
|
211
|
+
- Raw audio bytes
|
|
212
|
+
- Path to saved audio file
|
|
213
|
+
- AsyncGenerator yielding audio chunks
|
|
214
|
+
|
|
215
|
+
Raises:
|
|
216
|
+
AIProviderError: If text-to-speech conversion fails
|
|
217
|
+
"""
|
|
218
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
219
|
+
|
|
220
|
+
class ImageProvider(ABC):
|
|
221
|
+
"""Base class for text-to-image generation providers."""
|
|
222
|
+
|
|
223
|
+
@abstractmethod
|
|
224
|
+
def generate(self, prompt: str, amount: int = 1) -> List[bytes]:
|
|
225
|
+
"""Generate images from a text description.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
prompt: Text description of desired image
|
|
229
|
+
amount: Number of images to generate (default: 1)
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
List of generated images as bytes
|
|
233
|
+
|
|
234
|
+
Raises:
|
|
235
|
+
AIProviderError: If image generation fails
|
|
236
|
+
ValueError: If amount is less than 1
|
|
237
|
+
"""
|
|
238
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
239
|
+
|
|
240
|
+
@abstractmethod
|
|
241
|
+
def save(
|
|
242
|
+
self,
|
|
243
|
+
response: List[bytes],
|
|
244
|
+
name: Optional[str] = None,
|
|
245
|
+
dir: Optional[Union[str, Path]] = None
|
|
246
|
+
) -> List[str]:
|
|
247
|
+
"""Save generated images to disk.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
response: List of image data in bytes
|
|
251
|
+
name: Base filename for saved images (default: auto-generated)
|
|
252
|
+
dir: Directory to save images (default: current directory)
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
List of paths to saved image files
|
|
256
|
+
|
|
257
|
+
Raises:
|
|
258
|
+
AIProviderError: If saving images fails
|
|
259
|
+
ValueError: If response is empty
|
|
260
|
+
"""
|
|
261
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
262
|
+
|
|
263
|
+
class AsyncImageProvider(ABC):
|
|
264
|
+
"""Base class for asynchronous text-to-image generation providers."""
|
|
265
|
+
|
|
266
|
+
@abstractmethod
|
|
267
|
+
async def generate(
|
|
268
|
+
self,
|
|
269
|
+
prompt: str,
|
|
270
|
+
amount: int = 1
|
|
271
|
+
) -> Union[AsyncGenerator[bytes, None], List[bytes]]:
|
|
272
|
+
"""Asynchronously generate images from text.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
prompt: Text description of desired image
|
|
276
|
+
amount: Number of images to generate (default: 1)
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
Either:
|
|
280
|
+
- AsyncGenerator yielding image bytes for streaming
|
|
281
|
+
- List of image bytes if not streaming
|
|
282
|
+
|
|
283
|
+
Raises:
|
|
284
|
+
AIProviderError: If image generation fails
|
|
285
|
+
ValueError: If amount is less than 1
|
|
286
|
+
"""
|
|
287
|
+
raise NotImplementedError("Method needs to be implemented in subclass")
|
|
288
|
+
|
|
289
|
+
@abstractmethod
|
|
290
|
+
async def save(
|
|
291
|
+
self,
|
|
292
|
+
response: Union[AsyncGenerator[bytes, None], List[bytes]],
|
|
293
|
+
name: Optional[str] = None,
|
|
294
|
+
dir: Optional[Union[str, Path]] = None
|
|
295
|
+
) -> List[str]:
|
|
296
|
+
"""Asynchronously save generated images.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
response: Either AsyncGenerator yielding images or List of image bytes
|
|
300
|
+
name: Base filename for saved images (default: auto-generated)
|
|
301
|
+
dir: Directory to save images (default: current directory)
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
List of paths to saved image files
|
|
305
|
+
|
|
306
|
+
Raises:
|
|
307
|
+
AIProviderError: If saving images fails
|
|
308
|
+
ValueError: If response is empty
|
|
309
|
+
"""
|
|
240
310
|
raise NotImplementedError("Method needs to be implemented in subclass")
|