LeoWalker's picture
MCP source
33516f7 verified
Raw History Blame Contribute Delete
1.92 kB
"""FastAPI app for the local demo chat UI.
Start: `uv run python -m src.ui`
"""
from __future__ import annotations
import logging
from pathlib import Path
from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse, Response
from pydantic import BaseModel, Field
from src.ui.service import ChatUIError, arun_chat, health_payload
load_dotenv()
logger = logging.getLogger(__name__)
STATIC_DIR = Path(__file__).resolve().parent / "static"
app = FastAPI(
title="LearningFocused Chat",
description="Local demo UI for tool-backed Q&A with SourceChunk citation cards.",
version="0.1.0",
)
class ChatRequest(BaseModel):
question: str = Field(..., min_length=1)
thread_id: str | None = None
class ChatResponse(BaseModel):
answer: str
sources: list[dict]
thread_id: str
tool_backed: bool
tools_used: list[str]
@app.get("/")
async def index() -> FileResponse:
return FileResponse(STATIC_DIR / "index.html")
@app.get("/favicon.ico")
async def favicon() -> Response:
return Response(status_code=204)
@app.get("/api/health")
async def health() -> dict:
return health_payload()
@app.post("/api/chat", response_model=ChatResponse)
async def chat(body: ChatRequest) -> ChatResponse:
try:
payload = await arun_chat(body.question, thread_id=body.thread_id)
except ChatUIError as exc:
raise HTTPException(
status_code=exc.status_code,
detail={"error": exc.message, "code": exc.code},
) from exc
except Exception as exc: # noqa: BLE001
logger.exception("Chat request failed")
raise HTTPException(
status_code=500,
detail={
"error": "Chat failed. Check the server logs for details.",
"code": "chat_failed",
},
) from exc
return ChatResponse(**payload)