|
14 | 14 | from config import ( |
15 | 15 | get_antigravity_api_url, |
16 | 16 | get_antigravity_stream2nostream, |
| 17 | + get_antigravity_switch_credential_enabled, |
17 | 18 | get_auto_ban_error_codes, |
18 | 19 | ) |
19 | 20 | from log import log |
|
26 | 27 | # 导入共同的基础功能 |
27 | 28 | from src.api.utils import ( |
28 | 29 | handle_error_with_retry, |
| 30 | + check_should_auto_ban, |
29 | 31 | get_retry_config, |
30 | 32 | record_api_call_success, |
31 | 33 | record_api_call_error, |
@@ -262,6 +264,7 @@ async def stream_request( |
262 | 264 | Response对象(错误时)或 bytes流/str流(成功时) |
263 | 265 | """ |
264 | 266 | model_name = body.get("model", "") |
| 267 | + switch_credential_enabled = await get_antigravity_switch_credential_enabled() |
265 | 268 |
|
266 | 269 | # 1. 获取有效凭证 |
267 | 270 | cred_result = await credential_manager.get_valid_credential( |
@@ -361,6 +364,7 @@ def apply_cred_result(cred_result: Tuple[str, Dict[str, Any]]) -> bool: |
361 | 364 | for attempt in range(max_retries + 1): |
362 | 365 | success_recorded = False # 标记是否已记录成功 |
363 | 366 | need_retry = False # 标记是否需要重试 |
| 367 | + should_force_switch = False |
364 | 368 |
|
365 | 369 | try: |
366 | 370 | async for chunk in stream_post_async( |
@@ -393,8 +397,13 @@ def apply_cred_result(cred_result: Tuple[str, Dict[str, Any]]) -> bool: |
393 | 397 | except Exception: |
394 | 398 | pass |
395 | 399 |
|
| 400 | + if cooldown_until is not None: |
| 401 | + should_force_switch = True |
| 402 | + elif await check_should_auto_ban(status_code): |
| 403 | + should_force_switch = True |
| 404 | + |
396 | 405 | # 预热下一个凭证 |
397 | | - if next_cred_task is None and attempt < max_retries: |
| 406 | + if (switch_credential_enabled or should_force_switch) and next_cred_task is None and attempt < max_retries: |
398 | 407 | next_cred_task = asyncio.create_task( |
399 | 408 | credential_manager.get_valid_credential( |
400 | 409 | mode="antigravity", model_name=model_name |
@@ -479,21 +488,24 @@ def apply_cred_result(cred_result: Tuple[str, Dict[str, Any]]) -> bool: |
479 | 488 | if need_retry: |
480 | 489 | log.info(f"[ANTIGRAVITY STREAM] 重试请求 (attempt {attempt + 2}/{max_retries + 1})...") |
481 | 490 |
|
482 | | - switched, next_cred_task = await _switch_credential_for_retry( |
483 | | - next_cred_task=next_cred_task, |
484 | | - retry_interval=retry_interval, |
485 | | - refresh_credential_fast=refresh_credential_fast, |
486 | | - apply_cred_result=apply_cred_result, |
487 | | - log_prefix="[ANTIGRAVITY STREAM]", |
488 | | - ) |
489 | | - if not switched: |
490 | | - log.error("[ANTIGRAVITY STREAM] 重试时无可用凭证或令牌") |
491 | | - yield Response( |
492 | | - content=json.dumps({"error": "当前无可用凭证"}), |
493 | | - status_code=500, |
494 | | - media_type="application/json" |
| 491 | + if switch_credential_enabled or should_force_switch: |
| 492 | + switched, next_cred_task = await _switch_credential_for_retry( |
| 493 | + next_cred_task=next_cred_task, |
| 494 | + retry_interval=retry_interval, |
| 495 | + refresh_credential_fast=refresh_credential_fast, |
| 496 | + apply_cred_result=apply_cred_result, |
| 497 | + log_prefix="[ANTIGRAVITY STREAM]", |
495 | 498 | ) |
496 | | - return |
| 499 | + if not switched: |
| 500 | + log.error("[ANTIGRAVITY STREAM] 重试时无可用凭证或令牌") |
| 501 | + yield Response( |
| 502 | + content=json.dumps({"error": "当前无可用凭证"}), |
| 503 | + status_code=500, |
| 504 | + media_type="application/json" |
| 505 | + ) |
| 506 | + return |
| 507 | + else: |
| 508 | + await asyncio.sleep(retry_interval) |
497 | 509 | continue # 重试 |
498 | 510 |
|
499 | 511 | except Exception as e: |
@@ -558,6 +570,7 @@ async def non_stream_request( |
558 | 570 | log.debug("[ANTIGRAVITY] 使用传统非流式模式") |
559 | 571 |
|
560 | 572 | model_name = body.get("model", "") |
| 573 | + switch_credential_enabled = await get_antigravity_switch_credential_enabled() |
561 | 574 |
|
562 | 575 | # 1. 获取有效凭证 |
563 | 576 | cred_result = await credential_manager.get_valid_credential( |
@@ -654,6 +667,7 @@ def apply_cred_result(cred_result: Tuple[str, Dict[str, Any]]) -> bool: |
654 | 667 |
|
655 | 668 | for attempt in range(max_retries + 1): |
656 | 669 | need_retry = False # 标记是否需要重试 |
| 670 | + should_force_switch = False |
657 | 671 |
|
658 | 672 | try: |
659 | 673 | response = await post_async( |
@@ -725,8 +739,13 @@ def apply_cred_result(cred_result: Tuple[str, Dict[str, Any]]) -> bool: |
725 | 739 | except Exception: |
726 | 740 | pass |
727 | 741 |
|
| 742 | + if cooldown_until is not None: |
| 743 | + should_force_switch = True |
| 744 | + elif await check_should_auto_ban(status_code): |
| 745 | + should_force_switch = True |
| 746 | + |
728 | 747 | # 并行预热下一个凭证,不阻塞当前处理 |
729 | | - if next_cred_task is None and attempt < max_retries: |
| 748 | + if (switch_credential_enabled or should_force_switch) and next_cred_task is None and attempt < max_retries: |
730 | 749 | next_cred_task = asyncio.create_task( |
731 | 750 | credential_manager.get_valid_credential( |
732 | 751 | mode="antigravity", model_name=model_name |
@@ -767,20 +786,23 @@ def apply_cred_result(cred_result: Tuple[str, Dict[str, Any]]) -> bool: |
767 | 786 | if need_retry: |
768 | 787 | log.info(f"[ANTIGRAVITY] 重试请求 (attempt {attempt + 2}/{max_retries + 1})...") |
769 | 788 |
|
770 | | - switched, next_cred_task = await _switch_credential_for_retry( |
771 | | - next_cred_task=next_cred_task, |
772 | | - retry_interval=retry_interval, |
773 | | - refresh_credential_fast=refresh_credential_fast, |
774 | | - apply_cred_result=apply_cred_result, |
775 | | - log_prefix="[ANTIGRAVITY]", |
776 | | - ) |
777 | | - if not switched: |
778 | | - log.error("[ANTIGRAVITY] 重试时无可用凭证或令牌") |
779 | | - return Response( |
780 | | - content=json.dumps({"error": "当前无可用凭证"}), |
781 | | - status_code=500, |
782 | | - media_type="application/json" |
| 789 | + if switch_credential_enabled or should_force_switch: |
| 790 | + switched, next_cred_task = await _switch_credential_for_retry( |
| 791 | + next_cred_task=next_cred_task, |
| 792 | + retry_interval=retry_interval, |
| 793 | + refresh_credential_fast=refresh_credential_fast, |
| 794 | + apply_cred_result=apply_cred_result, |
| 795 | + log_prefix="[ANTIGRAVITY]", |
783 | 796 | ) |
| 797 | + if not switched: |
| 798 | + log.error("[ANTIGRAVITY] 重试时无可用凭证或令牌") |
| 799 | + return Response( |
| 800 | + content=json.dumps({"error": "当前无可用凭证"}), |
| 801 | + status_code=500, |
| 802 | + media_type="application/json" |
| 803 | + ) |
| 804 | + else: |
| 805 | + await asyncio.sleep(retry_interval) |
784 | 806 | continue # 重试 |
785 | 807 |
|
786 | 808 | except Exception as e: |
|
0 commit comments