Files
DevGen/devgen/providers/gemini.py
T
sankalp 8069895bc7 feat(devgen/providers): normalize token limit error handling
Add token limit error detection and formatting across all provider modules to surface clear diagnostics when context windows are exceeded, improving error messages and preventing silent failures.

New Features
- Introduce `is_token_limit_error` checks in Anthropic, Gemini, Hugging Face, Ollama, OpenAI, and OpenRouter providers.
- Use `format_token_limit_error` to generate user‑friendly error messages for token limit overs.

Enhancements
- Centralize token limit error handling for consistent diagnostics across providers.
- Explicitly re‑raise `RuntimeError` in Hugging Face to preserve original behavior.

Bug Fixes
- None
2026-06-06 16:45:05 +05:45

77 lines
3.3 KiB
Python

import time
from google import genai
from google.genai import types
from devgen.utils import format_token_limit_error, is_token_limit_error
class GeminiProvider:
"""Generates content using Google's Gemini models."""
def generate(
self, prompt: str, api_key: str, model: str = "gemini-2.5-flash", **kwargs
) -> str:
"""Generates a response using the Gemini API.
Default model is updated to gemini-2.5-flash which is the latest
recommended model.
"""
if not api_key:
raise ValueError(
"Gemini API key is missing. "
"Set it via `devgen setup config` or pass --api-key."
)
client = genai.Client(api_key=api_key)
max_retries = kwargs.get("max_retries", 5)
base_delay = kwargs.get("retry_delay", 10) # 10 seconds base delay for 429
for attempt in range(max_retries + 1):
try:
response = client.models.generate_content(
model=model,
contents=prompt,
config=types.GenerateContentConfig(
temperature=kwargs.get("temperature", 0.7),
top_p=kwargs.get("top_p", 0.95),
top_k=kwargs.get("top_k", 40),
max_output_tokens=kwargs.get("max_output_tokens", 2048),
),
)
return response.text.strip()
except Exception as e:
error_msg = str(e).upper()
# Token / context-window overflow is not retryable — no point
# backing off, the prompt is just too big.
if is_token_limit_error(e):
raise RuntimeError(format_token_limit_error("Gemini", e)) from e
# Check for 429 or ResourceExhausted in common error formats
if any(
x in error_msg
for x in [
"429",
"RESOURCE_EXHAUSTED",
"QUOTA_EXCEEDED",
"THROTTLED",
]
):
if attempt < max_retries:
delay = base_delay * (2**attempt)
print(
f"\n[Gemini] Quota limit hit (429). This is often a temporary rate limit (RPM). "
f"Waiting {delay}s and retrying... (Attempt {attempt + 1}/{max_retries})"
)
time.sleep(delay)
continue
else:
raise RuntimeError(
"Gemini API quota exhausted (429) after multiple retries.\n\n"
"POSSIBLE CAUSES:\n"
"1. Rate Limit (RPM/RPD): You are sending requests too fast for the Free Tier.\n"
"2. Daily Limit: You have reached the maximum free requests allowed for today (typically 1,500).\n"
"3. Credit/Billing: If on a paid plan, your credit may be exhausted.\n\n"
"Please check your usage metrics at: https://aistudio.google.com/app/usage"
) from e
raise RuntimeError(f"Gemini generation failed: {e}") from e