Luxx/luxx/api/rooms.py

157 lines
4.6 KiB
Python

"""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"
}
)