"""Chat Room API Routes""" from typing import List, Optional from fastapi import APIRouter, HTTPException from pydantic import BaseModel from luxx.services.room import chat_room_service router = APIRouter(prefix="/chat-rooms", tags=["chat-rooms"]) class CreateChatRoomRequest(BaseModel): name: str description: Optional[str] = None agent_ids: Optional[List[str]] = None class UpdateChatRoomRequest(BaseModel): name: Optional[str] = None description: Optional[str] = None is_active: Optional[bool] = None class SendMessageRequest(BaseModel): content: str class AddAgentRequest(BaseModel): agent_id: str def get_current_user_id() -> int: """Get current user ID from auth context""" return 1 @router.get("") async def list_chat_rooms(): """List all chat rooms""" user_id = get_current_user_id() rooms = chat_room_service.list_rooms(user_id=user_id) return {"rooms": rooms} @router.post("") async def create_chat_room(request: CreateChatRoomRequest): """Create a new chat room""" user_id = get_current_user_id() room = chat_room_service.create_room( name=request.name, owner_id=user_id, description=request.description, agent_ids=request.agent_ids ) return {"room": room} @router.get("/{room_id}") async def get_chat_room(room_id: str): """Get a chat room by ID""" room = chat_room_service.get_room(room_id) if not room: raise HTTPException(status_code=404, detail="Chat room not found") return {"room": room.to_dict(include_agents=True)} @router.put("/{room_id}") async def update_chat_room(room_id: str, request: UpdateChatRoomRequest): """Update a chat room""" room = chat_room_service.update_room( room_id=room_id, name=request.name, description=request.description, is_active=request.is_active ) if not room: raise HTTPException(status_code=404, detail="Chat room not found") return {"room": room} @router.delete("/{room_id}") async def delete_chat_room(room_id: str): """Delete a chat room""" success = chat_room_service.delete_room(room_id) if not success: raise HTTPException(status_code=404, detail="Chat room not found") return {"success": True} @router.get("/{room_id}/agents") async def get_room_agents(room_id: str): """Get all agents in a chat room""" agents = chat_room_service.get_room_agents(room_id) return {"agents": [a.to_dict() for a in agents]} @router.post("/{room_id}/agents") async def add_agent_to_room(room_id: str, request: AddAgentRequest): """Add an agent to a chat room""" success = chat_room_service.add_agent_to_room(room_id, request.agent_id) if not success: raise HTTPException(status_code=400, detail="Failed to add agent") return {"success": True} @router.delete("/{room_id}/agents/{agent_id}") async def remove_agent_from_room(room_id: str, agent_id: str): """Remove an agent from a chat room""" success = chat_room_service.remove_agent_from_room(room_id, agent_id) if not success: raise HTTPException(status_code=404, detail="Agent not found in room") return {"success": True} @router.get("/{room_id}/messages") async def get_room_messages(room_id: str, limit: int = 50, before_id: str = None): """Get messages from a chat room""" messages = chat_room_service.get_messages(room_id, limit=limit, before_id=before_id) return {"messages": messages} @router.post("/{room_id}/messages") async def send_message(room_id: str, request: SendMessageRequest): """Send a message to a chat room. Returns a streaming response via SSE.""" from fastapi.responses import StreamingResponse import json user_id = str(get_current_user_id()) user_name = "User" async def generate(): async for event in chat_room_service.process_message( room_id=room_id, user_message=request.content, user_id=user_id, user_name=user_name ): if event.get("event") in ["process_step", "done"]: chat_room_service.save_message( room_id=room_id, sender_type="user", sender_id=user_id, sender_name=user_name, content=request.content ) yield f"data: {json.dumps(event, ensure_ascii=False)}\n\n" return StreamingResponse( generate(), media_type="text/event-stream", headers={ "Cache-Control": "no-cache", "Connection": "keep-alive", "X-Accel-Buffering": "no" } )