Cyber Catalyst Team commited on
Commit
1e1e634
·
1 Parent(s): da93542

Add new NIM models + background health check loop

Browse files
Files changed (1) hide show
  1. backend.py +70 -0
backend.py CHANGED
@@ -27,6 +27,7 @@ from fastapi import FastAPI, Request, Header, HTTPException
27
  from fastapi.responses import StreamingResponse, JSONResponse
28
  from fastapi.middleware.cors import CORSMiddleware
29
  from openai import AsyncOpenAI
 
30
  import asyncpg
31
 
32
  # ---------------------------------------------------------------------------
@@ -41,6 +42,12 @@ MAX_TOOL_ROUNDS = int(os.environ.get("MAX_TOOL_ROUNDS", "10"))
41
 
42
  # NIM models that reliably support tool/function calling
43
  TOOL_CAPABLE_MODELS = {
 
 
 
 
 
 
44
  "meta/llama-3.1-70b-instruct": "Llama 3.1 70B (Agentic)",
45
  "meta/llama-3.1-405b-instruct": "Llama 3.1 405B (Agentic)",
46
  "qwen/qwen2.5-coder-32b-instruct": "Qwen 2.5 Coder 32B (Agentic)",
@@ -55,6 +62,8 @@ ALL_MODELS = {
55
  "mistralai/mistral-large-2-instruct": "Mistral Large 2 (Chat only)",
56
  }
57
 
 
 
58
  # Ensure workspace exists
59
  Path(WORKSPACE_DIR).mkdir(parents=True, exist_ok=True)
60
 
@@ -400,10 +409,70 @@ def auth(authorization: str = None):
400
  raise HTTPException(status_code=401, detail="Unauthorized")
401
 
402
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  @app.on_event("startup")
404
  async def startup():
405
  await init_db()
406
  Path(WORKSPACE_DIR).mkdir(parents=True, exist_ok=True)
 
 
407
  print(f"[Backend] Started. Workspace: {WORKSPACE_DIR}")
408
  print(f"[Backend] Tool-capable models: {list(TOOL_CAPABLE_MODELS.keys())}")
409
  print(f"[Backend] DB connected: {db_pool is not None}")
@@ -656,6 +725,7 @@ async def health():
656
  "workspace_exists": Path(WORKSPACE_DIR).exists(),
657
  "db_connected": db_pool is not None,
658
  "models_count": len(ALL_MODELS),
 
659
  }
660
 
661
 
 
27
  from fastapi.responses import StreamingResponse, JSONResponse
28
  from fastapi.middleware.cors import CORSMiddleware
29
  from openai import AsyncOpenAI
30
+ import anyio
31
  import asyncpg
32
 
33
  # ---------------------------------------------------------------------------
 
42
 
43
  # NIM models that reliably support tool/function calling
44
  TOOL_CAPABLE_MODELS = {
45
+ "nvidia/nemotron-3-ultra-550b-a55b": "Nemotron 3 Ultra 550B (Agentic)",
46
+ "z-ai/glm-5.1": "GLM 5.1 (Agentic)",
47
+ "moonshotai/kimi-k2.6": "Kimi K2.6 (Agentic)",
48
+ "minimaxai/minimax-m3": "MiniMax M3 (Agentic)",
49
+ "stepfun-ai/step-3.7-flash": "Step 3.7 Flash (Agentic)",
50
+ "minimaxai/minimax-m2.7": "MiniMax M2.7 (Agentic)",
51
  "meta/llama-3.1-70b-instruct": "Llama 3.1 70B (Agentic)",
52
  "meta/llama-3.1-405b-instruct": "Llama 3.1 405B (Agentic)",
53
  "qwen/qwen2.5-coder-32b-instruct": "Qwen 2.5 Coder 32B (Agentic)",
 
62
  "mistralai/mistral-large-2-instruct": "Mistral Large 2 (Chat only)",
63
  }
64
 
65
+ RECOMMENDED_MODEL = "nvidia/llama-3.1-nemotron-70b-instruct"
66
+
67
  # Ensure workspace exists
68
  Path(WORKSPACE_DIR).mkdir(parents=True, exist_ok=True)
69
 
 
409
  raise HTTPException(status_code=401, detail="Unauthorized")
410
 
411
 
412
+ async def check_models_health():
413
+ global RECOMMENDED_MODEL
414
+ # Top models to test
415
+ models_to_test = [
416
+ "nvidia/nemotron-3-ultra-550b-a55b",
417
+ "z-ai/glm-5.1",
418
+ "moonshotai/kimi-k2.6",
419
+ "minimaxai/minimax-m3",
420
+ "stepfun-ai/step-3.7-flash",
421
+ "minimaxai/minimax-m2.7",
422
+ "nvidia/llama-3.1-nemotron-70b-instruct",
423
+ "meta/llama-3.1-405b-instruct",
424
+ "qwen/qwen2.5-coder-32b-instruct",
425
+ "meta/llama-3.3-70b-instruct",
426
+ ]
427
+
428
+ best_model = None
429
+ best_latency = 999.0
430
+
431
+ print("[Health Check] Starting periodic model verification...")
432
+ for model in models_to_test:
433
+ start_time = time.time()
434
+ try:
435
+ # Send a fast test prompt
436
+ async with anyio.fail_after(15.0): # 15 seconds max timeout
437
+ await nim_client.chat.completions.create(
438
+ model=model,
439
+ messages=[{"role": "user", "content": "1+1="}],
440
+ max_tokens=3,
441
+ )
442
+ latency = time.time() - start_time
443
+ print(f"[Health Check] Model {model} is ONLINE. Latency: {latency:.2f}s")
444
+
445
+ # We want the model that is within 15 seconds
446
+ # and is the fastest (lowest latency)
447
+ if latency < best_latency:
448
+ best_latency = latency
449
+ best_model = model
450
+
451
+ except Exception as e:
452
+ print(f"[Health Check] Model {model} is OFFLINE or TIMEOUT: {e}")
453
+
454
+ if best_model:
455
+ RECOMMENDED_MODEL = best_model
456
+ print(f"[Health Check] Best model found: {RECOMMENDED_MODEL} ({best_latency:.2f}s)")
457
+ else:
458
+ print("[Health Check] Warning: All checked models failed or timed out!")
459
+
460
+ async def periodic_health_check_loop():
461
+ # Wait 30 seconds after startup before the first check to let the space boot fully
462
+ await asyncio.sleep(30)
463
+ while True:
464
+ try:
465
+ await check_models_health()
466
+ except Exception as e:
467
+ print(f"[Health Check] Loop error: {e}")
468
+ await asyncio.sleep(300) # every 5 minutes
469
+
470
  @app.on_event("startup")
471
  async def startup():
472
  await init_db()
473
  Path(WORKSPACE_DIR).mkdir(parents=True, exist_ok=True)
474
+ # Start background health checking
475
+ asyncio.create_task(periodic_health_check_loop())
476
  print(f"[Backend] Started. Workspace: {WORKSPACE_DIR}")
477
  print(f"[Backend] Tool-capable models: {list(TOOL_CAPABLE_MODELS.keys())}")
478
  print(f"[Backend] DB connected: {db_pool is not None}")
 
725
  "workspace_exists": Path(WORKSPACE_DIR).exists(),
726
  "db_connected": db_pool is not None,
727
  "models_count": len(ALL_MODELS),
728
+ "recommended_model": RECOMMENDED_MODEL,
729
  }
730
 
731