yangtb24 commited on
Commit
485c6ba
·
verified ·
1 Parent(s): f101853

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +270 -235
app.py CHANGED
@@ -970,223 +970,220 @@ def handsome_chat_completions():
970
  }
971
 
972
  if model_name in image_models:
973
- user_content = ""
974
- messages = data.get("messages", [])
975
- for message in messages:
976
- if message["role"] == "user":
977
- if isinstance(message["content"], str):
978
- user_content += message["content"] + " "
979
- elif isinstance(message["content"], list):
980
- for item in message["content"]:
981
- if (
982
- isinstance(item, dict) and
983
- item.get("type") == "text"
984
- ):
985
- user_content += (
986
- item.get("text", "") +
987
- " "
988
- )
989
- user_content = user_content.strip()
990
-
991
- siliconflow_data = {
992
  "model": model_name,
993
  "prompt": user_content,
994
-
995
  }
996
- if model_name == "black-forest-labs/FLUX.1-pro":
997
- siliconflow_data["width"] = data.get("width", 1024)
998
- siliconflow_data["height"] = data.get("height", 768)
999
- siliconflow_data["prompt_upsampling"] = data.get("prompt_upsampling", False)
1000
- siliconflow_data["image_prompt"] = data.get("image_prompt")
1001
- siliconflow_data["steps"] = data.get("steps", 20)
1002
- siliconflow_data["guidance"] = data.get("guidance", 3)
1003
- siliconflow_data["safety_tolerance"] = data.get("safety_tolerance", 2)
1004
- siliconflow_data["interval"] = data.get("interval", 2)
1005
- siliconflow_data["output_format"] = data.get("output_format", "png")
1006
- seed = data.get("seed")
1007
- if isinstance(seed, int) and 0 < seed < 9999999999:
1008
  siliconflow_data["seed"] = seed
1009
- if siliconflow_data["width"] < 256 or siliconflow_data["width"] > 1440 or siliconflow_data["width"] % 32 != 0:
1010
- siliconflow_data["width"] = 1024
1011
- if siliconflow_data["height"] < 256 or siliconflow_data["height"] > 1440 or siliconflow_data["height"] % 32 != 0:
1012
- siliconflow_data["height"] = 768
1013
-
1014
- if siliconflow_data["steps"] < 1 or siliconflow_data["steps"] > 50:
1015
  siliconflow_data["steps"] = 20
1016
- if siliconflow_data["guidance"] < 1.5 or siliconflow_data["guidance"] > 5:
1017
  siliconflow_data["guidance"] = 3
1018
- if siliconflow_data["safety_tolerance"] < 0 or siliconflow_data["safety_tolerance"] > 6:
1019
- siliconflow_data["safety_tolerance"] = 2
1020
- if siliconflow_data["interval"] < 1 or siliconflow_data["interval"] > 4 :
1021
  siliconflow_data["interval"] = 2
1022
- else:
1023
- siliconflow_data["image_size"] = "1024x1024"
1024
- siliconflow_data["batch_size"] = 1
1025
- siliconflow_data["num_inference_steps"] = 20
1026
- siliconflow_data["guidance_scale"] = 7.5
1027
- siliconflow_data["prompt_enhancement"] = False
1028
-
1029
- if data.get("size"):
1030
- siliconflow_data["image_size"] = data.get("size")
1031
- if data.get("n"):
1032
- siliconflow_data["batch_size"] = data.get("n")
1033
- if data.get("steps"):
1034
- siliconflow_data["num_inference_steps"] = data.get("steps")
1035
- if data.get("guidance_scale"):
1036
- siliconflow_data["guidance_scale"] = data.get("guidance_scale")
1037
- if data.get("negative_prompt"):
1038
- siliconflow_data["negative_prompt"] = data.get("negative_prompt")
1039
- if data.get("seed"):
1040
- siliconflow_data["seed"] = data.get("seed")
1041
- if data.get("prompt_enhancement"):
1042
- siliconflow_data["prompt_enhancement"] = data.get("prompt_enhancement")
1043
-
1044
- if siliconflow_data["batch_size"] < 1:
1045
  siliconflow_data["batch_size"] = 1
1046
- if siliconflow_data["batch_size"] > 4:
1047
  siliconflow_data["batch_size"] = 4
1048
 
1049
- if siliconflow_data["num_inference_steps"] < 1:
1050
- siliconflow_data["num_inference_steps"] = 1
1051
- if siliconflow_data["num_inference_steps"] > 50:
1052
  siliconflow_data["num_inference_steps"] = 50
1053
-
1054
- if siliconflow_data["guidance_scale"] < 0:
1055
  siliconflow_data["guidance_scale"] = 0
1056
- if siliconflow_data["guidance_scale"] > 100:
1057
  siliconflow_data["guidance_scale"] = 100
1058
 
1059
- if siliconflow_data["image_size"] not in ["1024x1024", "512x1024", "768x512", "768x1024", "1024x576", "576x1024", "960x1280", "720x1440", "720x1280"]:
1060
- siliconflow_data["image_size"] = "1024x1024"
1061
- try:
 
1062
  start_time = time.time()
1063
  response = requests.post(
1064
- "https://api-st.siliconflow.cn/v1/images/generations",
1065
- headers=headers,
1066
- json=siliconflow_data,
1067
- timeout=120,
1068
- stream=data.get("stream", False)
1069
  )
1070
-
1071
  if response.status_code == 429:
1072
- return jsonify(response.json()), 429
1073
 
1074
  if data.get("stream", False):
1075
- def generate():
1076
- first_chunk_time = None
1077
- full_response_content = ""
1078
- try:
1079
- response.raise_for_status()
1080
- end_time = time.time()
1081
- response_json = response.json()
1082
- total_time = end_time - start_time
1083
 
1084
- images = response_json.get("images", [])
1085
-
1086
- image_url = ""
1087
- if images and isinstance(images[0], dict) and "url" in images[0]:
1088
- image_url = images[0]["url"]
1089
- logging.info(f"Extracted image URL: {image_url}")
1090
- elif images and isinstance(images[0], str):
1091
- image_url = images[0]
1092
- logging.info(f"Extracted image URL: {image_url}")
1093
-
1094
- markdown_image_link = f"![image]({image_url})"
1095
- if image_url:
1096
- chunk_data = {
1097
- "id": f"chatcmpl-{uuid.uuid4()}",
1098
- "object": "chat.completion.chunk",
1099
- "created": int(time.time()),
1100
- "model": model_name,
1101
- "choices": [
1102
- {
1103
- "index": 0,
1104
- "delta": {
1105
- "role": "assistant",
1106
- "content": markdown_image_link
1107
- },
1108
- "finish_reason": None
1109
- }
1110
- ]
1111
- }
1112
- yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
1113
- full_response_content = markdown_image_link
1114
- else:
1115
- chunk_data = {
1116
- "id": f"chatcmpl-{uuid.uuid4()}",
1117
- "object": "chat.completion.chunk",
1118
- "created": int(time.time()),
1119
- "model": model_name,
1120
- "choices": [
1121
- {
1122
- "index": 0,
1123
- "delta": {
1124
- "role": "assistant",
1125
- "content": "Failed to generate image"
1126
- },
1127
- "finish_reason": None
1128
- }
1129
- ]
1130
- }
1131
- yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
1132
- full_response_content = "Failed to generate image"
1133
 
1134
- end_chunk_data = {
1135
- "id": f"chatcmpl-{uuid.uuid4()}",
1136
- "object": "chat.completion.chunk",
1137
- "created": int(time.time()),
1138
- "model": model_name,
1139
- "choices": [
1140
- {
1141
- "index": 0,
1142
- "delta": {},
1143
- "finish_reason": "stop"
1144
- }
1145
- ]
1146
- }
1147
- yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
1148
- with data_lock:
1149
- request_timestamps.append(time.time())
1150
- token_counts.append(0)
1151
- except requests.exceptions.RequestException as e:
1152
- logging.error(f"请求转发异常: {e}")
1153
- error_chunk_data = {
1154
- "id": f"chatcmpl-{uuid.uuid4()}",
1155
- "object": "chat.completion.chunk",
1156
- "created": int(time.time()),
1157
- "model": model_name,
1158
- "choices": [
1159
- {
1160
- "index": 0,
1161
- "delta": {
1162
- "role": "assistant",
1163
- "content": f"Error: {str(e)}"
1164
- },
1165
- "finish_reason": None
1166
- }
1167
- ]
1168
- }
1169
- yield f"data: {json.dumps(error_chunk_data)}\n\n".encode('utf-8')
1170
- end_chunk_data = {
1171
- "id": f"chatcmpl-{uuid.uuid4()}",
1172
- "object": "chat.completion.chunk",
1173
- "created": int(time.time()),
1174
- "model": model_name,
1175
- "choices": [
1176
- {
1177
- "index": 0,
1178
- "delta": {},
1179
- "finish_reason": "stop"
1180
- }
1181
- ]
1182
- }
1183
- yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
1184
- logging.info(
1185
- f"使用的key: {api_key}, "
1186
- f"使用的模型: {model_name}"
1187
- )
1188
- yield "data: [DONE]\n\n".encode('utf-8')
1189
- return Response(stream_with_context(generate()), content_type='text/event-stream')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1190
 
1191
  else:
1192
  response.raise_for_status()
@@ -1245,22 +1242,22 @@ def handsome_chat_completions():
1245
  }
1246
 
1247
  logging.info(
1248
- f"使用的key: {api_key}, "
1249
- f"总共用时: {total_time:.4f}秒, "
1250
- f"使用的模型: {model_name}"
1251
  )
1252
  with data_lock:
1253
- request_timestamps.append(time.time())
1254
- token_counts.append(0)
1255
  return jsonify(response_data)
1256
 
1257
- except requests.exceptions.RequestException as e:
1258
  logging.error(f"请求转发异常: {e}")
1259
  return jsonify({"error": str(e)}), 500
1260
  else:
1261
  tools = data.get("tools")
1262
  tool_choice = data.get("tool_choice")
1263
-
1264
  siliconflow_data = {
1265
  "model": model_name,
1266
  "messages": data.get("messages", []),
@@ -1312,15 +1309,16 @@ def handsome_chat_completions():
1312
  prompt_tokens = 0
1313
  completion_tokens = 0
1314
  response_content = ""
 
1315
  tool_calls = []
 
1316
  for line in full_response_content.splitlines():
1317
  if line.startswith("data:"):
1318
- line = line[5:].strip()
1319
- if line == "[DONE]":
1320
  continue
1321
- try:
1322
  response_json = json.loads(line)
1323
-
1324
  if (
1325
  "usage" in response_json and
1326
  "completion_tokens" in response_json["usage"]
@@ -1347,7 +1345,6 @@ def handsome_chat_completions():
1347
  if "tool_calls" in message:
1348
  tool_calls.extend(message["tool_calls"])
1349
 
1350
-
1351
  if (
1352
  "usage" in response_json and
1353
  "prompt_tokens" in response_json["usage"]
@@ -1356,23 +1353,24 @@ def handsome_chat_completions():
1356
  "usage"
1357
  ]["prompt_tokens"]
1358
 
1359
- except (
 
1360
  KeyError,
1361
  ValueError,
1362
  IndexError
1363
- ) as e:
1364
- logging.error(
1365
  f"解析流式响应单行 JSON 失败: {e}, "
1366
  f"行内容: {line}"
1367
- )
1368
 
1369
  user_content = ""
1370
  messages = data.get("messages", [])
1371
  for message in messages:
1372
- if message["role"] == "user":
1373
- if isinstance(message["content"], str):
1374
  user_content += message["content"] + " "
1375
- elif isinstance(message["content"], list):
1376
  for item in message["content"]:
1377
  if (
1378
  isinstance(item, dict) and
@@ -1390,7 +1388,7 @@ def handsome_chat_completions():
1390
  response_content_replaced = response_content.replace(
1391
  '\n', '\\n'
1392
  ).replace('\r', '\\n')
1393
-
1394
  log_message = (
1395
  f"使用的key: {api_key}, "
1396
  f"提示token: {prompt_tokens}, "
@@ -1401,17 +1399,16 @@ def handsome_chat_completions():
1401
  f"用户的内容: {user_content_replaced}, "
1402
  f"输出的内容: {response_content_replaced}"
1403
  )
 
1404
  if tool_calls:
1405
- log_message += f", tool_calls: {tool_calls}"
1406
-
1407
  logging.info(log_message)
1408
 
1409
  with data_lock:
1410
  request_timestamps.append(time.time())
1411
  token_counts.append(prompt_tokens+completion_tokens)
1412
-
1413
-
1414
-
1415
  # 构造 OpenAI 格式的响应数据
1416
  response_data = {
1417
  "id": f"chatcmpl-{uuid.uuid4()}",
@@ -1428,13 +1425,31 @@ def handsome_chat_completions():
1428
  }
1429
  ]
1430
  }
1431
-
1432
- if response_content:
1433
- response_data["choices"][0]["delta"]["content"] = response_content
1434
 
1435
  if tool_calls:
1436
- response_data["choices"][0]["delta"]["tool_calls"] = tool_calls
1437
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1438
  yield f"data: {json.dumps(response_data)}\n\n".encode('utf-8')
1439
 
1440
  end_chunk_data = {
@@ -1469,11 +1484,10 @@ def handsome_chat_completions():
1469
  response_content = response_json[
1470
  "choices"
1471
  ][0]["message"]["content"]
1472
-
1473
  if "tool_calls" in response_json["choices"][0]["message"]:
1474
  tool_calls = response_json["choices"][0]["message"]["tool_calls"]
1475
  else:
1476
- tool_calls = []
1477
  except (KeyError, ValueError, IndexError) as e:
1478
  logging.error(
1479
  f"解析非流式响应 JSON 失败: {e}, "
@@ -1497,7 +1511,8 @@ def handsome_chat_completions():
1497
  item.get("type") == "text"
1498
  ):
1499
  user_content += (
1500
- item.get("text", "") + " "
 
1501
  )
1502
 
1503
  user_content = user_content.strip()
@@ -1508,9 +1523,9 @@ def handsome_chat_completions():
1508
  response_content_replaced = response_content.replace(
1509
  '\n', '\\n'
1510
  ).replace('\r', '\\n')
1511
-
1512
  log_message = (
1513
- f"使用的key: {api_key}, "
1514
  f"提示token: {prompt_tokens}, "
1515
  f"输出token: {completion_tokens}, "
1516
  f"首字用时: 0, "
@@ -1519,11 +1534,11 @@ def handsome_chat_completions():
1519
  f"用户的内容: {user_content_replaced}, "
1520
  f"输出的内容: {response_content_replaced}"
1521
  )
1522
-
1523
  if tool_calls:
1524
  log_message += f", tool_calls: {tool_calls}"
1525
-
1526
  logging.info(log_message)
 
1527
  with data_lock:
1528
  request_timestamps.append(time.time())
1529
  if "prompt_tokens" in response_json["usage"] and "completion_tokens" in response_json["usage"]:
@@ -1542,17 +1557,37 @@ def handsome_chat_completions():
1542
  "index": 0,
1543
  "message": {
1544
  "role": "assistant",
1545
- "content": response_content,
 
1546
  },
1547
  "finish_reason": "stop",
1548
  }
1549
  ],
1550
  }
1551
-
1552
  if tool_calls:
1553
- response_data["choices"][0]["message"]["tool_calls"] = tool_calls
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1554
 
1555
  return jsonify(response_data)
 
 
1556
  except requests.exceptions.RequestException as e:
1557
  logging.error(f"请求转发异常: {e}")
1558
  return jsonify({"error": str(e)}), 500
 
970
  }
971
 
972
  if model_name in image_models:
973
+ user_content = ""
974
+ messages = data.get("messages", [])
975
+ for message in messages:
976
+ if message["role"] == "user":
977
+ if isinstance(message["content"], str):
978
+ user_content += message["content"] + " "
979
+ elif isinstance(message["content"], list):
980
+ for item in message["content"]:
981
+ if (
982
+ isinstance(item, dict) and
983
+ item.get("type") == "text"
984
+ ):
985
+ user_content += (
986
+ item.get("text", "") +
987
+ " "
988
+ )
989
+ user_content = user_content.strip()
990
+
991
+ siliconflow_data = {
992
  "model": model_name,
993
  "prompt": user_content,
 
994
  }
995
+ if model_name == "black-forest-labs/FLUX.1-pro":
996
+ siliconflow_data["width"] = data.get("width", 1024)
997
+ siliconflow_data["height"] = data.get("height", 768)
998
+ siliconflow_data["prompt_upsampling"] = data.get("prompt_upsampling", False)
999
+ siliconflow_data["image_prompt"] = data.get("image_prompt")
1000
+ siliconflow_data["steps"] = data.get("steps", 20)
1001
+ siliconflow_data["guidance"] = data.get("guidance", 3)
1002
+ siliconflow_data["safety_tolerance"] = data.get("safety_tolerance", 2)
1003
+ siliconflow_data["interval"] = data.get("interval", 2)
1004
+ siliconflow_data["output_format"] = data.get("output_format", "png")
1005
+ seed = data.get("seed")
1006
+ if isinstance(seed, int) and 0 < seed < 9999999999:
1007
  siliconflow_data["seed"] = seed
1008
+ if siliconflow_data["width"] < 256 or siliconflow_data["width"] > 1440 or siliconflow_data["width"] % 32 != 0:
1009
+ siliconflow_data["width"] = 1024
1010
+ if siliconflow_data["height"] < 256 or siliconflow_data["height"] > 1440 or siliconflow_data["height"] % 32 != 0:
1011
+ siliconflow_data["height"] = 768
1012
+ if siliconflow_data["steps"] < 1 or siliconflow_data["steps"] > 50:
 
1013
  siliconflow_data["steps"] = 20
1014
+ if siliconflow_data["guidance"] < 1.5 or siliconflow_data["guidance"] > 5:
1015
  siliconflow_data["guidance"] = 3
1016
+ if siliconflow_data["safety_tolerance"] < 0 or siliconflow_data["safety_tolerance"] > 6:
1017
+ siliconflow_data["safety_tolerance"] = 2
1018
+ if siliconflow_data["interval"] < 1 or siliconflow_data["interval"] > 4 :
1019
  siliconflow_data["interval"] = 2
1020
+ else:
1021
+ siliconflow_data["image_size"] = "1024x1024"
1022
+ siliconflow_data["batch_size"] = 1
1023
+ siliconflow_data["num_inference_steps"] = 20
1024
+ siliconflow_data["guidance_scale"] = 7.5
1025
+ siliconflow_data["prompt_enhancement"] = False
1026
+
1027
+ if data.get("size"):
1028
+ siliconflow_data["image_size"] = data.get("size")
1029
+ if data.get("n"):
1030
+ siliconflow_data["batch_size"] = data.get("n")
1031
+ if data.get("steps"):
1032
+ siliconflow_data["num_inference_steps"] = data.get("steps")
1033
+ if data.get("guidance_scale"):
1034
+ siliconflow_data["guidance_scale"] = data.get("guidance_scale")
1035
+ if data.get("negative_prompt"):
1036
+ siliconflow_data["negative_prompt"] = data.get("negative_prompt")
1037
+ if data.get("seed"):
1038
+ siliconflow_data["seed"] = data.get("seed")
1039
+ if data.get("prompt_enhancement"):
1040
+ siliconflow_data["prompt_enhancement"] = data.get("prompt_enhancement")
1041
+ if siliconflow_data["batch_size"] < 1:
 
1042
  siliconflow_data["batch_size"] = 1
1043
+ if siliconflow_data["batch_size"] > 4:
1044
  siliconflow_data["batch_size"] = 4
1045
 
1046
+ if siliconflow_data["num_inference_steps"] < 1:
1047
+ siliconflow_data["num_inference_steps"] = 1
1048
+ if siliconflow_data["num_inference_steps"] > 50:
1049
  siliconflow_data["num_inference_steps"] = 50
1050
+
1051
+ if siliconflow_data["guidance_scale"] < 0:
1052
  siliconflow_data["guidance_scale"] = 0
1053
+ if siliconflow_data["guidance_scale"] > 100:
1054
  siliconflow_data["guidance_scale"] = 100
1055
 
1056
+ if siliconflow_data["image_size"] not in ["1024x1024", "512x1024", "768x512", "768x1024", "1024x576", "576x1024", "960x1280", "720x1440", "720x1280"]:
1057
+ siliconflow_data["image_size"] = "1024x1024"
1058
+
1059
+ try:
1060
  start_time = time.time()
1061
  response = requests.post(
1062
+ "https://api-st.siliconflow.cn/v1/images/generations",
1063
+ headers=headers,
1064
+ json=siliconflow_data,
1065
+ timeout=120,
1066
+ stream=data.get("stream", False)
1067
  )
 
1068
  if response.status_code == 429:
1069
+ return jsonify(response.json()), 429
1070
 
1071
  if data.get("stream", False):
1072
+ def generate():
1073
+ first_chunk_time = None
1074
+ full_response_content = ""
1075
+ try:
1076
+ response.raise_for_status()
1077
+ end_time = time.time()
1078
+ response_json = response.json()
1079
+ total_time = end_time - start_time
1080
 
1081
+ images = response_json.get("images", [])
1082
+
1083
+ image_url = ""
1084
+ if images and isinstance(images[0], dict) and "url" in images[0]:
1085
+ image_url = images[0]["url"]
1086
+ logging.info(f"Extracted image URL: {image_url}")
1087
+ elif images and isinstance(images[0], str):
1088
+ image_url = images[0]
1089
+ logging.info(f"Extracted image URL: {image_url}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090
 
1091
+ markdown_image_link = f"![image]({image_url})"
1092
+ if image_url:
1093
+ chunk_data = {
1094
+ "id": f"chatcmpl-{uuid.uuid4()}",
1095
+ "object": "chat.completion.chunk",
1096
+ "created": int(time.time()),
1097
+ "model": model_name,
1098
+ "choices": [
1099
+ {
1100
+ "index": 0,
1101
+ "delta": {
1102
+ "role": "assistant",
1103
+ "content": markdown_image_link
1104
+ },
1105
+ "finish_reason": None
1106
+ }
1107
+ ]
1108
+ }
1109
+ yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
1110
+ full_response_content = markdown_image_link
1111
+ else:
1112
+ chunk_data = {
1113
+ "id": f"chatcmpl-{uuid.uuid4()}",
1114
+ "object": "chat.completion.chunk",
1115
+ "created": int(time.time()),
1116
+ "model": model_name,
1117
+ "choices": [
1118
+ {
1119
+ "index": 0,
1120
+ "delta": {
1121
+ "role": "assistant",
1122
+ "content": "Failed to generate image"
1123
+ },
1124
+ "finish_reason": None
1125
+ }
1126
+ ]
1127
+ }
1128
+ yield f"data: {json.dumps(chunk_data)}\n\n".encode('utf-8')
1129
+ full_response_content = "Failed to generate image"
1130
+
1131
+ end_chunk_data = {
1132
+ "id": f"chatcmpl-{uuid.uuid4()}",
1133
+ "object": "chat.completion.chunk",
1134
+ "created": int(time.time()),
1135
+ "model": model_name,
1136
+ "choices": [
1137
+ {
1138
+ "index": 0,
1139
+ "delta": {},
1140
+ "finish_reason": "stop"
1141
+ }
1142
+ ]
1143
+ }
1144
+ yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
1145
+ with data_lock:
1146
+ request_timestamps.append(time.time())
1147
+ token_counts.append(0)
1148
+ except requests.exceptions.RequestException as e:
1149
+ logging.error(f"请求转发异常: {e}")
1150
+ error_chunk_data = {
1151
+ "id": f"chatcmpl-{uuid.uuid4()}",
1152
+ "object": "chat.completion.chunk",
1153
+ "created": int(time.time()),
1154
+ "model": model_name,
1155
+ "choices": [
1156
+ {
1157
+ "index": 0,
1158
+ "delta": {
1159
+ "role": "assistant",
1160
+ "content": f"Error: {str(e)}"
1161
+ },
1162
+ "finish_reason": None
1163
+ }
1164
+ ]
1165
+ }
1166
+ yield f"data: {json.dumps(error_chunk_data)}\n\n".encode('utf-8')
1167
+ end_chunk_data = {
1168
+ "id": f"chatcmpl-{uuid.uuid4()}",
1169
+ "object": "chat.completion.chunk",
1170
+ "created": int(time.time()),
1171
+ "model": model_name,
1172
+ "choices": [
1173
+ {
1174
+ "index": 0,
1175
+ "delta": {},
1176
+ "finish_reason": "stop"
1177
+ }
1178
+ ]
1179
+ }
1180
+ yield f"data: {json.dumps(end_chunk_data)}\n\n".encode('utf-8')
1181
+ logging.info(
1182
+ f"使用的key: {api_key}, "
1183
+ f"使用的模型: {model_name}"
1184
+ )
1185
+ yield "data: [DONE]\n\n".encode('utf-8')
1186
+ return Response(stream_with_context(generate()), content_type='text/event-stream')
1187
 
1188
  else:
1189
  response.raise_for_status()
 
1242
  }
1243
 
1244
  logging.info(
1245
+ f"使用的key: {api_key}, "
1246
+ f"总共用时: {total_time:.4f}秒, "
1247
+ f"使用的模型: {model_name}"
1248
  )
1249
  with data_lock:
1250
+ request_timestamps.append(time.time())
1251
+ token_counts.append(0)
1252
  return jsonify(response_data)
1253
 
1254
+ except requests.exceptions.RequestException as e:
1255
  logging.error(f"请求转发异常: {e}")
1256
  return jsonify({"error": str(e)}), 500
1257
  else:
1258
  tools = data.get("tools")
1259
  tool_choice = data.get("tool_choice")
1260
+
1261
  siliconflow_data = {
1262
  "model": model_name,
1263
  "messages": data.get("messages", []),
 
1309
  prompt_tokens = 0
1310
  completion_tokens = 0
1311
  response_content = ""
1312
+ function_call = None
1313
  tool_calls = []
1314
+
1315
  for line in full_response_content.splitlines():
1316
  if line.startswith("data:"):
1317
+ line = line[5:].strip()
1318
+ if line == "[DONE]":
1319
  continue
1320
+ try:
1321
  response_json = json.loads(line)
 
1322
  if (
1323
  "usage" in response_json and
1324
  "completion_tokens" in response_json["usage"]
 
1345
  if "tool_calls" in message:
1346
  tool_calls.extend(message["tool_calls"])
1347
 
 
1348
  if (
1349
  "usage" in response_json and
1350
  "prompt_tokens" in response_json["usage"]
 
1353
  "usage"
1354
  ]["prompt_tokens"]
1355
 
1356
+
1357
+ except (
1358
  KeyError,
1359
  ValueError,
1360
  IndexError
1361
+ ) as e:
1362
+ logging.error(
1363
  f"解析流式响应单行 JSON 失败: {e}, "
1364
  f"行内容: {line}"
1365
+ )
1366
 
1367
  user_content = ""
1368
  messages = data.get("messages", [])
1369
  for message in messages:
1370
+ if message["role"] == "user":
1371
+ if isinstance(message["content"], str):
1372
  user_content += message["content"] + " "
1373
+ elif isinstance(message["content"], list):
1374
  for item in message["content"]:
1375
  if (
1376
  isinstance(item, dict) and
 
1388
  response_content_replaced = response_content.replace(
1389
  '\n', '\\n'
1390
  ).replace('\r', '\\n')
1391
+
1392
  log_message = (
1393
  f"使用的key: {api_key}, "
1394
  f"提示token: {prompt_tokens}, "
 
1399
  f"用户的内容: {user_content_replaced}, "
1400
  f"输出的内容: {response_content_replaced}"
1401
  )
1402
+
1403
  if tool_calls:
1404
+ log_message += f", tool_calls: {tool_calls}"
1405
+
1406
  logging.info(log_message)
1407
 
1408
  with data_lock:
1409
  request_timestamps.append(time.time())
1410
  token_counts.append(prompt_tokens+completion_tokens)
1411
+
 
 
1412
  # 构造 OpenAI 格式的响应数据
1413
  response_data = {
1414
  "id": f"chatcmpl-{uuid.uuid4()}",
 
1425
  }
1426
  ]
1427
  }
 
 
 
1428
 
1429
  if tool_calls:
1430
+ if isinstance(tool_calls, list) and len(tool_calls) > 0:
1431
+
1432
+ first_tool_call = tool_calls[0]
1433
+ if isinstance(first_tool_call, dict) and "function" in first_tool_call:
1434
+ function_call_data = first_tool_call.get("function")
1435
+ if isinstance(function_call_data, dict) and "name" in function_call_data and "arguments" in function_call_data:
1436
+ function_call = {
1437
+ "name": function_call_data["name"],
1438
+ "arguments": json.dumps(function_call_data["arguments"]) if isinstance(function_call_data.get("arguments"), dict) else function_call_data["arguments"]
1439
+ }
1440
+ response_data["choices"][0]["delta"]["function_call"] = function_call
1441
+ response_data["choices"][0]["delta"]["content"] = None
1442
+ response_data["choices"][0]["finish_reason"] = "function_call"
1443
+ else:
1444
+ response_data["choices"][0]["delta"]["tool_calls"] = tool_calls
1445
+ response_data["choices"][0]["delta"]["content"] = None
1446
+ else:
1447
+ response_data["choices"][0]["delta"]["tool_calls"] = tool_calls
1448
+ response_data["choices"][0]["delta"]["content"] = None
1449
+ elif response_content:
1450
+ response_data["choices"][0]["delta"]["content"] = response_content
1451
+
1452
+
1453
  yield f"data: {json.dumps(response_data)}\n\n".encode('utf-8')
1454
 
1455
  end_chunk_data = {
 
1484
  response_content = response_json[
1485
  "choices"
1486
  ][0]["message"]["content"]
 
1487
  if "tool_calls" in response_json["choices"][0]["message"]:
1488
  tool_calls = response_json["choices"][0]["message"]["tool_calls"]
1489
  else:
1490
+ tool_calls = []
1491
  except (KeyError, ValueError, IndexError) as e:
1492
  logging.error(
1493
  f"解析非流式响应 JSON 失败: {e}, "
 
1511
  item.get("type") == "text"
1512
  ):
1513
  user_content += (
1514
+ item.get("text", "") +
1515
+ " "
1516
  )
1517
 
1518
  user_content = user_content.strip()
 
1523
  response_content_replaced = response_content.replace(
1524
  '\n', '\\n'
1525
  ).replace('\r', '\\n')
1526
+
1527
  log_message = (
1528
+ f"使用的key: {api_key}, "
1529
  f"提示token: {prompt_tokens}, "
1530
  f"输出token: {completion_tokens}, "
1531
  f"首字用时: 0, "
 
1534
  f"用户的内容: {user_content_replaced}, "
1535
  f"输出的内容: {response_content_replaced}"
1536
  )
 
1537
  if tool_calls:
1538
  log_message += f", tool_calls: {tool_calls}"
1539
+
1540
  logging.info(log_message)
1541
+
1542
  with data_lock:
1543
  request_timestamps.append(time.time())
1544
  if "prompt_tokens" in response_json["usage"] and "completion_tokens" in response_json["usage"]:
 
1557
  "index": 0,
1558
  "message": {
1559
  "role": "assistant",
1560
+ "content": response_content,
1561
+
1562
  },
1563
  "finish_reason": "stop",
1564
  }
1565
  ],
1566
  }
 
1567
  if tool_calls:
1568
+ if isinstance(tool_calls, list) and len(tool_calls) > 0:
1569
+ first_tool_call = tool_calls[0]
1570
+ if isinstance(first_tool_call, dict) and "function" in first_tool_call:
1571
+ function_call_data = first_tool_call.get("function")
1572
+ if isinstance(function_call_data, dict) and "name" in function_call_data and "arguments" in function_call_data:
1573
+ function_call = {
1574
+ "name": function_call_data["name"],
1575
+ "arguments": json.dumps(function_call_data["arguments"]) if isinstance(function_call_data.get("arguments"), dict) else function_call_data["arguments"]
1576
+ }
1577
+ response_data["choices"][0]["message"]["function_call"] = function_call
1578
+ response_data["choices"][0]["message"]["content"] = None
1579
+ response_data["choices"][0]["finish_reason"] = "function_call"
1580
+ else:
1581
+ response_data["choices"][0]["message"]["tool_calls"] = tool_calls
1582
+ response_data["choices"][0]["message"]["content"] = None
1583
+ else:
1584
+ response_data["choices"][0]["message"]["tool_calls"] = tool_calls
1585
+ response_data["choices"][0]["message"]["content"] = None
1586
+
1587
 
1588
  return jsonify(response_data)
1589
+
1590
+
1591
  except requests.exceptions.RequestException as e:
1592
  logging.error(f"请求转发异常: {e}")
1593
  return jsonify({"error": str(e)}), 500