Skip to content

Commit 85bb98b

Browse files
authored
Merge pull request #2331 from danielaskdd/gemini-retry
Fix Gemini driver retry mechanism
2 parents cf732db + 3d9de5e commit 85bb98b

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

lightrag/llm/gemini.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,27 @@
3333

3434
import pipmaster as pm
3535

36-
# Install the Google Gemini client on demand
36+
# Install the Google Gemini client and its dependencies on demand
3737
if not pm.is_installed("google-genai"):
3838
pm.install("google-genai")
39+
if not pm.is_installed("google-api-core"):
40+
pm.install("google-api-core")
3941

4042
from google import genai # type: ignore
4143
from google.genai import types # type: ignore
44+
from google.api_core import exceptions as google_api_exceptions # type: ignore
4245

4346
DEFAULT_GEMINI_ENDPOINT = "https://generativelanguage.googleapis.com"
4447

4548
LOG = logging.getLogger(__name__)
4649

4750

51+
class InvalidResponseError(Exception):
52+
"""Custom exception class for triggering retry mechanism when Gemini returns empty responses"""
53+
54+
pass
55+
56+
4857
@lru_cache(maxsize=8)
4958
def _get_gemini_client(
5059
api_key: str, base_url: str | None, timeout: int | None = None
@@ -176,6 +185,21 @@ def _extract_response_text(
176185
return ("\n".join(regular_parts), "\n".join(thought_parts))
177186

178187

188+
@retry(
189+
stop=stop_after_attempt(3),
190+
wait=wait_exponential(multiplier=1, min=4, max=60),
191+
retry=(
192+
retry_if_exception_type(google_api_exceptions.InternalServerError)
193+
| retry_if_exception_type(google_api_exceptions.ServiceUnavailable)
194+
| retry_if_exception_type(google_api_exceptions.ResourceExhausted)
195+
| retry_if_exception_type(google_api_exceptions.GatewayTimeout)
196+
| retry_if_exception_type(google_api_exceptions.BadGateway)
197+
| retry_if_exception_type(google_api_exceptions.DeadlineExceeded)
198+
| retry_if_exception_type(google_api_exceptions.Aborted)
199+
| retry_if_exception_type(google_api_exceptions.Unknown)
200+
| retry_if_exception_type(InvalidResponseError)
201+
),
202+
)
179203
async def gemini_complete_if_cache(
180204
model: str,
181205
prompt: str,
@@ -382,7 +406,7 @@ async def _async_stream() -> AsyncIterator[str]:
382406
final_text = regular_text or ""
383407

384408
if not final_text:
385-
raise RuntimeError("Gemini response did not contain any text content.")
409+
raise InvalidResponseError("Gemini response did not contain any text content.")
386410

387411
if "\\u" in final_text:
388412
final_text = safe_unicode_decode(final_text.encode("utf-8"))
@@ -434,7 +458,14 @@ async def gemini_model_complete(
434458
stop=stop_after_attempt(3),
435459
wait=wait_exponential(multiplier=1, min=4, max=60),
436460
retry=(
437-
retry_if_exception_type(Exception) # Gemini uses generic exceptions
461+
retry_if_exception_type(google_api_exceptions.InternalServerError)
462+
| retry_if_exception_type(google_api_exceptions.ServiceUnavailable)
463+
| retry_if_exception_type(google_api_exceptions.ResourceExhausted)
464+
| retry_if_exception_type(google_api_exceptions.GatewayTimeout)
465+
| retry_if_exception_type(google_api_exceptions.BadGateway)
466+
| retry_if_exception_type(google_api_exceptions.DeadlineExceeded)
467+
| retry_if_exception_type(google_api_exceptions.Aborted)
468+
| retry_if_exception_type(google_api_exceptions.Unknown)
438469
),
439470
)
440471
async def gemini_embed(

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies = [
2424
"aiohttp",
2525
"configparser",
2626
"future",
27+
"google-api-core>=2.0.0,<3.0.0",
2728
"google-genai>=1.0.0,<2.0.0",
2829
"json_repair",
2930
"nano-vectordb",
@@ -60,6 +61,7 @@ api = [
6061
"tenacity",
6162
"tiktoken",
6263
"xlsxwriter>=3.1.0",
64+
"google-api-core>=2.0.0,<3.0.0",
6365
"google-genai>=1.0.0,<2.0.0",
6466
# API-specific dependencies
6567
"aiofiles",
@@ -108,6 +110,7 @@ offline-llm = [
108110
"aioboto3>=12.0.0,<16.0.0",
109111
"voyageai>=0.2.0,<1.0.0",
110112
"llama-index>=0.9.0,<1.0.0",
113+
"google-api-core>=2.0.0,<3.0.0",
111114
"google-genai>=1.0.0,<2.0.0",
112115
]
113116

requirements-offline-llm.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# LLM provider dependencies (with version constraints matching pyproject.toml)
1111
aioboto3>=12.0.0,<16.0.0
1212
anthropic>=0.18.0,<1.0.0
13+
google-api-core>=2.0.0,<3.0.0
1314
google-genai>=1.0.0,<2.0.0
1415
llama-index>=0.9.0,<1.0.0
1516
ollama>=0.1.0,<1.0.0

0 commit comments

Comments
 (0)