132 lines
4.3 KiB
Python
132 lines
4.3 KiB
Python
"""
|
|
Chat Playground routes for the backend API.
|
|
Implements the endpoints for chat playground workflow management.
|
|
"""
|
|
|
|
import logging
|
|
from typing import Optional, Dict, Any
|
|
from fastapi import APIRouter, HTTPException, Depends, Body, Path, Query, Request
|
|
from datetime import datetime
|
|
|
|
# Import auth modules
|
|
from modules.security.auth import limiter, getCurrentUser
|
|
|
|
# Import interfaces
|
|
import modules.interfaces.interfaceChatObjects as interfaceChatObjects
|
|
from modules.interfaces.interfaceChatObjects import getInterface
|
|
|
|
# Import models
|
|
from modules.interfaces.interfaceChatModel import (
|
|
ChatWorkflow,
|
|
UserInputRequest
|
|
)
|
|
from modules.interfaces.interfaceAppModel import User
|
|
|
|
# Import workflow control functions
|
|
from modules.features.chatPlayground.mainChatPlayground import chatStart, chatStop
|
|
|
|
# Configure logger
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Create router for chat playground endpoints
|
|
router = APIRouter(
|
|
prefix="/api/chat/playground",
|
|
tags=["Chat Playground"],
|
|
responses={404: {"description": "Not found"}}
|
|
)
|
|
|
|
def getServiceChat(currentUser: User):
|
|
return interfaceChatObjects.getInterface(currentUser)
|
|
|
|
# Workflow start endpoint
|
|
@router.post("/start", response_model=ChatWorkflow)
|
|
@limiter.limit("120/minute")
|
|
async def start_workflow(
|
|
request: Request,
|
|
workflowId: Optional[str] = Query(None, description="Optional ID of the workflow to continue"),
|
|
userInput: UserInputRequest = Body(...),
|
|
currentUser: User = Depends(getCurrentUser)
|
|
) -> ChatWorkflow:
|
|
"""
|
|
Starts a new workflow or continues an existing one.
|
|
Corresponds to State 1 in the state machine documentation.
|
|
"""
|
|
try:
|
|
# Get service center
|
|
interfaceChat = getServiceChat(currentUser)
|
|
|
|
# Start or continue workflow using playground controller
|
|
workflow = await chatStart(interfaceChat, currentUser, userInput, workflowId)
|
|
|
|
return workflow
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in start_workflow: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=str(e)
|
|
)
|
|
|
|
# State 8: Workflow Stopped endpoint
|
|
@router.post("/{workflowId}/stop", response_model=ChatWorkflow)
|
|
@limiter.limit("120/minute")
|
|
async def stop_workflow(
|
|
request: Request,
|
|
workflowId: str = Path(..., description="ID of the workflow to stop"),
|
|
currentUser: User = Depends(getCurrentUser)
|
|
) -> ChatWorkflow:
|
|
"""Stops a running workflow."""
|
|
try:
|
|
# Get service center
|
|
interfaceChat = getServiceChat(currentUser)
|
|
|
|
# Stop workflow using playground controller
|
|
workflow = await chatStop(interfaceChat, currentUser, workflowId)
|
|
|
|
return workflow
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in stop_workflow: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=str(e)
|
|
)
|
|
|
|
# Unified Chat Data Endpoint for Polling
|
|
@router.get("/{workflowId}/chatData")
|
|
@limiter.limit("120/minute")
|
|
async def get_workflow_chat_data(
|
|
request: Request,
|
|
workflowId: str = Path(..., description="ID of the workflow"),
|
|
afterTimestamp: Optional[float] = Query(None, description="Unix timestamp to get data after"),
|
|
currentUser: User = Depends(getCurrentUser)
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Get unified chat data (messages, logs, stats) for a workflow with timestamp-based selective data transfer.
|
|
Returns all data types in chronological order based on _createdAt timestamp.
|
|
"""
|
|
try:
|
|
# Get service center
|
|
interfaceChat = getServiceChat(currentUser)
|
|
|
|
# Verify workflow exists
|
|
workflow = interfaceChat.getWorkflow(workflowId)
|
|
if not workflow:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail=f"Workflow with ID {workflowId} not found"
|
|
)
|
|
|
|
# Get unified chat data using the new method
|
|
chatData = interfaceChat.getUnifiedChatData(workflowId, afterTimestamp)
|
|
|
|
return chatData
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error getting unified chat data: {str(e)}", exc_info=True)
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Error getting unified chat data: {str(e)}"
|
|
)
|