feat(devgen/providers): bump default Gemini model to gemini-2.5-flash and add retry handling for quota errors

The update changes the default model, refactors imports, and implements robust retry logic with exponential back‑off and clearer error messages. This improves resilience and clarifies usage.

New Features
- Exponential back‑off retry on 429/quota exhausted responses.
- Configurable max_retries and retry_delay parameters.

Enhancements
- Default model set to gemini-2.5-flash.
- Improved error output with actionable troubleshooting steps.
This commit is contained in:
sankalp committed 2026-01-30 22:36:31 +05:45
1 parent 06f25af35f
commit 9554f7af2a
5 files changed
+141 -267

No files matched your search

+6 -1
View File
@@ -466,10 +466,15 @@ class CommitEngine:
groups = self.group_files(files)
cache = self.load_cache()
for group, group_files in groups.items():
for i, (group, group_files) in enumerate(groups.items()):
try:
if not self.process_group(group, group_files, cache):
failed.append(group)
# Add a small delay between groups to respect RPM limits if not at the last group
if len(groups) > 1 and i < len(groups) - 1:
import time
time.sleep(15) # Conservative 15s delay to stay within 4 RPM (Free Tier)
except KeyboardInterrupt:
self.logger.warning("\nOperation interrupted by user.")
raise
+47 -12
View File
@@ -1,24 +1,59 @@
import google.generativeai as genai
import time
from google import genai
from google.genai import types
class GeminiProvider:
"""Generates content using Google's Gemini models."""
def generate(
self, prompt: str, api_key: str, model: str = "gemini-pro", **kwargs
self, prompt: str, api_key: str, model: str = "gemini-2.5-flash", **kwargs
) -> str:
"""Generates a response using the Gemini API."""
"""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 required.")
genai.configure(api_key=api_key)
client = genai.Client(api_key=api_key)
# Handle model name mapping if needed, or trust user input
# gemini-pro is a common default
max_retries = kwargs.get("max_retries", 5)
base_delay = kwargs.get("retry_delay", 10) # 10 seconds base delay for 429
try:
model_instance = genai.GenerativeModel(model)
response = model_instance.generate_content(prompt)
return response.text.strip()
except Exception as e:
raise RuntimeError(f"Gemini generation failed: {e}")
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()
# 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