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.
- webscout/AIutel.py +2 -0
- webscout/Bard.py +12 -6
- webscout/DWEBS.py +66 -57
- webscout/Provider/{UNFINISHED → AISEARCH}/PERPLEXED_search.py +34 -74
- webscout/Provider/AISEARCH/__init__.py +18 -11
- webscout/Provider/AISEARCH/scira_search.py +3 -1
- webscout/Provider/Aitopia.py +2 -3
- webscout/Provider/Andi.py +3 -3
- webscout/Provider/ChatGPTClone.py +1 -1
- webscout/Provider/ChatSandbox.py +1 -0
- webscout/Provider/Cloudflare.py +1 -1
- webscout/Provider/Cohere.py +1 -0
- webscout/Provider/Deepinfra.py +13 -10
- webscout/Provider/ExaAI.py +1 -1
- webscout/Provider/ExaChat.py +1 -80
- webscout/Provider/Flowith.py +6 -1
- webscout/Provider/Gemini.py +7 -5
- webscout/Provider/GeminiProxy.py +1 -0
- webscout/Provider/GithubChat.py +4 -1
- webscout/Provider/Groq.py +1 -1
- webscout/Provider/HeckAI.py +8 -4
- webscout/Provider/Jadve.py +23 -38
- webscout/Provider/K2Think.py +308 -0
- webscout/Provider/Koboldai.py +8 -186
- webscout/Provider/LambdaChat.py +2 -4
- webscout/Provider/Nemotron.py +3 -4
- webscout/Provider/Netwrck.py +6 -8
- webscout/Provider/OLLAMA.py +1 -0
- webscout/Provider/OPENAI/Cloudflare.py +6 -7
- webscout/Provider/OPENAI/FalconH1.py +2 -7
- webscout/Provider/OPENAI/FreeGemini.py +6 -8
- webscout/Provider/OPENAI/{monochat.py → K2Think.py} +180 -77
- webscout/Provider/OPENAI/NEMOTRON.py +3 -6
- webscout/Provider/OPENAI/PI.py +5 -4
- webscout/Provider/OPENAI/Qwen3.py +2 -3
- webscout/Provider/OPENAI/README.md +2 -1
- webscout/Provider/OPENAI/TogetherAI.py +52 -57
- webscout/Provider/OPENAI/TwoAI.py +3 -4
- webscout/Provider/OPENAI/__init__.py +17 -56
- webscout/Provider/OPENAI/ai4chat.py +313 -303
- webscout/Provider/OPENAI/base.py +9 -29
- webscout/Provider/OPENAI/chatgpt.py +7 -2
- webscout/Provider/OPENAI/chatgptclone.py +4 -7
- webscout/Provider/OPENAI/chatsandbox.py +84 -59
- webscout/Provider/OPENAI/deepinfra.py +12 -6
- webscout/Provider/OPENAI/e2b.py +60 -8
- webscout/Provider/OPENAI/flowith.py +4 -3
- webscout/Provider/OPENAI/generate_api_key.py +48 -0
- webscout/Provider/OPENAI/heckai.py +4 -1
- webscout/Provider/OPENAI/netwrck.py +9 -12
- webscout/Provider/OPENAI/refact.py +274 -0
- webscout/Provider/OPENAI/scirachat.py +6 -0
- webscout/Provider/OPENAI/textpollinations.py +3 -14
- webscout/Provider/OPENAI/toolbaz.py +14 -10
- webscout/Provider/OpenGPT.py +1 -1
- webscout/Provider/Openai.py +150 -402
- webscout/Provider/PI.py +1 -0
- webscout/Provider/Perplexitylabs.py +1 -2
- webscout/Provider/QwenLM.py +107 -89
- webscout/Provider/STT/__init__.py +17 -2
- webscout/Provider/{Llama3.py → Sambanova.py} +9 -10
- webscout/Provider/StandardInput.py +1 -1
- webscout/Provider/TTI/__init__.py +18 -12
- webscout/Provider/TTI/bing.py +14 -2
- webscout/Provider/TTI/together.py +10 -9
- webscout/Provider/TTS/README.md +0 -1
- webscout/Provider/TTS/__init__.py +18 -11
- webscout/Provider/TTS/base.py +479 -159
- webscout/Provider/TTS/deepgram.py +409 -156
- webscout/Provider/TTS/elevenlabs.py +425 -111
- webscout/Provider/TTS/freetts.py +317 -140
- webscout/Provider/TTS/gesserit.py +192 -128
- webscout/Provider/TTS/murfai.py +248 -113
- webscout/Provider/TTS/openai_fm.py +347 -129
- webscout/Provider/TTS/speechma.py +620 -586
- webscout/Provider/TeachAnything.py +1 -0
- webscout/Provider/TextPollinationsAI.py +5 -15
- webscout/Provider/TogetherAI.py +136 -142
- webscout/Provider/TwoAI.py +53 -309
- webscout/Provider/TypliAI.py +2 -1
- webscout/Provider/{GizAI.py → UNFINISHED/GizAI.py} +1 -1
- webscout/Provider/UNFINISHED/VercelAIGateway.py +339 -0
- webscout/Provider/Venice.py +2 -1
- webscout/Provider/VercelAI.py +1 -0
- webscout/Provider/WiseCat.py +2 -1
- webscout/Provider/WrDoChat.py +2 -1
- webscout/Provider/__init__.py +18 -174
- webscout/Provider/ai4chat.py +1 -1
- webscout/Provider/akashgpt.py +7 -10
- webscout/Provider/cerebras.py +194 -38
- webscout/Provider/chatglm.py +170 -83
- webscout/Provider/cleeai.py +1 -2
- webscout/Provider/deepseek_assistant.py +1 -1
- webscout/Provider/elmo.py +1 -1
- webscout/Provider/geminiapi.py +1 -1
- webscout/Provider/granite.py +1 -1
- webscout/Provider/hermes.py +1 -3
- webscout/Provider/julius.py +1 -0
- webscout/Provider/learnfastai.py +1 -1
- webscout/Provider/llama3mitril.py +1 -1
- webscout/Provider/llmchat.py +1 -1
- webscout/Provider/llmchatco.py +1 -1
- webscout/Provider/meta.py +3 -3
- webscout/Provider/oivscode.py +2 -2
- webscout/Provider/scira_chat.py +51 -124
- webscout/Provider/searchchat.py +1 -0
- webscout/Provider/sonus.py +1 -1
- webscout/Provider/toolbaz.py +15 -11
- webscout/Provider/turboseek.py +31 -22
- webscout/Provider/typefully.py +2 -1
- webscout/Provider/x0gpt.py +1 -0
- webscout/Provider/yep.py +2 -1
- webscout/conversation.py +22 -20
- webscout/sanitize.py +14 -10
- webscout/scout/README.md +20 -23
- webscout/scout/core/crawler.py +125 -38
- webscout/scout/core/scout.py +26 -5
- webscout/tempid.py +6 -0
- webscout/version.py +1 -1
- webscout/webscout_search.py +13 -6
- webscout/webscout_search_async.py +10 -8
- webscout/yep_search.py +13 -5
- {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/METADATA +3 -1
- {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/RECORD +132 -155
- webscout/Provider/AllenAI.py +0 -440
- webscout/Provider/Blackboxai.py +0 -793
- webscout/Provider/FreeGemini.py +0 -250
- webscout/Provider/Glider.py +0 -225
- webscout/Provider/Hunyuan.py +0 -283
- webscout/Provider/MCPCore.py +0 -322
- webscout/Provider/MiniMax.py +0 -207
- webscout/Provider/OPENAI/BLACKBOXAI.py +0 -1045
- webscout/Provider/OPENAI/MiniMax.py +0 -298
- webscout/Provider/OPENAI/autoproxy.py +0 -1067
- webscout/Provider/OPENAI/c4ai.py +0 -394
- webscout/Provider/OPENAI/copilot.py +0 -305
- webscout/Provider/OPENAI/glider.py +0 -330
- webscout/Provider/OPENAI/mcpcore.py +0 -431
- webscout/Provider/OPENAI/multichat.py +0 -378
- webscout/Provider/Reka.py +0 -214
- webscout/Provider/TTS/sthir.py +0 -94
- webscout/Provider/UNFINISHED/fetch_together_models.py +0 -90
- webscout/Provider/asksteve.py +0 -220
- webscout/Provider/copilot.py +0 -422
- webscout/Provider/freeaichat.py +0 -294
- webscout/Provider/koala.py +0 -182
- webscout/Provider/lmarena.py +0 -198
- webscout/Provider/monochat.py +0 -275
- webscout/Provider/multichat.py +0 -375
- webscout/Provider/scnet.py +0 -244
- webscout/Provider/talkai.py +0 -194
- /webscout/Provider/{Marcus.py → UNFINISHED/Marcus.py} +0 -0
- /webscout/Provider/{Qodo.py → UNFINISHED/Qodo.py} +0 -0
- /webscout/Provider/{XenAI.py → UNFINISHED/XenAI.py} +0 -0
- /webscout/Provider/{samurai.py → UNFINISHED/samurai.py} +0 -0
- {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/WHEEL +0 -0
- {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/entry_points.txt +0 -0
- {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.3.5.dist-info → webscout-8.3.7.dist-info}/top_level.txt +0 -0
webscout/Provider/chatglm.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
55
|
+
model: str = "0727-106B-API",
|
|
31
56
|
):
|
|
32
|
-
"""Initializes the
|
|
33
|
-
self.session = 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':
|
|
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 = (
|
|
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
|
|
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
|
|
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
|
-
|
|
110
|
-
self.session.headers.update({'X-Device-Id': device_id})
|
|
141
|
+
api_key = self._get_api_key()
|
|
111
142
|
payload = {
|
|
112
|
-
"
|
|
113
|
-
"
|
|
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 = ""
|
|
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,
|
|
137
|
-
|
|
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
|
-
|
|
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),
|
|
194
|
+
data=response.iter_content(chunk_size=None),
|
|
144
195
|
intro_value="data:",
|
|
145
|
-
to_json=True,
|
|
146
|
-
content_extractor=
|
|
147
|
-
yield_raw_on_error=False
|
|
196
|
+
to_json=True,
|
|
197
|
+
content_extractor=glm_content_extractor,
|
|
198
|
+
yield_raw_on_error=False,
|
|
199
|
+
raw=False
|
|
148
200
|
)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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.
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
|
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(
|
|
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)
|
webscout/Provider/cleeai.py
CHANGED
|
@@ -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
webscout/Provider/geminiapi.py
CHANGED
webscout/Provider/granite.py
CHANGED
|
@@ -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__(
|
webscout/Provider/hermes.py
CHANGED
|
@@ -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,
|
webscout/Provider/julius.py
CHANGED
webscout/Provider/learnfastai.py
CHANGED
webscout/Provider/llmchat.py
CHANGED
webscout/Provider/llmchatco.py
CHANGED
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,
|
|
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
|
|
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,
|
webscout/Provider/oivscode.py
CHANGED
|
@@ -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,
|
|
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",
|