Spaces:
Running
Running
updated error handling in utils
Browse files- __pycache__/utils.cpython-313.pyc +0 -0
- utils.py +33 -22
__pycache__/utils.cpython-313.pyc
CHANGED
|
Binary files a/__pycache__/utils.cpython-313.pyc and b/__pycache__/utils.cpython-313.pyc differ
|
|
|
utils.py
CHANGED
|
@@ -35,10 +35,11 @@ claude_client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
|
|
| 35 |
# --------------------------------------------------------------------------
|
| 36 |
# OpenAI
|
| 37 |
# --------------------------------------------------------------------------
|
| 38 |
-
|
| 39 |
-
|
| 40 |
model = model or os.getenv("OPENAI_MODEL", "gpt-4o-mini")
|
| 41 |
last_err = None
|
|
|
|
| 42 |
for attempt in range(1, max_retries + 1):
|
| 43 |
try:
|
| 44 |
resp = openai.ChatCompletion.create(
|
|
@@ -47,25 +48,26 @@ def call_openai_with_retries(prompt, model=None, max_retries=3, backoff=1.0):
|
|
| 47 |
temperature=0.2,
|
| 48 |
max_tokens=1200,
|
| 49 |
)
|
| 50 |
-
if
|
| 51 |
-
|
| 52 |
-
if text:
|
| 53 |
-
return text
|
| 54 |
raise RuntimeError("Empty response from OpenAI")
|
|
|
|
| 55 |
except Exception as e:
|
| 56 |
last_err = e
|
|
|
|
| 57 |
if attempt < max_retries:
|
| 58 |
time.sleep(backoff * attempt)
|
| 59 |
else:
|
| 60 |
-
raise
|
| 61 |
|
| 62 |
# --------------------------------------------------------------------------
|
| 63 |
# Claude
|
| 64 |
# --------------------------------------------------------------------------
|
| 65 |
-
|
| 66 |
-
|
| 67 |
model = model or os.getenv("CLAUDE_MODEL", "claude-3-sonnet-20240229")
|
| 68 |
last_err = None
|
|
|
|
| 69 |
for attempt in range(1, max_retries + 1):
|
| 70 |
try:
|
| 71 |
resp = claude_client.messages.create(
|
|
@@ -74,26 +76,27 @@ def call_claude_with_retries(prompt, model=None, max_retries=3, backoff=1.0):
|
|
| 74 |
temperature=0.2,
|
| 75 |
messages=[{"role": "user", "content": prompt}],
|
| 76 |
)
|
| 77 |
-
if resp.content and
|
| 78 |
text = resp.content[0].text.strip()
|
| 79 |
if text:
|
| 80 |
return text
|
| 81 |
raise RuntimeError("Empty response from Claude")
|
|
|
|
| 82 |
except Exception as e:
|
| 83 |
last_err = e
|
|
|
|
| 84 |
if attempt < max_retries:
|
| 85 |
time.sleep(backoff * attempt)
|
| 86 |
else:
|
| 87 |
-
raise
|
| 88 |
|
| 89 |
# --------------------------------------------------------------------------
|
| 90 |
# Groq
|
| 91 |
# --------------------------------------------------------------------------
|
| 92 |
-
|
| 93 |
-
|
| 94 |
api_key = os.getenv("GROQ_API_KEY")
|
| 95 |
model = model or os.getenv("GROQ_MODEL", "llama3-8b-8192")
|
| 96 |
-
|
| 97 |
if not api_key:
|
| 98 |
raise RuntimeError("Missing GROQ_API_KEY")
|
| 99 |
|
|
@@ -106,25 +109,31 @@ def call_groq_with_retries(prompt, model=None, max_retries=3, backoff=1.0):
|
|
| 106 |
"model": model,
|
| 107 |
"messages": [{"role": "user", "content": prompt}],
|
| 108 |
"temperature": 0.2,
|
| 109 |
-
"max_tokens": 1000
|
| 110 |
}
|
| 111 |
|
| 112 |
last_err = None
|
| 113 |
for attempt in range(1, max_retries + 1):
|
| 114 |
try:
|
| 115 |
-
resp = requests.post(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
if resp.status_code == 200:
|
| 117 |
data = resp.json()
|
| 118 |
-
if data.get("choices"):
|
| 119 |
return data["choices"][0]["message"]["content"].strip()
|
| 120 |
raise RuntimeError("Empty response from Groq")
|
| 121 |
|
| 122 |
-
|
| 123 |
-
print("Groq API error response:", resp.text)
|
| 124 |
resp.raise_for_status()
|
| 125 |
|
| 126 |
-
except Exception as e:
|
| 127 |
last_err = e
|
|
|
|
| 128 |
if attempt < max_retries:
|
| 129 |
time.sleep(backoff * attempt)
|
| 130 |
else:
|
|
@@ -134,8 +143,10 @@ def call_groq_with_retries(prompt, model=None, max_retries=3, backoff=1.0):
|
|
| 134 |
# Generic handler
|
| 135 |
# --------------------------------------------------------------------------
|
| 136 |
|
| 137 |
-
def call_llm(prompt):
|
|
|
|
| 138 |
provider = os.getenv("PROVIDER", "openai").lower()
|
|
|
|
| 139 |
if provider == "claude":
|
| 140 |
return call_claude_with_retries(prompt)
|
| 141 |
elif provider == "openai":
|
|
@@ -143,4 +154,4 @@ def call_llm(prompt):
|
|
| 143 |
elif provider == "groq":
|
| 144 |
return call_groq_with_retries(prompt)
|
| 145 |
else:
|
| 146 |
-
raise RuntimeError(f"Unsupported PROVIDER: {provider}")
|
|
|
|
| 35 |
# --------------------------------------------------------------------------
|
| 36 |
# OpenAI
|
| 37 |
# --------------------------------------------------------------------------
|
| 38 |
+
def call_openai_with_retries(prompt: str, model: str = None, max_retries: int = 3, backoff: float = 1.0) -> str:
|
| 39 |
+
"""Call OpenAI model with retry logic."""
|
| 40 |
model = model or os.getenv("OPENAI_MODEL", "gpt-4o-mini")
|
| 41 |
last_err = None
|
| 42 |
+
|
| 43 |
for attempt in range(1, max_retries + 1):
|
| 44 |
try:
|
| 45 |
resp = openai.ChatCompletion.create(
|
|
|
|
| 48 |
temperature=0.2,
|
| 49 |
max_tokens=1200,
|
| 50 |
)
|
| 51 |
+
if resp.choices and resp.choices[0].message.get("content"):
|
| 52 |
+
return resp.choices[0].message["content"].strip()
|
|
|
|
|
|
|
| 53 |
raise RuntimeError("Empty response from OpenAI")
|
| 54 |
+
|
| 55 |
except Exception as e:
|
| 56 |
last_err = e
|
| 57 |
+
logging.warning(f"OpenAI call failed (attempt {attempt}): {e}")
|
| 58 |
if attempt < max_retries:
|
| 59 |
time.sleep(backoff * attempt)
|
| 60 |
else:
|
| 61 |
+
raise RuntimeError(f"OpenAI failed after {max_retries} attempts: {last_err}")
|
| 62 |
|
| 63 |
# --------------------------------------------------------------------------
|
| 64 |
# Claude
|
| 65 |
# --------------------------------------------------------------------------
|
| 66 |
+
def call_claude_with_retries(prompt: str, model: str = None, max_retries: int = 3, backoff: float = 1.0) -> str:
|
| 67 |
+
"""Call Anthropic Claude model with retry logic."""
|
| 68 |
model = model or os.getenv("CLAUDE_MODEL", "claude-3-sonnet-20240229")
|
| 69 |
last_err = None
|
| 70 |
+
|
| 71 |
for attempt in range(1, max_retries + 1):
|
| 72 |
try:
|
| 73 |
resp = claude_client.messages.create(
|
|
|
|
| 76 |
temperature=0.2,
|
| 77 |
messages=[{"role": "user", "content": prompt}],
|
| 78 |
)
|
| 79 |
+
if resp.content and resp.content[0].type == "text":
|
| 80 |
text = resp.content[0].text.strip()
|
| 81 |
if text:
|
| 82 |
return text
|
| 83 |
raise RuntimeError("Empty response from Claude")
|
| 84 |
+
|
| 85 |
except Exception as e:
|
| 86 |
last_err = e
|
| 87 |
+
logging.warning(f"Claude call failed (attempt {attempt}): {e}")
|
| 88 |
if attempt < max_retries:
|
| 89 |
time.sleep(backoff * attempt)
|
| 90 |
else:
|
| 91 |
+
raise RuntimeError(f"Claude failed after {max_retries} attempts: {last_err}")
|
| 92 |
|
| 93 |
# --------------------------------------------------------------------------
|
| 94 |
# Groq
|
| 95 |
# --------------------------------------------------------------------------
|
| 96 |
+
def call_groq_with_retries(prompt: str, model: str = None, max_retries: int = 3, backoff: float = 1.0) -> str:
|
| 97 |
+
"""Call Groq model with retry logic."""
|
| 98 |
api_key = os.getenv("GROQ_API_KEY")
|
| 99 |
model = model or os.getenv("GROQ_MODEL", "llama3-8b-8192")
|
|
|
|
| 100 |
if not api_key:
|
| 101 |
raise RuntimeError("Missing GROQ_API_KEY")
|
| 102 |
|
|
|
|
| 109 |
"model": model,
|
| 110 |
"messages": [{"role": "user", "content": prompt}],
|
| 111 |
"temperature": 0.2,
|
| 112 |
+
"max_tokens": 1000,
|
| 113 |
}
|
| 114 |
|
| 115 |
last_err = None
|
| 116 |
for attempt in range(1, max_retries + 1):
|
| 117 |
try:
|
| 118 |
+
resp = requests.post(
|
| 119 |
+
"https://api.groq.com/openai/v1/chat/completions",
|
| 120 |
+
headers=headers,
|
| 121 |
+
json=payload,
|
| 122 |
+
timeout=30,
|
| 123 |
+
)
|
| 124 |
+
|
| 125 |
if resp.status_code == 200:
|
| 126 |
data = resp.json()
|
| 127 |
+
if data.get("choices") and data["choices"][0]["message"].get("content"):
|
| 128 |
return data["choices"][0]["message"]["content"].strip()
|
| 129 |
raise RuntimeError("Empty response from Groq")
|
| 130 |
|
| 131 |
+
logging.error(f"Groq API error ({resp.status_code}): {resp.text}")
|
|
|
|
| 132 |
resp.raise_for_status()
|
| 133 |
|
| 134 |
+
except (RequestException, Exception) as e:
|
| 135 |
last_err = e
|
| 136 |
+
logging.warning(f"Groq call failed (attempt {attempt}): {e}")
|
| 137 |
if attempt < max_retries:
|
| 138 |
time.sleep(backoff * attempt)
|
| 139 |
else:
|
|
|
|
| 143 |
# Generic handler
|
| 144 |
# --------------------------------------------------------------------------
|
| 145 |
|
| 146 |
+
def call_llm(prompt: str) -> str:
|
| 147 |
+
"""Route LLM calls based on PROVIDER environment variable."""
|
| 148 |
provider = os.getenv("PROVIDER", "openai").lower()
|
| 149 |
+
|
| 150 |
if provider == "claude":
|
| 151 |
return call_claude_with_retries(prompt)
|
| 152 |
elif provider == "openai":
|
|
|
|
| 154 |
elif provider == "groq":
|
| 155 |
return call_groq_with_retries(prompt)
|
| 156 |
else:
|
| 157 |
+
raise RuntimeError(f"Unsupported PROVIDER: {provider}")
|