ayb-bh92 commited on
Commit
edccd7b
·
verified ·
1 Parent(s): e97c91a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -17
app.py CHANGED
@@ -201,6 +201,22 @@ def execute_tool(name: str, inp: Dict[str, Any]) -> str:
201
  # G4F CALL — sync، يُشغَّل في thread pool
202
  # =========================================================
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  def _g4f_call_sync(messages: List[Dict], target_model: str) -> str:
205
  """
206
  محاولة g4f مع كل providers بالترتيب.
@@ -208,7 +224,9 @@ def _g4f_call_sync(messages: List[Dict], target_model: str) -> str:
208
  """
209
  mapped = CLAUDE_TO_G4F.get(target_model, target_model)
210
 
 
211
  for pobj, pmodels in PROVIDER_CHAIN:
 
212
  try_models = [mapped] + [m for m in pmodels if m != mapped]
213
 
214
  for model in try_models[:4]: # max 4 per provider
@@ -225,28 +243,47 @@ def _g4f_call_sync(messages: List[Dict], target_model: str) -> str:
225
  text = str(result or "")
226
  text = text.strip()
227
 
228
- # ── التعديل الجراحي: كشف وتصفية استجابات الخطأ الوهمية ──
229
- lower_text = text.lower()
230
- if (
231
- not text or
232
- len(text) <= 2 or
233
- ("choices" in lower_text and "nonetype" in lower_text) or
234
- "object has no attribute" in lower_text or
235
- "color-red-500" in lower_text or
236
- "var(--color-red-500)" in lower_text
237
- ):
238
- logger.warning("Rejected invalid/error response from provider %s (model: %s): %s",
239
- type(pobj).__name__, model, text[:150])
240
- continue # تخطي هذا المزود فوراً وجرب التالي في السلسلة
241
 
242
  logger.info("Success: provider=%s model=%s len=%d",
243
- type(pobj).__name__, model, len(text))
244
  return text
245
  except Exception as e:
246
- logger.debug("Failed %s/%s: %s", type(pobj).__name__, model, e)
247
  continue
248
 
249
- raise RuntimeError("All providers failed")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
 
251
 
252
  async def g4f_call(messages: List[Dict], model: str) -> str:
@@ -347,7 +384,7 @@ async def health():
347
  return {
348
  "status": "ok",
349
  "cookies": COOKIE_STATUS,
350
- "providers": [type(p).__name__ for p, _ in PROVIDER_CHAIN],
351
  }
352
 
353
 
 
201
  # G4F CALL — sync، يُشغَّل في thread pool
202
  # =========================================================
203
 
204
+ def _is_invalid_response(text: str) -> bool:
205
+ """تحليل النص والتحقق مما إذا كان يمثل رسالة خطأ داخلية من g4f أو HTML تالف."""
206
+ if not text or len(text) <= 2:
207
+ return True
208
+ lower_text = text.lower()
209
+ if "choices" in lower_text and "nonetype" in lower_text:
210
+ return True
211
+ if "object has no attribute" in lower_text:
212
+ return True
213
+ if "color-red-500" in lower_text or "var(--color-red-500)" in lower_text:
214
+ return True
215
+ if "error" in lower_text and "style=" in lower_text:
216
+ return True
217
+ return False
218
+
219
+
220
  def _g4f_call_sync(messages: List[Dict], target_model: str) -> str:
221
  """
222
  محاولة g4f مع كل providers بالترتيب.
 
224
  """
225
  mapped = CLAUDE_TO_G4F.get(target_model, target_model)
226
 
227
+ # ── 1. محاولة استخدام السلسلة المحددة للمزودين أولاً ──
228
  for pobj, pmodels in PROVIDER_CHAIN:
229
+ pname = pobj.__name__ if hasattr(pobj, "__name__") else type(pobj).__name__
230
  try_models = [mapped] + [m for m in pmodels if m != mapped]
231
 
232
  for model in try_models[:4]: # max 4 per provider
 
243
  text = str(result or "")
244
  text = text.strip()
245
 
246
+ # التحقق الجراحي من الاستجابة التالفة
247
+ if _is_invalid_response(text):
248
+ logger.warning("Rejected invalid response from provider %s (model: %s): %s",
249
+ pname, model, text[:150])
250
+ continue
 
 
 
 
 
 
 
 
251
 
252
  logger.info("Success: provider=%s model=%s len=%d",
253
+ pname, model, len(text))
254
  return text
255
  except Exception as e:
256
+ logger.debug("Failed %s/%s: %s", pname, model, e)
257
  continue
258
 
259
+ # ── 2. الإنقاذ التلقائي الفوري (Auto-Routing Fallback) في حال تعطل السلسلة بالكامل ──
260
+ logger.warning("All explicit providers failed. Attempting automatic fallback routing...")
261
+ fallback_models = [mapped, "qwen-3-235b", "qwen-3-32b"]
262
+
263
+ for model in fallback_models:
264
+ try:
265
+ # هنا نقوم بالاستدعاء بدون تحديد مزود (provider) لندع g4f يوجه الطلب ذاتياً لأي مزود عالمي شغال
266
+ result = g4f.ChatCompletion.create(
267
+ model=model,
268
+ messages=messages,
269
+ stream=False,
270
+ )
271
+ if hasattr(result, "__iter__") and not isinstance(result, str):
272
+ text = "".join(str(c) for c in result if c)
273
+ else:
274
+ text = str(result or "")
275
+ text = text.strip()
276
+
277
+ if not _is_invalid_response(text):
278
+ logger.info("Auto-routing Fallback SUCCESS: model=%s len=%d", model, len(text))
279
+ return text
280
+ else:
281
+ logger.warning("Auto-routing Fallback rejected invalid response for model %s", model)
282
+ except Exception as e:
283
+ logger.debug("Auto-routing fallback failed for model %s: %s", model, e)
284
+ continue
285
+
286
+ raise RuntimeError("All providers and automatic fallbacks failed")
287
 
288
 
289
  async def g4f_call(messages: List[Dict], model: str) -> str:
 
384
  return {
385
  "status": "ok",
386
  "cookies": COOKIE_STATUS,
387
+ "providers": [p.__name__ if hasattr(p, "__name__") else type(p).__name__ for p, _ in PROVIDER_CHAIN],
388
  }
389
 
390