webscout 8.2.6__py3-none-any.whl → 8.2.8__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.

Files changed (150) hide show
  1. webscout/AIauto.py +1 -1
  2. webscout/AIutel.py +298 -239
  3. webscout/Extra/Act.md +309 -0
  4. webscout/Extra/GitToolkit/gitapi/README.md +110 -0
  5. webscout/Extra/YTToolkit/README.md +375 -0
  6. webscout/Extra/YTToolkit/ytapi/README.md +44 -0
  7. webscout/Extra/YTToolkit/ytapi/extras.py +92 -19
  8. webscout/Extra/autocoder/autocoder.py +309 -114
  9. webscout/Extra/autocoder/autocoder_utiles.py +15 -15
  10. webscout/Extra/gguf.md +430 -0
  11. webscout/Extra/tempmail/README.md +488 -0
  12. webscout/Extra/weather.md +281 -0
  13. webscout/Litlogger/Readme.md +175 -0
  14. webscout/Provider/AISEARCH/DeepFind.py +41 -37
  15. webscout/Provider/AISEARCH/README.md +279 -0
  16. webscout/Provider/AISEARCH/__init__.py +0 -1
  17. webscout/Provider/AISEARCH/genspark_search.py +228 -86
  18. webscout/Provider/AISEARCH/hika_search.py +11 -11
  19. webscout/Provider/AISEARCH/scira_search.py +324 -322
  20. webscout/Provider/AllenAI.py +7 -14
  21. webscout/Provider/Blackboxai.py +518 -74
  22. webscout/Provider/Cloudflare.py +0 -1
  23. webscout/Provider/Deepinfra.py +23 -21
  24. webscout/Provider/Flowith.py +217 -0
  25. webscout/Provider/FreeGemini.py +250 -0
  26. webscout/Provider/GizAI.py +15 -5
  27. webscout/Provider/Glider.py +11 -8
  28. webscout/Provider/HeckAI.py +80 -52
  29. webscout/Provider/Koboldai.py +7 -4
  30. webscout/Provider/LambdaChat.py +2 -2
  31. webscout/Provider/Marcus.py +10 -18
  32. webscout/Provider/OPENAI/BLACKBOXAI.py +735 -0
  33. webscout/Provider/OPENAI/Cloudflare.py +378 -0
  34. webscout/Provider/OPENAI/FreeGemini.py +282 -0
  35. webscout/Provider/OPENAI/NEMOTRON.py +244 -0
  36. webscout/Provider/OPENAI/README.md +1253 -0
  37. webscout/Provider/OPENAI/__init__.py +8 -0
  38. webscout/Provider/OPENAI/ai4chat.py +293 -286
  39. webscout/Provider/OPENAI/api.py +810 -0
  40. webscout/Provider/OPENAI/base.py +217 -14
  41. webscout/Provider/OPENAI/c4ai.py +373 -367
  42. webscout/Provider/OPENAI/chatgpt.py +7 -0
  43. webscout/Provider/OPENAI/chatgptclone.py +7 -0
  44. webscout/Provider/OPENAI/chatsandbox.py +172 -0
  45. webscout/Provider/OPENAI/deepinfra.py +30 -20
  46. webscout/Provider/OPENAI/e2b.py +6 -0
  47. webscout/Provider/OPENAI/exaai.py +7 -0
  48. webscout/Provider/OPENAI/exachat.py +6 -0
  49. webscout/Provider/OPENAI/flowith.py +162 -0
  50. webscout/Provider/OPENAI/freeaichat.py +359 -352
  51. webscout/Provider/OPENAI/glider.py +323 -316
  52. webscout/Provider/OPENAI/groq.py +361 -354
  53. webscout/Provider/OPENAI/heckai.py +30 -64
  54. webscout/Provider/OPENAI/llmchatco.py +8 -0
  55. webscout/Provider/OPENAI/mcpcore.py +7 -0
  56. webscout/Provider/OPENAI/multichat.py +8 -0
  57. webscout/Provider/OPENAI/netwrck.py +356 -350
  58. webscout/Provider/OPENAI/opkfc.py +8 -0
  59. webscout/Provider/OPENAI/scirachat.py +471 -462
  60. webscout/Provider/OPENAI/sonus.py +9 -0
  61. webscout/Provider/OPENAI/standardinput.py +9 -1
  62. webscout/Provider/OPENAI/textpollinations.py +339 -329
  63. webscout/Provider/OPENAI/toolbaz.py +7 -0
  64. webscout/Provider/OPENAI/typefully.py +355 -0
  65. webscout/Provider/OPENAI/typegpt.py +358 -346
  66. webscout/Provider/OPENAI/uncovrAI.py +7 -0
  67. webscout/Provider/OPENAI/utils.py +103 -7
  68. webscout/Provider/OPENAI/venice.py +12 -0
  69. webscout/Provider/OPENAI/wisecat.py +19 -19
  70. webscout/Provider/OPENAI/writecream.py +7 -0
  71. webscout/Provider/OPENAI/x0gpt.py +7 -0
  72. webscout/Provider/OPENAI/yep.py +50 -21
  73. webscout/Provider/OpenGPT.py +1 -1
  74. webscout/Provider/TTI/AiForce/README.md +159 -0
  75. webscout/Provider/TTI/FreeAIPlayground/README.md +99 -0
  76. webscout/Provider/TTI/ImgSys/README.md +174 -0
  77. webscout/Provider/TTI/MagicStudio/README.md +101 -0
  78. webscout/Provider/TTI/Nexra/README.md +155 -0
  79. webscout/Provider/TTI/PollinationsAI/README.md +146 -0
  80. webscout/Provider/TTI/README.md +128 -0
  81. webscout/Provider/TTI/aiarta/README.md +134 -0
  82. webscout/Provider/TTI/artbit/README.md +100 -0
  83. webscout/Provider/TTI/fastflux/README.md +129 -0
  84. webscout/Provider/TTI/huggingface/README.md +114 -0
  85. webscout/Provider/TTI/piclumen/README.md +161 -0
  86. webscout/Provider/TTI/pixelmuse/README.md +79 -0
  87. webscout/Provider/TTI/talkai/README.md +139 -0
  88. webscout/Provider/TTS/README.md +192 -0
  89. webscout/Provider/TTS/__init__.py +2 -1
  90. webscout/Provider/TTS/speechma.py +500 -100
  91. webscout/Provider/TTS/sthir.py +94 -0
  92. webscout/Provider/TeachAnything.py +3 -7
  93. webscout/Provider/TextPollinationsAI.py +4 -2
  94. webscout/Provider/{aimathgpt.py → UNFINISHED/ChatHub.py} +88 -68
  95. webscout/Provider/UNFINISHED/liner_api_request.py +263 -0
  96. webscout/Provider/UNFINISHED/oivscode.py +351 -0
  97. webscout/Provider/UNFINISHED/test_lmarena.py +119 -0
  98. webscout/Provider/Writecream.py +11 -2
  99. webscout/Provider/__init__.py +8 -14
  100. webscout/Provider/ai4chat.py +4 -58
  101. webscout/Provider/asksteve.py +17 -9
  102. webscout/Provider/cerebras.py +3 -1
  103. webscout/Provider/koala.py +170 -268
  104. webscout/Provider/llmchat.py +3 -0
  105. webscout/Provider/lmarena.py +198 -0
  106. webscout/Provider/meta.py +7 -4
  107. webscout/Provider/samurai.py +223 -0
  108. webscout/Provider/scira_chat.py +4 -2
  109. webscout/Provider/typefully.py +23 -151
  110. webscout/__init__.py +4 -2
  111. webscout/cli.py +3 -28
  112. webscout/conversation.py +35 -35
  113. webscout/litagent/Readme.md +276 -0
  114. webscout/scout/README.md +402 -0
  115. webscout/swiftcli/Readme.md +323 -0
  116. webscout/version.py +1 -1
  117. webscout/webscout_search.py +2 -182
  118. webscout/webscout_search_async.py +1 -179
  119. webscout/zeroart/README.md +89 -0
  120. webscout/zeroart/__init__.py +134 -54
  121. webscout/zeroart/base.py +19 -13
  122. webscout/zeroart/effects.py +101 -99
  123. webscout/zeroart/fonts.py +1239 -816
  124. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/METADATA +116 -74
  125. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/RECORD +130 -103
  126. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/WHEEL +1 -1
  127. webscout-8.2.8.dist-info/entry_points.txt +3 -0
  128. webscout-8.2.8.dist-info/top_level.txt +1 -0
  129. webscout/Provider/AISEARCH/ISou.py +0 -256
  130. webscout/Provider/ElectronHub.py +0 -773
  131. webscout/Provider/Free2GPT.py +0 -241
  132. webscout/Provider/GPTWeb.py +0 -249
  133. webscout/Provider/bagoodex.py +0 -145
  134. webscout/Provider/geminiprorealtime.py +0 -160
  135. webscout/scout/core.py +0 -881
  136. webscout-8.2.6.dist-info/entry_points.txt +0 -3
  137. webscout-8.2.6.dist-info/top_level.txt +0 -2
  138. webstoken/__init__.py +0 -30
  139. webstoken/classifier.py +0 -189
  140. webstoken/keywords.py +0 -216
  141. webstoken/language.py +0 -128
  142. webstoken/ner.py +0 -164
  143. webstoken/normalizer.py +0 -35
  144. webstoken/processor.py +0 -77
  145. webstoken/sentiment.py +0 -206
  146. webstoken/stemmer.py +0 -73
  147. webstoken/tagger.py +0 -60
  148. webstoken/tokenizer.py +0 -158
  149. /webscout/Provider/{Youchat.py → UNFINISHED/Youchat.py} +0 -0
  150. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/licenses/LICENSE.md +0 -0
@@ -1,15 +1,69 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import List, Dict, Optional, Union, Generator, Any
2
+ from typing import List, Dict, Optional, Union, Generator, Any, TypedDict, Callable
3
+ import json
4
+ import logging
5
+ from dataclasses import dataclass
3
6
 
4
- # Re-define or import necessary response structure classes (like ChatCompletion, ChatCompletionChunk)
5
- # For simplicity, we'll assume they are defined elsewhere or passed directly.
6
- # You might want to define base versions of these classes here as well.
7
+ logger = logging.getLogger(__name__)
7
8
 
8
- class BaseChatCompletionChunk: # Placeholder
9
- pass
10
- class BaseChatCompletion: # Placeholder
11
- pass
12
9
 
10
+ # Import the utils for response structures
11
+ from webscout.Provider.OPENAI.utils import ChatCompletion, ChatCompletionChunk, Choice, ChatCompletionMessage, ToolCall, ToolFunction
12
+
13
+ # Define tool-related structures
14
+ class ToolDefinition(TypedDict):
15
+ """Definition of a tool that can be called by the AI"""
16
+ type: str
17
+ function: Dict[str, Any]
18
+
19
+ class FunctionParameters(TypedDict):
20
+ """Parameters for a function"""
21
+ type: str
22
+ properties: Dict[str, Dict[str, Any]]
23
+ required: List[str]
24
+
25
+ class FunctionDefinition(TypedDict):
26
+ """Definition of a function that can be called by the AI"""
27
+ name: str
28
+ description: str
29
+ parameters: FunctionParameters
30
+
31
+ @dataclass
32
+ class Tool:
33
+ """Tool class that can be passed to the provider"""
34
+ name: str
35
+ description: str
36
+ parameters: Dict[str, Dict[str, Any]]
37
+ required_params: List[str] = None
38
+ implementation: Optional[Callable] = None
39
+
40
+ def to_dict(self) -> ToolDefinition:
41
+ """Convert to OpenAI tool definition format"""
42
+ function_def = {
43
+ "name": self.name,
44
+ "description": self.description,
45
+ "parameters": {
46
+ "type": "object",
47
+ "properties": self.parameters,
48
+ "required": self.required_params or list(self.parameters.keys())
49
+ }
50
+ }
51
+
52
+ return {
53
+ "type": "function",
54
+ "function": function_def
55
+ }
56
+
57
+ def execute(self, arguments: Dict[str, Any]) -> Any:
58
+ """Execute the tool with the given arguments"""
59
+ if not self.implementation:
60
+ return f"Tool '{self.name}' does not have an implementation."
61
+
62
+ try:
63
+ return self.implementation(**arguments)
64
+ except Exception as e:
65
+ logger.error(f"Error executing tool '{self.name}': {str(e)}")
66
+ return f"Error executing tool '{self.name}': {str(e)}"
13
67
 
14
68
  class BaseCompletions(ABC):
15
69
  @abstractmethod
@@ -17,15 +71,101 @@ class BaseCompletions(ABC):
17
71
  self,
18
72
  *,
19
73
  model: str,
20
- messages: List[Dict[str, str]],
74
+ messages: List[Dict[str, Any]], # Changed to Any to support complex message structures
21
75
  max_tokens: Optional[int] = None,
22
76
  stream: bool = False,
23
77
  temperature: Optional[float] = None,
24
78
  top_p: Optional[float] = None,
79
+ tools: Optional[List[Union[Tool, Dict[str, Any]]]] = None, # Support for tool definitions
80
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None, # Support for tool_choice parameter
25
81
  **kwargs: Any
26
- ) -> Union[BaseChatCompletion, Generator[BaseChatCompletionChunk, None, None]]:
27
- """Abstract method to create chat completions."""
82
+ ) -> Union[ChatCompletion, Generator[ChatCompletionChunk, None, None]]:
83
+ """
84
+ Abstract method to create chat completions with tool support.
85
+
86
+ Args:
87
+ model: The model to use for completion
88
+ messages: List of message dictionaries
89
+ max_tokens: Maximum number of tokens to generate
90
+ stream: Whether to stream the response
91
+ temperature: Sampling temperature
92
+ top_p: Nucleus sampling parameter
93
+ tools: List of tool definitions available for the model to use
94
+ tool_choice: Control over which tool the model should use
95
+ **kwargs: Additional model-specific parameters
96
+
97
+ Returns:
98
+ Either a completion object or a generator of completion chunks if streaming
99
+ """
28
100
  raise NotImplementedError
101
+
102
+ def format_tool_calls(self, tools: List[Union[Tool, Dict[str, Any]]]) -> List[Dict[str, Any]]:
103
+ """Convert tools to the format expected by the provider"""
104
+ formatted_tools = []
105
+
106
+ for tool in tools:
107
+ if isinstance(tool, Tool):
108
+ formatted_tools.append(tool.to_dict())
109
+ elif isinstance(tool, dict):
110
+ # Assume already formatted correctly
111
+ formatted_tools.append(tool)
112
+ else:
113
+ logger.warning(f"Skipping invalid tool type: {type(tool)}")
114
+
115
+ return formatted_tools
116
+
117
+ def process_tool_calls(self, tool_calls: List[Dict[str, Any]], available_tools: Dict[str, Tool]) -> List[Dict[str, Any]]:
118
+ """
119
+ Process tool calls and execute the relevant tools.
120
+
121
+ Args:
122
+ tool_calls: List of tool calls from the model
123
+ available_tools: Dictionary mapping tool names to their implementations
124
+
125
+ Returns:
126
+ List of results from executing the tools
127
+ """
128
+ results = []
129
+
130
+ for call in tool_calls:
131
+ try:
132
+ function_call = call.get("function", {})
133
+ tool_name = function_call.get("name")
134
+ arguments_str = function_call.get("arguments", "{}")
135
+
136
+ # Parse arguments
137
+ try:
138
+ if isinstance(arguments_str, str):
139
+ arguments = json.loads(arguments_str)
140
+ else:
141
+ arguments = arguments_str
142
+ except json.JSONDecodeError:
143
+ results.append({
144
+ "tool_call_id": call.get("id"),
145
+ "result": f"Error: Could not parse arguments JSON: {arguments_str}"
146
+ })
147
+ continue
148
+
149
+ # Execute the tool if available
150
+ if tool_name in available_tools:
151
+ tool_result = available_tools[tool_name].execute(arguments)
152
+ results.append({
153
+ "tool_call_id": call.get("id"),
154
+ "result": str(tool_result)
155
+ })
156
+ else:
157
+ results.append({
158
+ "tool_call_id": call.get("id"),
159
+ "result": f"Error: Tool '{tool_name}' not found."
160
+ })
161
+ except Exception as e:
162
+ logger.error(f"Error processing tool call: {str(e)}")
163
+ results.append({
164
+ "tool_call_id": call.get("id", "unknown"),
165
+ "result": f"Error processing tool call: {str(e)}"
166
+ })
167
+
168
+ return results
29
169
 
30
170
 
31
171
  class BaseChat(ABC):
@@ -35,12 +175,75 @@ class BaseChat(ABC):
35
175
  class OpenAICompatibleProvider(ABC):
36
176
  """
37
177
  Abstract Base Class for providers mimicking the OpenAI Python client structure.
38
- Requires a nested 'chat.completions' structure.
178
+ Requires a nested 'chat.completions' structure with tool support.
39
179
  """
40
180
  chat: BaseChat
181
+ available_tools: Dict[str, Tool] = {} # Dictionary of available tools
182
+ supports_tools: bool = False # Whether the provider supports tools
183
+ supports_tool_choice: bool = False # Whether the provider supports tool_choice
41
184
 
42
185
  @abstractmethod
43
- def __init__(self, api_key: Optional[str] = None, **kwargs: Any):
44
- """Initialize the provider, potentially with an API key."""
186
+ def __init__(self, api_key: Optional[str] = None, tools: Optional[List[Tool]] = None, **kwargs: Any):
187
+ """
188
+ Initialize the provider, potentially with an API key and tools.
189
+
190
+ Args:
191
+ api_key: Optional API key for the provider
192
+ tools: Optional list of tools to make available to the provider
193
+ **kwargs: Additional provider-specific parameters
194
+ """
195
+ self.available_tools = {}
196
+ if tools:
197
+ self.register_tools(tools)
45
198
  raise NotImplementedError
46
199
 
200
+ @property
201
+ @abstractmethod
202
+ def models(self):
203
+ """
204
+ Property that returns an object with a .list() method returning available models.
205
+ Subclasses must implement this property.
206
+ """
207
+ pass
208
+
209
+ def register_tools(self, tools: List[Tool]) -> None:
210
+ """
211
+ Register tools with the provider.
212
+
213
+ Args:
214
+ tools: List of Tool objects to register
215
+ """
216
+ for tool in tools:
217
+ self.available_tools[tool.name] = tool
218
+
219
+ def get_tool_by_name(self, name: str) -> Optional[Tool]:
220
+ """Get a tool by name"""
221
+ return self.available_tools.get(name)
222
+
223
+ def format_tool_response(self, messages: List[Dict[str, Any]], tool_results: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
224
+ """
225
+ Format tool results as messages to be sent back to the provider.
226
+
227
+ Args:
228
+ messages: The original messages
229
+ tool_results: Results from executing tools
230
+
231
+ Returns:
232
+ Updated message list with tool results
233
+ """
234
+ updated_messages = messages.copy()
235
+
236
+ # Find the assistant message with tool calls
237
+ for i, msg in enumerate(reversed(updated_messages)):
238
+ if msg.get("role") == "assistant" and "tool_calls" in msg:
239
+ # For each tool result, add a tool message
240
+ for result in tool_results:
241
+ tool_message = {
242
+ "role": "tool",
243
+ "tool_call_id": result["tool_call_id"],
244
+ "content": result["result"]
245
+ }
246
+ updated_messages.append(tool_message)
247
+ break
248
+
249
+ return updated_messages