77 lines
3.0 KiB
Python
77 lines
3.0 KiB
Python
from fastapi import APIRouter, HTTPException, Query, Body, Request
|
|
from fastapi.responses import StreamingResponse
|
|
from typing import Optional, Dict, Any, List
|
|
from pydantic import BaseModel
|
|
|
|
from app.chat_service import (
|
|
list_universe_conversations,
|
|
create_universe_conversation,
|
|
get_conversation_messages,
|
|
stream_chat_messages,
|
|
rename_universe_conversation,
|
|
pin_universe_conversation,
|
|
delete_universe_conversation
|
|
)
|
|
|
|
router = APIRouter(prefix="/api/chat", tags=["Chat"])
|
|
|
|
class CreateConversationRequest(BaseModel):
|
|
title: Optional[str] = "Nouvelle conversation"
|
|
|
|
class UpdateConversationRequest(BaseModel):
|
|
title: Optional[str] = None
|
|
pinned: Optional[bool] = None
|
|
|
|
class SendMessageRequest(BaseModel):
|
|
message: str
|
|
|
|
@router.get("/{universe_id}/conversations")
|
|
async def get_conversations(universe_id: str):
|
|
"""Returns the list of conversations for a universe."""
|
|
convs = await list_universe_conversations(universe_id)
|
|
return {"ok": True, "universe_id": universe_id, "conversations": convs}
|
|
|
|
@router.post("/{universe_id}/conversations")
|
|
async def create_conversation(universe_id: str, body: CreateConversationRequest = Body(default_factory=CreateConversationRequest)):
|
|
"""Creates a new conversation in a universe."""
|
|
conv = await create_universe_conversation(universe_id, title=body.title)
|
|
return {"ok": True, "conversation": conv}
|
|
|
|
@router.get("/{universe_id}/conversations/{session_key}/messages")
|
|
async def get_messages(universe_id: str, session_key: str):
|
|
"""Retrieves full message history for a conversation."""
|
|
messages = await get_conversation_messages(universe_id, session_key)
|
|
return {"ok": True, "session_key": session_key, "messages": messages}
|
|
|
|
@router.post("/{universe_id}/conversations/{session_key}/send")
|
|
async def send_message(universe_id: str, session_key: str, body: SendMessageRequest):
|
|
"""Sends a message and streams SSE chunks back."""
|
|
if not body.message or not body.message.strip():
|
|
raise HTTPException(status_code=400, detail="Message cannot be empty")
|
|
|
|
stream = stream_chat_messages(universe_id, session_key, body.message.strip())
|
|
return StreamingResponse(
|
|
stream,
|
|
media_type="text/event-stream",
|
|
headers={
|
|
"Cache-Control": "no-cache",
|
|
"Connection": "keep-alive",
|
|
"X-Accel-Buffering": "no"
|
|
}
|
|
)
|
|
|
|
@router.patch("/{universe_id}/conversations/{session_key}")
|
|
async def update_conv(universe_id: str, session_key: str, body: UpdateConversationRequest):
|
|
"""Updates conversation title or pinned status."""
|
|
if body.title is not None:
|
|
await rename_universe_conversation(universe_id, session_key, body.title)
|
|
if body.pinned is not None:
|
|
await pin_universe_conversation(universe_id, session_key, body.pinned)
|
|
return {"ok": True}
|
|
|
|
@router.delete("/{universe_id}/conversations/{session_key}")
|
|
async def delete_conv(universe_id: str, session_key: str):
|
|
"""Deletes a conversation."""
|
|
await delete_universe_conversation(universe_id, session_key)
|
|
return {"ok": True}
|