amitbhatt6075 commited on
Commit
3eb5edf
Β·
1 Parent(s): 81e730f

fix: Correct model initialization order

Browse files
Files changed (1) hide show
  1. api/main.py +43 -90
api/main.py CHANGED
@@ -63,6 +63,7 @@ FINAL_EMBEDDING_PATH = EMBEDDING_MODEL_PATH if os.path.exists(EMBEDDING_MODEL_PA
63
  _llm_instance: Optional[Llama] = None
64
  _vector_store: Optional[Any] = None
65
  _ai_strategist: Optional[AIStrategist] = None
 
66
  _support_agent: Optional[SupportAgent] = None
67
  _budget_predictor = None
68
  _influencer_matcher = None
@@ -506,16 +507,15 @@ app = FastAPI(title="Reachify AI Service (Deploy-Ready)", version="11.0.0")
506
 
507
  @app.on_event("startup")
508
  def startup_event():
509
- global _llm_instance, _ai_strategist, _support_agent, _vector_store, \
 
510
  _budget_predictor, _influencer_matcher, _performance_predictor, _payout_forecaster, \
511
  _earnings_optimizer, _earnings_encoder, _likes_predictor, _comments_predictor, \
512
  _revenue_forecaster, _performance_scorer
513
 
514
- print("--- πŸš€ AI Service Starting Up (Hugging Face Mode)... ---")
515
-
516
- # === FIX #3: The Model Download and Loading Logic ===
517
  try:
518
- # Step 1: Download the model if it doesn't exist
519
  os.makedirs(MODEL_SAVE_DIRECTORY, exist_ok=True)
520
  if not os.path.exists(LLAMA_MODEL_PATH):
521
  print(f" - LLM model not found locally. Downloading '{MODEL_FILENAME}'...")
@@ -523,51 +523,48 @@ def startup_event():
523
  repo_id=MODEL_REPO,
524
  filename=MODEL_FILENAME,
525
  local_dir=MODEL_SAVE_DIRECTORY,
526
- local_dir_use_symlinks=False # This is safer for containers
527
  )
528
  print(" - βœ… Model downloaded successfully.")
529
  else:
530
  print(f" - LLM model found at {LLAMA_MODEL_PATH}. Skipping download.")
531
 
532
- # Step 2: Now that the file is guaranteed to be there, load it.
533
- print(" - Loading Llama LLM into memory from downloaded file...")
534
- _llm_instance = Llama(
535
- model_path=LLAMA_MODEL_PATH,
536
- n_gpu_layers=0, # Ensure CPU usage on free tier
537
- n_ctx=2048,
538
- verbose=False,
539
- use_mmap=False
540
- )
541
- print(" - βœ… LLM Loaded into Memory on CPU.")
542
 
543
  except Exception as e:
544
  print(f" - ❌ FATAL ERROR: Could not download or load LLM model: {e}")
545
  traceback.print_exc()
546
- _llm_instance = None # Ensure it is None if it fails
547
- # =========================================================
 
 
 
 
 
 
 
 
 
548
 
549
- # --- All the rest of your startup logic remains EXACTLY THE SAME ---
550
- if VectorStore:
551
- try:
552
  _vector_store = VectorStore()
553
  print(" - βœ… RAG Engine Ready.")
554
- except Exception:
555
- _vector_store = None
556
- else:
557
- _vector_store = None
558
-
559
- print(" - Initializing AI Strategist...")
560
- _ai_strategist = AIStrategist(llm_instance=_llm_instance, store=_vector_store)
561
- print(" - βœ… AI Strategist ready.")
562
-
563
- print(" - Initializing Support Agent...")
564
- _support_agent = SupportAgent(
565
- llm_instance=_llm_instance,
566
- embedding_path=EMBEDDING_MODEL_PATH,
567
- db_path=DB_PATH
568
- )
569
- print(" - βœ… Support Agent ready.")
570
-
571
  print(" - Loading ML models from joblib files...")
572
  model_paths = {
573
  'budget': ('_budget_predictor', 'budget_predictor_v1.joblib'),
@@ -1943,15 +1940,11 @@ def generate_weekly_plan_route(request: WeeklyPlanRequest): # <--- async hata d
1943
 
1944
  @app.post("/chat/creative", response_model=Dict[str, str], summary="Brainstorming chat with AI Creative Director")
1945
  def creative_chat_endpoint(request: CreativeChatRequest):
1946
- """
1947
- Takes user message, history, and task context.
1948
- Returns a short, punchy, expert response using RAG + LLM.
1949
- """
1950
  try:
1951
- # Convert Pydantic history to list of dicts
1952
  history_list = [m.model_dump() for m in request.history]
1953
-
1954
- response_text = director.chat(
1955
  user_message=request.message,
1956
  history=history_list,
1957
  task_context=request.task_context
@@ -1959,59 +1952,19 @@ def creative_chat_endpoint(request: CreativeChatRequest):
1959
  return {"reply": response_text}
1960
  except Exception as e:
1961
  print(f"🚨 Creative Chat Error: {e}")
1962
- raise HTTPException(status_code=500, detail="AI Director is busy.")
1963
 
1964
 
1965
  @app.post("/generate/final-from-chat", response_model=FinalScriptResponse, summary="Generates final structured script from chat history")
1966
  def finalize_script_endpoint(request: FinalizeScriptRequest):
1967
- """
1968
- Summarizes the conversation into a shoot plan.
1969
- This version is ROBUST and handles messy LLM output.
1970
- """
1971
  try:
1972
  history_list = [m.model_dump() for m in request.history]
1973
-
1974
- raw_text = director.generate_final_plan(
1975
  task_context=request.task_context,
1976
  history=history_list
1977
  )
1978
-
1979
- print(f" - πŸ€– Raw Final Plan from LLM:\n---\n{raw_text}\n---")
1980
-
1981
- # --- IDIOT-PROOF PARSING LOGIC ---
1982
- plan = { "hook": "", "script": "", "visuals": [], "tools": [] }
1983
-
1984
- # Try to find JSON first
1985
- try:
1986
- import json
1987
- json_match = re.search(r'\{.*\}', raw_text, re.DOTALL)
1988
- if json_match:
1989
- parsed = json.loads(json_match.group(0))
1990
- plan["hook"] = parsed.get("hook", "")
1991
- plan["script"] = parsed.get("script", "")
1992
- plan["visuals"] = parsed.get("visuals", [])
1993
- plan["tools"] = parsed.get("tools", [])
1994
-
1995
- # Agar ek bhi cheez mil gayi to return kar do
1996
- if plan["hook"] or plan["script"]:
1997
- return FinalScriptResponse(**plan)
1998
- except:
1999
- pass # JSON parsing fail hua to aage badho
2000
-
2001
- # Fallback to Regex if no JSON found
2002
- hook_match = re.search(r"Hook:?\s*\"(.*?)\"", raw_text, re.IGNORECASE)
2003
- script_match = re.search(r"Script:?\s*\"(.*?)\"", raw_text, re.IGNORECASE)
2004
-
2005
- plan["hook"] = hook_match.group(1) if hook_match else "Start with a bang!"
2006
-
2007
- # Agar script nahi mili to poora raw text hi script maan lo
2008
- plan["script"] = script_match.group(1) if script_match else raw_text
2009
-
2010
- plan["visuals"] = ["Close up shot", "Wide shot"]
2011
- plan["tools"] = ["CapCut"]
2012
-
2013
- return FinalScriptResponse(**plan)
2014
-
2015
  except Exception as e:
2016
  print(f"🚨 Finalize Script Error: {e}")
2017
- raise HTTPException(status_code=500, detail="Failed to generate final plan.")
 
63
  _llm_instance: Optional[Llama] = None
64
  _vector_store: Optional[Any] = None
65
  _ai_strategist: Optional[AIStrategist] = None
66
+ _creative_director: Optional[CreativeDirector] = None
67
  _support_agent: Optional[SupportAgent] = None
68
  _budget_predictor = None
69
  _influencer_matcher = None
 
507
 
508
  @app.on_event("startup")
509
  def startup_event():
510
+ # Make sure we can modify the global variables
511
+ global _llm_instance, _creative_director, _support_agent, _ai_strategist, _vector_store, \
512
  _budget_predictor, _influencer_matcher, _performance_predictor, _payout_forecaster, \
513
  _earnings_optimizer, _earnings_encoder, _likes_predictor, _comments_predictor, \
514
  _revenue_forecaster, _performance_scorer
515
 
516
+ # === MODEL DOWNLOAD AND LOAD LOGIC ===
517
+ print("--- πŸš€ AI Service Starting Up... ---")
 
518
  try:
 
519
  os.makedirs(MODEL_SAVE_DIRECTORY, exist_ok=True)
520
  if not os.path.exists(LLAMA_MODEL_PATH):
521
  print(f" - LLM model not found locally. Downloading '{MODEL_FILENAME}'...")
 
523
  repo_id=MODEL_REPO,
524
  filename=MODEL_FILENAME,
525
  local_dir=MODEL_SAVE_DIRECTORY,
526
+ local_dir_use_symlinks=False
527
  )
528
  print(" - βœ… Model downloaded successfully.")
529
  else:
530
  print(f" - LLM model found at {LLAMA_MODEL_PATH}. Skipping download.")
531
 
532
+ print(" - Loading Llama LLM into memory...")
533
+ _llm_instance = Llama(model_path=LLAMA_MODEL_PATH, n_gpu_layers=0, n_ctx=2048, verbose=False, use_mmap=False)
534
+ print(" - βœ… LLM Loaded.")
 
 
 
 
 
 
 
535
 
536
  except Exception as e:
537
  print(f" - ❌ FATAL ERROR: Could not download or load LLM model: {e}")
538
  traceback.print_exc()
539
+ # If LLM fails to load, we can't continue.
540
+ # Set instance to None and the rest of the app will know.
541
+ _llm_instance = None
542
+ return # Stop the startup process here.
543
+
544
+ # === INITIALIZE AI COMPONENTS (NOW THAT LLM IS LOADED) ===
545
+ # This logic now runs ONLY IF the LLM loaded successfully.
546
+ try:
547
+ print(" - Initializing Creative Director...")
548
+ _creative_director = CreativeDirector(llm_instance=_llm_instance)
549
+ print(" - βœ… Creative Director is online.")
550
 
551
+ if VectorStore:
552
+ print(" - Initializing Vector Store...")
 
553
  _vector_store = VectorStore()
554
  print(" - βœ… RAG Engine Ready.")
555
+
556
+ print(" - Initializing AI Strategist...")
557
+ _ai_strategist = AIStrategist(llm_instance=_llm_instance, store=_vector_store)
558
+ print(" - βœ… AI Strategist ready.")
559
+
560
+ print(" - Initializing Support Agent...")
561
+ _support_agent = SupportAgent(llm_instance=_llm_instance, embedding_path=EMBEDDING_MODEL_PATH, db_path=DB_PATH)
562
+ print(" - βœ… Support Agent ready.")
563
+ except Exception as e:
564
+ print(f" - ❌ FAILED to initialize core AI components: {e}")
565
+ traceback.print_exc()
566
+
567
+ # === LOAD SKLEARN MODELS (This part is independent of the LLM) ===
 
 
 
 
568
  print(" - Loading ML models from joblib files...")
569
  model_paths = {
570
  'budget': ('_budget_predictor', 'budget_predictor_v1.joblib'),
 
1940
 
1941
  @app.post("/chat/creative", response_model=Dict[str, str], summary="Brainstorming chat with AI Creative Director")
1942
  def creative_chat_endpoint(request: CreativeChatRequest):
1943
+ if not _creative_director:
1944
+ raise HTTPException(status_code=503, detail="AI Creative Director is not available due to a startup error.")
 
 
1945
  try:
 
1946
  history_list = [m.model_dump() for m in request.history]
1947
+ response_text = _creative_director.chat(
 
1948
  user_message=request.message,
1949
  history=history_list,
1950
  task_context=request.task_context
 
1952
  return {"reply": response_text}
1953
  except Exception as e:
1954
  print(f"🚨 Creative Chat Error: {e}")
1955
+ raise HTTPException(status_code=500, detail="An error occurred with the AI Director.")
1956
 
1957
 
1958
  @app.post("/generate/final-from-chat", response_model=FinalScriptResponse, summary="Generates final structured script from chat history")
1959
  def finalize_script_endpoint(request: FinalizeScriptRequest):
1960
+ if not _creative_director:
1961
+ raise HTTPException(status_code=503, detail="AI Creative Director is not available due to a startup error.")
 
 
1962
  try:
1963
  history_list = [m.model_dump() for m in request.history]
1964
+ return _creative_director.generate_final_plan(
 
1965
  task_context=request.task_context,
1966
  history=history_list
1967
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1968
  except Exception as e:
1969
  print(f"🚨 Finalize Script Error: {e}")
1970
+ raise HTTPException(status_code=500, detail="Failed to generate the final plan.")