XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Delete old GLM

562b1e17
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

1 个文件 +0 -289
Deleted g4f/Provider/GLM.py +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