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")
|