CoolFace
Modelpublic

aigenrec/luminabackend

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
chat.py168 linesDownload Raw Back to endpoints
1from fastapi import APIRouter, HTTPException, Depends2from fastapi.responses import StreamingResponse3from services.rag_service import rag_service4from models.schemas import ChatRequest, ChatResponse, ChatMessage5from typing import Any, List6from api.deps import get_current_user7from db.client import supabase_client8 9router = APIRouter()10 11@router.get("/history/{project_id}", response_model=List[ChatMessage])12async def get_chat_history(13    project_id: str,14    current_user: dict = Depends(get_current_user)15):16    """17    Get chat history for a project18    """19    try:20        # Verify access (simple check or RLS)21        response = supabase_client.table("chat_messages")\22            .select("*")\23            .eq("project_id", project_id)\24            .order("created_at", desc=False)\25            .execute()26            27        return [28            ChatMessage(role=msg["role"], content=msg["content"]) 29            for msg in response.data30        ]31    except Exception as e:32        raise HTTPException(500, str(e))33 34@router.post("/message", response_model=ChatResponse)35async def chat_message(36    request: ChatRequest,37    current_user: dict = Depends(get_current_user)38):39    """40    Send a message to the RAG chat (Blocking/Non-streaming)41    """42    try:43        # Save User Message44        supabase_client.table("chat_messages").insert({45            "project_id": request.project_id,46            "role": "user",47            "content": request.message48        }).execute()49 50        # Fetch full history for context51        history_res = supabase_client.table("chat_messages")\52            .select("*")\53            .eq("project_id", request.project_id)\54            .order("created_at", desc=False)\55            .execute()56            57        chat_history_dicts = [58            {"role": msg["role"], "content": msg["content"]} 59            for msg in history_res.data60        ]61        62        result = await rag_service.get_answer(63            project_id=request.project_id,64            question=request.message,65            selected_documents=request.selected_documents,66            chat_history=chat_history_dicts[:-1] # Exclude current msg to avoid duplication if RAG appends it67        )68        69        # Save Assistant Message70        supabase_client.table("chat_messages").insert({71            "project_id": request.project_id,72            "role": "assistant",73            "content": result["answer"],74            "sources": result["sources"]75        }).execute()76        77        return result78        79    except Exception as e:80        raise HTTPException(500, str(e))81 82@router.post("/stream")83async def chat_stream(84    request: ChatRequest,85    current_user: dict = Depends(get_current_user)86):87    """88    Send a message to the RAG chat (Streaming)89    """90    try:91        # Save User Message92        supabase_client.table("chat_messages").insert({93            "project_id": request.project_id,94            "role": "user",95            "content": request.message96        }).execute()97 98        # Fetch full history99        history_res = supabase_client.table("chat_messages")\100            .select("*")\101            .eq("project_id", request.project_id)\102            .order("created_at", desc=False)\103            .execute()104            105        chat_history_dicts = [106            {"role": msg["role"], "content": msg["content"]} 107            for msg in history_res.data108        ]109        110        # Wrapper generator to intercept and save the final answer111        async def stream_and_save():112            full_answer = ""113            sources = []114            115            async for chunk in rag_service.get_answer_stream(116                project_id=request.project_id,117                question=request.message,118                selected_documents=request.selected_documents,119                chat_history=chat_history_dicts[:-1]120            ):121                # Check for sources marker122                if "__SOURCES__:" in chunk:123                    parts = chunk.split("__SOURCES__:")124                    full_answer += parts[0]125                    yield parts[0] # Send final text part126                    127                    # Process sources128                    try:129                        import json130                        sources = json.loads(parts[1])131                    except: pass132                    133                    yield chunk # Forward the marker to frontend134                else:135                    full_answer += chunk136                    yield chunk137            138            # Save Assistant Message after stream ends139            try:140                supabase_client.table("chat_messages").insert({141                    "project_id": request.project_id,142                    "role": "assistant",143                    "content": full_answer,144                    "sources": sources145                }).execute()146            except Exception as save_err:147                print(f"Failed to save assistant message: {save_err}")148 149        return StreamingResponse(150            stream_and_save(),151            media_type="text/event-stream"152        )153    except Exception as e:154        raise HTTPException(500, str(e))155 156@router.get("/summary/{project_id}", response_model=ChatResponse)157async def get_project_summary(158    project_id: str,159    current_user: dict = Depends(get_current_user)160):161    """162    Generate a summary for the project documents163    """164    try:165        result = await rag_service.generate_summary(project_id)166        return result167    except Exception as e:168        raise HTTPException(500, str(e))