fix max token error
Browse files- app/constants.py +1 -2
- app/gemini_client.py +18 -22
- app/main.py +5 -2
app/constants.py
CHANGED
|
@@ -221,5 +221,4 @@ LLM_RETRY_WAIT_MESSAGES = [
|
|
| 221 |
"Dữ liệu khá lớn, mình đang tóm tắt lại những điểm chính. Bạn vui lòng đợi trong giây lát."
|
| 222 |
]
|
| 223 |
|
| 224 |
-
SHEET_RANGE = 'chat!A2:N'
|
| 225 |
-
VERSION_NUMBER = 123456800
|
|
|
|
| 221 |
"Dữ liệu khá lớn, mình đang tóm tắt lại những điểm chính. Bạn vui lòng đợi trong giây lát."
|
| 222 |
]
|
| 223 |
|
| 224 |
+
SHEET_RANGE = 'chat!A2:N'
|
|
|
app/gemini_client.py
CHANGED
|
@@ -70,38 +70,34 @@ class GeminiClient:
|
|
| 70 |
|
| 71 |
response = _model.generate_content(prompt, **kwargs)
|
| 72 |
|
| 73 |
-
#
|
| 74 |
-
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
|
| 77 |
-
error_message = f"Gemini response finished with reason: {
|
| 78 |
-
|
| 79 |
-
# Đây là lỗi logic, raise để lớp gọi xử lý (ví dụ: retry với prompt ngắn hơn)
|
| 80 |
raise GeminiResponseError(
|
| 81 |
error_message,
|
| 82 |
-
finish_reason=
|
| 83 |
usage_metadata=usage_metadata
|
| 84 |
)
|
| 85 |
|
|
|
|
| 86 |
self.limit_manager.log_request(key, model, success=True)
|
| 87 |
if hasattr(response, 'usage_metadata'):
|
| 88 |
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}")
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
return response.text
|
| 94 |
-
except ValueError as ve:
|
| 95 |
-
# Chuyển đổi ValueError thành GeminiResponseError nếu đó là lỗi do không có content
|
| 96 |
-
if "requires the response to contain a valid 'Part'" in str(ve):
|
| 97 |
-
finish_reason = response.candidates[0].finish_reason if response.candidates else None
|
| 98 |
-
usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
|
| 99 |
-
raise GeminiResponseError(
|
| 100 |
-
f"Gemini response has no valid content part. Original error: {ve}",
|
| 101 |
-
finish_reason=finish_reason.name if finish_reason else 'MAX_TOKENS_OR_SAFETY',
|
| 102 |
-
usage_metadata=usage_metadata
|
| 103 |
-
) from ve
|
| 104 |
-
raise ve # Ném lại các lỗi ValueError khác
|
| 105 |
except GeminiResponseError as e:
|
| 106 |
# Lỗi nội dung, không thể retry bằng cách đổi key. Propagate lên.
|
| 107 |
logger.error(f"[GEMINI] Non-retriable content error: {e}")
|
|
|
|
| 70 |
|
| 71 |
response = _model.generate_content(prompt, **kwargs)
|
| 72 |
|
| 73 |
+
# --- START: Cải tiến logic xử lý response ---
|
| 74 |
+
# 1. Kiểm tra response có hợp lệ không
|
| 75 |
+
if not response.candidates:
|
| 76 |
+
# Trường hợp bất thường, response không có candidate. Coi là lỗi tạm thời.
|
| 77 |
+
raise ValueError("Gemini response is missing 'candidates' field.")
|
| 78 |
+
|
| 79 |
+
candidate = response.candidates[0]
|
| 80 |
+
# getattr để truy cập an toàn, tránh AttributeError
|
| 81 |
+
finish_reason_name = getattr(getattr(candidate, 'finish_reason', None), 'name', 'UNKNOWN')
|
| 82 |
+
|
| 83 |
+
# 2. Phân loại lỗi: Lỗi logic (cần xử lý ở tầng nghiệp vụ)
|
| 84 |
+
if finish_reason_name not in ["STOP", "FINISH_REASON_UNSPECIFIED"]:
|
| 85 |
usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
|
| 86 |
+
error_message = f"Gemini response finished with non-OK reason: {finish_reason_name}."
|
|
|
|
|
|
|
| 87 |
raise GeminiResponseError(
|
| 88 |
error_message,
|
| 89 |
+
finish_reason=finish_reason_name,
|
| 90 |
usage_metadata=usage_metadata
|
| 91 |
)
|
| 92 |
|
| 93 |
+
# 3. Nếu không có lỗi logic, tiến hành lấy text
|
| 94 |
self.limit_manager.log_request(key, model, success=True)
|
| 95 |
if hasattr(response, 'usage_metadata'):
|
| 96 |
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}")
|
| 97 |
|
| 98 |
+
logger.info(f"[GEMINI][TEXT_RESPONSE] {_safe_truncate(response.text)}")
|
| 99 |
+
return response.text
|
| 100 |
+
# --- END: Cải tiến logic xử lý response ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
except GeminiResponseError as e:
|
| 102 |
# Lỗi nội dung, không thể retry bằng cách đổi key. Propagate lên.
|
| 103 |
logger.error(f"[GEMINI] Non-retriable content error: {e}")
|
app/main.py
CHANGED
|
@@ -4,13 +4,13 @@ from loguru import logger
|
|
| 4 |
import json
|
| 5 |
from typing import Dict, Any, List, Optional
|
| 6 |
import asyncio
|
|
|
|
| 7 |
from concurrent.futures import ThreadPoolExecutor
|
| 8 |
import os
|
| 9 |
import traceback
|
| 10 |
import difflib
|
| 11 |
|
| 12 |
from .config import Settings, get_settings
|
| 13 |
-
from .constants import VERSION_NUMBER
|
| 14 |
from .facebook import FacebookClient
|
| 15 |
from .sheets import SheetsClient
|
| 16 |
from .supabase_db import SupabaseClient
|
|
@@ -26,6 +26,9 @@ from app.channel_manager import channel_manager
|
|
| 26 |
|
| 27 |
app = FastAPI(title="WeBot Facebook Messenger API")
|
| 28 |
|
|
|
|
|
|
|
|
|
|
| 29 |
# Add CORS middleware
|
| 30 |
app.add_middleware(
|
| 31 |
CORSMiddleware,
|
|
@@ -117,7 +120,7 @@ def normalize_vehicle_keyword(keyword: str) -> str:
|
|
| 117 |
async def root():
|
| 118 |
"""Endpoint root để kiểm tra trạng thái app."""
|
| 119 |
logger.info("[HEALTH] Truy cập endpoint root /")
|
| 120 |
-
return {"version": VERSION_NUMBER}
|
| 121 |
|
| 122 |
@app.get("/webhook") #
|
| 123 |
async def verify_webhook(request: Request):
|
|
|
|
| 4 |
import json
|
| 5 |
from typing import Dict, Any, List, Optional
|
| 6 |
import asyncio
|
| 7 |
+
import time
|
| 8 |
from concurrent.futures import ThreadPoolExecutor
|
| 9 |
import os
|
| 10 |
import traceback
|
| 11 |
import difflib
|
| 12 |
|
| 13 |
from .config import Settings, get_settings
|
|
|
|
| 14 |
from .facebook import FacebookClient
|
| 15 |
from .sheets import SheetsClient
|
| 16 |
from .supabase_db import SupabaseClient
|
|
|
|
| 26 |
|
| 27 |
app = FastAPI(title="WeBot Facebook Messenger API")
|
| 28 |
|
| 29 |
+
# Khởi tạo version number một lần duy nhất khi server khởi động
|
| 30 |
+
VERSION_NUMBER = int(time.time())
|
| 31 |
+
|
| 32 |
# Add CORS middleware
|
| 33 |
app.add_middleware(
|
| 34 |
CORSMiddleware,
|
|
|
|
| 120 |
async def root():
|
| 121 |
"""Endpoint root để kiểm tra trạng thái app."""
|
| 122 |
logger.info("[HEALTH] Truy cập endpoint root /")
|
| 123 |
+
return {"version": VERSION_NUMBER, "status": "ok"}
|
| 124 |
|
| 125 |
@app.get("/webhook") #
|
| 126 |
async def verify_webhook(request: Request):
|