fix max token error
Browse files- app/gemini_client.py +14 -2
- app/llm.py +8 -2
app/gemini_client.py
CHANGED
|
@@ -100,8 +100,20 @@ class GeminiClient:
|
|
| 100 |
if hasattr(response, 'usage_metadata'):
|
| 101 |
logger.info(f"[GEMINI][USAGE] Prompt Token Count: {response.usage_metadata.prompt_token_count} - Candidate Token Count: {response.usage_metadata.candidates_token_count} - Total Token Count: {response.usage_metadata.total_token_count}")
|
| 102 |
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
# --- END: Cải tiến logic xử lý response ---
|
| 106 |
except GeminiResponseError as e:
|
| 107 |
# Lỗi nội dung, không thể retry bằng cách đổi key. Propagate lên.
|
|
|
|
| 100 |
if hasattr(response, 'usage_metadata'):
|
| 101 |
logger.info(f"[GEMINI][USAGE] Prompt Token Count: {response.usage_metadata.prompt_token_count} - Candidate Token Count: {response.usage_metadata.candidates_token_count} - Total Token Count: {response.usage_metadata.total_token_count}")
|
| 102 |
|
| 103 |
+
# Bọc lại phần truy cập .text để bắt lỗi ValueError một cách an toàn nhất
|
| 104 |
+
try:
|
| 105 |
+
logger.info(f"[GEMINI][TEXT_RESPONSE] {_safe_truncate(response.text)}")
|
| 106 |
+
return response.text
|
| 107 |
+
except ValueError as ve:
|
| 108 |
+
# Nếu truy cập .text thất bại dù các kiểm tra trước đó đã qua,
|
| 109 |
+
# đây chắc chắn là lỗi logic (MAX_TOKENS/SAFETY).
|
| 110 |
+
# Chuyển đổi nó thành GeminiResponseError để tầng trên xử lý đúng.
|
| 111 |
+
usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
|
| 112 |
+
raise GeminiResponseError(
|
| 113 |
+
f"Gemini response has no valid content part. Original error: {ve}",
|
| 114 |
+
finish_reason='STOP_NO_CONTENT',
|
| 115 |
+
usage_metadata=usage_metadata
|
| 116 |
+
) from ve
|
| 117 |
# --- END: Cải tiến logic xử lý response ---
|
| 118 |
except GeminiResponseError as e:
|
| 119 |
# Lỗi nội dung, không thể retry bằng cách đổi key. Propagate lên.
|
app/llm.py
CHANGED
|
@@ -23,8 +23,14 @@ from .utils import (
|
|
| 23 |
retry_on_llm_transient_error = retry(
|
| 24 |
stop=stop_after_attempt(4), # 1 lần gọi gốc + 3 lần thử lại
|
| 25 |
wait=wait_exponential(multiplier=5, min=10, max=60), # Chờ 10s, 20s, 40s
|
| 26 |
-
#
|
| 27 |
-
retry
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
before_sleep=lambda retry_state: logger.warning(
|
| 29 |
f"[LLM][RETRY] LLM call failed with transient error, retrying... "
|
| 30 |
f"Attempt: {retry_state.attempt_number}, Error: {retry_state.outcome.exception()}"
|
|
|
|
| 23 |
retry_on_llm_transient_error = retry(
|
| 24 |
stop=stop_after_attempt(4), # 1 lần gọi gốc + 3 lần thử lại
|
| 25 |
wait=wait_exponential(multiplier=5, min=10, max=60), # Chờ 10s, 20s, 40s
|
| 26 |
+
# Sửa lỗi: Điều kiện retry phải rõ ràng và an toàn
|
| 27 |
+
# Chỉ retry nếu có exception, và exception đó không phải là GeminiResponseError.
|
| 28 |
+
retry=lambda retry_state: (
|
| 29 |
+
# Phải có exception mới xét đến retry
|
| 30 |
+
retry_state.outcome.failed and
|
| 31 |
+
# Exception đó không được là GeminiResponseError (lỗi logic)
|
| 32 |
+
not isinstance(retry_state.outcome.exception(), GeminiResponseError)
|
| 33 |
+
),
|
| 34 |
before_sleep=lambda retry_state: logger.warning(
|
| 35 |
f"[LLM][RETRY] LLM call failed with transient error, retrying... "
|
| 36 |
f"Attempt: {retry_state.attempt_number}, Error: {retry_state.outcome.exception()}"
|