feat(devgen/providers):improve provider error handling and response parsing

This commit is contained in:
sankalp committed 2026-06-06 16:27:03 +05:45
1 parent 5660e40eb4
commit 51d2b7549f
6 files changed
+64 -39

No files matched your search

-24
View File
@@ -1,24 +0,0 @@
def get_provider(name):
name_lower = name.lower()
if name_lower == "gemini":
from devgen.providers.gemini import GeminiProvider
return GeminiProvider()
elif name_lower == "openai":
from devgen.providers.openai import OpenaiProvider
return OpenaiProvider()
elif name_lower == "huggingface":
from devgen.providers.huggingface import HuggingfaceProvider
return HuggingfaceProvider()
elif name_lower == "openrouter":
from devgen.providers.openrouter import OpenrouterProvider
return OpenrouterProvider()
elif name_lower == "anthropic":
from devgen.providers.anthropic import AnthropicProvider
return AnthropicProvider()
raise NotImplementedError(f"Provider '{name}' is not implemented yet.")
+4 -1
View File
@@ -9,7 +9,10 @@ class AnthropicProvider:
) -> str:
"""Generates a response using the Anthropic API."""
if not api_key:
raise ValueError("Anthropic API key is required.")
raise ValueError(
"Anthropic API key is missing. "
"Set it via `devgen setup config` or pass --api-key."
)
try:
client = anthropic.Anthropic(api_key=api_key)
+4 -1
View File
@@ -15,7 +15,10 @@ class GeminiProvider:
recommended model.
"""
if not api_key:
raise ValueError("Gemini API key is required.")
raise ValueError(
"Gemini API key is missing. "
"Set it via `devgen setup config` or pass --api-key."
)
client = genai.Client(api_key=api_key)
+27 -5
View File
@@ -15,7 +15,10 @@ class HuggingfaceProvider:
) -> str:
"""Generates a response using Hugging Face API."""
if not api_key:
raise ValueError("Hugging Face API token is required.")
raise ValueError(
"Hugging Face API token is missing. "
"Set it via `devgen setup config` or pass --api-key."
)
api_url = self.API_URL_TEMPLATE.format(model=model)
headers = {"Authorization": f"Bearer {api_key}"}
@@ -34,12 +37,31 @@ class HuggingfaceProvider:
response.raise_for_status()
result = response.json()
if isinstance(result, list) and "generated_text" in result[0]:
if isinstance(result, list) and result and "generated_text" in result[0]:
return result[0]["generated_text"].strip()
elif isinstance(result, dict) and "error" in result:
raise RuntimeError(f"Hugging Face API error: {result['error']}")
err = result["error"]
if "is currently loading" in str(err).lower():
raise RuntimeError(
f"Hugging Face model is loading: {err}. "
"Wait a minute and retry, or pick a different model."
)
raise RuntimeError(f"Hugging Face API error: {err}")
else:
return str(result)
raise RuntimeError(
"Hugging Face returned an unexpected response shape. "
"The model may not support text-generation."
)
except requests.HTTPError as e:
status = e.response.status_code if e.response is not None else "?"
raise RuntimeError(
f"Hugging Face request failed (HTTP {status}): {e}. "
"Check the model id and your token permissions."
) from e
except requests.RequestException as e:
raise RuntimeError(
f"Hugging Face network error: {e}. Check your connection."
) from e
except Exception as e:
raise RuntimeError(f"Hugging Face generation failed: {e}")
raise RuntimeError(f"Hugging Face generation failed: {e}") from e
+21 -6
View File
@@ -32,20 +32,35 @@ class OpenaiProvider:
Returns:
str: Generated response content.
"""
if not api_key:
raise ValueError(
"OpenAI API key is missing. "
"Set it via `devgen setup config` or pass --api-key."
)
# 1. Create a client instance with the API key.
try:
client = OpenAI(api_key=api_key)
except Exception as e:
# Add error handling if the client fails to initialize
raise RuntimeError(f"Failed to initialize OpenAI client: {e}")
raise RuntimeError(
f"Failed to initialize OpenAI client: {e}. "
"Verify the key is valid and that the `openai` package is installed."
) from e
# Remove debug from kwargs if present
kwargs.pop("debug", None)
# 2. Use the modern API syntax: client.chat.completions.create
response = client.chat.completions.create(
model=model or self.DEFAULT_MODEL,
messages=[{"role": "user", "content": prompt}],
**kwargs,
)
try:
response = client.chat.completions.create(
model=model or self.DEFAULT_MODEL,
messages=[{"role": "user", "content": prompt}],
**kwargs,
)
except Exception as e:
raise RuntimeError(
f"OpenAI request failed: {e}. "
"Check the model name, API key permissions, and your account quota."
) from e
return response.choices[0].message.content.strip()
+8 -2
View File
@@ -11,7 +11,10 @@ class OpenrouterProvider:
) -> str:
"""Generates a response using OpenRouter."""
if not api_key:
raise ValueError("OpenRouter API key is required.")
raise ValueError(
"OpenRouter API key is missing. "
"Set it via `devgen setup config` or pass --api-key."
)
try:
client = OpenAI(
@@ -33,4 +36,7 @@ class OpenrouterProvider:
)
return response.choices[0].message.content.strip()
except Exception as e:
raise RuntimeError(f"OpenRouter generation failed: {e}")
raise RuntimeError(
f"OpenRouter request failed: {e}. "
"Verify the model id (e.g. `openai/gpt-4o`) and your API key credits."
) from e