VietCat commited on
Commit
0d5bd79
·
1 Parent(s): 844483c

fix max token error

Browse files
Files changed (1) hide show
  1. app/gemini_client.py +20 -18
app/gemini_client.py CHANGED
@@ -87,41 +87,43 @@ class GeminiClient:
87
  # --- START: Cải tiến logic xử lý response ---
88
  # 1. Kiểm tra response có hợp lệ không
89
  if not response.candidates:
90
- # Trường hợp bất thường, response không candidate. Coi lỗi tạm thời.
91
- raise ValueError("Gemini response is missing 'candidates' field.")
92
 
93
  candidate = response.candidates[0]
94
  finish_reason_name = getattr(getattr(candidate, 'finish_reason', None), 'name', 'UNKNOWN')
95
  # Kiểm tra xem có nội dung thực sự không
96
- has_content = bool(candidate.content and candidate.content.parts)
 
97
 
98
- # 2. Phân loại lỗi: Lỗi logic (cần xử lý ở tầng nghiệp vụ)
99
- # Lỗi xảy ra nếu: (A) do kết thúc không phải STOP, HOẶC (B) do là STOP nhưng lại không có nội dung.
100
- if finish_reason_name != "STOP" or not has_content:
101
  usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
102
- if finish_reason_name == "STOP" and not has_content:
103
- error_message = "Gemini response finished with STOP but has no content parts."
104
- else:
105
- error_message = f"Gemini response finished with non-OK reason: {finish_reason_name}."
106
  raise GeminiResponseError(
107
- error_message,
108
- finish_reason=finish_reason_name if finish_reason_name != "STOP" else "STOP_NO_CONTENT",
109
- usage_metadata=usage_metadata
110
  )
111
 
112
- # 3. Nếu khônglỗi logic, tiến hành lấy text
 
 
 
 
 
 
 
 
113
  self.limit_manager.log_request(key, model, success=True)
114
  if hasattr(response, 'usage_metadata'):
115
  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}")
116
 
117
- # Bọc lại phần truy cập .text để bắt lỗi ValueError một cách an toàn nhất
118
  try:
119
  logger.info(f"[GEMINI][TEXT_RESPONSE] {_safe_truncate(response.text)}")
120
  return response.text
121
  except ValueError as ve:
122
- # Nếu truy cập .text thất bại dù các kiểm tra trước đó đã qua,
123
- # đây chắc chắn là lỗi logic (MAX_TOKENS/SAFETY).
124
- # Chuyển đổi nó thành GeminiResponseError để tầng trên xử lý đúng.
125
  usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
126
  raise GeminiResponseError(
127
  f"Gemini response has no valid content part. Original error: {ve}",
 
87
  # --- START: Cải tiến logic xử lý response ---
88
  # 1. Kiểm tra response có hợp lệ không
89
  if not response.candidates:
90
+ # Lỗi này nên được coi lỗi tạm thời, thử lại với key/model khác
91
+ raise ValueError("Gemini response is missing 'candidates' field. Retrying...")
92
 
93
  candidate = response.candidates[0]
94
  finish_reason_name = getattr(getattr(candidate, 'finish_reason', None), 'name', 'UNKNOWN')
95
  # Kiểm tra xem có nội dung thực sự không
96
+ # Sửa: Dùng getattr để tránh AttributeError nếu 'parts' không tồn tại
97
+ has_content = bool(candidate.content and getattr(candidate.content, 'parts', None))
98
 
99
+ # 2. Phân loại lỗi xử lý
100
+ # Case 1: Lỗi nội dung không thể thử lại (SAFETY, MAX_TOKENS, etc.)
101
+ if finish_reason_name != "STOP":
102
  usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
103
+ error_message = f"Gemini response finished with non-OK reason: {finish_reason_name}."
 
 
 
104
  raise GeminiResponseError(
105
+ error_message, finish_reason=finish_reason_name, usage_metadata=usage_metadata
 
 
106
  )
107
 
108
+ # Case 2: Lỗithể thử lại (STOP nhưng không có nội dung)
109
+ if not has_content: # Tại đây, ta biết chắc chắn finish_reason_name là "STOP"
110
+ usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
111
+ last_error = GeminiResponseError("Gemini response finished with STOP but has no content parts.", finish_reason='STOP_NO_CONTENT', usage_metadata=usage_metadata)
112
+ logger.warning(f"[GEMINI] Model returned STOP with no content. Retrying with another key/model... (Attempt {attempt + 1}/{max_retries})")
113
+ self.limit_manager.log_request(key, model, success=False, retry_delay=5)
114
+ continue # Thử lại vòng lặp với key/model mới
115
+
116
+ # Case 3: Thành công (STOP và có nội dung)
117
  self.limit_manager.log_request(key, model, success=True)
118
  if hasattr(response, 'usage_metadata'):
119
  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}")
120
 
 
121
  try:
122
  logger.info(f"[GEMINI][TEXT_RESPONSE] {_safe_truncate(response.text)}")
123
  return response.text
124
  except ValueError as ve:
125
+ # Safety net: Nếu truy cập .text thất bại dù các kiểm tra trước đó đã qua,
126
+ # coi như đây là lỗi STOP_NO_CONTENT và ném ra để tầng trên xử lý.
 
127
  usage_metadata = response.usage_metadata if hasattr(response, 'usage_metadata') else None
128
  raise GeminiResponseError(
129
  f"Gemini response has no valid content part. Original error: {ve}",