Spaces:
Sleeping
Sleeping
| """ | |
| Document processing and RAG router for Lily LLM API | |
| """ | |
| from fastapi import APIRouter, HTTPException, UploadFile, File, Form | |
| from typing import Optional, List | |
| import logging | |
| import time | |
| import os | |
| import uuid | |
| from ...models.schemas import ( | |
| DocumentUploadResponse, RAGQueryRequest, RAGQueryResponse, | |
| DocumentProcessResponse, MultimodalRAGResponse | |
| ) | |
| from ...services.session_registry import set_user_for_room, set_flag_for_room, set_last_document_for_room | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter() | |
| async def upload_document( | |
| file: UploadFile = File(...), | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default") | |
| ): | |
| """๋ฌธ์ ์ ๋ก๋ ๋ฐ ์ฒ๋ฆฌ""" | |
| try: | |
| start_time = time.time() | |
| # ํ์ผ ์ฝ๊ธฐ ๋ฐ ์์ ์ ์ฅ (ํ์ผ ๊ฒฝ๋ก ๊ธฐ๋ฐ ์ฒ๋ฆฌ๊ธฐ ํธํ) | |
| content = await file.read() | |
| filename = file.filename | |
| temp_dir = os.path.join("data", "uploads") | |
| os.makedirs(temp_dir, exist_ok=True) | |
| temp_name = f"{int(time.time()*1000)}_{uuid.uuid4().hex}_{filename}" | |
| temp_path = os.path.join(temp_dir, temp_name) | |
| with open(temp_path, "wb") as f: | |
| f.write(content) | |
| # ๋ฌธ์ ์ฒ๋ฆฌ๊ธฐ ์ฌ์ฉ (์ฐ์ RAG์ ์ ์ฅ ํฌํจ ๊ฒฝ๋ก) | |
| try: | |
| from lily_llm_core.rag_processor import rag_processor | |
| document_id = f"doc_{int(time.time()*1000)}_{uuid.uuid4().hex}" | |
| result = rag_processor.process_and_store_document( | |
| user_id=user_id, | |
| document_id=document_id, | |
| file_path=temp_path, | |
| ) | |
| # ์ ๋ก๋ ์ ๋ฐฉ-์ฌ์ฉ์ ๋งคํ ์ ์ฅ (ํ์ ์์ฑ์์ ์๋ ๋ณด์ ) | |
| try: | |
| set_user_for_room(room_id, user_id) | |
| except Exception: | |
| pass | |
| if result.get("success"): | |
| processing_time = time.time() - start_time | |
| # ์ ๋ก๋ ์งํ, ๊ฐ์ ๋ฐฉ์์ ๋ค์ 1ํ ์์ฑ์ ์ด๋ฏธ์ง ๋ณต๊ตฌ๋ฅผ ํ์ฉ | |
| try: | |
| set_flag_for_room(room_id, "use_rag_images_once", True) | |
| except Exception: | |
| pass | |
| # ๋ฐฉ๋ณ ๋ง์ง๋ง ๋ฌธ์ID ๊ธฐ๋ก (ํ์ ์์ฒญ์์ ๊ธฐ๋ณธ ๋ฌธ์ ์ ํ) | |
| try: | |
| set_last_document_for_room(room_id, result.get("document_id", document_id)) | |
| except Exception: | |
| pass | |
| return DocumentUploadResponse( | |
| success=True, | |
| document_id=result.get("document_id", document_id), | |
| message="๋ฌธ์ ์ ๋ก๋ ๋ฐ ์ฒ๋ฆฌ ์๋ฃ", | |
| chunks=result.get("chunks", 0), | |
| latex_count=result.get("latex_count", 0), | |
| auto_response=result.get("auto_response") | |
| ) | |
| else: | |
| return DocumentUploadResponse( | |
| success=False, | |
| document_id="", | |
| message="๋ฌธ์ ์ฒ๋ฆฌ ์คํจ", | |
| error=result.get("error", "Unknown error") | |
| ) | |
| except ImportError: | |
| # ํด๋ฐฑ: ์์ ๋ฌธ์ ํ์๋ก ์ฒ๋ฆฌ๋ง ์ํ | |
| try: | |
| from lily_llm_core.document_processor import document_processor | |
| docs = document_processor.process_document(temp_path) | |
| processing_time = time.time() - start_time | |
| return DocumentUploadResponse( | |
| success=True, | |
| document_id="", | |
| message="๋ฌธ์ ์ ๋ก๋ ๋ฐ ์ฒ๋ฆฌ ์๋ฃ (๋ฒกํฐ ์ ์ฅ ๋ฏธ์ํ)", | |
| chunks=len(docs) if docs else 0, | |
| latex_count=0, | |
| auto_response=None | |
| ) | |
| except Exception as e: | |
| return DocumentUploadResponse( | |
| success=False, | |
| document_id="", | |
| message="๋ฌธ์ ์ฒ๋ฆฌ๊ธฐ import ์คํจ", | |
| error=str(e) | |
| ) | |
| except Exception as e: | |
| logger.error(f"๋ฌธ์ ์ ๋ก๋ ์คํจ: {e}") | |
| return DocumentUploadResponse( | |
| success=False, | |
| document_id="", | |
| message="๋ฌธ์ ์ ๋ก๋ ์ค ์ค๋ฅ ๋ฐ์", | |
| error=str(e) | |
| ) | |
| async def upload_document_trailing_slash( | |
| file: UploadFile = File(...), | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default") | |
| ): | |
| # ์ฌ๋์ ์ ๋ฌด ๋ชจ๋ ํ์ฉ (FastAPI 307 ๋ฆฌ๋๋ ์ ํํผ) | |
| return await upload_document(file=file, user_id=user_id, room_id=room_id) | |
| async def rag_query( | |
| query: str = Form(...), | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default"), | |
| max_results: int = Form(5), | |
| include_sources: bool = Form(True) | |
| ): | |
| """RAG ์ฟผ๋ฆฌ ์ฒ๋ฆฌ""" | |
| try: | |
| start_time = time.time() | |
| try: | |
| from lily_llm_core.rag_processor import rag_processor | |
| # RAG ์ฟผ๋ฆฌ ์คํ | |
| result = rag_processor.query( | |
| query=query, | |
| user_id=user_id, | |
| room_id=room_id, | |
| max_results=max_results, | |
| include_sources=include_sources | |
| ) | |
| if result.get("success"): | |
| processing_time = time.time() - start_time | |
| return RAGQueryResponse( | |
| success=True, | |
| response=result.get("response", ""), | |
| sources=result.get("sources", []), | |
| search_results=len(result.get("sources", [])), | |
| processing_time=processing_time | |
| ) | |
| else: | |
| return RAGQueryResponse( | |
| success=False, | |
| response="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0, | |
| error=result.get("error", "RAG ์ฟผ๋ฆฌ ์คํจ") | |
| ) | |
| except ImportError: | |
| return RAGQueryResponse( | |
| success=False, | |
| response="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0, | |
| error="RAG processor not available" | |
| ) | |
| except Exception as e: | |
| logger.error(f"RAG ์ฟผ๋ฆฌ ์คํจ: {e}") | |
| return RAGQueryResponse( | |
| success=False, | |
| response="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0, | |
| error=str(e) | |
| ) | |
| async def rag_generate( | |
| prompt: str = Form(...), | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default"), | |
| max_results: int = Form(5) | |
| ): | |
| """RAG ๊ธฐ๋ฐ ํ ์คํธ ์์ฑ""" | |
| try: | |
| start_time = time.time() | |
| try: | |
| from lily_llm_core.rag_processor import rag_processor | |
| # RAG ์์ฑ ์คํ | |
| result = rag_processor.generate_with_context( | |
| prompt=prompt, | |
| user_id=user_id, | |
| room_id=room_id, | |
| max_results=max_results | |
| ) | |
| if result.get("success"): | |
| processing_time = time.time() - start_time | |
| return RAGQueryResponse( | |
| success=True, | |
| response=result.get("response", ""), | |
| sources=result.get("sources", []), | |
| search_results=len(result.get("sources", [])), | |
| processing_time=processing_time | |
| ) | |
| else: | |
| return RAGQueryResponse( | |
| success=False, | |
| response="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0, | |
| error=result.get("error", "RAG ์์ฑ ์คํจ") | |
| ) | |
| except ImportError: | |
| return RAGQueryResponse( | |
| success=False, | |
| response="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0, | |
| error="RAG processor not available" | |
| ) | |
| except Exception as e: | |
| logger.error(f"RAG ์์ฑ ์คํจ: {e}") | |
| return RAGQueryResponse( | |
| success=False, | |
| response="", | |
| sources=[], | |
| search_results=0, | |
| processing_time=0, | |
| error=str(e) | |
| ) | |
| async def generate_rag_summary( | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default") | |
| ): | |
| """RAG ๋ฌธ์ ์์ฝ ์์ฑ""" | |
| try: | |
| try: | |
| from lily_llm_core.rag_processor import rag_processor | |
| # RAG ์์ฝ ์์ฑ | |
| result = rag_processor.generate_summary( | |
| user_id=user_id, | |
| room_id=room_id | |
| ) | |
| if result.get("success"): | |
| return {"status": "success", "summary": result.get("summary", "")} | |
| else: | |
| raise HTTPException(status_code=500, detail=result.get("error", "RAG ์์ฝ ์์ฑ ์คํจ")) | |
| except ImportError: | |
| raise HTTPException(status_code=500, detail="RAG processor not available") | |
| except Exception as e: | |
| logger.error(f"RAG ์์ฝ ์์ฑ ์คํจ: {e}") | |
| raise HTTPException(status_code=500, detail=f"RAG ์์ฝ ์์ฑ ์คํจ: {str(e)}") | |
| async def clear_rag_context( | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default") | |
| ): | |
| """RAG ์ปจํ ์คํธ ์ ๋ฆฌ""" | |
| try: | |
| try: | |
| from lily_llm_core.rag_processor import rag_processor | |
| # RAG ์ปจํ ์คํธ ์ ๋ฆฌ | |
| success = rag_processor.clear_context( | |
| user_id=user_id, | |
| room_id=room_id | |
| ) | |
| if success: | |
| return {"status": "success", "message": "RAG ์ปจํ ์คํธ ์ ๋ฆฌ ์๋ฃ"} | |
| else: | |
| raise HTTPException(status_code=500, detail="RAG ์ปจํ ์คํธ ์ ๋ฆฌ ์คํจ") | |
| except ImportError: | |
| raise HTTPException(status_code=500, detail="RAG processor not available") | |
| except Exception as e: | |
| logger.error(f"RAG ์ปจํ ์คํธ ์ ๋ฆฌ ์คํจ: {e}") | |
| raise HTTPException(status_code=500, detail=f"RAG ์ปจํ ์คํธ ์ ๋ฆฌ ์คํจ: {str(e)}") | |
| async def batch_process_documents( | |
| files: List[UploadFile] = File(...), | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default") | |
| ): | |
| """์ฌ๋ฌ ๋ฌธ์ ์ผ๊ด ์ฒ๋ฆฌ""" | |
| try: | |
| start_time = time.time() | |
| results = [] | |
| try: | |
| from lily_llm_core.rag_processor import rag_processor | |
| for file in files: | |
| content = await file.read() | |
| filename = file.filename | |
| # ์์ ์ ์ฅ ํ RAG์ ์ ์ฅ ํฌํจ ์ฒ๋ฆฌ | |
| temp_dir = os.path.join("data", "uploads") | |
| os.makedirs(temp_dir, exist_ok=True) | |
| temp_name = f"{int(time.time()*1000)}_{uuid.uuid4().hex}_{filename}" | |
| temp_path = os.path.join(temp_dir, temp_name) | |
| with open(temp_path, "wb") as f: | |
| f.write(content) | |
| document_id = f"doc_{int(time.time()*1000)}_{uuid.uuid4().hex}" | |
| result = rag_processor.process_and_store_document( | |
| user_id=user_id, | |
| document_id=document_id, | |
| file_path=temp_path, | |
| ) | |
| results.append({ | |
| "filename": filename, | |
| "success": result.get("success", False), | |
| "document_id": result.get("document_id", document_id), | |
| "chunks": result.get("chunks", 0), | |
| "error": result.get("error") | |
| }) | |
| processing_time = time.time() - start_time | |
| return { | |
| "status": "success", | |
| "results": results, | |
| "total_files": len(files), | |
| "processing_time": processing_time | |
| } | |
| except ImportError: | |
| # ํด๋ฐฑ: ์ ์ฅ ์์ด ์ฒ๋ฆฌ๋ง ์ํ | |
| try: | |
| from lily_llm_core.document_processor import document_processor | |
| for file in files: | |
| content = await file.read() | |
| filename = file.filename | |
| temp_dir = os.path.join("data", "uploads") | |
| os.makedirs(temp_dir, exist_ok=True) | |
| temp_name = f"{int(time.time()*1000)}_{uuid.uuid4().hex}_{filename}" | |
| temp_path = os.path.join(temp_dir, temp_name) | |
| with open(temp_path, "wb") as f: | |
| f.write(content) | |
| docs = document_processor.process_document(temp_path) | |
| results.append({ | |
| "filename": filename, | |
| "success": bool(docs), | |
| "document_id": "", | |
| "chunks": len(docs) if docs else 0, | |
| "error": None if docs else "processing failed" | |
| }) | |
| processing_time = time.time() - start_time | |
| return { | |
| "status": "success", | |
| "results": results, | |
| "total_files": len(files), | |
| "processing_time": processing_time | |
| } | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| except Exception as e: | |
| logger.error(f"์ผ๊ด ๋ฌธ์ ์ฒ๋ฆฌ ์คํจ: {e}") | |
| raise HTTPException(status_code=500, detail=f"์ผ๊ด ๋ฌธ์ ์ฒ๋ฆฌ ์คํจ: {str(e)}") | |
| async def search_rag_history( | |
| user_id: str = "anonymous", | |
| room_id: str = "default", | |
| query: str = "", | |
| limit: int = 10 | |
| ): | |
| """RAG ๊ฒ์ ํ์คํ ๋ฆฌ ์กฐํ""" | |
| try: | |
| try: | |
| from lily_llm_core.rag_processor import rag_processor | |
| # RAG ๊ฒ์ ํ์คํ ๋ฆฌ ์กฐํ | |
| history = rag_processor.get_search_history( | |
| user_id=user_id, | |
| room_id=room_id, | |
| query=query, | |
| limit=limit | |
| ) | |
| return {"status": "success", "history": history} | |
| except ImportError: | |
| raise HTTPException(status_code=500, detail="RAG processor not available") | |
| except Exception as e: | |
| logger.error(f"RAG ๊ฒ์ ํ์คํ ๋ฆฌ ์กฐํ ์คํจ: {e}") | |
| raise HTTPException(status_code=500, detail=f"RAG ๊ฒ์ ํ์คํ ๋ฆฌ ์กฐํ ์คํจ: {str(e)}") | |
| async def upload_multimodal_document( | |
| file: UploadFile = File(...), | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default") | |
| ): | |
| """๋ฉํฐ๋ชจ๋ฌ ๋ฌธ์ ์ ๋ก๋""" | |
| try: | |
| start_time = time.time() | |
| # ํ์ผ ์ฝ๊ธฐ | |
| content = await file.read() | |
| filename = file.filename | |
| try: | |
| from lily_llm_core.hybrid_rag_processor import hybrid_rag_processor | |
| # ์์ ์ ์ฅ ํ ํ์ผ ๊ฒฝ๋ก ๊ธฐ๋ฐ ์ฒ๋ฆฌ | |
| temp_dir = os.path.join("data", "uploads") | |
| os.makedirs(temp_dir, exist_ok=True) | |
| temp_name = f"{int(time.time()*1000)}_{uuid.uuid4().hex}_{filename}" | |
| temp_path = os.path.join(temp_dir, temp_name) | |
| with open(temp_path, "wb") as f: | |
| f.write(content) | |
| result = hybrid_rag_processor.process_document( | |
| file_path=temp_path, | |
| user_id=user_id, | |
| room_id=room_id | |
| ) | |
| if result.get("success"): | |
| processing_time = time.time() - start_time | |
| return { | |
| "status": "success", | |
| "document_id": result.get("document_id", ""), | |
| "processing_time": processing_time, | |
| "message": "๋ฉํฐ๋ชจ๋ฌ ๋ฌธ์ ์ ๋ก๋ ์๋ฃ" | |
| } | |
| else: | |
| raise HTTPException(status_code=500, detail=result.get("error", "๋ฉํฐ๋ชจ๋ฌ ๋ฌธ์ ์ฒ๋ฆฌ ์คํจ")) | |
| except ImportError: | |
| raise HTTPException(status_code=500, detail="Hybrid RAG processor not available") | |
| except Exception as e: | |
| logger.error(f"๋ฉํฐ๋ชจ๋ฌ ๋ฌธ์ ์ ๋ก๋ ์คํจ: {e}") | |
| raise HTTPException(status_code=500, detail=f"๋ฉํฐ๋ชจ๋ฌ ๋ฌธ์ ์ ๋ก๋ ์คํจ: {str(e)}") | |
| async def generate_multimodal_rag( | |
| prompt: str = Form(...), | |
| user_id: str = Form("anonymous"), | |
| room_id: str = Form("default") | |
| ): | |
| """๋ฉํฐ๋ชจ๋ฌ RAG ๊ธฐ๋ฐ ํ ์คํธ ์์ฑ""" | |
| try: | |
| start_time = time.time() | |
| try: | |
| from lily_llm_core.hybrid_rag_processor import hybrid_rag_processor | |
| # ๋ฉํฐ๋ชจ๋ฌ RAG ์์ฑ | |
| result = hybrid_rag_processor.generate( | |
| prompt=prompt, | |
| user_id=user_id, | |
| room_id=room_id | |
| ) | |
| if result.get("success"): | |
| processing_time = time.time() - start_time | |
| return MultimodalRAGResponse( | |
| success=True, | |
| response=result.get("response", ""), | |
| image_processed=result.get("image_processed", False), | |
| processing_time=processing_time | |
| ) | |
| else: | |
| return MultimodalRAGResponse( | |
| success=False, | |
| response="", | |
| image_processed=False, | |
| processing_time=0, | |
| error=result.get("error", "๋ฉํฐ๋ชจ๋ฌ RAG ์์ฑ ์คํจ") | |
| ) | |
| except ImportError: | |
| return MultimodalRAGResponse( | |
| success=False, | |
| response="", | |
| image_processed=False, | |
| processing_time=0, | |
| error="Hybrid RAG processor not available" | |
| ) | |
| except Exception as e: | |
| logger.error(f"๋ฉํฐ๋ชจ๋ฌ RAG ์์ฑ ์คํจ: {e}") | |
| return MultimodalRAGResponse( | |
| success=False, | |
| response="", | |
| image_processed=False, | |
| processing_time=0, | |
| error=str(e) | |
| ) | |