File size: 4,658 Bytes
6a3de9e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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)}")