Update app.py
Browse files
app.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import json
|
|
|
|
| 2 |
import time
|
| 3 |
import asyncio
|
| 4 |
import uvicorn
|
|
@@ -74,7 +75,7 @@ def get_headers():
|
|
| 74 |
# 负载均衡,轮询选择token
|
| 75 |
if len(DEEPSIDER_TOKEN) > 0:
|
| 76 |
current_token = DEEPSIDER_TOKEN[TOKEN_INDEX % len(DEEPSIDER_TOKEN)]
|
| 77 |
-
TOKEN_INDEX = (TOKEN_INDEX + 1) % len(DEEPSIDER_TOKEN)
|
| 78 |
|
| 79 |
# 检查token状态
|
| 80 |
if current_token in token_status and not token_status[current_token]["active"]:
|
|
@@ -149,6 +150,7 @@ async def initialize_token_status():
|
|
| 149 |
|
| 150 |
active = False
|
| 151 |
quota_info = {}
|
|
|
|
| 152 |
|
| 153 |
if response.status_code == 200:
|
| 154 |
data = response.json()
|
|
@@ -159,7 +161,7 @@ async def initialize_token_status():
|
|
| 159 |
for item in quota_list:
|
| 160 |
item_type = item.get('type', '')
|
| 161 |
available = item.get('available', 0)
|
| 162 |
-
|
| 163 |
if available > 0:
|
| 164 |
active = True
|
| 165 |
|
|
@@ -173,7 +175,8 @@ async def initialize_token_status():
|
|
| 173 |
"active": active,
|
| 174 |
"quota": quota_info,
|
| 175 |
"last_checked": datetime.now(),
|
| 176 |
-
"failed_count": 0
|
|
|
|
| 177 |
}
|
| 178 |
|
| 179 |
logger.info(f"Token {token[:8]}... 状态:{'活跃' if active else '无效'}")
|
|
@@ -213,7 +216,10 @@ def format_messages_for_deepsider(messages: List[ChatMessage]) -> str:
|
|
| 213 |
elif role == "user":
|
| 214 |
prompt += f"Human: {msg.content}\n\n"
|
| 215 |
elif role == "assistant":
|
|
|
|
|
|
|
| 216 |
prompt += f"Assistant: {msg.content}\n\n"
|
|
|
|
| 217 |
else:
|
| 218 |
# 其他角色按用户处理
|
| 219 |
prompt += f"Human ({role}): {msg.content}\n\n"
|
|
@@ -251,8 +257,13 @@ def update_token_status(token: str, success: bool, error_message: str = None):
|
|
| 251 |
logger.warning(f"Token {token[:8]}... 连续失败{token_status[token]['failed_count']}次,已标记为不活跃")
|
| 252 |
else:
|
| 253 |
# 成功则重置失败计数
|
|
|
|
| 254 |
token_status[token]["failed_count"] = 0
|
| 255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
|
| 257 |
async def generate_openai_response(full_response: str, request_id: str, model: str) -> Dict:
|
| 258 |
"""生成符合OpenAI API响应格式的完整响应"""
|
|
@@ -284,6 +295,7 @@ async def stream_openai_response(response, request_id: str, model: str, token: s
|
|
| 284 |
"""流式返回OpenAI API格式的响应"""
|
| 285 |
timestamp = int(time.time())
|
| 286 |
full_response = ""
|
|
|
|
| 287 |
|
| 288 |
try:
|
| 289 |
# 将DeepSider响应流转换为OpenAI流格式
|
|
@@ -319,9 +331,31 @@ async def stream_openai_response(response, request_id: str, model: str, token: s
|
|
| 319 |
}
|
| 320 |
]
|
| 321 |
}
|
|
|
|
|
|
|
|
|
|
| 322 |
yield f"data: {json.dumps(chunk)}\n\n"
|
| 323 |
|
| 324 |
elif data.get('code') == 203:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
# 生成完成信号
|
| 326 |
chunk = {
|
| 327 |
"id": f"chatcmpl-{request_id}",
|
|
@@ -410,8 +444,21 @@ async def create_chat_completion(
|
|
| 410 |
# 映射模型
|
| 411 |
deepsider_model = map_openai_to_deepsider_model(chat_request.model)
|
| 412 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
# 准备DeepSider API所需的提示
|
| 414 |
-
|
|
|
|
|
|
|
|
|
|
| 415 |
|
| 416 |
# 准备请求体
|
| 417 |
payload = {
|
|
@@ -421,6 +468,9 @@ async def create_chat_completion(
|
|
| 421 |
"timezone": "Asia/Shanghai"
|
| 422 |
}
|
| 423 |
|
|
|
|
|
|
|
|
|
|
| 424 |
# 获取当前token
|
| 425 |
headers = get_headers()
|
| 426 |
current_token = headers["authorization"].replace("Bearer ", "")
|
|
|
|
| 1 |
import json
|
| 2 |
+
import re
|
| 3 |
import time
|
| 4 |
import asyncio
|
| 5 |
import uvicorn
|
|
|
|
| 75 |
# 负载均衡,轮询选择token
|
| 76 |
if len(DEEPSIDER_TOKEN) > 0:
|
| 77 |
current_token = DEEPSIDER_TOKEN[TOKEN_INDEX % len(DEEPSIDER_TOKEN)]
|
| 78 |
+
# TOKEN_INDEX = (TOKEN_INDEX + 1) % len(DEEPSIDER_TOKEN)
|
| 79 |
|
| 80 |
# 检查token状态
|
| 81 |
if current_token in token_status and not token_status[current_token]["active"]:
|
|
|
|
| 150 |
|
| 151 |
active = False
|
| 152 |
quota_info = {}
|
| 153 |
+
count = 0
|
| 154 |
|
| 155 |
if response.status_code == 200:
|
| 156 |
data = response.json()
|
|
|
|
| 161 |
for item in quota_list:
|
| 162 |
item_type = item.get('type', '')
|
| 163 |
available = item.get('available', 0)
|
| 164 |
+
count += available
|
| 165 |
if available > 0:
|
| 166 |
active = True
|
| 167 |
|
|
|
|
| 175 |
"active": active,
|
| 176 |
"quota": quota_info,
|
| 177 |
"last_checked": datetime.now(),
|
| 178 |
+
"failed_count": 0,
|
| 179 |
+
"count": count
|
| 180 |
}
|
| 181 |
|
| 182 |
logger.info(f"Token {token[:8]}... 状态:{'活跃' if active else '无效'}")
|
|
|
|
| 216 |
elif role == "user":
|
| 217 |
prompt += f"Human: {msg.content}\n\n"
|
| 218 |
elif role == "assistant":
|
| 219 |
+
content = msg.content
|
| 220 |
+
re.sub(r'\[clId:(.*)]','' ,content)
|
| 221 |
prompt += f"Assistant: {msg.content}\n\n"
|
| 222 |
+
|
| 223 |
else:
|
| 224 |
# 其他角色按用户处理
|
| 225 |
prompt += f"Human ({role}): {msg.content}\n\n"
|
|
|
|
| 257 |
logger.warning(f"Token {token[:8]}... 连续失败{token_status[token]['failed_count']}次,已标记为不活跃")
|
| 258 |
else:
|
| 259 |
# 成功则重置失败计数
|
| 260 |
+
token_status[token]["count"] -= 1
|
| 261 |
token_status[token]["failed_count"] = 0
|
| 262 |
|
| 263 |
+
if token_status[token]["count"] <= 0:
|
| 264 |
+
token_status[token]["active"] = False
|
| 265 |
+
logger.warning(f"Token {token[:8]}... 余额不足,已标记为不活跃")
|
| 266 |
+
|
| 267 |
|
| 268 |
async def generate_openai_response(full_response: str, request_id: str, model: str) -> Dict:
|
| 269 |
"""生成符合OpenAI API响应格式的完整响应"""
|
|
|
|
| 295 |
"""流式返回OpenAI API格式的响应"""
|
| 296 |
timestamp = int(time.time())
|
| 297 |
full_response = ""
|
| 298 |
+
codeFlag = False
|
| 299 |
|
| 300 |
try:
|
| 301 |
# 将DeepSider响应流转换为OpenAI流格式
|
|
|
|
| 331 |
}
|
| 332 |
]
|
| 333 |
}
|
| 334 |
+
|
| 335 |
+
if '验证码提示' in content:
|
| 336 |
+
codeFlag = True
|
| 337 |
yield f"data: {json.dumps(chunk)}\n\n"
|
| 338 |
|
| 339 |
elif data.get('code') == 203:
|
| 340 |
+
# 尾巴
|
| 341 |
+
if codeFlag:
|
| 342 |
+
chunk = {
|
| 343 |
+
"id": f"chatcmpl-{request_id}",
|
| 344 |
+
"object": "chat.completion.chunk",
|
| 345 |
+
"created": timestamp,
|
| 346 |
+
"model": model,
|
| 347 |
+
"choices": [
|
| 348 |
+
{
|
| 349 |
+
"index": 0,
|
| 350 |
+
"delta": {
|
| 351 |
+
"content": f"\n[clId:{data.get('data', {}).get('clId')}]"
|
| 352 |
+
},
|
| 353 |
+
"finish_reason": None
|
| 354 |
+
}
|
| 355 |
+
]
|
| 356 |
+
}
|
| 357 |
+
yield f"data: {json.dumps(chunk)}\n\n"
|
| 358 |
+
|
| 359 |
# 生成完成信号
|
| 360 |
chunk = {
|
| 361 |
"id": f"chatcmpl-{request_id}",
|
|
|
|
| 444 |
# 映射模型
|
| 445 |
deepsider_model = map_openai_to_deepsider_model(chat_request.model)
|
| 446 |
|
| 447 |
+
# 验证验证码
|
| 448 |
+
isCode = False
|
| 449 |
+
clId = None
|
| 450 |
+
|
| 451 |
+
if len(chat_request.messages) > 1:
|
| 452 |
+
msg = chat_request.messages[-2]
|
| 453 |
+
if msg.role == 'assistant' and '验证码提示' in msg.content and 'clId' in msg.content:
|
| 454 |
+
isCode = True
|
| 455 |
+
clId = re.search(r'\[clId:(.*)]', msg.content).group(1)
|
| 456 |
+
|
| 457 |
# 准备DeepSider API所需的提示
|
| 458 |
+
if isCode:
|
| 459 |
+
prompt = chat_request.messages[-1].content
|
| 460 |
+
else:
|
| 461 |
+
prompt = format_messages_for_deepsider(chat_request.messages)
|
| 462 |
|
| 463 |
# 准备请求体
|
| 464 |
payload = {
|
|
|
|
| 468 |
"timezone": "Asia/Shanghai"
|
| 469 |
}
|
| 470 |
|
| 471 |
+
if isCode:
|
| 472 |
+
payload["clId"] = clId
|
| 473 |
+
|
| 474 |
# 获取当前token
|
| 475 |
headers = get_headers()
|
| 476 |
current_token = headers["authorization"].replace("Bearer ", "")
|