bahi-bh commited on
Commit
b535f09
·
verified ·
1 Parent(s): 1cbc6ba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -18
app.py CHANGED
@@ -65,23 +65,41 @@ STREAM_RESPONSE_HEADERS = {
65
  # MODELS
66
  # =========================================================
67
 
 
 
 
 
 
 
 
 
 
68
  MODEL_MAP = {
69
- "claude-sonnet-4-6": "deepseek-v4-flash-free",
70
- "claude-sonnet-4-5": "deepseek-v4-flash-free",
71
- "claude-haiku-4-6": "deepseek-v4-flash-free",
72
- "claude-haiku-4-5": "deepseek-v4-flash-free",
73
  "claude-haiku-4-5-20251001": "deepseek-v4-flash-free",
74
- "claude-opus-4-6": "nemotron-3-super-free",
75
-
76
- "deepseek-v4-flash-free": "deepseek-v4-flash-free",
77
- "nemotron-3-super-free": "nemotron-3-super-free",
78
- "qwen3.6-plus-free": "qwen3.6-plus-free",
79
- "minimax-m2.5-free": "minimax-m2.5-free",
80
- "big-pickle": "big-pickle",
81
  }
82
 
83
  DEFAULT_MODEL = "deepseek-v4-flash-free"
84
 
 
 
 
 
 
 
 
 
 
 
85
  # =========================================================
86
  # BROWSER TOOLS FILTER
87
  # =========================================================
@@ -1316,9 +1334,17 @@ async def messages(
1316
 
1317
  last_error = raw_error
1318
 
1319
- # 429 = rate limit: stop immediately
1320
  if response.status_code == 429:
1321
- break
 
 
 
 
 
 
 
 
1322
 
1323
  await asyncio.sleep(RETRY_DELAY)
1324
 
@@ -1353,9 +1379,17 @@ async def messages(
1353
 
1354
  last_error = response.text
1355
 
1356
- # 429 = rate limit: stop immediately
1357
  if response.status_code == 429:
1358
- break
 
 
 
 
 
 
 
 
1359
 
1360
  await asyncio.sleep(RETRY_DELAY)
1361
 
@@ -1403,9 +1437,9 @@ async def messages(
1403
  await asyncio.sleep(RETRY_DELAY)
1404
 
1405
  return JSONResponse(
1406
- status_code=429 if "429" in str(last_error) else 502,
1407
  content={
1408
- "error": "Rate limited" if "429" in str(last_error) else "Upstream failed",
1409
- "details": last_error
1410
  },
1411
  )
 
65
  # MODELS
66
  # =========================================================
67
 
68
+ # Pool of free models — rotated automatically on 429
69
+ FREE_MODELS_POOL = [
70
+ "deepseek-v4-flash-free",
71
+ "qwen3.6-plus-free",
72
+ "minimax-m2.5-free",
73
+ "nemotron-3-super-free",
74
+ "big-pickle",
75
+ ]
76
+
77
  MODEL_MAP = {
78
+ "claude-sonnet-4-6": "deepseek-v4-flash-free",
79
+ "claude-sonnet-4-5": "deepseek-v4-flash-free",
80
+ "claude-haiku-4-6": "deepseek-v4-flash-free",
81
+ "claude-haiku-4-5": "deepseek-v4-flash-free",
82
  "claude-haiku-4-5-20251001": "deepseek-v4-flash-free",
83
+ "claude-opus-4-6": "nemotron-3-super-free",
84
+ "deepseek-v4-flash-free": "deepseek-v4-flash-free",
85
+ "nemotron-3-super-free": "nemotron-3-super-free",
86
+ "qwen3.6-plus-free": "qwen3.6-plus-free",
87
+ "minimax-m2.5-free": "minimax-m2.5-free",
88
+ "big-pickle": "big-pickle",
 
89
  }
90
 
91
  DEFAULT_MODEL = "deepseek-v4-flash-free"
92
 
93
+
94
+ def _next_model(current_model):
95
+ """Return the next free model in the pool after current_model."""
96
+ try:
97
+ idx = FREE_MODELS_POOL.index(current_model)
98
+ except ValueError:
99
+ idx = -1
100
+ next_idx = (idx + 1) % len(FREE_MODELS_POOL)
101
+ return FREE_MODELS_POOL[next_idx]
102
+
103
  # =========================================================
104
  # BROWSER TOOLS FILTER
105
  # =========================================================
 
1334
 
1335
  last_error = raw_error
1336
 
1337
+ # 429 = rate limit: rotate to next free model
1338
  if response.status_code == 429:
1339
+ next_m = _next_model(mapped_model)
1340
+ logger.warning(
1341
+ "[%s] 429 on %s -> rotating to %s",
1342
+ request_id, mapped_model, next_m,
1343
+ )
1344
+ mapped_model = next_m
1345
+ payload["model"] = mapped_model
1346
+ await asyncio.sleep(1)
1347
+ continue
1348
 
1349
  await asyncio.sleep(RETRY_DELAY)
1350
 
 
1379
 
1380
  last_error = response.text
1381
 
1382
+ # 429 = rate limit: rotate to next free model
1383
  if response.status_code == 429:
1384
+ next_m = _next_model(mapped_model)
1385
+ logger.warning(
1386
+ "[%s] 429 on %s -> rotating to %s",
1387
+ request_id, mapped_model, next_m,
1388
+ )
1389
+ mapped_model = next_m
1390
+ payload["model"] = mapped_model
1391
+ await asyncio.sleep(1)
1392
+ continue
1393
 
1394
  await asyncio.sleep(RETRY_DELAY)
1395
 
 
1437
  await asyncio.sleep(RETRY_DELAY)
1438
 
1439
  return JSONResponse(
1440
+ status_code=502,
1441
  content={
1442
+ "error": "All free models exhausted or upstream failed",
1443
+ "details": last_error,
1444
  },
1445
  )