Ge-AI commited on
Commit
d602347
·
verified ·
1 Parent(s): 11d68bb

Update openai_ondemand_adapter.py

Browse files
Files changed (1) hide show
  1. openai_ondemand_adapter.py +35 -70
openai_ondemand_adapter.py CHANGED
@@ -255,35 +255,32 @@ def _execute_one_stream_attempt(apikey_for_attempt, session_id_for_attempt, quer
255
  accumulated_text_parts = []
256
  api_error_yielded = False
257
 
258
- # Inner retry loop for 500 errors specifically for this attempt
259
  max_500_retries_for_this_call = 5
260
  current_500_retry_count = 0
261
 
262
  while current_500_retry_count < max_500_retries_for_this_call:
263
  current_500_retry_count += 1
264
- if current_500_retry_count > 1: # Log if this is a 500-retry
265
  logging.info(f"【流式请求子尝试 {current_attempt_num_logging} - 500错误重试 {current_500_retry_count-1}/{max_500_retries_for_this_call-1}】Key: {keymgr.display_key(apikey_for_attempt)}")
266
  else:
267
  logging.info(f"【流式请求子尝试 {current_attempt_num_logging}】发送到 OnDemand: Session={session_id_for_attempt}, Endpoint={endpoint_id}, Key={keymgr.display_key(apikey_for_attempt)}")
268
 
269
-
270
  try:
271
  with requests.post(url, json=payload, headers=headers, stream=True, timeout=180) as resp:
272
- if resp.status_code == 500: # Specific handling for 500 error
273
  logging.warning(f"【OnDemand流错误】(子尝试 {current_attempt_num_logging}, 500重试 {current_500_retry_count}) 收到500错误。Session: {session_id_for_attempt}")
274
  if current_500_retry_count >= max_500_retries_for_this_call:
275
  logging.error(f"【OnDemand流错误】(子尝试 {current_attempt_num_logging}) 达到500错误最大重试次数。将错误传递给上层。")
276
- # Yield a specific error for persistent 500 after retries
277
  api_error_yielded = True
278
  error_payload = {"error": {"message": f"OnDemand API persistent 500 error after {max_500_retries_for_this_call} retries (Attempt {current_attempt_num_logging}).",
279
  "type": "on_demand_persistent_500_error", "code": 500}}
280
  yield format_openai_sse_delta(error_payload)
281
  yield "data: [DONE]\n\n"
282
  return "".join(accumulated_text_parts).strip(), api_error_yielded
283
- time.sleep(1) # Wait before retrying the 500 error
284
- continue # Go to the next iteration of the 500-retry loop
285
 
286
- if resp.status_code != 200: # Handle other non-200, non-500 errors
287
  api_error_yielded = True
288
  error_text = resp.text
289
  logging.error(f"【OnDemand流错误】请求失败 (子尝试 {current_attempt_num_logging})。状态码: {resp.status_code}, Session: {session_id_for_attempt}, 响应: {error_text[:500]}")
@@ -298,7 +295,6 @@ def _execute_one_stream_attempt(apikey_for_attempt, session_id_for_attempt, quer
298
  yield "data: [DONE]\n\n"
299
  return "".join(accumulated_text_parts).strip(), api_error_yielded
300
 
301
- # Successful 200 response, process stream
302
  first_chunk_sent = False
303
  last_line_str = ""
304
  for line_bytes in resp.iter_lines():
@@ -356,17 +352,13 @@ def _execute_one_stream_attempt(apikey_for_attempt, session_id_for_attempt, quer
356
  if not api_error_yielded and not last_line_str.startswith("data: [DONE]"):
357
  logging.info(f"【OnDemand流】(子尝试 {current_attempt_num_logging}) 流迭代完成,补充发送 [DONE]。Session: {session_id_for_attempt}")
358
  yield "data: [DONE]\n\n"
359
- return "".join(accumulated_text_parts).strip(), api_error_yielded # Success for this attempt
360
 
361
  except requests.exceptions.RequestException as e_req_inner:
362
- # This catches network errors or HTTP errors if resp.raise_for_status() was called (e.g. for persistent 500)
363
  logging.error(f"【OnDemand流】(子尝试 {current_attempt_num_logging}) 请求时发生异常: {e_req_inner}, Key: {keymgr.display_key(apikey_for_attempt)}")
364
- # If this was the last 500-retry, or another RequestException, re-raise to be handled by handle_stream_request's try-except
365
  if current_500_retry_count >= max_500_retries_for_this_call or (hasattr(e_req_inner, 'response') and e_req_inner.response is not None and e_req_inner.response.status_code != 500):
366
  raise e_req_inner
367
- # If it was a 500 and we still have retries for 500, the loop will continue after a delay.
368
- time.sleep(1) # Wait before retrying the 500 error
369
- # The loop will continue to the next 500-retry.
370
 
371
  except Exception as e_inner_unknown:
372
  logging.error(f"【OnDemand流】处理流时发生未知��误 (子尝试 {current_attempt_num_logging}): {e_inner_unknown}, Session: {session_id_for_attempt}", exc_info=True)
@@ -378,10 +370,7 @@ def _execute_one_stream_attempt(apikey_for_attempt, session_id_for_attempt, quer
378
  yield "data: [DONE]\n\n"
379
  return "".join(accumulated_text_parts).strip(), api_error_yielded
380
 
381
- # If 500-retry loop exhausted without returning (should ideally raise inside or return success)
382
  logging.error(f"【OnDemand流】(子尝试 {current_attempt_num_logging}) 500错误重试循环意外结束。")
383
- # This case should ideally not be reached if logic inside loop is correct.
384
- # Re-raise a generic error to be caught by the caller if it does.
385
  raise requests.exceptions.RequestException(f"Exhausted internal 500 retries for attempt {current_attempt_num_logging} without success or specific error propagation.")
386
 
387
 
@@ -517,7 +506,7 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
517
  while empty_retry_attempt_num < max_empty_response_retries:
518
  empty_retry_attempt_num += 1
519
  accumulated_text_this_attempt = ""
520
- api_error_in_attempt = False # Renamed from api_error_yielded for clarity in this scope
521
 
522
  if empty_retry_attempt_num > 1:
523
  logging.info(f"【流式请求-空回复重试 {empty_retry_attempt_num-1}】获取新Key/Session...")
@@ -553,7 +542,6 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
553
  log_attempt_str = f"初始尝试" if empty_retry_attempt_num == 1 else f"空回复重试 {empty_retry_attempt_num-1}"
554
 
555
  try:
556
- # result_tuple will be (accumulated_text, api_error_yielded_flag_from_execute)
557
  result_tuple = yield from _execute_one_stream_attempt(
558
  current_apikey_for_attempt,
559
  current_session_id_for_attempt,
@@ -563,9 +551,9 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
563
  f"{log_attempt_str} (Overall attempt {empty_retry_attempt_num})"
564
  )
565
  accumulated_text_this_attempt = result_tuple[0]
566
- api_error_in_attempt = result_tuple[1] # This tells if _execute_one_stream_attempt itself yielded an error SSE
567
 
568
- except requests.exceptions.RequestException as e_req: # Catch errors from _execute_one_stream_attempt's requests.post
569
  log_key_display = keymgr.display_key(current_apikey_for_attempt) if current_apikey_for_attempt else "N/A"
570
  status_code_from_exc_stream = None
571
  if hasattr(e_req, 'response') and e_req.response is not None:
@@ -582,11 +570,8 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
582
  keymgr.mark_bad(current_apikey_for_attempt)
583
 
584
  if empty_retry_attempt_num == 1:
585
- # If the very first attempt (initial_apikey) fails with RequestException,
586
- # re-raise to let with_valid_key_and_session handle key rotation.
587
  raise e_req
588
 
589
- # If it's an empty-response retry (attempt_num > 1) that failed with RequestException
590
  if empty_retry_attempt_num >= max_empty_response_retries:
591
  final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
592
  final_error_code = "max_retries_check_context_contact_admin"
@@ -595,20 +580,16 @@ def handle_stream_request(initial_apikey, initial_session_id, query_str, endpoin
595
  yield "data: [DONE]\n\n"
596
  return
597
  time.sleep(1)
598
- continue # To the next iteration of the empty_retry_attempt_num loop (will try new key/session)
599
 
600
- # After _execute_one_stream_attempt has finished (either normally or yielded its own error)
601
  if api_error_in_attempt:
602
- # This means _execute_one_stream_attempt handled an API error (like 429, or persistent 500) and yielded an error SSE.
603
- # The stream is already complete with an error.
604
  logging.warning(f"【流式请求】({log_attempt_str}) 子尝试已处理并流式传输API错误。")
605
- return # Stop further empty response retries.
606
 
607
  if accumulated_text_this_attempt:
608
  logging.info(f"【流式请求】({log_attempt_str}) 成功获取非空内容。")
609
- return # Stream was successful and content yielded.
610
 
611
- # If we reach here, content was empty from _execute_one_stream_attempt, and no API error was yielded by it.
612
  logging.warning(f"【流式请求】({log_attempt_str}) 返回空内容。")
613
  if empty_retry_attempt_num >= max_empty_response_retries:
614
  final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
@@ -637,6 +618,8 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
637
  current_apikey_for_attempt = initial_apikey
638
  current_session_id_for_attempt = initial_session_id
639
 
 
 
640
  while empty_retry_attempt_num < max_empty_response_retries:
641
  empty_retry_attempt_num += 1
642
 
@@ -671,10 +654,12 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
671
 
672
  log_attempt_str = f"初始尝试" if empty_retry_attempt_num == 1 else f"空回复重试 {empty_retry_attempt_num-1}"
673
 
674
- # Inner loop for 500-error retries for the current key/session
675
  max_500_retries_for_this_call = 5
676
  current_500_retry_count = 0
677
 
 
 
 
678
  while current_500_retry_count < max_500_retries_for_this_call:
679
  current_500_retry_count += 1
680
  if current_500_retry_count > 1:
@@ -682,8 +667,9 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
682
  else:
683
  logging.info(f"【同步请求】({log_attempt_str}, 总尝试 {empty_retry_attempt_num}) Session={current_session_id_for_attempt}, Key={keymgr.display_key(current_apikey_for_attempt)}")
684
 
685
- url = f"{ONDEMAND_API_BASE}/sessions/{current_session_id_for_attempt}/query" # Ensure URL uses current session
686
- payload = { "query": final_query_to_ondemand, "endpointId": target_endpoint_id, "pluginIds": [], "responseMode": "sync" } # Use correct query and endpoint
 
687
  headers = {"apikey": current_apikey_for_attempt, "Content-Type": "application/json"}
688
 
689
  try:
@@ -693,13 +679,12 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
693
  logging.warning(f"【OnDemand同步错误】({log_attempt_str}, 500重试 {current_500_retry_count}) 收到500错误。")
694
  if current_500_retry_count >= max_500_retries_for_this_call:
695
  logging.error(f"【OnDemand同步错误】({log_attempt_str}) 达到500错误最大重试次数。将错误传递给上层。")
696
- resp.raise_for_status() # Re-raise HTTPError(500) to be caught by outer RequestException handler
697
  time.sleep(1)
698
- continue # Next 500-retry iteration
699
 
700
- resp.raise_for_status() # For other non-200 errors (will be caught by RequestException below)
701
 
702
- # Successful 200 OK
703
  response_json = resp.json()
704
  if "data" not in response_json or "answer" not in response_json["data"]:
705
  logging.error(f"【OnDemand同步错误】响应格式不符合预期 ({log_attempt_str})。Session: {current_session_id_for_attempt}, 响应: {str(response_json)[:500]}")
@@ -718,13 +703,10 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
718
  }
719
  return jsonify(openai_response_obj) # SUCCESS
720
  else:
721
- # Empty response after a 200 OK (and non-500 error)
722
  logging.warning(f"【同步请求】({log_attempt_str}, 500重试 {current_500_retry_count}) 返回空回复。")
723
- # This attempt (for this key/session) resulted in an empty response.
724
- # Break from the 500-retry loop to let the outer empty-response loop handle it.
725
- break # Break from current_500_retry_count loop
726
 
727
- except requests.exceptions.RequestException as e_req: # Catches HTTPError (including re-raised 500) or other network issues
728
  log_key_display_sync = keymgr.display_key(current_apikey_for_attempt) if current_apikey_for_attempt else "N/A"
729
  status_code_from_exc_sync = None
730
  if hasattr(e_req, 'response') and e_req.response is not None:
@@ -732,38 +714,25 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
732
 
733
  logging.warning(f"【同步请求】({log_attempt_str}, 500重试 {current_500_retry_count} using key {log_key_display_sync}) 发生请求级错误: {e_req}, Status: {status_code_from_exc_sync}")
734
 
735
- # Key marking is handled by with_valid_key_and_session based on what's re-raised.
736
- # If it's a 500 that exhausted its inner retries, it will be re-raised.
737
- # If it's another RequestException, it's also re-raised.
738
-
739
- # If this was the initial overall attempt (empty_retry_attempt_num == 1)
740
- # AND this specific 500-retry loop has exhausted OR it's not a 500 error that can be retried by this inner loop:
741
  if current_500_retry_count >= max_500_retries_for_this_call or status_code_from_exc_sync != 500:
742
  if empty_retry_attempt_num == 1:
743
- raise e_req # Re-raise for with_valid_key_and_session to handle key rotation
744
  else:
745
- # This was an empty-response retry that then hit a persistent 500 or other RequestException.
746
- # This attempt for this key has failed. Break 500-retry loop to go to next empty-response attempt.
747
- # To signal this failure for the current key/session to the outer empty-response loop:
748
- raise e_req # This will be caught by the outer try-except in the empty_retry_attempt_num loop
749
 
750
- # If it was a 500 and we still have 500-retries, the loop will continue after sleep.
751
  time.sleep(1)
752
- continue # To the next iteration of current_500_retry_count loop
753
 
754
  except (ValueError, KeyError, json.JSONDecodeError) as e_parse:
755
  logging.error(f"【同步请求】({log_attempt_str}, 500重试 {current_500_retry_count}) 处理响应或格式时出错: {e_parse}", exc_info=True)
756
- if empty_retry_attempt_num == 1 and current_500_retry_count == 1 : # Format error on very first try
757
  raise requests.exceptions.RequestException(f"Response format error on first attempt: {e_parse}") from e_parse
758
- # If format error during a retry, it's a failure for this key/session attempt
759
- # Break from 500-retry loop, let empty-response loop handle it.
760
- # To signal this failure for the current key/session:
761
  raise requests.exceptions.RequestException(f"Response format error during retry: {e_parse}") from e_parse
762
 
763
-
764
- # If the 500-retry loop completed (either successfully got non-empty, or broke due to empty, or raised an error)
765
- # Check if we are here because of an empty response (meaning the 500-retry loop broke after a 200 OK but empty content)
766
- if not ai_response_content.strip() and not ( 'resp' in locals() and resp.status_code != 200 ): # Check if it was an empty response from a 200 OK
767
  if empty_retry_attempt_num >= max_empty_response_retries:
768
  final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
769
  final_error_code = "max_retries_check_context_contact_admin"
@@ -777,12 +746,8 @@ def handle_non_stream_request(initial_apikey, initial_session_id, query_str, end
777
  }), 500
778
  logging.info(f"【同步请求】空回复(在500-重试循环之后),准备进行下一个空回复尝试。当前总尝试 {empty_retry_attempt_num}/{max_empty_response_retries}")
779
  time.sleep(1)
780
- # Outer loop (empty_retry_attempt_num) will continue
781
- # If we are here and didn't return a success, it means the 500-retry loop might have been exhausted by 500s
782
- # but didn't re-raise correctly, or some other path. This is a fallback.
783
- # However, if it exhausted 500s, it should have re-raised an exception.
784
 
785
- # Fallback if outer empty_retry_attempt_num loop finishes
786
  final_fallback_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
787
  final_fallback_error_code = "max_retries_check_context_contact_admin_fallback"
788
  logging.error(f"【同步请求】意外退出空回复重试循环。返回最终错误。")
 
255
  accumulated_text_parts = []
256
  api_error_yielded = False
257
 
 
258
  max_500_retries_for_this_call = 5
259
  current_500_retry_count = 0
260
 
261
  while current_500_retry_count < max_500_retries_for_this_call:
262
  current_500_retry_count += 1
263
+ if current_500_retry_count > 1:
264
  logging.info(f"【流式请求子尝试 {current_attempt_num_logging} - 500错误重试 {current_500_retry_count-1}/{max_500_retries_for_this_call-1}】Key: {keymgr.display_key(apikey_for_attempt)}")
265
  else:
266
  logging.info(f"【流式请求子尝试 {current_attempt_num_logging}】发送到 OnDemand: Session={session_id_for_attempt}, Endpoint={endpoint_id}, Key={keymgr.display_key(apikey_for_attempt)}")
267
 
 
268
  try:
269
  with requests.post(url, json=payload, headers=headers, stream=True, timeout=180) as resp:
270
+ if resp.status_code == 500:
271
  logging.warning(f"【OnDemand流错误】(子尝试 {current_attempt_num_logging}, 500重试 {current_500_retry_count}) 收到500错误。Session: {session_id_for_attempt}")
272
  if current_500_retry_count >= max_500_retries_for_this_call:
273
  logging.error(f"【OnDemand流错误】(子尝试 {current_attempt_num_logging}) 达到500错误最大重试次数。将错误传递给上层。")
 
274
  api_error_yielded = True
275
  error_payload = {"error": {"message": f"OnDemand API persistent 500 error after {max_500_retries_for_this_call} retries (Attempt {current_attempt_num_logging}).",
276
  "type": "on_demand_persistent_500_error", "code": 500}}
277
  yield format_openai_sse_delta(error_payload)
278
  yield "data: [DONE]\n\n"
279
  return "".join(accumulated_text_parts).strip(), api_error_yielded
280
+ time.sleep(1)
281
+ continue
282
 
283
+ if resp.status_code != 200:
284
  api_error_yielded = True
285
  error_text = resp.text
286
  logging.error(f"【OnDemand流错误】请求失败 (子尝试 {current_attempt_num_logging})。状态码: {resp.status_code}, Session: {session_id_for_attempt}, 响应: {error_text[:500]}")
 
295
  yield "data: [DONE]\n\n"
296
  return "".join(accumulated_text_parts).strip(), api_error_yielded
297
 
 
298
  first_chunk_sent = False
299
  last_line_str = ""
300
  for line_bytes in resp.iter_lines():
 
352
  if not api_error_yielded and not last_line_str.startswith("data: [DONE]"):
353
  logging.info(f"【OnDemand流】(子尝试 {current_attempt_num_logging}) 流迭代完成,补充发送 [DONE]。Session: {session_id_for_attempt}")
354
  yield "data: [DONE]\n\n"
355
+ return "".join(accumulated_text_parts).strip(), api_error_yielded
356
 
357
  except requests.exceptions.RequestException as e_req_inner:
 
358
  logging.error(f"【OnDemand流】(子尝试 {current_attempt_num_logging}) 请求时发生异常: {e_req_inner}, Key: {keymgr.display_key(apikey_for_attempt)}")
 
359
  if current_500_retry_count >= max_500_retries_for_this_call or (hasattr(e_req_inner, 'response') and e_req_inner.response is not None and e_req_inner.response.status_code != 500):
360
  raise e_req_inner
361
+ time.sleep(1)
 
 
362
 
363
  except Exception as e_inner_unknown:
364
  logging.error(f"【OnDemand流】处理流时发生未知��误 (子尝试 {current_attempt_num_logging}): {e_inner_unknown}, Session: {session_id_for_attempt}", exc_info=True)
 
370
  yield "data: [DONE]\n\n"
371
  return "".join(accumulated_text_parts).strip(), api_error_yielded
372
 
 
373
  logging.error(f"【OnDemand流】(子尝试 {current_attempt_num_logging}) 500错误重试循环意外结束。")
 
 
374
  raise requests.exceptions.RequestException(f"Exhausted internal 500 retries for attempt {current_attempt_num_logging} without success or specific error propagation.")
375
 
376
 
 
506
  while empty_retry_attempt_num < max_empty_response_retries:
507
  empty_retry_attempt_num += 1
508
  accumulated_text_this_attempt = ""
509
+ api_error_in_attempt = False
510
 
511
  if empty_retry_attempt_num > 1:
512
  logging.info(f"【流式请求-空回复重试 {empty_retry_attempt_num-1}】获取新Key/Session...")
 
542
  log_attempt_str = f"初始尝试" if empty_retry_attempt_num == 1 else f"空回复重试 {empty_retry_attempt_num-1}"
543
 
544
  try:
 
545
  result_tuple = yield from _execute_one_stream_attempt(
546
  current_apikey_for_attempt,
547
  current_session_id_for_attempt,
 
551
  f"{log_attempt_str} (Overall attempt {empty_retry_attempt_num})"
552
  )
553
  accumulated_text_this_attempt = result_tuple[0]
554
+ api_error_in_attempt = result_tuple[1]
555
 
556
+ except requests.exceptions.RequestException as e_req:
557
  log_key_display = keymgr.display_key(current_apikey_for_attempt) if current_apikey_for_attempt else "N/A"
558
  status_code_from_exc_stream = None
559
  if hasattr(e_req, 'response') and e_req.response is not None:
 
570
  keymgr.mark_bad(current_apikey_for_attempt)
571
 
572
  if empty_retry_attempt_num == 1:
 
 
573
  raise e_req
574
 
 
575
  if empty_retry_attempt_num >= max_empty_response_retries:
576
  final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
577
  final_error_code = "max_retries_check_context_contact_admin"
 
580
  yield "data: [DONE]\n\n"
581
  return
582
  time.sleep(1)
583
+ continue
584
 
 
585
  if api_error_in_attempt:
 
 
586
  logging.warning(f"【流式请求】({log_attempt_str}) 子尝试已处理并流式传输API错误。")
587
+ return
588
 
589
  if accumulated_text_this_attempt:
590
  logging.info(f"【流式请求】({log_attempt_str}) 成功获取非空内容。")
591
+ return
592
 
 
593
  logging.warning(f"【流式请求】({log_attempt_str}) 返回空内容。")
594
  if empty_retry_attempt_num >= max_empty_response_retries:
595
  final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
 
618
  current_apikey_for_attempt = initial_apikey
619
  current_session_id_for_attempt = initial_session_id
620
 
621
+ ai_response_content = "" # Define ai_response_content outside the try block to ensure it's available for the final empty check
622
+
623
  while empty_retry_attempt_num < max_empty_response_retries:
624
  empty_retry_attempt_num += 1
625
 
 
654
 
655
  log_attempt_str = f"初始尝试" if empty_retry_attempt_num == 1 else f"空回复重试 {empty_retry_attempt_num-1}"
656
 
 
657
  max_500_retries_for_this_call = 5
658
  current_500_retry_count = 0
659
 
660
+ # Reset ai_response_content for each new attempt (especially for the 500-retry loop)
661
+ ai_response_content = ""
662
+
663
  while current_500_retry_count < max_500_retries_for_this_call:
664
  current_500_retry_count += 1
665
  if current_500_retry_count > 1:
 
667
  else:
668
  logging.info(f"【同步请求】({log_attempt_str}, 总尝试 {empty_retry_attempt_num}) Session={current_session_id_for_attempt}, Key={keymgr.display_key(current_apikey_for_attempt)}")
669
 
670
+ url = f"{ONDEMAND_API_BASE}/sessions/{current_session_id_for_attempt}/query"
671
+ # Corrected: Use query_str and endpoint_id parameters passed to the function
672
+ payload = { "query": query_str, "endpointId": endpoint_id, "pluginIds": [], "responseMode": "sync" }
673
  headers = {"apikey": current_apikey_for_attempt, "Content-Type": "application/json"}
674
 
675
  try:
 
679
  logging.warning(f"【OnDemand同步错误】({log_attempt_str}, 500重试 {current_500_retry_count}) 收到500错误。")
680
  if current_500_retry_count >= max_500_retries_for_this_call:
681
  logging.error(f"【OnDemand同步错误】({log_attempt_str}) 达到500错误最大重试次数。将错误传递给上层。")
682
+ resp.raise_for_status()
683
  time.sleep(1)
684
+ continue
685
 
686
+ resp.raise_for_status()
687
 
 
688
  response_json = resp.json()
689
  if "data" not in response_json or "answer" not in response_json["data"]:
690
  logging.error(f"【OnDemand同步错误】响应格式不符合预期 ({log_attempt_str})。Session: {current_session_id_for_attempt}, 响应: {str(response_json)[:500]}")
 
703
  }
704
  return jsonify(openai_response_obj) # SUCCESS
705
  else:
 
706
  logging.warning(f"【同步请求】({log_attempt_str}, 500重试 {current_500_retry_count}) 返回空回复。")
707
+ break
 
 
708
 
709
+ except requests.exceptions.RequestException as e_req:
710
  log_key_display_sync = keymgr.display_key(current_apikey_for_attempt) if current_apikey_for_attempt else "N/A"
711
  status_code_from_exc_sync = None
712
  if hasattr(e_req, 'response') and e_req.response is not None:
 
714
 
715
  logging.warning(f"【同步请求】({log_attempt_str}, 500重试 {current_500_retry_count} using key {log_key_display_sync}) 发生请求级错误: {e_req}, Status: {status_code_from_exc_sync}")
716
 
 
 
 
 
 
 
717
  if current_500_retry_count >= max_500_retries_for_this_call or status_code_from_exc_sync != 500:
718
  if empty_retry_attempt_num == 1:
719
+ raise e_req
720
  else:
721
+ raise e_req
 
 
 
722
 
 
723
  time.sleep(1)
724
+ # Continue to the next iteration of current_500_retry_count loop
725
 
726
  except (ValueError, KeyError, json.JSONDecodeError) as e_parse:
727
  logging.error(f"【同步请求】({log_attempt_str}, 500重试 {current_500_retry_count}) 处理响应或格式时出错: {e_parse}", exc_info=True)
728
+ if empty_retry_attempt_num == 1 and current_500_retry_count == 1 :
729
  raise requests.exceptions.RequestException(f"Response format error on first attempt: {e_parse}") from e_parse
 
 
 
730
  raise requests.exceptions.RequestException(f"Response format error during retry: {e_parse}") from e_parse
731
 
732
+ # After the 500-retry loop for the current key/session
733
+ if ai_response_content.strip(): # Should have been returned if non-empty
734
+ pass # Should not reach here if content was found
735
+ else: # Content is still empty for this key/session after 500-retries (or if 200 OK but empty)
736
  if empty_retry_attempt_num >= max_empty_response_retries:
737
  final_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
738
  final_error_code = "max_retries_check_context_contact_admin"
 
746
  }), 500
747
  logging.info(f"【同步请求】空回复(在500-重试循环之后),准备进行下一个空回复尝试。当前总尝试 {empty_retry_attempt_num}/{max_empty_response_retries}")
748
  time.sleep(1)
749
+ # Outer loop (empty_retry_attempt_num) will continue to try a new key/session
 
 
 
750
 
 
751
  final_fallback_error_message = "重试次数过多,请检查上下文长度! 或联系管理员!"
752
  final_fallback_error_code = "max_retries_check_context_contact_admin_fallback"
753
  logging.error(f"【同步请求】意外退出空回复重试循环。返回最终错误。")