Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -109,6 +109,7 @@ CONFIG = {
|
|
109 |
"PORT": int(os.environ.get("PORT", 5200))
|
110 |
},
|
111 |
"RETRY": {
|
|
|
112 |
"MAX_ATTEMPTS": 2
|
113 |
},
|
114 |
"SHOW_THINKING": os.environ.get("SHOW_THINKING") == "true",
|
@@ -252,13 +253,15 @@ class AuthTokenManager:
|
|
252 |
except Exception as error:
|
253 |
logger.error(f"重置校对token请求次数时发生错误: {str(error)}", "TokenManager")
|
254 |
return False
|
255 |
-
def get_next_token_for_model(self, model_id):
|
256 |
normalized_model = self.normalize_model_name(model_id)
|
257 |
|
258 |
if normalized_model not in self.token_model_map or not self.token_model_map[normalized_model]:
|
259 |
return None
|
260 |
|
261 |
token_entry = self.token_model_map[normalized_model][0]
|
|
|
|
|
262 |
|
263 |
if token_entry:
|
264 |
if token_entry["StartCallTime"] is None:
|
@@ -411,6 +414,14 @@ class AuthTokenManager:
|
|
411 |
for entry in model_tokens:
|
412 |
all_tokens.add(entry["token"])
|
413 |
return list(all_tokens)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
414 |
|
415 |
def get_token_status_map(self):
|
416 |
return self.token_status_map
|
@@ -435,8 +446,8 @@ class Utils:
|
|
435 |
return '\n\n'.join(formatted_results)
|
436 |
|
437 |
@staticmethod
|
438 |
-
def create_auth_headers(model):
|
439 |
-
return token_manager.get_next_token_for_model(model)
|
440 |
|
441 |
@staticmethod
|
442 |
def get_proxy_options():
|
@@ -455,8 +466,7 @@ class Utils:
|
|
455 |
username, password = auth_part.split(':')
|
456 |
proxy_options["proxy_auth"] = (username, password)
|
457 |
else:
|
458 |
-
proxy_options["proxies"] = {"https": proxy, "http": proxy}
|
459 |
-
print(proxy_options)
|
460 |
return proxy_options
|
461 |
|
462 |
class GrokApiClient:
|
@@ -485,7 +495,40 @@ class GrokApiClient:
|
|
485 |
"mimeType": mime_type,
|
486 |
"fileName": file_name
|
487 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
488 |
|
|
|
|
|
|
|
489 |
def upload_base64_image(self, base64_data, url):
|
490 |
try:
|
491 |
if 'data:image' in base64_data:
|
@@ -549,6 +592,9 @@ class GrokApiClient:
|
|
549 |
messages = ''
|
550 |
last_role = None
|
551 |
last_content = ''
|
|
|
|
|
|
|
552 |
search = request["model"] in ['grok-2-search', 'grok-3-search']
|
553 |
|
554 |
# 移除<think>标签及其内容和base64图片
|
@@ -598,7 +644,9 @@ class GrokApiClient:
|
|
598 |
|
599 |
|
600 |
text_content = process_content(current.get("content", ""))
|
601 |
-
|
|
|
|
|
602 |
if text_content or (is_last_message and file_attachments):
|
603 |
if role == last_role and text_content:
|
604 |
last_content += '\n' + text_content
|
@@ -607,7 +655,14 @@ class GrokApiClient:
|
|
607 |
messages += f"{role.upper()}: {text_content or '[图片]'}\n"
|
608 |
last_content = text_content
|
609 |
last_role = role
|
610 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
611 |
return {
|
612 |
"temporary": CONFIG["API"].get("IS_TEMP_CONVERSATION", False),
|
613 |
"modelName": self.model_id,
|
@@ -943,7 +998,20 @@ def add_token():
|
|
943 |
except Exception as error:
|
944 |
logger.error(str(error), "Server")
|
945 |
return jsonify({"error": '添加sso令牌失败'}), 500
|
946 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
947 |
@app.route('/delete/token', methods=['POST'])
|
948 |
def delete_token():
|
949 |
auth_token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
@@ -1026,33 +1094,26 @@ def chat_completions():
|
|
1026 |
impersonate="chrome133a",
|
1027 |
stream=True,
|
1028 |
**proxy_options)
|
1029 |
-
logger.info(
|
1030 |
if response.status_code == 200:
|
1031 |
response_status_code = 200
|
1032 |
logger.info("请求成功", "Server")
|
1033 |
-
logger.info(
|
1034 |
-
f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}",
|
1035 |
-
"Server")
|
1036 |
|
1037 |
try:
|
1038 |
if stream:
|
1039 |
return Response(stream_with_context(
|
1040 |
-
handle_stream_response(response, model)),
|
1041 |
-
content_type='text/event-stream')
|
1042 |
else:
|
1043 |
-
content = handle_non_stream_response(
|
1044 |
-
response, model)
|
1045 |
return jsonify(
|
1046 |
-
MessageProcessor.create_chat_response(
|
1047 |
-
content, model))
|
1048 |
|
1049 |
except Exception as error:
|
1050 |
logger.error(str(error), "Server")
|
1051 |
if CONFIG["API"]["IS_CUSTOM_SSO"]:
|
1052 |
raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
|
1053 |
-
|
1054 |
-
token_manager.remove_token_from_model(
|
1055 |
-
model, CONFIG["API"]["SIGNATURE_COOKIE"])
|
1056 |
if token_manager.get_token_count_for_model(model) == 0:
|
1057 |
raise ValueError(f"{model} 次数已达上限,请切换其他模型或者重新对话")
|
1058 |
elif response.status_code == 403:
|
@@ -1076,10 +1137,8 @@ def chat_completions():
|
|
1076 |
if CONFIG["API"]["IS_CUSTOM_SSO"]:
|
1077 |
raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
|
1078 |
|
1079 |
-
logger.error(f"令牌异常错误状态!status: {response.status_code}",
|
1080 |
-
|
1081 |
-
token_manager.remove_token_from_model(
|
1082 |
-
model, CONFIG["API"]["SIGNATURE_COOKIE"])
|
1083 |
logger.info(
|
1084 |
f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}",
|
1085 |
"Server")
|
|
|
109 |
"PORT": int(os.environ.get("PORT", 5200))
|
110 |
},
|
111 |
"RETRY": {
|
112 |
+
"RETRYSWITCH": False,
|
113 |
"MAX_ATTEMPTS": 2
|
114 |
},
|
115 |
"SHOW_THINKING": os.environ.get("SHOW_THINKING") == "true",
|
|
|
253 |
except Exception as error:
|
254 |
logger.error(f"重置校对token请求次数时发生错误: {str(error)}", "TokenManager")
|
255 |
return False
|
256 |
+
def get_next_token_for_model(self, model_id, is_return=False):
|
257 |
normalized_model = self.normalize_model_name(model_id)
|
258 |
|
259 |
if normalized_model not in self.token_model_map or not self.token_model_map[normalized_model]:
|
260 |
return None
|
261 |
|
262 |
token_entry = self.token_model_map[normalized_model][0]
|
263 |
+
if is_return:
|
264 |
+
return token_entry["token"]
|
265 |
|
266 |
if token_entry:
|
267 |
if token_entry["StartCallTime"] is None:
|
|
|
414 |
for entry in model_tokens:
|
415 |
all_tokens.add(entry["token"])
|
416 |
return list(all_tokens)
|
417 |
+
def get_current_token(self, model_id):
|
418 |
+
normalized_model = self.normalize_model_name(model_id)
|
419 |
+
|
420 |
+
if normalized_model not in self.token_model_map or not self.token_model_map[normalized_model]:
|
421 |
+
return None
|
422 |
+
|
423 |
+
token_entry = self.token_model_map[normalized_model][0]
|
424 |
+
return token_entry["token"]
|
425 |
|
426 |
def get_token_status_map(self):
|
427 |
return self.token_status_map
|
|
|
446 |
return '\n\n'.join(formatted_results)
|
447 |
|
448 |
@staticmethod
|
449 |
+
def create_auth_headers(model, is_return=False):
|
450 |
+
return token_manager.get_next_token_for_model(model, is_return)
|
451 |
|
452 |
@staticmethod
|
453 |
def get_proxy_options():
|
|
|
466 |
username, password = auth_part.split(':')
|
467 |
proxy_options["proxy_auth"] = (username, password)
|
468 |
else:
|
469 |
+
proxy_options["proxies"] = {"https": proxy, "http": proxy}
|
|
|
470 |
return proxy_options
|
471 |
|
472 |
class GrokApiClient:
|
|
|
495 |
"mimeType": mime_type,
|
496 |
"fileName": file_name
|
497 |
}
|
498 |
+
def upload_base64_file(self, message, model):
|
499 |
+
try:
|
500 |
+
message_base64 = base64.b64encode(message.encode('utf-8')).decode('utf-8')
|
501 |
+
upload_data = {
|
502 |
+
"fileName": "message.txt",
|
503 |
+
"fileMimeType": "text/plain",
|
504 |
+
"content": message_base64
|
505 |
+
}
|
506 |
+
|
507 |
+
logger.info("发送文字文件请求", "Server")
|
508 |
+
cookie = f"{Utils.create_auth_headers(model, True)};{CONFIG['SERVER']['CF_CLEARANCE']}"
|
509 |
+
proxy_options = Utils.get_proxy_options()
|
510 |
+
response = curl_requests.post(
|
511 |
+
"https://grok.com/rest/app-chat/upload-file",
|
512 |
+
headers={
|
513 |
+
**DEFAULT_HEADERS,
|
514 |
+
"Cookie":cookie
|
515 |
+
},
|
516 |
+
json=upload_data,
|
517 |
+
impersonate="chrome133a",
|
518 |
+
**proxy_options
|
519 |
+
)
|
520 |
+
|
521 |
+
if response.status_code != 200:
|
522 |
+
logger.error(f"上传文件失败,状态码:{response.status_code}", "Server")
|
523 |
+
return ''
|
524 |
+
|
525 |
+
result = response.json()
|
526 |
+
logger.info(f"上传文件成功: {result}", "Server")
|
527 |
+
return result.get("fileMetadataId", "")
|
528 |
|
529 |
+
except Exception as error:
|
530 |
+
logger.error(str(error), "Server")
|
531 |
+
return ''
|
532 |
def upload_base64_image(self, base64_data, url):
|
533 |
try:
|
534 |
if 'data:image' in base64_data:
|
|
|
592 |
messages = ''
|
593 |
last_role = None
|
594 |
last_content = ''
|
595 |
+
message_length = 0
|
596 |
+
convert_to_file = False
|
597 |
+
last_message_content = ''
|
598 |
search = request["model"] in ['grok-2-search', 'grok-3-search']
|
599 |
|
600 |
# 移除<think>标签及其内容和base64图片
|
|
|
644 |
|
645 |
|
646 |
text_content = process_content(current.get("content", ""))
|
647 |
+
if is_last_message:
|
648 |
+
last_message_content = f"{role.upper()}: {text_content or '[图片]'}\n"
|
649 |
+
continue
|
650 |
if text_content or (is_last_message and file_attachments):
|
651 |
if role == last_role and text_content:
|
652 |
last_content += '\n' + text_content
|
|
|
655 |
messages += f"{role.upper()}: {text_content or '[图片]'}\n"
|
656 |
last_content = text_content
|
657 |
last_role = role
|
658 |
+
message_length += len(messages)
|
659 |
+
if message_length >= 40000:
|
660 |
+
convert_to_file = True
|
661 |
+
if convert_to_file:
|
662 |
+
file_id = self.upload_base64_file(messages, request["model"])
|
663 |
+
if file_id:
|
664 |
+
file_attachments.insert(0, file_id)
|
665 |
+
messages = last_message_content.strip()
|
666 |
return {
|
667 |
"temporary": CONFIG["API"].get("IS_TEMP_CONVERSATION", False),
|
668 |
"modelName": self.model_id,
|
|
|
998 |
except Exception as error:
|
999 |
logger.error(str(error), "Server")
|
1000 |
return jsonify({"error": '添加sso令牌失败'}), 500
|
1001 |
+
|
1002 |
+
@app.route('/set/cf_clearance', methods=['POST'])
|
1003 |
+
def setCf_clearance():
|
1004 |
+
auth_token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
1005 |
+
if auth_token != CONFIG["API"]["API_KEY"]:
|
1006 |
+
return jsonify({"error": 'Unauthorized'}), 401
|
1007 |
+
try:
|
1008 |
+
cf_clearance = request.json.get('cf_clearance')
|
1009 |
+
CONFIG["SERVER"]['CF_CLEARANCE'] = cf_clearance
|
1010 |
+
return jsonify({"message": '设置cf_clearance成功'}), 200
|
1011 |
+
except Exception as error:
|
1012 |
+
logger.error(str(error), "Server")
|
1013 |
+
return jsonify({"error": '设置cf_clearance失败'}), 500
|
1014 |
+
|
1015 |
@app.route('/delete/token', methods=['POST'])
|
1016 |
def delete_token():
|
1017 |
auth_token = request.headers.get('Authorization', '').replace('Bearer ', '')
|
|
|
1094 |
impersonate="chrome133a",
|
1095 |
stream=True,
|
1096 |
**proxy_options)
|
1097 |
+
logger.info(CONFIG["SERVER"]['COOKIE'],"Server")
|
1098 |
if response.status_code == 200:
|
1099 |
response_status_code = 200
|
1100 |
logger.info("请求成功", "Server")
|
1101 |
+
logger.info(f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}","Server")
|
|
|
|
|
1102 |
|
1103 |
try:
|
1104 |
if stream:
|
1105 |
return Response(stream_with_context(
|
1106 |
+
handle_stream_response(response, model)),content_type='text/event-stream')
|
|
|
1107 |
else:
|
1108 |
+
content = handle_non_stream_response(response, model)
|
|
|
1109 |
return jsonify(
|
1110 |
+
MessageProcessor.create_chat_response(content, model))
|
|
|
1111 |
|
1112 |
except Exception as error:
|
1113 |
logger.error(str(error), "Server")
|
1114 |
if CONFIG["API"]["IS_CUSTOM_SSO"]:
|
1115 |
raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
|
1116 |
+
token_manager.remove_token_from_model(model, CONFIG["API"]["SIGNATURE_COOKIE"])
|
|
|
|
|
1117 |
if token_manager.get_token_count_for_model(model) == 0:
|
1118 |
raise ValueError(f"{model} 次数已达上限,请切换其他模型或者重新对话")
|
1119 |
elif response.status_code == 403:
|
|
|
1137 |
if CONFIG["API"]["IS_CUSTOM_SSO"]:
|
1138 |
raise ValueError(f"自定义SSO令牌当前模型{model}的请求次数已失效")
|
1139 |
|
1140 |
+
logger.error(f"令牌异常错误状态!status: {response.status_code}","Server")
|
1141 |
+
token_manager.remove_token_from_model(model, CONFIG["API"]["SIGNATURE_COOKIE"])
|
|
|
|
|
1142 |
logger.info(
|
1143 |
f"当前{model}剩余可用令牌数: {token_manager.get_token_count_for_model(model)}",
|
1144 |
"Server")
|