返回提交历史
Deleted
g4f/Provider/GLM.py
+0
-289
XFEstudio/gpt4free
Delete old GLM
562b1e17
代码差异
1 个文件
+0
-289
@@ -1,289 +0,0 @@
1
from __future__ import annotations
2
3
import os
4
import json
5
import time
6
import hashlib
7
import uuid
8
import requests
9
import urllib.parse
10
11
from ..typing import AsyncResult, Messages
12
from ..providers.response import Usage, Reasoning
13
from ..requests import StreamSession, raise_for_status
14
from ..errors import ModelNotFoundError, ProviderException
15
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin
16
from .helper import get_last_user_message
17
18
class GLM(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
19
url = "https://chat.z.ai"
20
api_endpoint = "https://chat.z.ai/api/chat/completions"
21
working = True
22
active_by_default = True
23
default_model = "GLM-4.5"
24
25
api_key = None
26
auth_user_id = None
27
28
@classmethod
29
def _build_url_params(cls, token: str, user_id: str) -> str:
30
"""Build URL query parameters including browser fingerprint data."""
31
current_time = str(int(time.time() * 1000))
32
request_id = str(uuid.uuid1())
33
34
params = {
35
"timestamp": current_time,
36
"requestId": request_id,
37
"user_id": user_id or "",
38
"version": "0.0.1",
39
"platform": "web",
40
"token": token,
41
"user_agent": (
42
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
43
"AppleWebKit/537.36 (KHTML, like Gecko) "
44
"Chrome/130.0.0.0 Safari/537.36"
45
),
46
"language": "en-US",
47
"languages": "en-US,en",
48
"timezone": "America/New_York",
49
"cookie_enabled": "true",
50
"screen_width": "1920",
51
"screen_height": "1080",
52
"screen_resolution": "1920x1080",
53
"viewport_height": "900",
54
"viewport_width": "1440",
55
"viewport_size": "1440x900",
56
"color_depth": "24",
57
"pixel_ratio": "1",
58
"current_url": "https://chat.z.ai/",
59
"pathname": "/",
60
"search": "",
61
"hash": "",
62
"host": "chat.z.ai",
63
"hostname": "chat.z.ai",
64
"protocol": "https:",
65
"referrer": "",
66
"title": "Z.ai",
67
"timezone_offset": str(-(time.timezone if time.daylight == 0 else time.altzone) // 60),
68
"local_time": time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime()),
69
"utc_time": time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime()),
70
"is_mobile": "false",
71
"is_touch": "false",
72
"max_touch_points": "0",
73
"browser_name": "Chrome",
74
"os_name": "Windows",
75
}
76
77
return urllib.parse.urlencode(params)
78
79
@classmethod
80
def _compute_signature(cls, body_json: str) -> str:
81
"""Compute x-signature as SHA-256 hex digest of the serialised request body."""
82
return hashlib.sha256(body_json.encode("utf-8")).hexdigest()
83
84
@classmethod
85
def get_auth_from_cache(cls):
86
cache_file_path = cls.get_cache_file()
87
if cache_file_path.is_file():
88
file_mtime = cache_file_path.stat().st_mtime
89
if time.time() - file_mtime < 5 * 60:
90
try:
91
with open(cache_file_path, 'r') as f:
92
return json.load(f)
93
except (json.JSONDecodeError, IOError):
94
try:
95
os.remove(cache_file_path)
96
except OSError:
97
pass
98
return None
99
100
@classmethod
101
def save_auth_to_cache(cls, data):
102
cache_file_path = cls.get_cache_file()
103
with cache_file_path.open('w') as f:
104
json.dump(data, f)
105
106
@classmethod
107
def get_models(cls, **kwargs) -> list:
108
if not cls.models:
109
response = requests.get(f"{cls.url}/api/v1/auths/")
110
auth_data = response.json()
111
cls.api_key = auth_data.get("token")
112
cls.auth_user_id = auth_data.get("id", "")
113
response = requests.get(
114
f"{cls.url}/api/models",
115
headers={"Authorization": f"Bearer {cls.api_key}"}
116
)
117
items = response.json().get("data", [])
118
cls.model_aliases = {
119
item.get("name", "").replace("\u4efb\u52a1\u4e13\u7528", "ChatGLM"): item.get("id")
120
for item in items
121
}
122
cls.models = list(cls.model_aliases.keys())
123
return cls.models
124
125
@classmethod
126
def get_last_user_message_content(cls, messages):
127
for message in reversed(messages):
128
if message.get('role') == 'user':
129
return message.get('content', '')
130
return ''
131
132
@classmethod
133
async def create_async_generator(
134
cls,
135
model: str,
136
messages: Messages,
137
proxy: str = None,
138
reasoning_effort: str = "max",
139
enable_thinking: bool = True,
140
web_search: bool = False,
141
**kwargs
142
) -> AsyncResult:
143
cls.get_models()
144
try:
145
model = cls.get_model(model)
146
except ModelNotFoundError:
147
pass
148
149
if not cls.api_key:
150
raise ProviderException("Failed to obtain API key from Z.ai authentication endpoint")
151
152
# Build the request body first so we can sign the exact bytes we send.
153
# Shape matches the browser's actual chat completions payload.
154
message_id = str(uuid.uuid4())
155
prompt = get_last_user_message(messages)
156
data = {
157
"chat": {
158
"id": "",
159
"title": "New Chat",
160
"models": [
161
"glm-4.7"
162
],
163
"params": {},
164
"history": {
165
"messages": {
166
message_id: {
167
"id": message_id,
168
"parentId": None,
169
"childrenIds": [],
170
"role": "user",
171
"content": prompt,
172
"timestamp": int(time.time() * 1000),
173
"models": [
174
"glm-4.7"
175
]
176
}
177
},
178
"currentId": message_id
179
},
180
"tags": [],
181
"flags": [],
182
"features": [],
183
"mcp_servers": [],
184
"enable_thinking": enable_thinking,
185
"reasoning_effort": reasoning_effort,
186
"auto_web_search": web_search,
187
"message_version": 1,
188
"extra": {},
189
"timestamp": int(time.time() * 1000),
190
"type": "default"
191
}
192
}
193
async with StreamSession(
194
impersonate="chrome",
195
proxy=proxy,
196
) as session:
197
url = "https://chat.z.ai/api/v1/chats/new"
198
async with session.post(
199
url,
200
json=data,
201
headers={
202
"Authorization": f"Bearer {cls.api_key}",
203
"Content-Type": "application/json",
204
}
205
) as response:
206
await raise_for_status(response)
207
chat_data = await response.json()
208
chat_id = chat_data.get("id")
209
if not chat_id:
210
raise ProviderException("Failed to create new chat session")
211
# Compact JSON matching browser JSON.stringify() output.
212
data = {
213
"stream": True,
214
"model": "glm-4.7",
215
"messages": [
216
{
217
"role": "user",
218
"content": prompt,
219
}
220
],
221
"signature_prompt": prompt,
222
"params": {},
223
"extra": {},
224
"features": {
225
"image_generation": False,
226
"web_search": False,
227
"auto_web_search": False,
228
"preview_mode": True,
229
"flags": [],
230
"vlm_tools_enable": False,
231
"vlm_web_search_enable": False,
232
"vlm_website_mode": False,
233
"enable_thinking": True
234
},
235
"variables": {
236
"{{USER_NAME}}": "Guest-1783644168311",
237
"{{USER_LOCATION}}": "Unknown",
238
"{{CURRENT_DATETIME}}": "2026-07-10 03:54:21",
239
"{{CURRENT_DATE}}": "2026-07-10",
240
"{{CURRENT_TIME}}": "03:54:21",
241
"{{CURRENT_WEEKDAY}}": "Friday",
242
"{{CURRENT_TIMEZONE}}": "Europe/Berlin",
243
"{{USER_LANGUAGE}}": "en-US"
244
},
245
"chat_id": chat_id,
246
"id": str(uuid.uuid4()),
247
"current_user_message_id": message_id,
248
"current_user_message_parent_id": None,
249
"background_tasks": {
250
"title_generation": True,
251
"tags_generation": True
252
},
253
"captcha_verify_param": "eyJjZXJ0aWZ5SWQiOiJ1eTZSaXVCSkxaIiwic2NlbmVJZCI6ImRpZGszM2UwIiwiaXNTaWduIjp0cnVlLCJzZWN1cml0eVRva2VuIjoiNm9PbzdlNzJuQTYxdVZMaVpWS2lMWXFGMW05ck9ubzN2RUlQSkthTDdLTHhDSnFiMVVCd1JwbDRwN0VjRlRnZFA1OVdiNDA1WVhZRmZkRVlzZjMzZ05qUGNxYWZscWJRTFpRZFgycllkLzhiaG5xaElwQzdTblJsSXhHUHNxdlgifQ=="
254
}
255
body_json = json.dumps(data, separators=(',', ':'))
256
257
url_params = cls._build_url_params(cls.api_key, cls.auth_user_id or "")
258
signature = cls._compute_signature(body_json)
259
endpoint = f"https://chat.z.ai/api/v2/chat/completions?{url_params}"
260
async with session.get(
261
endpoint,
262
headers={
263
"Authorization": f"Bearer {cls.api_key}",
264
"Content-Type": "application/json",
265
"x-fe-version": "prod-fe-1.0.95",
266
"x-signature": signature,
267
},
268
) as response:
269
await raise_for_status(response)
270
usage = None
271
async for chunk in response.sse():
272
if chunk.get("type") == "chat:completion":
273
if not usage:
274
usage = chunk.get("data", {}).get("usage")
275
if usage:
276
yield Usage(**usage)
277
if chunk.get("data", {}).get("phase") == "thinking":
278
delta_content = chunk.get("data", {}).get("delta_content")
279
delta_content = delta_content.split("</summary>\n>")[-1] if delta_content else ""
280
if delta_content:
281
yield Reasoning(delta_content)
282
else:
283
edit_content = chunk.get("data", {}).get("edit_content")
284
if edit_content:
285
yield edit_content.split("\n</details>\n")[-1]
286
else:
287
delta_content = chunk.get("data", {}).get("delta_content")
288
if delta_content:
289
yield delta_content