# app.py from fastapi import FastAPI from pydantic import BaseModel from fastapi.middleware.cors import CORSMiddleware #from bot_instance import gemini_bot, llama_bot # singleton ErrorBot instance from typing import List, Optional,Any import os from dotenv import load_dotenv from util import ErrorBot # from mongo_to_qdrant_ingestor import MongoToQdrantIngestor # from qdrant_instance import qdrant # from embedding_model_instance import embedding_model # from json_to_qdrant_ingestor import JsonToQdrantIngestor app = FastAPI(title="ErrorBot API") # ✅ Allow all origins (adjust in production) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # ---------------- Request Models ---------------- class MessageItem(BaseModel): role: str # "user" or "bot" content: str class ChatRequest(BaseModel): message: str history: Optional[List[MessageItem]] = [] # optional conversation history lastContext: List[Any] = None # ---------------- Endpoints ---------------- @app.get("/") def root(): return {"status": "ok"} # @app.post("/chat") # def chat(request: ChatRequest): # """ # Main chat endpoint: # - Accepts a message and optional conversation history # - Uses ErrorBot with RAG + LLM # """ # history_list = [ # {"role": msg.role, "content": msg.content} for msg in request.history # ] # # Ask bot with history # answer = bot.ask(request.message, history=history_list) # return {"reply": answer} load_dotenv() #GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY") #GROQ_API_KEY = os.getenv("GROQ_API_KEY") #EMBEDDING_MODEL = "BAAI/bge-large-en-v1.5" #EMBEDDING_MODEL = "all-MiniLM-L6-v2" #EMBEDDING_MODEL = "BAAI/bge-m3" @app.post("/gemini/chat") def gemini_chat(request: ChatRequest): history_list = [{"role": msg.role, "content": msg.content} for msg in request.history] gemini_bot = ErrorBot( llm_model_name="gemini-2.5-flash", llm_provider="gemini", last_context = request.lastContext ) #print("In App.py") #print(request.lastContext) answer, last_context = gemini_bot.ask(request.message, history=history_list) #print(answer) #print(last_context) return {"reply": answer, "last_context": last_context} @app.post("/llama/chat") def llama_chat(request: ChatRequest): history_list = [{"role": msg.role, "content": msg.content} for msg in request.history] llama_bot = ErrorBot( llm_model_name="llama-3.3-70b-versatile", llm_provider="groq", last_context = request.lastContext ) answer, last_context = llama_bot.ask(request.message, history=history_list) #print(answer) #print(last_context) return {"reply": answer, "last_context": last_context} # @app.post("/ingest/mongodb") # def ingest_mongodb(): # """ # Ingest documents from MongoDB into the bot's knowledge base. # """ # ingestor = MongoToQdrantIngestor(qdrant, embedding_model, collection_name="technical_errors") # # def build_content(doc, entity_type): # # """Simple example function to build textual content.""" # # return f"{entity_type}: {doc.get('title', '')} {doc.get('description', '')}" # def build_content(doc: dict, entity_type: str) -> str: # """Convert MongoDB document into natural text for embeddings.""" # parts = [f"{entity_type} ID: {doc.get('id', str(doc.get('_id', '')))}"] # for k, v in doc.items(): # if k in ["_id"]: # skip ObjectId # continue # if isinstance(v, list): # parts.append(f"{k}: {', '.join(map(str, v))}") # elif isinstance(v, dict): # nested = "; ".join([f"{nk}: {nv}" for nk, nv in v.items() if nv]) # parts.append(f"{k}: {nested}") # else: # if v: # parts.append(f"{k}: {v}") # return "\n".join(parts) # ingestor.ingest_from_mongodb( # build_content_fn=build_content, # batch_size=500, # ) # return {"status": "ingestion started"} # @app.post("/ingest/json") # def ingest_json(): # """ # Ingest documents from JSON into the bot's knowledge base. # """ # json_sources = { # "ProblemReport": "./json/problemReports.json", # "Correction": "./json/corrections.json", # "FaultAnalysis": "./json/faultanalysis.json", # } # ingestor = JsonToQdrantIngestor(qdrant, embedding_model, collection_name="technical_errors") # def build_content(doc, entity_type): # """Simple example function to build textual content.""" # return f"{entity_type}: {doc.get('title', '')} {doc.get('description', '')}" # ingestor.ingest_from_json( # json_sources, # build_content_fn=build_content, # batch_size=500, # ) # return {"status": "ingestion started"}