webscout 8.3.5__py3-none-any.whl → 8.3.7__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 (159) hide show
  1. webscout/AIutel.py +2 -0
  2. webscout/Bard.py +12 -6
  3. webscout/DWEBS.py +66 -57
  4. webscout/Provider/{UNFINISHED → AISEARCH}/PERPLEXED_search.py +34 -74
  5. webscout/Provider/AISEARCH/__init__.py +18 -11
  6. webscout/Provider/AISEARCH/scira_search.py +3 -1
  7. webscout/Provider/Aitopia.py +2 -3
  8. webscout/Provider/Andi.py +3 -3
  9. webscout/Provider/ChatGPTClone.py +1 -1
  10. webscout/Provider/ChatSandbox.py +1 -0
  11. webscout/Provider/Cloudflare.py +1 -1
  12. webscout/Provider/Cohere.py +1 -0
  13. webscout/Provider/Deepinfra.py +13 -10
  14. webscout/Provider/ExaAI.py +1 -1
  15. webscout/Provider/ExaChat.py +1 -80
  16. webscout/Provider/Flowith.py +6 -1
  17. webscout/Provider/Gemini.py +7 -5
  18. webscout/Provider/GeminiProxy.py +1 -0
  19. webscout/Provider/GithubChat.py +4 -1
  20. webscout/Provider/Groq.py +1 -1
  21. webscout/Provider/HeckAI.py +8 -4
  22. webscout/Provider/Jadve.py +23 -38
  23. webscout/Provider/K2Think.py +308 -0
  24. webscout/Provider/Koboldai.py +8 -186
  25. webscout/Provider/LambdaChat.py +2 -4
  26. webscout/Provider/Nemotron.py +3 -4
  27. webscout/Provider/Netwrck.py +6 -8
  28. webscout/Provider/OLLAMA.py +1 -0
  29. webscout/Provider/OPENAI/Cloudflare.py +6 -7
  30. webscout/Provider/OPENAI/FalconH1.py +2 -7
  31. webscout/Provider/OPENAI/FreeGemini.py +6 -8
  32. webscout/Provider/OPENAI/{monochat.py → K2Think.py} +180 -77
  33. webscout/Provider/OPENAI/NEMOTRON.py +3 -6
  34. webscout/Provider/OPENAI/PI.py +5 -4
  35. webscout/Provider/OPENAI/Qwen3.py +2 -3
  36. webscout/Provider/OPENAI/README.md +2 -1
  37. webscout/Provider/OPENAI/TogetherAI.py +52 -57
  38. webscout/Provider/OPENAI/TwoAI.py +3 -4
  39. webscout/Provider/OPENAI/__init__.py +17 -56
  40. webscout/Provider/OPENAI/ai4chat.py +313 -303
  41. webscout/Provider/OPENAI/base.py +9 -29
  42. webscout/Provider/OPENAI/chatgpt.py +7 -2
  43. webscout/Provider/OPENAI/chatgptclone.py +4 -7
  44. webscout/Provider/OPENAI/chatsandbox.py +84 -59
  45. webscout/Provider/OPENAI/deepinfra.py +12 -6
  46. webscout/Provider/OPENAI/e2b.py +60 -8
  47. webscout/Provider/OPENAI/flowith.py +4 -3
  48. webscout/Provider/OPENAI/generate_api_key.py +48 -0
  49. webscout/Provider/OPENAI/heckai.py +4 -1
  50. webscout/Provider/OPENAI/netwrck.py +9 -12
  51. webscout/Provider/OPENAI/refact.py +274 -0
  52. webscout/Provider/OPENAI/scirachat.py +6 -0
  53. webscout/Provider/OPENAI/textpollinations.py +3 -14
  54. webscout/Provider/OPENAI/toolbaz.py +14 -10
  55. webscout/Provider/OpenGPT.py +1 -1
  56. webscout/Provider/Openai.py +150 -402
  57. webscout/Provider/PI.py +1 -0
  58. webscout/Provider/Perplexitylabs.py +1 -2
  59. webscout/Provider/QwenLM.py +107 -89
  60. webscout/Provider/STT/__init__.py +17 -2
  61. webscout/Provider/{Llama3.py → Sambanova.py} +9 -10
  62. webscout/Provider/StandardInput.py +1 -1
  63. webscout/Provider/TTI/__init__.py +18 -12
  64. webscout/Provider/TTI/bing.py +14 -2
  65. webscout/Provider/TTI/together.py +10 -9
  66. webscout/Provider/TTS/README.md +0 -1
  67. webscout/Provider/TTS/__init__.py +18 -11
  68. webscout/Provider/TTS/base.py +479 -159
  69. webscout/Provider/TTS/deepgram.py +409 -156
  70. webscout/Provider/TTS/elevenlabs.py +425 -111
  71. webscout/Provider/TTS/freetts.py +317 -140
  72. webscout/Provider/TTS/gesserit.py +192 -128
  73. webscout/Provider/TTS/murfai.py +248 -113
  74. webscout/Provider/TTS/openai_fm.py +347 -129
  75. webscout/Provider/TTS/speechma.py +620 -586
  76. webscout/Provider/TeachAnything.py +1 -0
  77. webscout/Provider/TextPollinationsAI.py +5 -15
  78. webscout/Provider/TogetherAI.py +136 -142
  79. webscout/Provider/TwoAI.py +53 -309
  80. webscout/Provider/TypliAI.py +2 -1
  81. webscout/Provider/{GizAI.py → UNFINISHED/GizAI.py} +1 -1
  82. webscout/Provider/UNFINISHED/VercelAIGateway.py +339 -0
  83. webscout/Provider/Venice.py +2 -1
  84. webscout/Provider/VercelAI.py +1 -0
  85. webscout/Provider/WiseCat.py +2 -1
  86. webscout/Provider/WrDoChat.py +2 -1
  87. webscout/Provider/__init__.py +18 -174
  88. webscout/Provider/ai4chat.py +1 -1
  89. webscout/Provider/akashgpt.py +7 -10
  90. webscout/Provider/cerebras.py +194 -38
  91. webscout/Provider/chatglm.py +170 -83
  92. webscout/Provider/cleeai.py +1 -2
  93. webscout/Provider/deepseek_assistant.py +1 -1
  94. webscout/Provider/elmo.py +1 -1
  95. webscout/Provider/geminiapi.py +1 -1
  96. webscout/Provider/granite.py +1 -1
  97. webscout/Provider/hermes.py +1 -3
  98. webscout/Provider/julius.py +1 -0
  99. webscout/Provider/learnfastai.py +1 -1
  100. webscout/Provider/llama3mitril.py +1 -1
  101. webscout/Provider/llmchat.py +1 -1
  102. webscout/Provider/llmchatco.py +1 -1
  103. webscout/Provider/meta.py +3 -3
  104. webscout/Provider/oivscode.py +2 -2
  105. webscout/Provider/scira_chat.py +51 -124
  106. webscout/Provider/searchchat.py +1 -0
  107. webscout/Provider/sonus.py +1 -1
  108. webscout/Provider/toolbaz.py +15 -11
  109. webscout/Provider/turboseek.py +31 -22
  110. webscout/Provider/typefully.py +2 -1
  111. webscout/Provider/x0gpt.py +1 -0
  112. webscout/Provider/yep.py +2 -1
  113. webscout/conversation.py +22 -20
  114. webscout/sanitize.py +14 -10
  115. webscout/scout/README.md +20 -23
  116. webscout/scout/core/crawler.py +125 -38
  117. webscout/scout/core/scout.py +26 -5
  118. webscout/tempid.py +6 -0
  119. webscout/version.py +1 -1
  120. webscout/webscout_search.py +13 -6
  121. webscout/webscout_search_async.py +10 -8
  122. webscout/yep_search.py +13 -5
  123. {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/METADATA +3 -1
  124. {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/RECORD +132 -155
  125. webscout/Provider/AllenAI.py +0 -440
  126. webscout/Provider/Blackboxai.py +0 -793
  127. webscout/Provider/FreeGemini.py +0 -250
  128. webscout/Provider/Glider.py +0 -225
  129. webscout/Provider/Hunyuan.py +0 -283
  130. webscout/Provider/MCPCore.py +0 -322
  131. webscout/Provider/MiniMax.py +0 -207
  132. webscout/Provider/OPENAI/BLACKBOXAI.py +0 -1045
  133. webscout/Provider/OPENAI/MiniMax.py +0 -298
  134. webscout/Provider/OPENAI/autoproxy.py +0 -1067
  135. webscout/Provider/OPENAI/c4ai.py +0 -394
  136. webscout/Provider/OPENAI/copilot.py +0 -305
  137. webscout/Provider/OPENAI/glider.py +0 -330
  138. webscout/Provider/OPENAI/mcpcore.py +0 -431
  139. webscout/Provider/OPENAI/multichat.py +0 -378
  140. webscout/Provider/Reka.py +0 -214
  141. webscout/Provider/TTS/sthir.py +0 -94
  142. webscout/Provider/UNFINISHED/fetch_together_models.py +0 -90
  143. webscout/Provider/asksteve.py +0 -220
  144. webscout/Provider/copilot.py +0 -422
  145. webscout/Provider/freeaichat.py +0 -294
  146. webscout/Provider/koala.py +0 -182
  147. webscout/Provider/lmarena.py +0 -198
  148. webscout/Provider/monochat.py +0 -275
  149. webscout/Provider/multichat.py +0 -375
  150. webscout/Provider/scnet.py +0 -244
  151. webscout/Provider/talkai.py +0 -194
  152. /webscout/Provider/{Marcus.py → UNFINISHED/Marcus.py} +0 -0
  153. /webscout/Provider/{Qodo.py → UNFINISHED/Qodo.py} +0 -0
  154. /webscout/Provider/{XenAI.py → UNFINISHED/XenAI.py} +0 -0
  155. /webscout/Provider/{samurai.py → UNFINISHED/samurai.py} +0 -0
  156. {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/WHEEL +0 -0
  157. {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/entry_points.txt +0 -0
  158. {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/licenses/LICENSE.md +0 -0
  159. {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,7 @@
1
1
  from curl_cffi import CurlError
2
2
  from curl_cffi.requests import Session
3
- import json
4
3
  from typing import Any, Dict, Optional, Generator, List, Union
5
4
  import uuid
6
-
7
5
  from webscout.AIutel import Optimizers
8
6
  from webscout.AIutel import Conversation
9
7
  from webscout.AIutel import AwesomePrompts, sanitize_stream # Import sanitize_stream
@@ -11,11 +9,38 @@ from webscout.AIbase import Provider
11
9
  from webscout import exceptions
12
10
  from webscout.litagent import LitAgent
13
11
 
12
+
14
13
  class ChatGLM(Provider):
15
14
  """
16
- A class to interact with the ChatGLM API.
15
+ A class to interact with the Z.AI Chat API (GLM-4.5).
17
16
  """
17
+ required_auth = False
18
+ url = "https://chat.z.ai"
19
+ # Model nickname mapping system
20
+ MODEL_MAPPING = {
21
+ "glm-4.5V": "glm-4.5v",
22
+ "glm-4-32B": "main_chat",
23
+ "glm-4.5-Air": "0727-106B-API",
24
+ "glm-4.5": "0727-360B-API",
25
+ # Add more nicknames as needed
26
+ }
27
+ # Reverse mapping: API format to nickname
28
+ GLM_TO_MODEL = {v: k for k, v in MODEL_MAPPING.items()}
29
+ AVAILABLE_MODELS = list(MODEL_MAPPING.keys()) + list(GLM_TO_MODEL.keys()) + ["0727-106B-API", "0727-360B-API", "glm-4.5v", "main_chat"]
18
30
 
31
+ @classmethod
32
+ def _resolve_model(cls, model: str) -> str:
33
+ """
34
+ Resolve a model nickname or API name to the API format.
35
+ """
36
+ if model in cls.GLM_TO_MODEL:
37
+ return model
38
+ if model in cls.MODEL_MAPPING:
39
+ return cls.MODEL_MAPPING[model]
40
+ # fallback to direct API name if present
41
+ if model in ["0727-106B-API", "0727-360B-API", "glm-4.5v", "main_chat"]:
42
+ return model
43
+ raise ValueError(f"Invalid model: {model}. Choose from: {cls.AVAILABLE_MODELS}")
19
44
  def __init__(
20
45
  self,
21
46
  is_conversation: bool = True,
@@ -27,36 +52,32 @@ class ChatGLM(Provider):
27
52
  proxies: dict = {},
28
53
  history_offset: int = 10250,
29
54
  act: str = None,
30
- plus_model: bool = True,
55
+ model: str = "0727-106B-API",
31
56
  ):
32
- """Initializes the ChatGLM API client."""
33
- self.session = Session() # Use curl_cffi Session
57
+ """Initializes the Z.AI Chat API client."""
58
+ self.session = Session()
34
59
  self.is_conversation = is_conversation
35
60
  self.max_tokens_to_sample = max_tokens
36
- self.api_endpoint = "https://chatglm.cn/chatglm/mainchat-api/guest/stream"
37
- self.stream_chunk_size = 64
38
61
  self.timeout = timeout
39
62
  self.last_response = {}
40
- self.plus_model = plus_model
41
63
  self.headers = {
42
64
  'Accept-Language': 'en-US,en;q=0.9',
43
65
  'App-Name': 'chatglm',
44
- 'Authorization': 'undefined',
45
66
  'Content-Type': 'application/json',
46
- 'Origin': 'https://chatglm.cn',
67
+ 'Origin': self.url,
47
68
  'User-Agent': LitAgent().random(),
48
69
  'X-App-Platform': 'pc',
49
70
  'X-App-Version': '0.0.1',
50
- 'X-Device-Id': '', #Will be generated each time
51
71
  'Accept': 'text/event-stream',
52
72
  }
73
+ self.api_endpoint = f"{self.url}/api/chat/completions"
53
74
  self.__available_optimizers = (
54
75
  method
55
76
  for method in dir(Optimizers)
56
77
  if callable(getattr(Optimizers, method)) and not method.startswith("__")
57
78
  )
58
79
  self.session.headers.update(self.headers)
59
- Conversation.intro = ( # type: ignore
80
+ Conversation.intro = (
60
81
  AwesomePrompts().get_act(
61
82
  act, raise_not_found=True, default=None, case_insensitive=True
62
83
  )
@@ -67,16 +88,26 @@ class ChatGLM(Provider):
67
88
  is_conversation, self.max_tokens_to_sample, filepath, update_file
68
89
  )
69
90
  self.conversation.history_offset = history_offset
70
- self.session.proxies = proxies # Assign proxies directly
91
+ self.session.proxies = proxies
92
+ # Use nickname resolution for model
93
+ self.model = self._resolve_model(model)
94
+
95
+ def _get_api_key(self):
96
+ if not hasattr(self, 'api_key') or not self.api_key:
97
+ response = self.session.get(f"{self.url}/api/v1/auths/")
98
+ self.api_key = response.json().get("token")
99
+ return self.api_key
100
+
101
+ def _get_cookie(self):
102
+ """Get authentication cookie from the site"""
103
+ if not hasattr(self, 'cookie') or not self.cookie:
104
+ response = self.session.get(f"{self.url}/")
105
+ self.cookie = response.headers.get('Set-Cookie', '')
106
+ return self.cookie
107
+
108
+
109
+ # _zai_extractor removed; use extract_regexes in sanitize_stream
71
110
 
72
- @staticmethod
73
- def _chatglm_extractor(chunk: Union[str, Dict[str, Any]]) -> Optional[str]:
74
- """Extracts content from ChatGLM stream JSON objects."""
75
- if isinstance(chunk, dict):
76
- parts = chunk.get('parts', [])
77
- if parts and isinstance(parts[0].get('content'), list) and parts[0]['content']:
78
- return parts[0]['content'][0].get('text')
79
- return None
80
111
 
81
112
  def ask(
82
113
  self,
@@ -86,13 +117,14 @@ class ChatGLM(Provider):
86
117
  optimizer: str = None,
87
118
  conversationally: bool = False,
88
119
  ) -> Union[Dict[str, Any], Generator[Any, None, None]]:
89
- """Chat with AI
120
+ """Chat with Z.AI API
90
121
  Args:
91
122
  prompt (str): Prompt to be sent.
92
123
  stream (bool, optional): Flag for streaming response. Defaults to False.
93
124
  raw (bool, optional): Stream back raw response as received. Defaults to False.
94
- optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
125
+ optimizer (str, optional): Prompt optimizer name. Defaults to None.
95
126
  conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
127
+ model (str, optional): Model name. Defaults to None.
96
128
  Returns:
97
129
  Union[Dict, Generator[Dict, None, None]]: Response generated
98
130
  """
@@ -106,110 +138,165 @@ class ChatGLM(Provider):
106
138
  raise exceptions.FailedToGenerateResponseError(
107
139
  f"Optimizer is not one of {self.__available_optimizers}"
108
140
  )
109
- device_id = str(uuid.uuid4()).replace('-', '')
110
- self.session.headers.update({'X-Device-Id': device_id})
141
+ api_key = self._get_api_key()
111
142
  payload = {
112
- "assistant_id": "65940acff94777010aa6b796",
113
- "conversation_id": "",
114
- "meta_data": {
115
- "if_plus_model": self.plus_model,
116
- "is_test": False,
117
- "input_question_type": "xxxx",
118
- "channel": "",
119
- "draft_id": "",
120
- "quote_log_id": "",
121
- "platform": "pc",
122
- },
143
+ "stream": True,
144
+ "model": self.model, # Already resolved to API format
123
145
  "messages": [
124
- {
125
- "role": "user",
126
- "content": [{"type": "text", "text": conversation_prompt}],
127
- }
146
+ {"role": "user", "content": conversation_prompt}
128
147
  ],
148
+ "params": {},
149
+ "features": {"image_generation": False, "web_search": False, "auto_web_search": False, "preview_mode": True, "flags": [], "features": [{"type": "mcp", "server": "vibe-coding", "status": "hidden"}, {"type": "mcp", "server": "ppt-maker", "status": "hidden"}, {"type": "mcp", "server": "image-search", "status": "hidden"}], "enable_thinking": True},
150
+ "actions": [],
151
+ "tags": [],
152
+ "chat_id": "local",
153
+ "id": str(uuid.uuid4())
129
154
  }
130
155
 
131
156
  def for_stream():
132
- streaming_text = "" # Initialize outside try block
133
- last_processed_content = "" # Track the last processed content
157
+ streaming_text = ""
134
158
  try:
159
+ cookie = self._get_cookie()
135
160
  response = self.session.post(
136
- self.api_endpoint, json=payload, stream=True, timeout=self.timeout,
137
- impersonate="chrome120" # Add impersonate
161
+ self.api_endpoint,
162
+ json=payload,
163
+ stream=True,
164
+ timeout=self.timeout,
165
+ impersonate="chrome120",
166
+ headers={
167
+ "Authorization": f"Bearer {api_key}",
168
+ "x-fe-version": "prod-fe-1.0.70",
169
+ }
138
170
  )
139
171
  response.raise_for_status()
140
172
 
141
- # Use sanitize_stream
173
+ def glm_content_extractor(chunk):
174
+ if not isinstance(chunk, dict) or chunk.get("type") != "chat:completion":
175
+ return None
176
+ data = chunk.get("data", {})
177
+ phase = data.get("phase")
178
+ usage = data.get("usage")
179
+ if usage:
180
+ return None
181
+ delta_content = data.get("delta_content")
182
+ if delta_content:
183
+ if phase == "thinking":
184
+ # Remove details/summary tags if present
185
+ split_text = delta_content.split("</summary>\n>")[-1]
186
+ return {"reasoning_content": split_text}
187
+ elif phase == "answer":
188
+ return {"content": delta_content}
189
+ else:
190
+ return {"content": delta_content}
191
+ return None
192
+
142
193
  processed_stream = sanitize_stream(
143
- data=response.iter_content(chunk_size=None), # Pass byte iterator
194
+ data=response.iter_content(chunk_size=None),
144
195
  intro_value="data:",
145
- to_json=True, # Stream sends JSON
146
- content_extractor=self._chatglm_extractor, # Use the specific extractor
147
- yield_raw_on_error=False # Skip non-JSON lines or lines where extractor fails
196
+ to_json=True,
197
+ content_extractor=glm_content_extractor,
198
+ yield_raw_on_error=False,
199
+ raw=False
148
200
  )
149
-
150
- for current_full_text in processed_stream:
151
- # current_full_text is the full text extracted by _chatglm_extractor
152
- if current_full_text and isinstance(current_full_text, str):
153
- new_text = current_full_text[len(last_processed_content):]
154
- if new_text: # Check for new content
155
- streaming_text += new_text
156
- last_processed_content = current_full_text # Update tracker
157
- yield new_text if raw else dict(text=new_text)
158
-
201
+ last_content = ""
202
+ last_reasoning = ""
203
+ in_think = False
204
+ for chunk in processed_stream:
205
+ if not chunk:
206
+ continue
207
+ content = chunk.get('content') if isinstance(chunk, dict) else None
208
+ reasoning = chunk.get('reasoning_content') if isinstance(chunk, dict) else None
209
+ # Handle reasoning_content with <think> tags
210
+ if reasoning and reasoning != last_reasoning:
211
+ if not in_think:
212
+ yield "<think>\n\n"
213
+ in_think = True
214
+ yield reasoning
215
+ last_reasoning = reasoning
216
+ # If we were in <think> and now have new content, close <think>
217
+ if in_think and content and content != last_content:
218
+ yield "\n</think>\n\n"
219
+ in_think = False
220
+ # Handle normal content
221
+ if content and content != last_content:
222
+ yield content
223
+ streaming_text += content
224
+ last_content = content
225
+ if not raw:
226
+ self.last_response = {"text": content}
227
+ self.conversation.update_chat_history(prompt, streaming_text)
159
228
  except CurlError as e:
160
- raise exceptions.ProviderConnectionError(f"Request failed (CurlError): {e}") from e
229
+ raise exceptions.APIConnectionError(f"Request failed (CurlError): {e}") from e
161
230
  except Exception as e:
162
231
  raise exceptions.FailedToGenerateResponseError(f"An unexpected error occurred ({type(e).__name__}): {e}") from e
163
- finally:
164
- # Update history after stream finishes or fails
165
- if streaming_text:
166
- self.last_response.update(dict(text=streaming_text))
167
- self.conversation.update_chat_history(
168
- prompt, self.get_message(self.last_response)
169
- )
170
232
 
171
233
  def for_non_stream():
172
- for _ in for_stream():
173
- pass
174
- return self.last_response
234
+ full_text = ""
235
+ try:
236
+ for chunk_data in for_stream():
237
+ if raw:
238
+ if isinstance(chunk_data, str):
239
+ full_text += chunk_data
240
+ else:
241
+ if isinstance(chunk_data, dict) and "text" in chunk_data:
242
+ full_text += chunk_data["text"]
243
+ except Exception as e:
244
+ if not full_text:
245
+ raise exceptions.FailedToGenerateResponseError(f"Failed to get non-stream response: {str(e)}") from e
246
+ self.last_response = {"text": full_text}
247
+ return full_text if raw else self.last_response
175
248
  return for_stream() if stream else for_non_stream()
176
249
 
250
+
177
251
  def chat(
178
252
  self,
179
253
  prompt: str,
180
254
  stream: bool = False,
181
255
  optimizer: str = None,
182
256
  conversationally: bool = False,
257
+ raw: bool = False,
183
258
  ) -> Union[str, Generator[str, None, None]]:
184
259
  """Generate response `str`"""
185
260
 
186
261
  def for_stream():
187
262
  for response in self.ask(
188
- prompt, True, optimizer=optimizer, conversationally=conversationally
263
+ prompt, True, raw=raw, optimizer=optimizer, conversationally=conversationally
189
264
  ):
190
- yield self.get_message(response)
265
+ if raw:
266
+ yield response
267
+ else:
268
+ # Only call get_message on dicts, yield str directly
269
+ if isinstance(response, dict):
270
+ yield self.get_message(response)
271
+ elif isinstance(response, str):
272
+ yield response
191
273
 
192
274
  def for_non_stream():
193
- return self.get_message(
194
- self.ask(
195
- prompt,
196
- False,
197
- optimizer=optimizer,
198
- conversationally=conversationally,
199
- )
275
+ result = self.ask(
276
+ prompt,
277
+ False,
278
+ raw=raw,
279
+ optimizer=optimizer,
280
+ conversationally=conversationally,
200
281
  )
282
+ if raw:
283
+ return result if isinstance(result, str) else self.get_message(result)
284
+ else:
285
+ return self.get_message(result)
201
286
 
202
287
  return for_stream() if stream else for_non_stream()
203
288
 
289
+
204
290
  def get_message(self, response: dict) -> str:
205
291
  """Retrieves message only from response"""
206
292
  assert isinstance(response, dict), "Response should be of dict data-type only"
207
- return response["text"]
293
+ return response.get("text", "")
294
+
208
295
 
209
296
 
210
297
  if __name__ == "__main__":
211
298
  from rich import print
212
- ai = ChatGLM()
213
- response = ai.chat(input(">>> "), stream=True)
299
+ ai = ChatGLM(model="glm-4-32B")
300
+ response = ai.chat("hi", stream=True, raw=False)
214
301
  for chunk in response:
215
302
  print(chunk, end="", flush=True)
@@ -1,5 +1,4 @@
1
1
  import requests
2
- import json
3
2
  from uuid import uuid4
4
3
 
5
4
  from webscout.AIutel import Optimizers
@@ -12,7 +11,7 @@ class Cleeai(Provider):
12
11
  """
13
12
  A class to interact with the Cleeai.com API.
14
13
  """
15
-
14
+ required_auth = False
16
15
  def __init__(
17
16
  self,
18
17
  is_conversation: bool = True,
@@ -31,7 +31,7 @@ class DeepSeekAssistant(Provider):
31
31
  """
32
32
 
33
33
  AVAILABLE_MODELS = ["V3 model", "R1 model"]
34
-
34
+ required_auth = False
35
35
  @staticmethod
36
36
  def _deepseek_assistant_extractor(chunk: Union[str, Dict[str, Any]]) -> Optional[str]:
37
37
  """Extracts content from DeepSeek Assistant stream JSON objects."""
webscout/Provider/elmo.py CHANGED
@@ -15,7 +15,7 @@ class Elmo(Provider):
15
15
  """
16
16
  A class to interact with the Elmo.chat API.
17
17
  """
18
-
18
+ required_auth = False
19
19
  def __init__(
20
20
  self,
21
21
  is_conversation: bool = True,
@@ -19,7 +19,7 @@ class GEMINIAPI(Provider):
19
19
  """
20
20
  A class to interact with the Gemini API using the google-generativeai library.
21
21
  """
22
-
22
+ required_auth = True
23
23
  def __init__(
24
24
  self,
25
25
  api_key,
@@ -13,7 +13,7 @@ class IBMGranite(Provider):
13
13
  A class to interact with the IBM Granite API (accessed via d18n68ssusgr7r.cloudfront.net)
14
14
  using Lit agent for the user agent.
15
15
  """
16
-
16
+ required_auth = False
17
17
  AVAILABLE_MODELS = ["granite-3-8b-instruct", "granite-3-2-8b-instruct", "granite-3-3-8b-instruct"]
18
18
 
19
19
  def __init__(
@@ -2,20 +2,18 @@ from curl_cffi.requests import Session
2
2
  from curl_cffi import CurlError
3
3
  import json
4
4
  from typing import Union, Any, Dict, Generator, Optional
5
-
6
5
  from webscout.AIutel import Optimizers
7
6
  from webscout.AIutel import Conversation, sanitize_stream # Import sanitize_stream
8
7
  from webscout.AIutel import AwesomePrompts
9
8
  from webscout.AIbase import Provider
10
9
  from webscout import exceptions
11
- from webscout.litagent import LitAgent
12
10
  class NousHermes(Provider):
13
11
  """
14
12
  A class to interact with the Hermes API.
15
13
  """
16
14
 
17
15
  AVAILABLE_MODELS = ["Hermes-3-Llama-3.1-70B", "Hermes-3-Llama-3.1-8B"]
18
-
16
+ required_auth = False
19
17
  def __init__(
20
18
  self,
21
19
  cookies_path: str,
@@ -12,6 +12,7 @@ from typing import Union, Any, AsyncGenerator, Dict
12
12
 
13
13
 
14
14
  class Julius(Provider):
15
+ required_auth = True
15
16
  AVAILABLE_MODELS = [
16
17
  "Llama 3",
17
18
  "GPT-4o",
@@ -16,7 +16,7 @@ class LearnFast(Provider):
16
16
  """
17
17
  A class to interact with the LearnFast.ai API.
18
18
  """
19
-
19
+ required_auth = False
20
20
  def __init__(
21
21
  self,
22
22
  is_conversation: bool = True,
@@ -13,7 +13,7 @@ class Llama3Mitril(Provider):
13
13
  """
14
14
  A class to interact with the Llama3 Mitril API. Implements the WebScout provider interface.
15
15
  """
16
-
16
+ required_auth = False
17
17
  def __init__(
18
18
  self,
19
19
  is_conversation: bool = True,
@@ -14,7 +14,7 @@ class LLMChat(Provider):
14
14
  """
15
15
  A class to interact with the LLMChat API
16
16
  """
17
-
17
+ required_auth = False
18
18
  AVAILABLE_MODELS = [
19
19
  "@cf/meta/llama-3.1-70b-instruct",
20
20
  "@cf/meta/llama-3.1-8b-instruct",
@@ -16,7 +16,7 @@ class LLMChatCo(Provider):
16
16
  """
17
17
  A class to interact with the LLMChat.co API
18
18
  """
19
-
19
+ required_auth = False
20
20
  AVAILABLE_MODELS = [
21
21
  "gemini-flash-2.0", # Default model
22
22
  "llama-4-scout",
webscout/Provider/meta.py CHANGED
@@ -3,7 +3,7 @@ import logging
3
3
  import time
4
4
  import urllib
5
5
  import uuid
6
- from typing import Dict, Generator, Iterator, List, Union
6
+ from typing import Dict, Generator, List, Union
7
7
 
8
8
  import random
9
9
  from curl_cffi import CurlError
@@ -12,7 +12,7 @@ from webscout.scout import Scout
12
12
 
13
13
  from webscout.AIutel import Optimizers
14
14
  from webscout.AIutel import Conversation
15
- from webscout.AIutel import AwesomePrompts, sanitize_stream
15
+ from webscout.AIutel import AwesomePrompts
16
16
  from webscout.AIbase import Provider
17
17
  from webscout import exceptions
18
18
  from webscout.litagent import LitAgent as Lit
@@ -299,7 +299,7 @@ class Meta(Provider):
299
299
  A class to interact with the Meta AI API to obtain and use access tokens for sending
300
300
  and receiving messages from the Meta AI Chat API.
301
301
  """
302
-
302
+ required_auth = False
303
303
  def __init__(
304
304
  self,
305
305
  fb_email: str = None,
@@ -1,9 +1,8 @@
1
1
  import secrets
2
2
  import requests
3
- import json
4
3
  import random
5
4
  import string
6
- from typing import Union, Any, Dict, Optional, Generator
5
+ from typing import Union, Any, Dict, Generator
7
6
 
8
7
  from webscout.AIutel import Optimizers
9
8
  from webscout.AIutel import Conversation
@@ -16,6 +15,7 @@ class oivscode(Provider):
16
15
  """
17
16
  A class to interact with a test API.
18
17
  """
18
+ required_auth = False
19
19
  AVAILABLE_MODELS = [
20
20
  "*",
21
21
  "Qwen/Qwen2.5-72B-Instruct-Turbo",