Abdullahcoder54's picture
push
6a3de9e
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__)
@router.post("/{user_id}/chat")
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)}")
@router.get("/{user_id}/conversations")
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)}")
@router.get("/{user_id}/conversations/{conversation_id}")
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)}")