fix(pos): retry con backoff para rate limit 429 de OpenRouter
3 reintentos con espera 5s/10s/15s. Si agota reintentos, muestra mensaje amigable en vez de error. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,42 +60,53 @@ def chat(user_message, conversation_history=None):
|
|||||||
messages.extend(conversation_history)
|
messages.extend(conversation_history)
|
||||||
messages.append({"role": "user", "content": user_message})
|
messages.append({"role": "user", "content": user_message})
|
||||||
|
|
||||||
try:
|
import time
|
||||||
resp = requests.post(
|
max_retries = 3
|
||||||
OPENROUTER_URL,
|
|
||||||
headers={
|
|
||||||
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
json={
|
|
||||||
"model": MODEL,
|
|
||||||
"messages": messages,
|
|
||||||
"max_tokens": 500,
|
|
||||||
"temperature": 0.3,
|
|
||||||
},
|
|
||||||
timeout=15,
|
|
||||||
)
|
|
||||||
resp.raise_for_status()
|
|
||||||
data = resp.json()
|
|
||||||
content = data["choices"][0]["message"]["content"]
|
|
||||||
|
|
||||||
# Try to parse JSON response
|
for attempt in range(max_retries):
|
||||||
try:
|
try:
|
||||||
# Handle markdown-wrapped JSON (```json ... ```)
|
resp = requests.post(
|
||||||
stripped = content.strip()
|
OPENROUTER_URL,
|
||||||
if stripped.startswith("```"):
|
headers={
|
||||||
lines = stripped.split("\n")
|
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
|
||||||
# Remove first and last lines (``` markers)
|
"Content-Type": "application/json",
|
||||||
json_str = "\n".join(lines[1:-1])
|
},
|
||||||
parsed = json.loads(json_str)
|
json={
|
||||||
else:
|
"model": MODEL,
|
||||||
parsed = json.loads(stripped)
|
"messages": messages,
|
||||||
return parsed
|
"max_tokens": 500,
|
||||||
except (json.JSONDecodeError, IndexError):
|
"temperature": 0.3,
|
||||||
return {"message": content, "search_query": None, "vehicle": None}
|
},
|
||||||
except Exception as e:
|
timeout=20,
|
||||||
return {
|
)
|
||||||
"message": f"Error de conexion: {str(e)}",
|
if resp.status_code == 429:
|
||||||
"search_query": None,
|
# Rate limited — wait and retry
|
||||||
"vehicle": None,
|
wait = (attempt + 1) * 5 # 5s, 10s, 15s
|
||||||
}
|
if attempt < max_retries - 1:
|
||||||
|
time.sleep(wait)
|
||||||
|
continue
|
||||||
|
return {"message": "El asistente está ocupado. Intenta de nuevo en unos segundos.", "search_query": None, "vehicle": None}
|
||||||
|
resp.raise_for_status()
|
||||||
|
data = resp.json()
|
||||||
|
content = data["choices"][0]["message"]["content"]
|
||||||
|
|
||||||
|
# Try to parse JSON response
|
||||||
|
try:
|
||||||
|
stripped = content.strip()
|
||||||
|
if stripped.startswith("```"):
|
||||||
|
lines = stripped.split("\n")
|
||||||
|
json_str = "\n".join(lines[1:-1])
|
||||||
|
parsed = json.loads(json_str)
|
||||||
|
else:
|
||||||
|
parsed = json.loads(stripped)
|
||||||
|
return parsed
|
||||||
|
except (json.JSONDecodeError, IndexError):
|
||||||
|
return {"message": content, "search_query": None, "vehicle": None}
|
||||||
|
except Exception as e:
|
||||||
|
if attempt < max_retries - 1:
|
||||||
|
continue
|
||||||
|
return {
|
||||||
|
"message": f"Error de conexion: {str(e)}",
|
||||||
|
"search_query": None,
|
||||||
|
"vehicle": None,
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user