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
This commit is contained in:
sankalp committed 2026-06-06 16:45:05 +05:45
1 parent d991af9c47
commit 8069895bc7
6 files changed
+37 -1

No files matched your search

+8 -1
View File
@@ -1,5 +1,7 @@
import anthropic
from devgen.utils import format_token_limit_error, is_token_limit_error
class AnthropicProvider:
"""Generates content using Anthropic's Claude models."""
@@ -23,4 +25,9 @@ class AnthropicProvider:
)
return message.content[0].text.strip()
except Exception as e:
raise RuntimeError(f"Anthropic generation failed: {e}")
if is_token_limit_error(e):
raise RuntimeError(format_token_limit_error("Anthropic", e)) from e
raise RuntimeError(
f"Anthropic generation failed: {e}. "
"Check the model id and your account credits."
) from e
+6
View File
@@ -2,6 +2,8 @@ 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."""
@@ -40,6 +42,10 @@ class GeminiProvider:
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
+12
View File
@@ -1,5 +1,7 @@
import requests
from devgen.utils import format_token_limit_error, is_token_limit_error
class HuggingfaceProvider:
"""Generates content using Hugging Face Inference API."""
@@ -46,6 +48,10 @@ class HuggingfaceProvider:
f"Hugging Face model is loading: {err}. "
"Wait a minute and retry, or pick a different model."
)
if is_token_limit_error(err):
raise RuntimeError(
format_token_limit_error("Hugging Face", err)
) from err
raise RuntimeError(f"Hugging Face API error: {err}")
else:
raise RuntimeError(
@@ -55,6 +61,8 @@ class HuggingfaceProvider:
except requests.HTTPError as e:
status = e.response.status_code if e.response is not None else "?"
if is_token_limit_error(e):
raise RuntimeError(format_token_limit_error("Hugging Face", e)) from e
raise RuntimeError(
f"Hugging Face request failed (HTTP {status}): {e}. "
"Check the model id and your token permissions."
@@ -63,5 +71,9 @@ class HuggingfaceProvider:
raise RuntimeError(
f"Hugging Face network error: {e}. Check your connection."
) from e
except RuntimeError:
raise
except Exception as e:
if is_token_limit_error(e):
raise RuntimeError(format_token_limit_error("Hugging Face", e)) from e
raise RuntimeError(f"Hugging Face generation failed: {e}") from e
+3
View File
@@ -1,3 +1,4 @@
from devgen.utils import format_token_limit_error, is_token_limit_error
class OllamaProvider:
@@ -37,6 +38,8 @@ class OllamaProvider:
**kwargs,
)
except Exception as e:
if is_token_limit_error(e):
raise RuntimeError(format_token_limit_error("Ollama", e)) from e
raise RuntimeError(
f"Ollama request failed (host={host}, model={chosen_model}): {e}. "
"Is the Ollama server running? Start it with `ollama serve` and "
+4
View File
@@ -1,5 +1,7 @@
from openai import OpenAI
from devgen.utils import format_token_limit_error, is_token_limit_error
class OpenaiProvider:
"""Generates a response string using the OpenAI ChatCompletion API based on the provided prompt and parameters. This method initializes an OpenAI client with the given API key, sends a chat completion request with specified model and additional parameters, and returns the content of the generated message.
@@ -59,6 +61,8 @@ class OpenaiProvider:
**kwargs,
)
except Exception as e:
if is_token_limit_error(e):
raise RuntimeError(format_token_limit_error("OpenAI", e)) from e
raise RuntimeError(
f"OpenAI request failed: {e}. "
"Check the model name, API key permissions, and your account quota."
+4
View File
@@ -1,5 +1,7 @@
from openai import OpenAI
from devgen.utils import format_token_limit_error, is_token_limit_error
class OpenrouterProvider:
"""Generates content using OpenRouter (OpenAI-compatible API)."""
@@ -36,6 +38,8 @@ class OpenrouterProvider:
)
return response.choices[0].message.content.strip()
except Exception as e:
if is_token_limit_error(e):
raise RuntimeError(format_token_limit_error("OpenRouter", e)) from e
raise RuntimeError(
f"OpenRouter request failed: {e}. "
"Verify the model id (e.g. `openai/gpt-4o`) and your API key credits."