Ge-AI commited on
Commit
b7f225b
·
verified ·
1 Parent(s): 9dbbfff

Update openai_ondemand_adapter.py

Browse files
Files changed (1) hide show
  1. openai_ondemand_adapter.py +86 -40
openai_ondemand_adapter.py CHANGED
@@ -440,11 +440,14 @@ def chat_completions():
440
  logging.warning(f"【请求处理 - Key轮换尝试 {key_retry_count}】HTTP/请求错误。Status: {status_code_from_exc}, Key: {keymgr.display_key(selected_apikey_for_outer_retry) if selected_apikey_for_outer_retry else 'N/A'}, Error: {http_err_outer}")
441
 
442
  if selected_apikey_for_outer_retry:
443
- if status_code_from_exc == 524:
444
  logging.info(f"【KeyManager】Key {keymgr.display_key(selected_apikey_for_outer_retry)} not marked bad due to 524 error.")
445
- else:
 
446
  keymgr.mark_bad(selected_apikey_for_outer_retry)
447
-
 
 
448
  if key_retry_count >= max_key_retries:
449
  logging.error(f"【请求处理】所有Key轮换尝试均失败。最后错误: {last_exception_for_key_retry}")
450
  break
@@ -455,22 +458,23 @@ def chat_completions():
455
  except Exception as e_outer:
456
  last_exception_for_key_retry = e_outer
457
  logging.error(f"【请求处理 - Key轮换尝试 {key_retry_count}】发生意外严重错误: {e_outer}", exc_info=True)
458
- if selected_apikey_for_outer_retry:
459
  keymgr.mark_bad(selected_apikey_for_outer_retry)
460
  break
461
 
462
- error_message = "All attempts to process the request failed after multiple key/session retries."
463
- if last_exception_for_key_retry:
464
- error_message += f" Last known error during key/session phase: {str(last_exception_for_key_retry)}"
465
- logging.error(error_message)
 
466
 
467
  if is_stream_request:
468
  def error_stream_gen():
469
- yield format_openai_sse_delta({"error": {"message": error_message, "type": "proxy_setup_error", "code": "proxy_error_503"}}) # Changed code
470
  yield "data: [DONE]\n\n"
471
- return Response(error_stream_gen(), content_type='text/event-stream', status=503)
472
  else:
473
- return jsonify({"error": error_message, "code": "proxy_error_503"}), 503 # Added code here
474
 
475
  return with_valid_key_and_session(attempt_ondemand_request_wrapper)
476
 
@@ -494,17 +498,22 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
494
  logging.info(f"【流式请求-空回复重试 {empty_retry_attempt_num-1}】新Key/Session获取成功: Key={keymgr.display_key(current_apikey_for_attempt)}, Session={current_session_id_for_attempt}")
495
  except (ValueError, requests.exceptions.RequestException) as e_key_session:
496
  logging.warning(f"【流式请求-空回复重试 {empty_retry_attempt_num-1}】获取新Key/Session失败: {e_key_session}")
 
 
 
 
497
  if current_apikey_for_attempt and not isinstance(e_key_session, ValueError):
498
- status_code_from_exc = None
499
- if hasattr(e_key_session, 'response') and e_key_session.response is not None:
500
- status_code_from_exc = e_key_session.response.status_code
501
- if status_code_from_exc == 524:
502
- logging.info(f"【KeyManager】Key {keymgr.display_key(current_apikey_for_attempt)} not marked bad for 524 error during key/session acquisition for retry.")
503
  else:
504
  keymgr.mark_bad(current_apikey_for_attempt)
505
 
506
  if empty_retry_attempt_num >= max_empty_response_retries:
507
- yield format_openai_sse_delta({"error": {"message": f"Failed to get new key/session for final empty stream retry. Error: {str(e_key_session)}", "type": "internal_proxy_error", "code": "proxy_retry_setup_failed"}})
 
 
 
 
508
  yield "data: [DONE]\n\n"
509
  return
510
  time.sleep(1)
@@ -543,8 +552,10 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
543
  raise e_req
544
 
545
  if empty_retry_attempt_num >= max_empty_response_retries:
546
- logging.error(f"【流式请求】在最后一次空回复重试时发生请求错误。")
547
- yield format_openai_sse_delta({"error": {"message": f"Request failed on final empty stream retry attempt: {str(e_req)}", "type": "internal_proxy_error", "code": "proxy_final_retry_failed"}})
 
 
548
  yield "data: [DONE]\n\n"
549
  return
550
  time.sleep(1)
@@ -560,9 +571,11 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
560
 
561
  logging.warning(f"【流式请求】({log_attempt_str}) 返回空内容。")
562
  if empty_retry_attempt_num >= max_empty_response_retries:
563
- logging.error(f"【流式请求】达到最大空回复重试次数 ({max_empty_response_retries})。")
 
 
564
  yield format_openai_sse_delta({
565
- "error": {"message": "返回空回复,请重试", "type": "empty_response_after_retries", "code": "empty_response_please_retry"} # Changed message and code
566
  })
567
  yield "data: [DONE]\n\n"
568
  return
@@ -570,8 +583,13 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
570
  logging.info(f"【流式请求】空回复,将在1秒后重试下一个Key。当前总尝试 {empty_retry_attempt_num}/{max_empty_response_retries}")
571
  time.sleep(1)
572
 
573
- logging.error("【流式请求】意外退出空回复重试循环。")
574
- yield format_openai_sse_delta({"error": {"message": "Unexpected error in stream handling.", "type": "internal_proxy_error", "code":"unexpected_stream_exit"}})
 
 
 
 
 
575
  yield "data: [DONE]\n\n"
576
 
577
 
@@ -596,16 +614,21 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
596
  logging.info(f"【同步请求-空回复重试 {empty_retry_attempt_num-1}】新Key/Session获取成功: Key={keymgr.display_key(current_apikey_for_attempt)}, Session={current_session_id_for_attempt}")
597
  except (ValueError, requests.exceptions.RequestException) as e_key_session:
598
  logging.warning(f"【同步请求-空回复重试 {empty_retry_attempt_num-1}】获取新Key/Session失败: {e_key_session}")
 
 
 
 
599
  if current_apikey_for_attempt and not isinstance(e_key_session, ValueError):
600
- status_code_from_exc = None
601
- if hasattr(e_key_session, 'response') and e_key_session.response is not None:
602
- status_code_from_exc = e_key_session.response.status_code
603
- if status_code_from_exc == 524:
604
  logging.info(f"【KeyManager】Key {keymgr.display_key(current_apikey_for_attempt)} not marked bad for 524 error during key/session acquisition for non-stream retry.")
605
  else:
606
  keymgr.mark_bad(current_apikey_for_attempt)
607
  if empty_retry_attempt_num >= max_empty_response_retries:
608
- return jsonify({"error": f"Failed to get new key/session for final empty response retry. Error: {str(e_key_session)}", "code":"proxy_retry_setup_failed"}), 503
 
 
 
 
609
  time.sleep(1)
610
  current_apikey_for_attempt = None
611
  continue
@@ -623,7 +646,10 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
623
  response_json = resp.json()
624
  if "data" not in response_json or "answer" not in response_json["data"]:
625
  logging.error(f"【OnDemand同步错误】响应格式不符合预期 ({log_attempt_str})。Session: {current_session_id_for_attempt}, 响应: {str(response_json)[:500]}")
626
- raise ValueError("OnDemand API sync response missing 'data.answer' field.")
 
 
 
627
 
628
  ai_response_content = response_json["data"]["answer"]
629
  if ai_response_content is None: ai_response_content = ""
@@ -640,15 +666,17 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
640
  else:
641
  logging.warning(f"【同步请求】({log_attempt_str}) 返回空回复。")
642
  if empty_retry_attempt_num >= max_empty_response_retries:
643
- logging.error(f"【同步请求】达到最大空回复重试次数 ({max_empty_response_retries})。")
 
 
644
  return jsonify({
645
- "error": "返回空回复,请重试", # Changed message
646
  "id": "chatcmpl-" + str(uuid.uuid4())[:12], "object": "chat.completion", "created": int(time.time()),
647
  "model": openai_model_name_for_response,
648
- "choices": [{"index": 0, "message": {"role": "assistant", "content": ""}, "finish_reason": "length"}], # or "error" finish_reason
649
  "usage": {},
650
- "code": "empty_response_please_retry" # Added code
651
- }), 503 # Changed status code to 503 for "please retry"
652
  logging.info(f"【同步请求】空回复,将在1秒后重试下一个Key。当前总尝试 {empty_retry_attempt_num}/{max_empty_response_retries}")
653
  time.sleep(1)
654
 
@@ -669,16 +697,34 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
669
  if empty_retry_attempt_num == 1:
670
  raise e_req
671
  if empty_retry_attempt_num >= max_empty_response_retries:
672
- logging.error(f"【同步请求】在最后一次空回复重试时发生请求错误。")
673
- return jsonify({"error": f"Request failed on final empty response retry attempt. Last error: {str(e_req)}", "code":"proxy_final_retry_failed"}), 503
 
 
674
  time.sleep(1)
675
  continue
676
  except (ValueError, KeyError, json.JSONDecodeError) as e_parse:
677
- logging.error(f"【同步请求】({log_attempt_str}) 处理响应时出错: {e_parse}", exc_info=True)
678
- return jsonify({"error": f"Error processing OnDemand sync response: {str(e_parse)}", "code": "on_demand_parse_error"}), 502
 
 
 
 
 
 
 
 
 
 
 
 
 
679
 
680
- logging.error(f"【同步请求】意外退出空回复重试循环。")
681
- return jsonify({"error": "返回空回复,请重试", "code": "unexpected_empty_retry_exit_please_retry"}), 503 # Changed message and code, and status
 
 
 
682
 
683
 
684
  @app.route("/v1/models", methods=["GET"])
 
440
  logging.warning(f"【请求处理 - Key轮换尝试 {key_retry_count}】HTTP/请求错误。Status: {status_code_from_exc}, Key: {keymgr.display_key(selected_apikey_for_outer_retry) if selected_apikey_for_outer_retry else 'N/A'}, Error: {http_err_outer}")
441
 
442
  if selected_apikey_for_outer_retry:
443
+ if status_code_from_exc == 524: # HTTP 524: A Timeout Occurred (Cloudflare)
444
  logging.info(f"【KeyManager】Key {keymgr.display_key(selected_apikey_for_outer_retry)} not marked bad due to 524 error.")
445
+ # For other client/server errors that might indicate a key issue or persistent service issue with this key
446
+ elif status_code_from_exc and (400 <= status_code_from_exc < 500 or status_code_from_exc in [500, 502, 503]): # excluding 524
447
  keymgr.mark_bad(selected_apikey_for_outer_retry)
448
+ elif not status_code_from_exc : # Network errors without a status code (e.g., connection refused, DNS failure)
449
+ keymgr.mark_bad(selected_apikey_for_outer_retry)
450
+
451
  if key_retry_count >= max_key_retries:
452
  logging.error(f"【请求处理】所有Key轮换尝试均失败。最后错误: {last_exception_for_key_retry}")
453
  break
 
458
  except Exception as e_outer:
459
  last_exception_for_key_retry = e_outer
460
  logging.error(f"【请求处理 - Key轮换尝试 {key_retry_count}】发生意外严重错误: {e_outer}", exc_info=True)
461
+ if selected_apikey_for_outer_retry: # Mark key bad on any other unexpected exception during setup
462
  keymgr.mark_bad(selected_apikey_for_outer_retry)
463
  break
464
 
465
+ # This block is reached if all key_retry_count attempts in with_valid_key_and_session fail
466
+ error_message = "重试次数过多,请检查上下文长度! 或联系管理员!" # User requested message
467
+ error_code_str = "max_retries_check_context_contact_admin" # Custom code for this scenario
468
+
469
+ logging.error(f"【请求处理】所有Key/Session获取尝试失败。最终错误: {error_message} Last underlying exception: {last_exception_for_key_retry}")
470
 
471
  if is_stream_request:
472
  def error_stream_gen():
473
+ yield format_openai_sse_delta({"error": {"message": error_message, "type": "proxy_setup_error_max_retries", "code": error_code_str}})
474
  yield "data: [DONE]\n\n"
475
+ return Response(error_stream_gen(), content_type='text/event-stream', status=500) # Status 500 as requested
476
  else:
477
+ return jsonify({"error": error_message, "code": error_code_str}), 500 # Status 500 as requested
478
 
479
  return with_valid_key_and_session(attempt_ondemand_request_wrapper)
480
 
 
498
  logging.info(f"【流式请求-空回复重试 {empty_retry_attempt_num-1}】新Key/Session获取成功: Key={keymgr.display_key(current_apikey_for_attempt)}, Session={current_session_id_for_attempt}")
499
  except (ValueError, requests.exceptions.RequestException) as e_key_session:
500
  logging.warning(f"【流式请求-空回复重试 {empty_retry_attempt_num-1}】获取新Key/Session失败: {e_key_session}")
501
+ status_code_from_exc_retry_setup = None
502
+ if hasattr(e_key_session, 'response') and e_key_session.response is not None:
503
+ status_code_from_exc_retry_setup = e_key_session.response.status_code
504
+
505
  if current_apikey_for_attempt and not isinstance(e_key_session, ValueError):
506
+ if status_code_from_exc_retry_setup == 524:
507
+ logging.info(f"【KeyManager】Key {keymgr.display_key(current_apikey_for_attempt)} not marked bad for 524 error during key/session acquisition for stream retry.")
 
 
 
508
  else:
509
  keymgr.mark_bad(current_apikey_for_attempt)
510
 
511
  if empty_retry_attempt_num >= max_empty_response_retries:
512
+ # Final failure to get key/session for the last empty response retry
513
+ final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
514
+ final_error_code = "max_retries_check_context_contact_admin"
515
+ logging.error(f"【流式请求】无法为最终空回复重试获取新Key/Session。错误: {e_key_session}")
516
+ yield format_openai_sse_delta({"error": {"message": final_error_message, "type": "proxy_final_retry_setup_failed", "code": final_error_code}})
517
  yield "data: [DONE]\n\n"
518
  return
519
  time.sleep(1)
 
552
  raise e_req
553
 
554
  if empty_retry_attempt_num >= max_empty_response_retries:
555
+ final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
556
+ final_error_code = "max_retries_check_context_contact_admin"
557
+ logging.error(f"【流式请求】在最后一次空回复重试时发生请求错误: {e_req}")
558
+ yield format_openai_sse_delta({"error": {"message": final_error_message, "type": "proxy_final_retry_request_failed", "code": final_error_code}})
559
  yield "data: [DONE]\n\n"
560
  return
561
  time.sleep(1)
 
571
 
572
  logging.warning(f"【流式请求】({log_attempt_str}) 返回空内容。")
573
  if empty_retry_attempt_num >= max_empty_response_retries:
574
+ final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
575
+ final_error_code = "max_retries_check_context_contact_admin"
576
+ logging.error(f"【流式请求】达到最大空回复重试次数 ({max_empty_response_retries})。将返回指定错误。")
577
  yield format_openai_sse_delta({
578
+ "error": {"message": final_error_message, "type": "max_retries_exceeded_empty_response", "code": final_error_code}
579
  })
580
  yield "data: [DONE]\n\n"
581
  return
 
583
  logging.info(f"【流式请求】空回复,将在1秒后重试下一个Key。当前总尝试 {empty_retry_attempt_num}/{max_empty_response_retries}")
584
  time.sleep(1)
585
 
586
+ # Fallback if loop finishes unexpectedly (shouldn't happen with current logic)
587
+ # This case means all max_empty_response_retries were exhausted, and the last one was also empty.
588
+ # The specific error for this is handled inside the loop. This is a safeguard.
589
+ final_fallback_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
590
+ final_fallback_error_code = "max_retries_check_context_contact_admin_fallback"
591
+ logging.error(f"【流式请求】意外退出空回复重试循环。返回最终错误。")
592
+ yield format_openai_sse_delta({"error": {"message": final_fallback_error_message, "type": "internal_proxy_error_unexpected_exit", "code": final_fallback_error_code}})
593
  yield "data: [DONE]\n\n"
594
 
595
 
 
614
  logging.info(f"【同步请求-空回复重试 {empty_retry_attempt_num-1}】新Key/Session获取成功: Key={keymgr.display_key(current_apikey_for_attempt)}, Session={current_session_id_for_attempt}")
615
  except (ValueError, requests.exceptions.RequestException) as e_key_session:
616
  logging.warning(f"【同步请求-空回复重试 {empty_retry_attempt_num-1}】获取新Key/Session失败: {e_key_session}")
617
+ status_code_from_exc_retry_setup_ns = None
618
+ if hasattr(e_key_session, 'response') and e_key_session.response is not None:
619
+ status_code_from_exc_retry_setup_ns = e_key_session.response.status_code
620
+
621
  if current_apikey_for_attempt and not isinstance(e_key_session, ValueError):
622
+ if status_code_from_exc_retry_setup_ns == 524:
 
 
 
623
  logging.info(f"【KeyManager】Key {keymgr.display_key(current_apikey_for_attempt)} not marked bad for 524 error during key/session acquisition for non-stream retry.")
624
  else:
625
  keymgr.mark_bad(current_apikey_for_attempt)
626
  if empty_retry_attempt_num >= max_empty_response_retries:
627
+ # Final failure to get key/session for the last empty response retry
628
+ final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
629
+ final_error_code = "max_retries_check_context_contact_admin"
630
+ logging.error(f"【同步请求】无法为最终空回复重试获取新Key/Session。错误: {e_key_session}")
631
+ return jsonify({"error": final_error_message, "code": final_error_code}), 500 # Status 500
632
  time.sleep(1)
633
  current_apikey_for_attempt = None
634
  continue
 
646
  response_json = resp.json()
647
  if "data" not in response_json or "answer" not in response_json["data"]:
648
  logging.error(f"【OnDemand同步错误】响应格式不符合预期 ({log_attempt_str})。Session: {current_session_id_for_attempt}, 响应: {str(response_json)[:500]}")
649
+ # This is an API format error, not an empty response.
650
+ # If this happens on the first attempt, it will be re-raised to with_valid_key_and_session
651
+ # If on a retry for empty response, it's a new kind of failure for that attempt.
652
+ raise ValueError(f"OnDemand API sync response missing 'data.answer' field on attempt {empty_retry_attempt_num}.")
653
 
654
  ai_response_content = response_json["data"]["answer"]
655
  if ai_response_content is None: ai_response_content = ""
 
666
  else:
667
  logging.warning(f"【同步请求】({log_attempt_str}) 返回空回复。")
668
  if empty_retry_attempt_num >= max_empty_response_retries:
669
+ final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
670
+ final_error_code = "max_retries_check_context_contact_admin"
671
+ logging.error(f"【同步请求】达到最大空回复重试次数 ({max_empty_response_retries})。将返回指定错误。")
672
  return jsonify({
673
+ "error": final_error_message,
674
  "id": "chatcmpl-" + str(uuid.uuid4())[:12], "object": "chat.completion", "created": int(time.time()),
675
  "model": openai_model_name_for_response,
676
+ "choices": [{"index": 0, "message": {"role": "assistant", "content": ""}, "finish_reason": "length"}],
677
  "usage": {},
678
+ "code": final_error_code
679
+ }), 500 # Status 500 as requested
680
  logging.info(f"【同步请求】空回复,将在1秒后重试下一个Key。当前总尝试 {empty_retry_attempt_num}/{max_empty_response_retries}")
681
  time.sleep(1)
682
 
 
697
  if empty_retry_attempt_num == 1:
698
  raise e_req
699
  if empty_retry_attempt_num >= max_empty_response_retries:
700
+ final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
701
+ final_error_code = "max_retries_check_context_contact_admin"
702
+ logging.error(f"【同步请求】在最后一次空回复重试时发生请求错误: {e_req}")
703
+ return jsonify({"error": final_error_message, "code":final_error_code, "details": str(e_req)}), 500 # Status 500
704
  time.sleep(1)
705
  continue
706
  except (ValueError, KeyError, json.JSONDecodeError) as e_parse:
707
+ # This catches the ValueError from "data.answer" missing, or JSON decode errors
708
+ logging.error(f"【同步请求】({log_attempt_str}) 处理响应或格式时出错: {e_parse}", exc_info=True)
709
+ if empty_retry_attempt_num == 1:
710
+ # If format error on first attempt, re-raise to be caught by with_valid_key_and_session
711
+ # This implies a more fundamental issue than just an empty response.
712
+ raise requests.exceptions.RequestException(f"Response format error on first attempt: {e_parse}") from e_parse
713
+
714
+ # If it's a format error during an empty-response retry, it's problematic.
715
+ if empty_retry_attempt_num >= max_empty_response_retries:
716
+ final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
717
+ final_error_code = "max_retries_check_context_contact_admin"
718
+ logging.error(f"【同步请求】在最后一次空回复重试时发生响应解析错误: {e_parse}")
719
+ return jsonify({"error": final_error_message, "code": final_error_code, "details": f"Parse error: {str(e_parse)}"}), 500 # Status 500
720
+ time.sleep(1)
721
+ continue # Try next key for empty response retry
722
 
723
+ # Fallback if loop finishes unexpectedly (e.g. all retries were empty and the last one didn't hit the specific return)
724
+ final_fallback_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
725
+ final_fallback_error_code = "max_retries_check_context_contact_admin_fallback"
726
+ logging.error(f"【同步请求】意外退出空回复重试循环。返回最终错误。")
727
+ return jsonify({"error": final_fallback_error_message, "code": final_fallback_error_code}), 500 # Status 500
728
 
729
 
730
  @app.route("/v1/models", methods=["GET"])