dashboard-nanobot/backend/api/dashboard_bot_io_router.py

198 lines
7.7 KiB
Python

from typing import List, Optional
from fastapi import APIRouter, Depends, File, Form, Request, UploadFile, WebSocket
from sqlmodel import Session
from core.database import get_session
from schemas.dashboard import (
CommandRequest,
MessageFeedbackRequest,
WorkspaceFileUpdateRequest,
)
from api.dashboard_router_support import DashboardRouterDeps
def build_dashboard_bot_io_router(*, deps: DashboardRouterDeps) -> APIRouter:
router = APIRouter()
@router.post("/api/bots/{bot_id}/command")
def send_command(bot_id: str, payload: CommandRequest, request: Request, session: Session = Depends(get_session)):
return deps.runtime_service.send_command_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
payload=payload,
)
@router.get("/api/bots/{bot_id}/messages")
def list_bot_messages(bot_id: str, limit: int = 200, session: Session = Depends(get_session)):
return deps.bot_message_service.list_messages(session=session, bot_id=bot_id, limit=limit)
@router.get("/api/bots/{bot_id}/messages/page")
def list_bot_messages_page(bot_id: str, limit: Optional[int] = None, before_id: Optional[int] = None, session: Session = Depends(get_session)):
return deps.bot_message_service.list_messages_page(
session=session,
bot_id=bot_id,
limit=limit,
before_id=before_id,
)
@router.get("/api/bots/{bot_id}/messages/by-date")
def list_bot_messages_by_date(
bot_id: str,
date: str,
tz_offset_minutes: Optional[int] = None,
limit: Optional[int] = None,
session: Session = Depends(get_session),
):
return deps.bot_message_service.list_messages_by_date(
session=session,
bot_id=bot_id,
date=date,
tz_offset_minutes=tz_offset_minutes,
limit=limit,
)
@router.put("/api/bots/{bot_id}/messages/{message_id}/feedback")
def update_bot_message_feedback(bot_id: str, message_id: int, payload: MessageFeedbackRequest, session: Session = Depends(get_session)):
return deps.bot_message_service.update_feedback(
session=session,
bot_id=bot_id,
message_id=message_id,
feedback=payload.feedback,
)
@router.delete("/api/bots/{bot_id}/messages")
def clear_bot_messages(bot_id: str, request: Request, session: Session = Depends(get_session)):
return deps.runtime_service.clear_messages_for_bot(app_state=request.app.state, session=session, bot_id=bot_id)
@router.post("/api/bots/{bot_id}/sessions/dashboard-direct/clear")
def clear_bot_dashboard_direct_session(bot_id: str, request: Request, session: Session = Depends(get_session)):
return deps.runtime_service.clear_dashboard_direct_session_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
)
@router.get("/api/bots/{bot_id}/logs")
def get_bot_logs(bot_id: str, tail: int = 300, request: Request = None, session: Session = Depends(get_session)):
return deps.runtime_service.get_logs_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
tail=tail,
)
@router.get("/api/bots/{bot_id}/workspace/tree")
def get_workspace_tree(bot_id: str, path: Optional[str] = None, recursive: bool = False, request: Request = None, session: Session = Depends(get_session)):
return deps.workspace_service.list_tree_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
path=path,
recursive=recursive,
)
@router.get("/api/bots/{bot_id}/workspace/file")
def read_workspace_file(bot_id: str, path: str, max_bytes: int = 200000, request: Request = None, session: Session = Depends(get_session)):
return deps.workspace_service.read_file_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
path=path,
max_bytes=max_bytes,
)
@router.put("/api/bots/{bot_id}/workspace/file")
def update_workspace_file(bot_id: str, path: str, payload: WorkspaceFileUpdateRequest, request: Request = None, session: Session = Depends(get_session)):
return deps.workspace_service.write_markdown_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
path=path,
content=str(payload.content or ""),
)
@router.get("/api/bots/{bot_id}/workspace/download")
def download_workspace_file(bot_id: str, path: str, download: bool = False, request: Request = None, session: Session = Depends(get_session)):
return deps.workspace_service.serve_file_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
path=path,
download=download,
request=request,
public=False,
redirect_html_to_raw=True,
)
@router.get("/public/bots/{bot_id}/workspace/download")
def public_download_workspace_file(bot_id: str, path: str, download: bool = False, request: Request = None, session: Session = Depends(get_session)):
return deps.workspace_service.serve_file_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
path=path,
download=download,
request=request,
public=True,
redirect_html_to_raw=True,
)
@router.get("/api/bots/{bot_id}/workspace/raw/{path:path}")
def raw_workspace_file(bot_id: str, path: str, download: bool = False, request: Request = None, session: Session = Depends(get_session)):
return deps.workspace_service.serve_file_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
path=path,
download=download,
request=request,
public=False,
redirect_html_to_raw=False,
)
@router.get("/public/bots/{bot_id}/workspace/raw/{path:path}")
def public_raw_workspace_file(bot_id: str, path: str, download: bool = False, request: Request = None, session: Session = Depends(get_session)):
return deps.workspace_service.serve_file_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
path=path,
download=download,
request=request,
public=True,
redirect_html_to_raw=False,
)
@router.post("/api/bots/{bot_id}/workspace/upload")
async def upload_workspace_files(bot_id: str, files: List[UploadFile] = File(...), path: Optional[str] = None, request: Request = None, session: Session = Depends(get_session)):
return await deps.workspace_service.upload_files_for_bot(
app_state=request.app.state,
session=session,
bot_id=bot_id,
files=files,
path=path,
)
@router.post("/api/bots/{bot_id}/speech/transcribe")
async def transcribe_bot_speech(
bot_id: str,
file: UploadFile = File(...),
language: Optional[str] = Form(None),
session: Session = Depends(get_session),
):
return await deps.speech_transcription_service.transcribe(
session=session,
bot_id=bot_id,
file=file,
language=language,
)
@router.websocket("/ws/monitor/{bot_id}")
async def websocket_endpoint(websocket: WebSocket, bot_id: str):
await deps.app_lifecycle_service.handle_websocket(websocket, bot_id)
return router