Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI | |
| from pydantic import BaseModel | |
| import os | |
| import requests | |
| from rag import RAGEngine | |
| from loader import smart_load | |
| from llm import generate_answer | |
| from langdetect import detect | |
| from normalizer import normalize_text | |
| from config import FALLBACK_ANSWER | |
| from memory import ConversationMemory | |
| app = FastAPI() | |
| # memory per agent | |
| agent_memories = {} | |
| # RAG cache per agent <<< NEW | |
| agent_rags = {} | |
| def get_agent_memory(agent_id): | |
| if agent_id not in agent_memories: | |
| agent_memories[agent_id] = ConversationMemory( | |
| max_messages=10 | |
| ) | |
| return agent_memories[agent_id] | |
| # add | |
| # load rag one time | |
| def get_agent_rag(agent_id): | |
| if agent_id in agent_rags: | |
| print("Agent ID", agent_id) | |
| return agent_rags[agent_id] | |
| agent_folder = f"agents/{agent_id}" | |
| index_file = os.path.join( | |
| agent_folder, | |
| "index.faiss" | |
| ) | |
| text_file = os.path.join( | |
| agent_folder, | |
| "texts.pkl" | |
| ) | |
| if not os.path.exists(index_file) or not os.path.exists(text_file): | |
| print("Agent exists but not trained:", agent_id) | |
| return None | |
| print("Loading RAG first time:", agent_id) | |
| rag = RAGEngine() | |
| rag.load(agent_folder) | |
| agent_rags[agent_id] = rag | |
| return rag | |
| class TrainRequest(BaseModel): | |
| agent_id: str | |
| file_url: str | |
| file_type: str | |
| file_name: str | |
| agent_type: str | |
| class ChatRequest(BaseModel): | |
| agent_id: str | |
| message: str | |
| def home(): | |
| return { | |
| "service": "Customer Support AI", | |
| "status": "running" | |
| } | |
| async def train_agent(request: TrainRequest): | |
| try: | |
| agent_folder = f"agents/{request.agent_id}" | |
| os.makedirs( | |
| agent_folder, | |
| exist_ok=True | |
| ) | |
| dataset_path = os.path.join( | |
| agent_folder, | |
| request.file_name | |
| ) | |
| # download dataset | |
| response = requests.get( | |
| request.file_url, | |
| timeout=60 | |
| ) | |
| response.raise_for_status() | |
| with open(dataset_path,"wb") as f: | |
| f.write( | |
| response.content | |
| ) | |
| # load dataset | |
| chunks = smart_load(dataset_path) | |
| if not chunks: | |
| return { | |
| "success":False, | |
| "message":"No valid data found" | |
| } | |
| rag = RAGEngine() | |
| rag.build_index( | |
| chunks | |
| ) | |
| rag.save( | |
| agent_folder | |
| ) | |
| # NEW | |
| # keep trained rag in memory | |
| agent_rags[request.agent_id] = rag | |
| return { | |
| "success":True, | |
| "agent_id":request.agent_id, | |
| "chunks":len(chunks) | |
| } | |
| except Exception as e: | |
| return { | |
| "success":False, | |
| "message":str(e) | |
| } | |
| async def chat(request:ChatRequest): | |
| try: | |
| # NEW | |
| # get cached RAG | |
| rag = get_agent_rag( | |
| request.agent_id | |
| ) | |
| if rag is None: | |
| return { | |
| "answer":"Agent not found", | |
| "sources":[] | |
| } | |
| question = request.message | |
| try: | |
| lang = detect(question) | |
| except: | |
| lang="en" | |
| normalized = normalize_text( | |
| question | |
| ) | |
| # memory | |
| memory = get_agent_memory( | |
| request.agent_id | |
| ) | |
| memory.add_user_message( | |
| question | |
| ) | |
| # retrieval | |
| retrieved = rag.retrieve_multi_query( | |
| normalized, | |
| # changed for speed | |
| use_expansion=False | |
| ) | |
| if not retrieved: | |
| retrieved, confidence = rag.retrieve_with_confidence( | |
| normalized, | |
| confidence_threshold=0.10 | |
| ) | |
| if not retrieved: | |
| return { | |
| "answer":FALLBACK_ANSWER.get( | |
| lang, | |
| FALLBACK_ANSWER["en"] | |
| ), | |
| "sources":[] | |
| } | |
| context = "\n".join( | |
| retrieved | |
| ) | |
| answer = generate_answer( | |
| context, | |
| question, | |
| lang, | |
| memory.get_memory() | |
| ) | |
| memory.add_assistant_message( | |
| answer | |
| ) | |
| return { | |
| "answer":answer, | |
| "sources":[] | |
| } | |
| except Exception as e: | |
| return { | |
| "answer":"Error", | |
| "error":str(e) | |
| } | |