Spaces:
Sleeping
Sleeping
| from fastapi import APIRouter, HTTPException, Depends | |
| from typing import Dict, Any, List, Optional | |
| from uuid import UUID | |
| import logging | |
| import json | |
| from pydantic import BaseModel | |
| from sqlmodel.ext.asyncio.session import AsyncSession | |
| from models.conversation import Conversation, ConversationCreate | |
| from models.message import Message, MessageCreate, MessageRoleEnum | |
| from database.session import get_session_dep | |
| from sqlmodel import select | |
| router = APIRouter(tags=["chat"]) | |
| class ChatRequest(BaseModel): | |
| message: str | |
| conversation_id: Optional[UUID] = None | |
| logger = logging.getLogger(__name__) | |
| async def chat_with_ai( | |
| user_id: str, | |
| request: ChatRequest, | |
| db_session: AsyncSession = Depends(get_session_dep) | |
| ): | |
| """ | |
| Send a message to the AI chatbot and receive a response. | |
| The AI agent will handle tool execution through the MCP server. | |
| """ | |
| try: | |
| # Import inside function to avoid Pydantic schema generation issues at startup | |
| from ai.agents.conversation_manager import ConversationManager | |
| from ai.agents.todo_agent import TodoAgent | |
| # Initialize conversation manager | |
| conversation_manager = ConversationManager(db_session) | |
| # Get or create conversation | |
| if request.conversation_id is None: | |
| conversation = await conversation_manager.create_conversation(user_id) | |
| else: | |
| conversation = await conversation_manager.get_conversation(request.conversation_id) | |
| if not conversation: | |
| # If conversation doesn't exist, create a new one | |
| conversation = await conversation_manager.create_conversation(user_id) | |
| # Add user message to conversation | |
| await conversation_manager.add_message( | |
| conversation_id=conversation.id, | |
| role=MessageRoleEnum.user, | |
| content=request.message | |
| ) | |
| # Initialize AI agent | |
| todo_agent = TodoAgent() | |
| # Process the message with the AI agent | |
| # The agent will handle tool execution internally through the MCP server | |
| result = await todo_agent.process_message(user_id, request.message, conversation) | |
| # Add AI response to conversation | |
| await conversation_manager.add_message( | |
| conversation_id=conversation.id, | |
| role=MessageRoleEnum.assistant, | |
| content=result["response"] | |
| ) | |
| # Update conversation timestamp | |
| await conversation_manager.update_conversation_timestamp(conversation.id) | |
| return result | |
| except Exception as e: | |
| logger.error(f"Error processing chat message: {str(e)}") | |
| raise HTTPException(status_code=500, detail=f"Error processing message: {str(e)}") | |
| async def get_user_conversations( | |
| user_id: str, | |
| db_session: AsyncSession = Depends(get_session_dep) | |
| ): | |
| """ | |
| Get a list of user's conversations. | |
| """ | |
| try: | |
| from ai.agents.conversation_manager import ConversationManager | |
| conversation_manager = ConversationManager(db_session) | |
| conversations = await conversation_manager.get_recent_conversations(user_id) | |
| return conversations | |
| except Exception as e: | |
| logger.error(f"Error getting user conversations: {str(e)}") | |
| raise HTTPException(status_code=500, detail=f"Error retrieving conversations: {str(e)}") | |
| async def get_conversation_history( | |
| user_id: str, | |
| conversation_id: UUID, | |
| db_session: AsyncSession = Depends(get_session_dep) | |
| ): | |
| """ | |
| Get the full history of a specific conversation. | |
| """ | |
| try: | |
| from ai.agents.conversation_manager import ConversationManager | |
| conversation_manager = ConversationManager(db_session) | |
| conversation = await conversation_manager.get_conversation(conversation_id) | |
| # Verify that the conversation belongs to the user | |
| if conversation and conversation.user_id != user_id: | |
| raise HTTPException(status_code=403, detail="Access denied") | |
| if not conversation: | |
| raise HTTPException(status_code=404, detail="Conversation not found") | |
| messages = await conversation_manager.get_conversation_history(conversation_id) | |
| return {"id": conversation_id, "messages": messages} | |
| except HTTPException: | |
| # Re-raise HTTP exceptions as they are | |
| raise | |
| except Exception as e: | |
| logger.error(f"Error getting conversation history: {str(e)}") | |
| raise HTTPException(status_code=500, detail=f"Error retrieving conversation history: {str(e)}") |