86 lines
3.2 KiB
Python
86 lines
3.2 KiB
Python
"""
|
|
===============================================================================
|
|
FILE: modules/web_api/routers/chat.py
|
|
PROJECT: SCUD Orion AI (Unified Architecture)
|
|
MODULE: web_api / routers
|
|
ROLE: Маршрутизация диалогов с LLM и эндпоинт сохранения онлайн-черновиков.
|
|
===============================================================================
|
|
"""
|
|
|
|
# ANCHOR[CHAT_ROUTER_IMPORTS]
|
|
from typing import Optional, Dict, Any
|
|
from fastapi import APIRouter, Depends, UploadFile, File, Form, HTTPException
|
|
from pydantic import BaseModel
|
|
|
|
from .auth import get_current_user
|
|
from llm.agent import process_chat_message
|
|
from llm.file_parser import extract_text_from_file
|
|
from llm.db_tools import db_set_session_state, db_get_session_state
|
|
|
|
router = APIRouter(prefix="/api/v1/chat", tags=["chat"])
|
|
|
|
|
|
# ANCHOR[DRAFT_SCHEMA]
|
|
class UpdateDraftRequest(BaseModel):
|
|
session_id: str
|
|
draft_text: str
|
|
|
|
|
|
# ANCHOR[CHAT_ENDPOINTS]
|
|
@router.post("")
|
|
async def chat_endpoint(
|
|
session_id: str = Form("web_session_main"),
|
|
message: str = Form(""),
|
|
file: Optional[UploadFile] = File(default=None),
|
|
current_user: Dict[str, Any] = Depends(get_current_user)
|
|
):
|
|
"""Диалог авторизованного пользователя с агентом."""
|
|
parsed_file = {"text": "", "image_b64": None}
|
|
if file and file.filename:
|
|
file_bytes = await file.read()
|
|
parsed_file = extract_text_from_file(file_bytes, file.filename)
|
|
|
|
reply, history, action_type = process_chat_message(
|
|
user_id=current_user["id"],
|
|
user_message=message,
|
|
file_context=parsed_file["text"],
|
|
image_b64=parsed_file["image_b64"],
|
|
session_id=session_id
|
|
)
|
|
return {"reply": reply, "history": history, "action_type": action_type}
|
|
|
|
|
|
@router.post("/guest")
|
|
async def guest_chat_endpoint(
|
|
session_id: str = Form("web_session_main"),
|
|
message: str = Form(""),
|
|
file: Optional[UploadFile] = File(default=None)
|
|
):
|
|
"""Гостевой диалог (user_id=0)."""
|
|
parsed_file = {"text": "", "image_b64": None}
|
|
if file and file.filename:
|
|
file_bytes = await file.read()
|
|
parsed_file = extract_text_from_file(file_bytes, file.filename)
|
|
|
|
reply, history, action_type = process_chat_message(
|
|
user_id=0,
|
|
user_message=message,
|
|
file_context=parsed_file["text"],
|
|
image_b64=parsed_file["image_b64"],
|
|
session_id=session_id
|
|
)
|
|
return {"reply": reply, "history": history, "action_type": action_type}
|
|
|
|
|
|
@router.post("/draft")
|
|
def update_draft_endpoint(
|
|
req: UpdateDraftRequest,
|
|
current_user: Dict[str, Any] = Depends(get_current_user)
|
|
):
|
|
"""Обновляет черновик системного промпта напрямую из интерактивной онлайн-формы."""
|
|
state = db_get_session_state(req.session_id)
|
|
if not state or state.get("state_type") != "PROMPT_PREVIEW":
|
|
raise HTTPException(status_code=400, detail="Нет активного превью для редактирования")
|
|
|
|
db_set_session_state(req.session_id, "PROMPT_PREVIEW", {"draft_text": req.draft_text.strip()})
|
|
return {"status": "success", "message": "Черновик успешно обновлен в сессии"} |